Reading — step 1 of 5
Read
Terminal Raw Mode
By default, the terminal is in cooked mode: it line-buffers input, echoes typed characters, intercepts Ctrl+C/Ctrl+Z, and translates \r to \n. Great for shell scripts. Terrible for an editor — you want to react to every single keystroke the moment it happens.
Every serious terminal editor flips the same set of bits in termios:
struct termios raw = orig;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~(OPOST);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
What each flag does, and why we kill it:
| Flag | Field | Meaning | Why disable |
|---|---|---|---|
ECHO | lflag | Echo typed chars | We render the buffer ourselves |
ICANON | lflag | Line buffering | We want chars, not lines |
ISIG | lflag | Ctrl+C, Ctrl+Z → signals | We want Ctrl+C as a key |
IEXTEN | lflag | Ctrl+V literal-next | Avoid double-key consumption |
IXON | iflag | Ctrl+S, Ctrl+Q flow control | We want those as keys |
ICRNL | iflag | \r → \n translation | We want raw \r |
OPOST | oflag | Output \n → \r\n translation | We emit \r\n ourselves |
BRKINT, INPCK, ISTRIP | iflag | Legacy 7-bit serial cruft | Modern hygiene |
CS8 | cflag | 8-bit chars | Required for UTF-8 |
Always save the original termios and restore it on exit (atexit, or RAII in C++/Rust). If your editor crashes without restoring, the user's shell is left in raw mode — broken until they reset.
This lesson simulates the bit manipulation so you can verify which flags are cleared without needing an actual terminal. The same mental model carries to Windows console mode (SetConsoleMode with ENABLE_VIRTUAL_TERMINAL_INPUT) and to UI toolkits like crossterm (Rust), tcell (Go), prompt_toolkit (Python).
Reference: termios(3), kilo enableRawMode(), Hecto chapter 2.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…