Project status: finished & fully working; probably will not receive further updates, except for bug fixes.
kilo is a minimal (1200 soc) yet somewhat full-featured text editor. It supports basic editing, (incremental) searching, creating new files, syntax highlighting, and many more.
nix developto enable Nix env with all dependenciescmake . -B buildcmake --build build./build/src/kiloto create and open a new file./build/src/kilo <existing-file>to open an existing file
- by default the terminal starts in canonical mode, a.k.a. cooked mode
- keyboard input only sent to the program if user presses
<Enter>
- keyboard input only sent to the program if user presses
- we want the raw mode
- type
resetthen<Enter>in terminal resets it back to normal - by default
ICANONis set - Escape sequence
- 3 or 4 bytes
- starts with the
27byte- which is the
<Esc>key
- which is the
<Ctrl-Z>takes job to background- type
fgto bring it to the front
- type
<Ctrl-S>- stop sending me outputXOFF- press
<Ctrl-Q>to resume sending me outputXON
<Ctrl-C>sendsSIGINT<Ctrl-Z>sendsSIGSTP<Ctrl-C>represents byte3<Ctrl-D>represents byte3<Ctrl-Z>represents byte26IXONI- input flag
<Ctrl-S>represents byte19<Ctrl-Q>represents byte17<Ctrl-V>- terminal waits for another character input
- then sends that character literally
IEXTENflag
<Ctrl-M>- represented as
10byte <Ctrl-J>also represents10- so does
<Enter>
- represented as
- Terminal translates any carriage returns (
13,\r) inputted by user into newlines (10,\n)ICRNLI- input flagCR- carriage returnNL- new line
- Terminal translates each newline (
"\n") users print into a carriage return followed by a newline -"\r\n"- both
"\r"and"\n"are required to start a new line - carriage return moves the cursor back to the beginning of the current line
- newline moves cursor down a line, scrolling the screen if necessary
- both
- Likely the only output processing feature turned on by default:
"\n"->"\r\n" OPOST- the output processing flagBRKINT- a break condition will cause aSIGINTsent to the program- similar to
<Ctrl-C>
- similar to
INPCK- enables parity checkingISTRIP- sets the 8th bit of each input byte to be0- most likely already turned off
CS8- a bit mask, not a flag- sets the character size (CS) to 8 bits per byte
EAGAIN- resource temporarily unavailable- In C, bitmasks generally specified in hex
- use
Jcommand to clear the screen - VT100 User Guide
- If a tilde (
~) is in a row - row is not part of the file and cannot contain any text - To get window size of terminal,
ioctl- control device- the
TIOCGWINSZrequest- Terminal IOCtl Get WINdow SiZe
- from
<sys/ioctl.h>
- However,
ioctl()is not guaranteed to query the window size on all systems - Use
"\x1b[K"to clear the line after the"~", instead of clearing the entire screen snprintf()- writes to the buffer string at most number of chars- How to move cursors around?
- keep track of cursor's x and y position
- move cursor to position stored in
E.cxandE.cyineditor_refresh_screen()
- Use
JKHLto move cursors, like Vim - Pressing
Ctrlwith another key- clears the 6th and 7th bits of the char presses with
Ctrl
- clears the 6th and 7th bits of the char presses with
Page up&Page downkeys<esc>[5~-Page up<esc>[6~-Page down
Home&EndkeysHomecould be sent as:<esc>[1~<esc>[7~<esc>[H<esc>OH
Endcould be sent as:<esc>[4~<esc>[8~<esc>[F<esc>OF
Deletekey -<esc>[3~- Create a data type for storing a row of text in the editor
getline()- read lines from a file while how much memory is allocated is unknown- takes care memory management for you
- returns length of the read line;
-1if error
- Strategy for vertical scrolling for long text
- check if cursor has moved out of the visible window
- if so, adjust
E.rowoffso that cursor is just inside the visible window
- We allow users to scroll one line/column pass the edge - allowing users to insert lines/characters
- Rendering tabs
- we want to render tabs as multiple spaces
- tab stop - a column that's divisible by 8
- each tab must advance the cursor forward at least one column
Page Up&Page Downshould scroll up/down an entire page- Status bar
- display file name & current row number
- Select Graphic Rendition (SGR)
ESC [ Ps ; . . . ; Ps m
- status message & timestamp
- Originally,
Backspacewas mapped toCtrl-H- control code8- but now mapped to
127 DELmapped to<esc>[3~
- but now mapped to
<Ctrl-L>- refresh screen in terminal programsO_TRUNC- truncates the file to zero length
- normally a file is overwritten by passing
O_TRUNCtoopen()- truncates the file completely
- then write data to it
- Syntax Highlighting
- now we have to feed the substring of
renderto print intoabuf_append() - but character-by-character
- now we have to feed the substring of
- Filetype detection
- call
editor_select_syntax_highlight()whenever/whereverfilenamechanges
- call
- the audible bell character -
7 - We need to translate nonprintable characters into printable ones
- we render them using inverted colors (black on white)