我偶然发现一个有趣的问题
在 Windows 中:
C:\> lua
> print("\x1b[95mMagenta\x1b[0m")
-[95mMagenta-[0m
但如果我跑os.execute()
即使使用空命令,
在此之前,它按预期工作:
C:\> lua
> os.system(""); print("\x1b[95mMagenta\x1b[0m")
Magenta
(最后一行用洋红色打印)
为什么会发生这种情况,以及如何使 ANSI 代码正常工作
不打电话os.execute()
?
为了使 ANSI 代码在控制台中工作,您应该设置特定的ENABLE_VIRTUAL_TERMINAL_PROCESSING
通过调用WinAPI函数进入模式SetConsoleMode
.
当你调用os.execute()
在Lua中,Lua调用C运行时函数system()
,这会创建cmd.exe
进程,它初始化所有的花里胡哨的东西。
但是 Lua 当然不知道 Windows 控制台功能;它仅适用于具有默认设置的控制台。
UPDATE:
这是如何从 LuaJIT 脚本打开 ANSI 转义序列的示例:
local ffi = require"ffi"
ffi.cdef[[
typedef int BOOL;
static const int INVALID_HANDLE_VALUE = -1;
static const int STD_OUTPUT_HANDLE = -11;
static const int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;
intptr_t GetStdHandle(int nStdHandle);
BOOL GetConsoleMode(intptr_t hConsoleHandle, int* lpMode);
BOOL SetConsoleMode(intptr_t hConsoleHandle, int dwMode);
]]
local console_handle = ffi.C.GetStdHandle(ffi.C.STD_OUTPUT_HANDLE)
assert(console_handle ~= ffi.C.INVALID_HANDLE_VALUE)
local prev_console_mode = ffi.new"int[1]"
assert(ffi.C.GetConsoleMode(console_handle, prev_console_mode) ~= 0, "This script must be run from a console application")
local function turn_VT(on_off)
assert(ffi.C.SetConsoleMode(console_handle, bit.bor(prev_console_mode[0], on_off and ffi.C.ENABLE_VIRTUAL_TERMINAL_PROCESSING or 0)) ~= 0)
end
print('\x1b[95mMagenta\x1b[m')
turn_VT(true)
print('\x1b[95mMagenta\x1b[m')
turn_VT(false)
print('\x1b[95mMagenta\x1b[m')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)