【发布时间】:2015-07-22 22:52:58
【问题描述】:
当您输入vim 时,它会“清除”屏幕。退出后,它会“恢复”原始内容。
我知道可以使用\x1b[2J 清除控制台并重置光标位置,但这会覆盖终端内容。
我假设 Vim 在后台使用 ncurses,在这种情况下,我想更好的问题是 ncurses 是如何做到这一点的,但它是如何做到的?
【问题讨论】:
当您输入vim 时,它会“清除”屏幕。退出后,它会“恢复”原始内容。
我知道可以使用\x1b[2J 清除控制台并重置光标位置,但这会覆盖终端内容。
我假设 Vim 在后台使用 ncurses,在这种情况下,我想更好的问题是 ncurses 是如何做到这一点的,但它是如何做到的?
【问题讨论】:
关于@Keith Thompson 的回答——不完全是:
smcup 和rmcup 的ncurses 的屏幕优化。相反,它是termcap application。它遵循大多数(不是全部)termcap 应用程序使用的约定。 vi 的一些实现例如没有(可能在 IRIX64 上)。smcup 是set-mode-cursor-positioning 或start cursor-positioning mode 的(晦涩)缩写。 (也是光标寻址)。 rmcup 中的 r 表示“重置”(m 表示“模式”)。设置/重置与保存/恢复有不同的内涵;后者会让用户相信这些值可以叠加。【讨论】:
大多数终端模拟器都能够保存和恢复屏幕内容。
用于此的 terminfo 代码是 smcup 进入全屏模式和 rmcup 离开它。 (旧的 termcap 代码是 ti 和 te。)
如果在terminfo 数据库中启用了这些功能,则任何使用ncurses 的程序都会在进入时打印smcup 字符串,并在退出时打印rmcup 字符串。
在我目前使用的系统上,字符串是(\E 代表转义字符):
smcup: \E7\E[?1;47h
rmcup: \E[2J\E[?1;47l\E8
这将恢复屏幕的先前内容以及光标位置。
序列的具体含义(对于xterm)是documented here:
\E7保存光标\E[?1;47h 应用程序光标键;使用备用屏幕缓冲区\E[2J擦除屏幕\E[?1;47l 应用程序光标键;使用普通屏幕缓冲区\E8 恢复光标(假设我正确理解了分号的用法;我不是 100% 确定这一点。)