第 5 章 · 04 终端渲染:termios 与 VT100 本节摘要:编辑器要在终端里「接管一切」——逐字符捕获按键(不等回车)、不回显(自己控制显示)、在任意位置画字符。这靠两套底层技术:termios(把终端切到「原始模式」)与 VT100 转义码(控制光标位置、清屏、上色)。本节讲清它们的基础用法——这是所有 TUI(终端用户界面)程序的共通底层,不只编辑器用。 内容来源:基于终端编程整理的导读。 学习目标 阅读完本节,你应当能够: 用 termios 把终端从「cooked 模式」(行缓冲+回显)切到「raw 模式」(逐字符+不回显)。 用 VT100 转义码控制光标位置( )、清屏( )、上色( )。 理解「原始模式」对编辑器/TUI 的必要性。
本节摘要:编辑器要在终端里「接管一切」——逐字符捕获按键(不等回车)、不回显(自己控制显示)、在任意位置画字符。这靠两套底层技术:termios(把终端切到「原始模式」)与 VT100 转义码(控制光标位置、清屏、上色)。本节讲清它们的基础用法——这是所有 TUI(终端用户界面)程序的共通底层,不只编辑器用。
内容来源:基于终端编程整理的导读。
阅读完本节,你应当能够:
\033[r;cH)、清屏(\033[2J)、上色(\033[31m)。终端默认是「cooked 模式」:输入要按回车才送达程序(line buffering)、你敲的字符终端自动回显。这对普通命令行程序友好,但对编辑器是灾难——编辑器要逐字符响应(不等回车)、自己控制显示(不回显)。
termios 的「原始模式」关掉这些「友好」行为,让程序拿到原始控制权。配合 VT100 转义码,程序能在终端任意位置画字符、移动光标、上色。这套底层不只编辑器用——任何 TUI 程序(top、htop、vim、tmux、dialog)都靠它。理解本节,你打开了 TUI 编程的大门。
终端默认 cooked 模式的行为:
原始模式(raw)用 termios 关掉这些:
tcgetattr(0, &orig) # 保存原始终端设置(退出时恢复) raw = orig raw.c_lflag &= ~(ECHO | ICANON | ISIG) # 关回显/行缓冲/信号 raw.c_iflag &= ~(IXON) # 关 Ctrl+S/Q 流控 tcsetattr(0, TCSAFLUSH, &raw) # 应用原始模式
进入原始模式后:你敲一个键,程序立刻收到(不等回车)、终端不自动显示(程序自己决定画什么)。退出时务必恢复 orig,否则终端会一直处于异常状态(不回显、不识别 Ctrl+C)。
⚠️ 难点预警:程序崩溃/退出前必须恢复 termios,否则用户的终端会「坏掉」(不回显、行缓冲关了)。用
atexit或第 9 章的trap思路,确保无论怎么退出都恢复。
VT100 是 70 年代的终端,它的转义码成了事实标准。所有以 \033[(ESC [)开头的序列是「控制序列」:
| 转义码 | 作用 |
|---|---|
\033[2J |
清屏 |
\033[H |
光标移到左上(1;1) |
\033[r;cH |
光标移到 r 行 c 列 |
\033[K |
清到行尾 |
\033[31m |
设前景色红(31-37 基本) |
\033[0m |
重置所有属性 |
\033[?25l / h |
隐藏/显示光标 |
编辑器渲染循环:清屏 → 把缓冲区每行写到对应位置 → 移光标到编辑位置。靠这些转义码完成。
原始模式下,按键以字节流到达。普通字符是单字节(如 a);特殊键是多字节转义(如方向键是 \033[A 上)。你要解析这些序列,识别「用户按了什么键」。
参考「kilo」编辑器(几百行 C 实现一个能用的编辑器)是经典教学项目。
\033[xxx):控制光标位置、清屏、上色;所有终端的事实标准。\033[A 等),需解析识别。下一节讲撤销重做——命令模式的应用,也是本章综合。