【问题标题】:What mechanism allows ViM to temporarily overwrite the entire console?什么机制允许 ViM 临时覆盖整个控制台?
【发布时间】:2015-07-22 22:52:58
【问题描述】:

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

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

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

【问题讨论】:

    标签: vim ncurses tty


    【解决方案1】:

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

    • vim 不使用自动发送smcuprmcup 的ncurses 的屏幕优化。相反,它是termcap application。它遵循大多数(不是全部)termcap 应用程序使用的约定。 vi 的一些实现例如没有(可能在 IRIX64 上)。
    • 至于“大多数终端”——实际上,xterm 相似只是terminal database 的一小部分(即使计算变化,不到 10%)。将其改写为“Linux 上最常见的终端模拟器”。
    • 终端不保存恢复屏幕内容。相反,它在两个屏幕之间切换(在 xterm 的文档中为“正常”和“备用”)。例如,在 xterm 中,总是可以使用菜单条目在两者之间切换。 xterm 常见问题解答 Why doesn't the screen clear when running vi? 提供了更多详细信息。
    • 为了获得更好的上下文,请注意smcupset-mode-cursor-positioningstart cursor-positioning mode 的(晦涩)缩写。 (也是光标寻址)。 rmcup 中的 r 表示“重置”(m 表示“模式”)。设置/重置与保存/恢复有不同的内涵;后者会让用户相信这些值可以叠加。

    【讨论】:

      【解决方案2】:

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

      用于此的 terminfo 代码是 smcup 进入全屏模式和 rmcup 离开它。 (旧的 termcap 代码是 tite。)

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

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

      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% 确定这一点。)

      【讨论】:

      • 学到了一些新东西。这解释了很多;谢谢。
      • 在 smcup/rmcup 中通常不会设置应用程序光标键 - 大多数程序假定它是在初始化字符串 (is2) 中完成的。例如,参见 ncurses 终端数据库中的 putty。当然,模式 47 早已被 xterm 淘汰(自 1998 起)。
      • @ThomasDickey:显然我的 termcap/terminfo 条目已经过时(这并不奇怪)。感谢您的信息。我会做一些研究并立即更新我的答案。
      • 试试echo -e '\E7\E[?1;47h'echo -e '\E[2J\E[?1;47l\E8'
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 2016-02-18
      • 2020-04-04
      相关资源
      最近更新 更多