tmux、vim、emacs 等如何超越 *nix 终端的 UI 限制?
How does tmux, vim, emacs, etc transcend the UI limitations of *nix terminals?
当我编写用于命令行的程序时,我注意到存在一些限制。例如,我无法像 tmux 在 window 中分隔窗格时那样绘制 1 像素粗的水平线或垂直线。我只能向下移动光标,不能像 VI 那样向上移动。如果光标在底部,我无法刷新页面顶部的信息。
因此,当像 tmux 和 vi 这样的程序执行此操作时,我不得不怀疑它们是否:
每次更新都从上到下绘制屏幕(我认为这不太可能,否则我可以在我的终端中向上滚动并看到每次重绘)
使用一些在终端中启用图形的库,比如 SDL,我也认为这不太可能。
使用一些我不知道的标准系统调用
或最后
- 利用 Linux/Unix 我完全不知道的某些功能。
那么,这些程序是如何在看似有限的shell中产生如此丰富的UI的呢?只要答案给我足够的饲料来继续 Google 横冲直撞,我就会很高兴。
我还假设这些程序使用一些通用方法来执行这些操作,但如果有误请告诉我。
您可以通过将终端置于原始模式并使用低级操作直接写入终端来手动完成,但标准方法是使用 ncurses 库。
一个典型的终端仿真器具有的功能比立即显现的要多得多。
本质上,一个程序只需要输出代表各种命令的短字节序列,例如移动光标(上|下|左|右)、更改颜色、滚动区域、擦除区域等。
这些命令通常以转义字符(与您在终端中键入时按 esc 键时生成的字符相同)开头,后跟各种其他字符,具体取决于所需的操作。
了解其工作原理的一个很好的起点是关于 ANSI escape codes
的维基百科文章
当我编写用于命令行的程序时,我注意到存在一些限制。例如,我无法像 tmux 在 window 中分隔窗格时那样绘制 1 像素粗的水平线或垂直线。我只能向下移动光标,不能像 VI 那样向上移动。如果光标在底部,我无法刷新页面顶部的信息。
因此,当像 tmux 和 vi 这样的程序执行此操作时,我不得不怀疑它们是否:
每次更新都从上到下绘制屏幕(我认为这不太可能,否则我可以在我的终端中向上滚动并看到每次重绘)
使用一些在终端中启用图形的库,比如 SDL,我也认为这不太可能。
使用一些我不知道的标准系统调用
或最后
- 利用 Linux/Unix 我完全不知道的某些功能。
那么,这些程序是如何在看似有限的shell中产生如此丰富的UI的呢?只要答案给我足够的饲料来继续 Google 横冲直撞,我就会很高兴。
我还假设这些程序使用一些通用方法来执行这些操作,但如果有误请告诉我。
您可以通过将终端置于原始模式并使用低级操作直接写入终端来手动完成,但标准方法是使用 ncurses 库。
一个典型的终端仿真器具有的功能比立即显现的要多得多。
本质上,一个程序只需要输出代表各种命令的短字节序列,例如移动光标(上|下|左|右)、更改颜色、滚动区域、擦除区域等。
这些命令通常以转义字符(与您在终端中键入时按 esc 键时生成的字符相同)开头,后跟各种其他字符,具体取决于所需的操作。
了解其工作原理的一个很好的起点是关于 ANSI escape codes
的维基百科文章