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 develop
to enable Nix env with all dependenciescmake . -B build
cmake --build build
./build/src/kilo
to 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
reset
then<Enter>
in terminal resets it back to normal - by default
ICANON
is set - Escape sequence
- 3 or 4 bytes
- starts with the
27
byte- which is the
<Esc>
key
- which is the
<Ctrl-Z>
takes job to background- type
fg
to 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 byte26
IXON
I
- input flag
<Ctrl-S>
represents byte19
<Ctrl-Q>
represents byte17
<Ctrl-V>
- terminal waits for another character input
- then sends that character literally
IEXTEN
flag
<Ctrl-M>
- represented as
10
byte <Ctrl-J>
also represents10
- so does
<Enter>
- represented as
- Terminal translates any carriage returns (
13
,\r
) inputted by user into newlines (10
,\n
)ICRNL
I
- 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 aSIGINT
sent 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
J
command 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
TIOCGWINSZ
request- 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.cx
andE.cy
ineditor_refresh_screen()
- Use
JKHL
to move cursors, like Vim - Pressing
Ctrl
with 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 down
keys<esc>[5~
-Page up
<esc>[6~
-Page down
Home
&End
keysHome
could be sent as:<esc>[1~
<esc>[7~
<esc>[H
<esc>OH
End
could be sent as:<esc>[4~
<esc>[8~
<esc>[F
<esc>OF
Delete
key -<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;
-1
if error
- Strategy for vertical scrolling for long text
- check if cursor has moved out of the visible window
- if so, adjust
E.rowoff
so 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 Down
should 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,
Backspace
was mapped toCtrl-H
- control code8
- but now mapped to
127
DEL
mapped 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_TRUNC
toopen()
- truncates the file completely
- then write data to it
- Syntax Highlighting
- now we have to feed the substring of
render
to print intoabuf_append()
- but character-by-character
- now we have to feed the substring of
- Filetype detection
- call
editor_select_syntax_highlight()
whenever/whereverfilename
changes
- call
- the audible bell character -
7
- We need to translate nonprintable characters into printable ones
- we render them using inverted colors (black on white)