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

时间:2015-07-22 22:52:59

标签: vim ncurses tty

当您输入vim时,它会“清除”屏幕。退出后,它“恢复”原始内容。

我知道可以使用\x1b[2J清除控制台并重置光标位置,但这会覆盖终端内容。

我认为Vim使用了ncurses,在这种情况下我认为更好的问题是ncurses如何做到这一点,但它是如何完成的?

2 个答案:

答案 0 :(得分:10)

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

  • vim不使用自动发送smcuprmcup的ncurses的屏幕优化。相反,它是termcap application遵循大多数(并非所有)termcap应用程序使用的约定。有些vi的实现并不是(例如,在IRIX64上)。
  • 至于#34;大多数终端" - 实际上,xterm看起来相似只是terminal database的一小部分(即使计算变化,小于10%)。将其改为类似" Linux上最常见的终端模拟器。
  • 终端保存恢复屏幕内容。相反,它在两个屏幕之间切换(在xterm的文档中#34;正常""替代")。例如,在xterm中,可以使用菜单条目在两者之间切换。 xterm常见问题 Why doesn't the screen clear when running vi? 提供了更多详细信息。
  • 为了获得更好的上下文,请注意smcup set-mode-cursor-positioning 开始光标定位模式的(模糊)缩写。 (还有游标寻址)。 r中的rmcup表示"重置" (m表示"模式")。 set / reset与save / restore有不同的含义;使用后者,用户可以相信价值可以叠加。

答案 1 :(得分:8)

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

为此,terminfo代码为smcup以进入全屏模式,rmcup将其保留。 (较旧的termcap代码为tite。)

如果在terminfo数据库中启用了这些功能,则使用ncurses的任何程序都会在输入时打印smcup字符串,并在退出时打印rmcup字符串。 / p>

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

smcup: \E7\E[?1;47h
rmcup: \E[2J\E[?1;47l\E8

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

序列的具体含义(对于xterm)是documented here

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

(这假设我正确理解分号的使用;我并非100%肯定。)