什么机制允许ViM临时覆盖整个控制台?

Qix*_*Qix 9 vim ncurses tty

当你输入vim时,它会"清除"屏幕.退出时,它"恢复"原始内容.

我理解可以\x1b[2J用来清除控制台并重置光标位置,但这会覆盖终端内容.

我假设Vim 在引擎盖下使用ncurses,在这种情况下我想更好的问题是ncurses如何做到这一点,但它是如何完成的?

Tho*_*key 11

关于@Keith Thompson的答案- 不完全是:

  • Vim不使用它发送的ncurses的画面优化smcuprmcup自动.相反,它是一个termcap应用程序.它遵循大多数(并非所有)termcap应用程序使用的约定.有一些实现vi不是(例如,在IRIX64上).
  • 至于"大多数终端" - 实际上,xterm look-alikes是终端数据库的一小部分(即使计算变化,不到10%).将其改为"Linux上最常见的终端模拟器".
  • 终端不保存恢复屏幕内容.相反,它两个屏幕之间切换(在xterm的文档中为"normal"和"alternate").例如,在xterm中,可以使用菜单条目在两者之间切换.xterm常见问题为什么运行vi时屏幕不清晰?提供更多细节.
  • 为了更好的上下文,请注意这smcupset-mode-cursor-positioning开始光标定位模式的(模糊)缩写.(还有光标寻址).的rrmcup装置"复位"(和m表示"模式").set/reset与save/restore有不同的含义; 对于后者,用户被认为可以堆积价值.


Kei*_*son 10

大多数终端仿真器都能够保存和恢复屏幕内容.

对此的terminfo代码是smcup进入全屏模式并rmcup离开它.(较旧的termcap代码是tite.)

如果在terminfo数据库中启用了这些功能,则使用的任何程序都ncursessmcup在条目上打印字符串,并rmcup在退出时打印字符串.

在我正在使用的系统上,字符串是(\E代表Escape字符):

smcup: \E7\E[?1;47h
rmcup: \E[2J\E[?1;47l\E8
Run Code Online (Sandbox Code Playgroud)

这将恢复屏幕的先前内容以及光标位置.

该序列(xterm中)的具体含义记录在这里:

  • smcup:
    • \E7 保存光标
    • \E[?1;47h应用程序游标键; 使用备用屏幕缓冲区
  • rmcup:
    • \E[2J 擦除屏幕
    • \E[?1;47l应用程序游标键; 使用普通屏幕缓冲区
    • \E8 恢复光标

(这假设我正确理解分号的使用;我不是百分之百确定.)

  • 通常不在smcup/rmcup中设置应用程序光标键 - 大多数程序都假定它是在初始化字符串(is2)中完成的.请参阅ncurses终端数据库中的[putty](http://invisible-island.net/ncurses/terminfo.src.html#tic-putty).当然,模式47早已被xterm淘汰(自[1998](http://invisible-island.net/xterm/xterm.log.html#xterm_90)). (2认同)