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

What mechanism allows ViM to temporarily overwrite the entire console?

当您输入 vim 时,它会 "clears" 屏幕。退出后,它"restores"原来的内容。

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

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

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

这个的术语信息代码是 smcup 进入全屏模式和 rmcup 离开它。 (较旧的 termcap 代码是 tite。)

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

在我目前使用的系统上,字符串是(\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% 确定。)

关于 @Keith Thompson 的回答——不完全是:

  • vim 不使用自动发送 smcuprmcup 的 ncurses 屏幕优化。相反,它是一个 termcap application。它遵循 大多数(不是所有)termcap 应用程序使用的约定。 vi 的一些实现没有,例如(可能在 IRIX64 上)。
  • 至于 "most terminals" — 实际上,xterm 的相似之处只是 terminal database 的一小部分(即使算上变化,也不到 10%)。将其改写为“Linux 上最常见的终端仿真器”。
  • 终端不保存恢复屏幕内容。相反,它会在 两个屏幕之间切换(在 xterm 的文档 "normal" 和 "alternate" 中)。例如,在 xterm 中,总是可以使用菜单项在两者之间切换。 xterm FAQ Why doesn't the screen clear when running vi? 提供了更多详细信息。
  • 为了更好的上下文,请注意 smcupset-mode-cursor-positioningstart cursor- 的(晦涩)缩写定位模式。 (还有 游标寻址)。 rmcup 中的 r 表示 "reset"(而 m 表示 "mode")。 set/reset与save/restore的含义不同;后者会让用户相信这些值可以叠加。