Page Up & Page Down with Kilo Editor
I've recently started going through this brilliant article on creating your own text editor (read: nano/pico clone). If you've never built one this article breaks it down into easy to follow chunks.
If you do go through it, you might notice the same thing I did. Page Up
and Page Down
doesn't seem to work right (in Mac OS' Terminal.app).
If you're also like me, you might end up googling why those keys don't work right. Let me break it down for you:
- Yes, Terminal.app is capturing the keys
- Yes, you can hold
Shift
while pressingPage Up
orPage Down
Page Up
andPage Down
works in vim
Wait, what? How does it work in vim? Is it actually Terminal.app or is kilo not actually entering the elusive "raw mode"?
If you google "terminfo alternate screen" you'll figure out that terminals have a feature allowing programs to switch to, you guessed it, an alternate screen. This is how vim and other programs show you their full screen content while then returning back without disrupting what you were doing.
Terminal.app detects this transition and then treats Page Up
and Page Down
as expected. Some more googling will show you that we can get this to work by sending the terminal smcup
and rmcup
commands.
Note
Some people hate smcup and rmcup. There's definitive tradeoffs but my expectation is that when I enter and exit a terminal text editor I don't lose my previous screen.
Just add the following in the prescribed sections to fix Page Up
and Page Down
and add in the terminal "saving" stuff.
void initEditor() {
write(STDOUT_FILENO, "\033[?47h", 6); // New (smcup)
EditorConfig.cursor.x = 0;
EditorConfig.cursor.y = 0;
if (getWindowSize(&EditorConfig.screenRows, &EditorConfig.screenCols) == -1) die("getWindowSize");
terminalClearScreen();
}
// ...
void disableRawMode() {
write(STDOUT_FILENO, "\033[?47l", 6); // New (rmcup)
tcsetattr(STDIN_FILENO, TCSAFLUSH, &EditorConfig.orig_termios);
}
Easy peasy!