木匣子

Web/Game/Programming/Life etc.

Lua> io.write("\27[2J")

Programming in Lua 第六章 More About Function 开头有一个例子。它在终端屏幕上输出一个用*号组成的正弦曲线:

function eraseTerminal()
	io.write("\27\[2J")
end
-- writes an `*' at column \`x' , row \`y'
function mark (x,y)
	io.write(string.format(**"\\27\[%d;%dH*"**, y, x))
end
-- Terminal size
TermSize = {w = 80, h = 24}

-- plot a function
-- (assume that domain and image are in the range \[-1,1\])
function plot (f)
	eraseTerminal()
	for i=1,TermSize.w do
		local x = (i/TermSize.w)*2 - 1
		local y = (f(x) + 1)/2 * TermSize.h
		mark(i, y)
	end
	io.read() -- wait before spoiling the screen
end

plot(function (x) return math.sin(x\*2\*math.pi) end)

这段看似没什么稀奇的 example code 里第二行的 “\27[2J” 和第七行的 “\27[%d;%dH” 吸引了我。 我在 Lua 解释器的交互模式下,动手试了一下 :

io.write("\27\[2J")

屏幕被清空了,就好像在终端里执行了 clear 一样!而根据注释说明:

io.write(string.format("\27\[%d;%dH*", y, x))

这段代码的用途就是在屏幕的第y行,第x列打印一个 * 号。 这个神奇的 \27 打头的字符串是什么东西呢?\27 在 ascii 码表示的是 ,但这和终端又有什么关系? 经过一番搜索,在 google 的帮助下终于找到源头:Terminal codes - http://wiki.bash-hackers.org/scripting/terminalcodes

Terminal (control-)codes are needed to give specific commands to your terminal. This can be related to switching colors or positioning the cursor, simply everything that can’t be done by the application itself.

这是一种用来控制终端界面的指令,可以改变光标所在的位置和颜色——那些CLI程序无法完成的事情。 在另一份代码中,我找一了一个封装好的终端控制代码。更直观了说明了 Terminal codes 的作用: https://bitbucket.org/lmb/diluculum/src/44c52aec561b/Lua/ANSITerminal.lua