kg —
a small text editor with Emacs keybindings
-R
- Open all files given on the command line in read-only mode.
-V
- Print version and exit.
-h
- Print a short usage message and exit.
kg is a minimal terminal text editor with
Emacs-style keybindings. It supports syntax highlighting for many programming
languages, multiple buffers, split windows, incremental search, a kill ring,
and undo/redo.
kg does not depend on curses; it uses VT100
escape sequences directly.
If no files are given,
kg opens a scratch
buffer. Multiple files each open in their own buffer.
| Key |
Action |
| C-f / → |
Move forward one character |
| C-b / ← |
Move backward one character |
| C-n / ↓ |
Move to next line |
| C-p / ↑ |
Move to previous line |
| C-a / Home |
Move to beginning of line |
| C-e / End |
Move to end of line |
| C-v / PgDn |
Scroll down one page |
| M-v / PgUp |
Scroll up one page |
| M-f / C-→ |
Move forward one word |
| M-b / C-← |
Move backward one word |
| C-↑ |
Move to previous paragraph |
| C-↓ |
Move to next paragraph |
| C-Home |
Move to beginning of buffer |
| C-End |
Move to end of buffer |
| M-g |
Go to line (prompts for line or line:col) |
| Key |
Action |
| Enter |
Insert newline with auto-indent |
| Tab |
Insert tab (with bracket autocomplete) |
| Backspace |
Delete character before point |
| Delete |
Delete character at point |
| C-d |
Delete character before point |
| C-k |
Kill from point to end of line |
| C-o |
Open line (insert newline, keep cursor) |
| M-^ |
Join current line with the previous one |
| M-u |
Upcase word forward from point |
| M-l |
Downcase word forward from point |
| M-c |
Capitalize word forward from point |
| M-; |
Toggle line comment |
C-k at end of line joins it with the next
line (Emacs behavior). Killed text is appended to the kill ring when
C-k commands are consecutive.
M-; toggles a line comment on the current
line using the comment prefix defined by the current syntax (e.g.
‘//’ for C, ‘#’ for Python and Shell). If the mark
is set, every line between the mark and the cursor is toggled. When adding a
comment the prefix is inserted at column 0 followed by a space; when removing
one, the prefix and the optional following space are deleted.
| Key |
Action |
| C-Space |
Set mark at point |
| C-w |
Kill region (cut to kill ring) |
| M-w |
Copy region (copy to kill ring) |
| C-y |
Yank from kill ring (paste) |
Set the mark with
C-Space, move the cursor to
define the region, then cut with
C-w or
copy with
M-w. Paste anywhere with
C-y. The kill ring is shared across all
buffers.
| Key |
Action |
| C-s |
Incremental search forward |
| C-r |
Incremental search backward |
| M-% |
Query replace |
While searching: type to extend the query;
C-s or
→ or
↓ finds the next match;
C-r or
← or
↑ finds the previous match;
Enter accepts the match;
Esc cancels and returns to the original
position;
Backspace removes the last
character from the query.
M-% prompts for a search string and a
replacement string, then steps through every match from the current position
to the end of the buffer. At each match:
y
or
Enter replaces the match and moves to
the next;
n skips the match;
! replaces the current match and all
remaining matches without prompting;
q,
Esc, or
C-g stops the search. Each replacement is
independently reversible with
C-_.
| Key |
Action |
| C-_ / C-/ |
Undo last change |
Undo history is per-buffer. Each buffer keeps up to 1000 operations. The buffer
is marked unmodified when undo returns to the last-saved state.
| Key |
Action |
| C-x C-s |
Save current buffer |
| C-x s |
Save all modified buffers |
| C-x C-x |
Exchange point and mark |
| C-x C-w |
Write buffer to a different file (save as) |
| C-x i |
Insert file contents at point |
| C-x C-f |
Open file in new buffer |
| C-x C-r |
Open file read-only in new buffer |
| C-x C-q |
Toggle read-only mode on current buffer |
| C-x b |
Switch to buffer (interactive) |
| C-x k |
Kill (close) current buffer |
| C-x C-b |
Open buffer list |
| C-x C-c |
Quit |
| Key |
Action |
| C-x 2 |
Split window horizontally |
| C-x 3 |
Split window vertically |
| C-x o |
Switch to next window |
| C-x 0 |
Delete current window |
| C-x 1 |
Delete all other windows |
| Key |
Action |
| C-x (/ F3 |
Start recording a keyboard macro |
| C-x) / F4 |
Stop recording |
| C-x e / F4 |
Execute (replay) last macro |
While recording,
C-x) or
F4 stops the macro. When not recording,
F4 (or
C-x
e) replays it. Every keystroke during recording is captured, including
characters typed into prompts (search strings, goto-line numbers, etc.), so
the macro replays the full interaction faithfully. The macro buffer holds up
to 1024 keystrokes.
| Key |
Action |
| C-g |
Cancel current operation |
| C-l |
Recenter: cycle current line to center, top, then bottom of window |
| C-h |
Toggle built-in help screen |
| M-x |
Execute named command |
M-x prompts for a command name and executes
it. Available commands:
- capitalize-word
- Capitalize the word forward from point (first letter upper, rest lower).
Equivalent to
M-c.
- delete-trailing-space
- Remove trailing whitespace from the current line only. Reversible with
C-_.
- downcase-word
- Convert the word forward from point to lower case. Equivalent to
M-l.
- goto-line
- Go to a specific line (prompts for line or line:col). Equivalent to
M-g.
- join-line
- Join the current line with the previous one, stripping leading whitespace
from the current line and inserting a space at the join point. Equivalent
to
M-^.
- not-modified
- Clear the modified flag without saving.
- revert-buffer
- Re-read the current file from disk, discarding all unsaved changes. If the
buffer is modified a confirmation prompt is shown.
- save-buffer
- Save the current buffer to its file. Equivalent to
C-x C-s.
- toggle-read-only
- Toggle read-only mode on the current buffer. Equivalent to
C-x C-q.
- upcase-word
- Convert the word forward from point to upper case. Equivalent to
M-u.
- version
- Print the editor version string in the status bar.
- what-cursor-position
- Show current line, column, and percentage through the buffer.
- whitespace-cleanup
- Remove trailing whitespace from every line in the buffer. Each modified
line is independently reversible with
C-_.
kg supports up to 20 open buffers. Each
buffer has its own undo history, dirty flag, and read-only state. Special
system buffers (such as the buffer list) have names enclosed in
‘*’ and can be closed with
q.
The kill ring is global and shared across all buffers, so text killed in one
buffer can be yanked in another.
The terminal can be divided into multiple windows with
C-x 2 (horizontal split) or
C-x 3 (vertical split). Each window shows
one buffer and maintains its own scroll position and cursor. Multiple windows
may show the same buffer. Use
C-x o to
cycle between windows. Up to 8 windows may be open simultaneously.
Syntax highlighting is detected automatically from the file extension or type,
e.g., Makefile. Hash-bang lines (#!) are used as a fallback when the extension
is not recognised.
| Language |
Extensions |
| C/C++ |
.c .h .cpp .hpp .cc |
| Python |
.py .pyw .pyi .pyx |
| Shell |
.sh .bash .zsh .profile .bashrc .zshrc |
| JavaScript |
.js .mjs .cjs |
| TypeScript |
.ts .tsx .d.ts |
| Rust |
.rs .rlib |
| Java |
.java |
| C# |
.cs .csx |
| PHP |
.php .phtml |
| Ruby |
.rb .rbw .rake |
| Swift |
.swift |
| SQL |
.sql .ddl .dml |
| Dart |
.dart |
| HTML |
.html .htm .xhtml |
| JSX |
.jsx |
| Vue |
.vue |
| Angular |
.component.ts .service.ts .module.ts .directive.ts .pipe.ts |
| Svelte |
.svelte |
| Makefile |
Makefile .mk .mak |
| Markdown |
.md .markdown .mkd |
kg automatically inserts matching closing
brackets when an opening bracket is typed, provided the cursor is at the end
of a line. Recognised pairs are ‘()’, ‘[]’, and
‘{}’. Autocomplete is suppressed when text arrives quickly, such
as during a paste operation.
M-g prompts for a line number, optionally
followed by a colon and a column number (e.g.
42:10). The cursor is moved to that position
and the view is centred vertically.
kg uses the controlling terminal
/dev/tty for raw-mode input and output.
Terminal size changes (SIGWINCH) are handled gracefully.
- /dev/tty
- Terminal device used for raw-mode I/O.
mg(1),
emacs(1),
vi(1)
kg is derived from
kilo by
Salvatore Sanfilippo. The name is a nod to
mg(1) (Micro GNU Emacs),
suggesting a kilo-gram-weight minimal editor with Emacs keybindings.
The
kg editor was created by
Joachim Wiberg (troglobit) based on the
original
kilo by
Salvatore Sanfilippo (antirez).