【问题标题】:How does vi restore terminal content after quitting it?vi退出后如何恢复终端内容?
【发布时间】:2020-05-08 04:12:38
【问题描述】:

像 vi 或 man 这样的程序或任何其他程序如何将终端内容替换为程序自己的内容,然后在退出这些程序后又带回旧的终端内容?

【问题讨论】:

  • 通过向终端(xterm、vt-220)或ncurses(如mc)发送控制序列,请参阅此问题:stackoverflow.com/questions/8476332/…
  • 我阅读了那个问题,但我仍然无法确定可以发送到终端的控制序列。我正在使用 Solaris 11.0。

标签: linux unix


【解决方案1】:

Vi 翻转到终端支持的备用屏幕缓冲区。这是使用转义序列实现的。详情请参阅this link

它们的 termcap 条目是“ti”进入,“te”退出全屏模式。

正如@Celada 在下面指出的那样,硬编码 xterm 转义序列并不是一个好主意™,因为序列根据 $TERM 而有所不同,例如:

xterm-颜色 ti: 7 [ ? 47 小时 te: [ 2 J [ ? 4 7 l 8 xterm-256color ti: [ ? 1 0 4 9 小时 te: [ ? 1 0 4 9 升

另一方面,现在非 xterm 终端对 xterm 的支持非常广泛。仅支持 xterm 不太可能导致问题,除非用户具有特殊或过时的 $TERM 设置。来源:我支持这样做的产品。

【讨论】:

  • 谢谢,但是如何在我的 C 程序中切换到备用缓冲区?
  • @PaulBeckingham 你知道terminfo 的能力名称吗(我不知道)。如果您这样做,我建议将其添加到您的答案中,因为这是软件应该使用的,而不是特定类型终端的硬编码转义序列,以便与任何类型的终端兼容(由$TERM 设置)。
  • @PaulBeckingham 哦,实际上在您发布的链接中就有:smcuprmcup
  • 我还是不明白如何将所有这些都放在 C 程序中?我只能使用 ?1049h 转义字符,但我不知道如何使用 ti 或 te。
  • 试试“man termcap”。您将看到一个用于获取“ti”和“te”值的 API。然后你只需在标准输出上发出它们。 @pce 向您展示如何硬编码。你应该使用 termcap 和 printf。
【解决方案2】:

通过向终端发送控制序列(xterm、vt-220)或使用 ncurses(如 mc)。

ANSI Escape SequenceESC(\033 八进制)[ 开头。 ; 分隔数字。

清除屏幕并将光标移动到 1,1 的 C 示例。

#include <stdio.h>

int main()
{
    // clear the terminal
    printf("\033[2J\033[1;1H");
    printf("hello");

}

切换到备用缓冲区并返回 (xterm) 的示例。

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("\033[?1049h\033[H");
    printf("hello\n");
    sleep(1);
    printf("bye");
    sleep(1);
    printf("\033[?1049l");
}

【讨论】:

  • 我不知道,但它有效。它显示一个带有输出的备用屏幕,然后在完成执行后切换回正常屏幕。
  • 为什么是 1049?因为 xterm 支持数百种不同的转义序列,用于颜色、滚动矩形、清屏、光标移动等。
  • @PaulBeckingham 谢谢,我将 /Control/ 替换为 /Ansi Escape/ 序列(ascii-table.com/ansi-escape-sequences.php
  • 请不要使用八进制数,请使用\e\x1b 而不是\033
  • 关于 1049 - 最初有 47 个有问题,我添加了 1047/1048(使它们不同),最后添加了 1049。当然在 xterm 常见问题解答中:invisible-island.net/xterm/xterm.faq.html#xterm_tite
猜你喜欢
  • 2019-03-30
  • 2016-02-29
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
  • 2017-02-22
  • 2014-11-04
  • 2011-04-16
相关资源
最近更新 更多