Skip to the content.

The first two hours of Kakoune in two minutes

Learning a new editor can be a daunting task, especially when coming over from a non-modal editor. I personally started with Emacs, and it took me weeks to be productive when I started using Vim. The modal paradigm is a powerful tool, but picking it up is generally not a painless experience.

When I discovered Kakoune a few years ago, it felt like the jump from Vim to it was even bigger than the one I’d made when transitioning over from Emacs to Vim. Despite the two being fairly close on paper, one still needs to unlearn all the muscle memory patiently cultivated over the years and grow it back up from scratch. If we ignore the fact that in those days the only (comparatively sparse) documentation was centralised in the README file of the project, which might have contributed to why the jump made itself felt so strongly, new comers still have to primarily focus their efforts towards learning the “modal language”, or flavour, of Kakoune.

In order to save them some time, whether they’re disembarking off the Emacs (non-modal) or Vim (modal) boats, I’ve documented in the following article some common configuration options. They won’t fit anyone’s workflow exactly right, I trust the user to tweak the settings how they see fit. They will however allow turning the two hours it would have taken me to figure out what lines to write down in my user configuration to get a boilerplate setup going into two minutes — the time it takes to read this introduction and save the final kakrc onto one’s system.

The configuration file

You’ll find below an inlined, commented configuration file to steal from. You can also download it directly, and save it as ~/.config/kak/kakrc (or $XDG_CONFIG_HOME/kak/kakrc).

# Set the colour scheme
colorscheme kaleidoscope-dark

# Width of a tab
set-option global tabstop 4

# Indent with 4 spaces
set-option global indentwidth 4

# Always keep one line and three columns displayed around the cursor
set-option global scrolloff 1,3

# Display the status bar on top
set-option global ui_options ncurses_status_on_top=true

# Display line numbers
add-highlighter global/ number-lines -hlcursor

# Highlight trailing whitespace
add-highlighter global/ regex \h+$ 0:Error

# Softwrap long lines
add-highlighter global/ wrap -word -indent

# Clipboard management mappings
map -docstring "yank the selection into the clipboard" global user y "<a-|> xsel -i<ret>"
map -docstring "paste the clipboard" global user p "<a-!> xsel<ret>"

# Shortcut to quickly exit the editor
define-command -docstring "save and quit" x "write-all; quit"

Explanations

These explanations expand on the purpose of the lines in the above file, the salient parts in them, and hopefully give you a bird-eye view of the various configuration instructions you might recognise in the kakrc configurations of more advanced users.

The details are intentionally glossed over and might seem fuzzy, feel free to refer to the list of recommended further readings at the end of this article if you’re curious.

# Set the colour scheme
colorscheme kaleidoscope-dark

The Kaleidoscope colour scheme (also known as theme) is a high-contrast, colour blind friendly palette of colours that should suit the largest subset of users, at first. You can go for the dark variant (kaleidoscope-dark) or the light one (kaleidoscope-light).

If you don’t care either way, comment this line and the default theme will do just fine.

# Width of a tab
set-option global tabstop 4

Options are scoped, which means that they can hold different values depending on the context in which they’re being used. For general configuration purposes, use the global scope.

The tabstop option holds the amount of space characters that tabulation characters (stored in a file opened with Kakoune) will be rendered as.

# Indent with 4 spaces
set-option global indentwidth 4

This option impacts the behaviour of a couple of primitives (a primitive is a “key”, more details about keys/primitives below) that indent or de-indent a line, in normal mode.

In non-modal editors, hitting keys results in the letter associated with them being inserted into the buffer (the “file”) as-is. In modal editors, this behaviour applies only to the “insert mode”, which can be entered by hitting i in normal mode — which is the default mode when starting Kakoune.

The indentwidth option dictates how many space characters are inserted or removed when using (respectively) the normal mode primitive > and <.

Note that when editing a file that is recognised by the editor, manual indentation of lines should not be necessary, as that side-effect will be handled automatically upon hitting the return key.

# Always keep one line and three columns displayed around the cursor
set-option global scrolloff 1,3

When scrolling around a large file, the cursor tends to stick to the borders of the window if more content needs to be displayed. You can have the window show more context (i.e. lines and characters) when that happens with the scrolloff option.

The first integer (1 above) in the comma separated pair is the amount of lines to show above/below the cursor when it hits the top/bottom of the window, and more lines remain to be displayed in the file.

Similarly, the second integer (3 above) is the amount of characters displayed on the left/right when the cursor hits the left/right hand window border.

# Display the status bar on top
set-option global ui_options ncurses_status_on_top=true

Kakoune follows a server/client architecture, and the behaviour of the user interface (run by the client) can be tweaked via ui_options. It accepts a list of equal-sign separated key/value pairs, and the above instructs the NCurses client (default) to display the status bar on top.

Feel free to comment this line if the default behaviour (status bar on the bottom) suits you.

# Display line numbers
add-highlighter global/ number-lines -hlcursor

Highlighters are decorators for the window or the text it contains. Similarly to options (c.f. above), they are scoped, but we only care about their global value. You might have noticed however that the above line uses global/, and you might be tempted to remove it on account of it being redundant — don’t, the character is significant.

The number-lines highlighter displays a file’s line numbers on the left hand side of the screen. The -hlcursor flag allows highlighting the number of the line that the cursor lies on.

# Highlight trailing whitespace
add-highlighter global/ regex \h+$ 0:Error

This line adds a regex highlighter which decorates trailing whitespace with the built-in Error face. The number refers to the index of the match within the regex. For instance, 0 refers to the text matched by the regex (but not to the entire line).

# Softwrap long lines
add-highlighter global/ wrap -word -indent

The wrap highlighter applies “soft wrapping” (e.g. the lines appear broken up, but no newline characters are inserted into the file itself) to lines that cannot be fully displayed within the window. The flags passed to it keep words whole, and the indentation of the lines newly created will have the same indentation level as their stem.

# Clipboard management mappings
map -docstring "yank the selection into the clipboard" global user y "<a-|> xsel -i<ret>"
map -docstring "paste the clipboard" global user p "<a-!> xsel<ret>"

Mappings (also known as “key bindings”, or more simply “bindings”) allow customising the side effect upon hitting a key. Here is a breakdown of the two lines above:

As you can see, quite a few concepts have been packed into merely two instructions.

In terms of functionality, these two mappings copy the current selection to the clipboard and paste whatever is in it. They’re triggered by hitting the comma , key followed by respectively y and p.

Read on if you’re not familiar with modal edition, or want to compare the declaration of mappings in Kakoune with other modal editors.

The user mode
Mappings allow overriding the behaviour of a given key, but since they all have a specific purpose (c.f. primitives below) by default, one would have to forego whatever functionality the key being overridden provided with, in order to instantiate a custom mapping.

The user mode is entered from normal mode upon hitting the comma , key, and allows “user mappings” to be declared within it. It’s a way to address the above problem: you don’t have to override default keys/primitives, you can just place them one keystroke away (“behind” the comma , key) and be free to pick any key you see fit.

Primitives
The difference between “key” and “primitive” is one of semantic, and both can commonly be used interchangeably.

Keys are referred to as the letter (or symbol, for example the return key) that is printed on them, on a QWERTY keyboard.

Primitives are triggered by single keys or a combination of them, and can be invoked from a prompt (interactively) or script (programmatically). They are referred to using a custom notation that allows combining letters and modifiers (c.f. below).

When placing those cryptic definitions back into the context of the clipboard management mappings above, we get:

Prompt history
You might have noticed that a whitespace lies between the <a-|>/<a-!> primitives and the shell commands they run:

As mentioned previously, these two primitives prompt the user for a shell command, which will be inserted into the prompt’s history upon validation, and suggested back to the user upon a subsequent invocation.

Since our mappings merely rely on the side-effect of the primitives themselves (i.e. running commands, optionally piping data into them), we don’t want the associated commands to be inserted into the interactive prompt history, littering it with potentially multiple calls to xsel.

Mapping recursivity
Mappings execute a series of keys when another is being hit, which might have left you wondering what would happen if one were to run the following:

map global normal x "x"

Would hitting the x key result in an infinite loop? Psyke!

Mappings can call primitives, but never truly replace them, resulting into the above statement effectively being a no-op: the x primitive will be executed upon hitting the x key, which is already the default side effect.

This behaviour allows remapping the keyboard as one sees fit, keeping the series of primitives bound to a key consistent (they don’t depend on the user’s custom mappings).

A popular user configuration instruction is to re-map the key that enters user mode (also known as “leader”) to the space <space> key. We’ll leave it as an exercise to the reader to find out how that would be implemented in a Kakoune configuration. Just be aware that the space primitive is quite valuable to the editing model, so the comma , and space <space> keys would have to be swapped (hint: two calls to map).

# Shortcut to quickly exit the editor
define-command -docstring "save and quit" x "write-all; quit"

The x command is ubiquitous in modal editors: it allows saving all files and quitting.

The define-command command allows executing an arbitrary series of commands from the prompt (invoked using the colon : primitive). Similarly to map, a description of the side effects of the custom command can be passed to -docstring "…". You can read the documentation string of a given command by typing its name into a prompt (:), it will show up in a popup window on the main window.

The above command definition is thus quite straight-forward: declare a new command x which calls write-all and quit. These last two commands are built-in, and unsurprisingly respectively save all open files, and quit the editor.

Further readings

I hope this introduction will be useful to new comers who want to get started quickly. However, we’ve barely scratched the surface of the concepts explained above, let alone what was not mentioned at all. If you want to learn more, feel to check out the following documents:

If you have comments or questions, feel free to drop by the official IRC channel: #kakoune @ FreeNode.

— written by Frank Lenormand · · license CC BY-SA 4.0