终端仿真器中似乎有一些行与行的概念,我想了解更多。
演示我所说的行与行的意思
下面的 Python 脚本显示三行“a”并等待,然后显示三行“b”。
import sys, struct, fcntl, termios
write = sys.stdout.write
def clear_screen(): write('\x1b[2J')
def move_cursor(row, col): write('\x1b['+str(row)+';'+str(col)+'H')
def current_width(): #taken from blessings so this example doesn't have dependencies
return struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, '\000' * 8))[1]
clear_screen()
for c in 'ab':
#clear_screen between loops changes this behavior
width = current_width()
move_cursor(5, 1)
write(c*width+'\n')
move_cursor(6, 1)
write(c*width+'\n')
move_cursor(7, 1)
write(c*width+'\n')
sys.stdout.flush()
try: input() # pause and wait for ENTER in python 2 and 3
except: pass
如果在此中断期间将终端窗口宽度缩小一个字符,您会看到
这似乎很合理——每一行都被单独包装。当我们再次按回车键打印b
s 时,
一切都按预期工作。我使用了绝对光标定位,并写入了我之前写入的相同行——这当然不会覆盖所有的 a,因为它们中的许多都在其他行上。
但是,当我们将窗口再缩小一个字符时,换行的工作方式会有所不同:
为什么第二行和第三行b
wrap在一起,为什么'的最后一行a
和b'的第一行合并了?为什么在上面可见的顶部行中给出了一个提示——我们看到了两个a
,因为它们的两行仍然是链接的——当然,如果我们再次移动窗口,那一行将继续以相同的方式换行。即使对于我们替换了一整行的行,这似乎也在发生。
事实证明,之前包装的行现在链接到它们相应的父行;更明显的是,一旦我们将终端扩大很多,它们属于同一条逻辑线:
我的问题
实际上,我的问题是如何防止或预测这些行组合成行。清除整个屏幕可以消除这种行为,但如果可能的话,最好只对需要它的个别行执行此操作,这样我就可以按行保持缓存,这显着加快了我的应用程序。清除到行尾会取消该行与其下方行的链接,但清除到行首不会取消该行与其上方行的链接。
我很好奇 - 这些线是什么?我在哪里可以了解它们?我可以找出哪些行是同一行的一部分吗?
我已经使用 terminal.app 和 iterm 观察到了这种行为,使用和不使用 tmux。我想即使没有规范,深入研究其中任何一个都会产生答案——但我想某处有规范!
背景:我想制作一个终端用户界面,如果用户减小窗口宽度,它可以预测终端换行的方式。我知道全屏模式( ncurses 使用的 'tput smcup
或python -c 'print "\x1b[?1049h"
')之类的东西可以防止换行,但不想在这里使用它。
编辑:更清楚地表明我已经了解脚本的覆盖行为并想要解释包装行为。