My Kakoune Editor Configuration
A friendly explanation of how Kakoune is configured.

Most likely, you are reading this because you already have some idea of what the Kakoune editor is. If you don’t, you can think of Kakoune as Vim for dummies. Yes, I include myself in that category. I have what amounts to a goldfish memory when it comes to remembering tons of commands in advance coding editors.
Read more: Kakoune, the Text Editor I Didn’t Know I Needed.
I quite like the whole concept of Vim, but I can never quite get used to it. Instead I prefer to use more GUI-oriented editors such as TextMate and VSCode. However, there are many cases where a more terminal oriented editor such as Vim and Emacs is preferable. Vim has been my go-to editor in these cases. But if you, like me, are more of a casual user of Vim, I think you will find Kakoune a superior alternative. It operates in very similar fashion to Vim. But it is like a modern more user-friendly version of Vim.
Here is a quick example to see the benefits. With Vim, you would delete three words with the d3w
command. The logic of Vim is: First you type what you want to do, which is d
for delete. Next you type the part of the text to apply this to. In this case, it is 3w
, meaning three words from the word you are currently at.
The problem with this approach is that it is never readily apparent what you are going to perform your operation on.
Kakoune makes some minor changes to the Vim formula to make this more user friend. With Kakoune, the command is 3Wd
. When you first just type 3W
you will see the following in your editor:

In other words, you actually see what part of the text will get affected by the command that you are about to press next. Please note that W
means Shift-W
. In Kakoune, like in a regular GUI editor, you typically use Shift
key to expand a selection. Thus in Kakoune 3w
will jump to the third word and highlight it, while 3W
will highlight all three words. Alternatively you can can jump three words with www
or highlight three words with WWW
.
Anyway, this was just quick intro to Kakoune. Next I will cover how you configure the operations of the editor by specifically looking at the configurations I use.
Read more: Most Useful Kakoune Editor Commands.
Configuring the Kakoune Editor
This is my Kakoune configuration file on macOS. The location of the configuration file will be similar on Linux:
$ cat ~/.config/kak/kakrc
hook global InsertCompletionShow .* %{
try %{
execute-keys -draft 'h<a-K>\h<ret>'
map window insert <tab> <c-n>
map window insert <s-tab> <c-p>
hook -once -always window InsertCompletionHide .* %{
map window insert <tab> <tab>
map window insert <s-tab> <s-tab>
}
}
}
set global indentwidth 4
set global tabstop 4
# add-highlighter global/ number-lines
Normally, there will be no file at .config/kak/kakrc
in your home directory, so you will have to create it.
This particular configuration file is set to do a couple of different things. The part that starts with hook
reconfigures how I do word completions in Kakoune. When you type in Kakoune, it typically gives you completion suggestions.

Typically, Kakoune is set up so you cycle through these with Ctrl-N
. That is not something obvious or natural for me. I greatly prefer to use tab for this purpose. That is what this hook is for. It replaces Ctrl-N
and Ctrl-P
used for cycling forwards or backwards in completions with Tab
and Shift-Tab
. Note that in Kakoune we use much shorter abbreviations for hotkeys. For example, Ctrl-N
is written as <c-n>
.
How to Discover Functionality in Kakoune
You may wonder how you figure out how to write a configuration like this. Of course you can Google, but it useful to understand how to modify this code to suit your needs. All the stuff that you can write into the .config/kak/kakrc
file can also be written while in the editor. Just like Vim, you can hit Esc
and the :
to get into a sort of command mode. Kakoune is very helpful when you do this because it shows live help in a yellow box, giving you advice and suggestions. For instance, when I type :hook
I get this advice:

You can see that I began typing the second argument that specifies scope for this command. Kakoune is helpful in giving me completions for possible scopes. Thus, if I want to add line numbers to the current window I am working on, I can simple write:
:add-highlighter window/ number-lines
As you type that out, you will be given completions and explanations to help do it. Sure, it may be awkward to write this every time, but you can simply begin to write :add-high
and use the up and down arrow keys to complete based on your previous history. Thus, you can quickly cycle through any commands you have used in the past that started with :add-high
.
Don’t want to use line numbers? No problem, we can remove them with:
:remove-highlighter window/number-lines
This works in a practical fashion because when I have just written window/
I will get completions based on the highlighters I have previously installed.
Okay, I know I have been talking about highlighters as if it is obvious what I mean by that. This is a rather broad concept in Kakoune and one that we will get into shortly.
Kakoune Concepts
To better understand how to configure and modify Kakoune, it helps to understand the key concepts that exist in Kakoune. To summarize, these are:
- Scopes — Gives a context for where a command applies. Does a command apply to all of Kakoune, a particular buffer or window? Note that windows in Kakoune mean a view of a buffer. A buffer is an instance of an open file.
- Hooks — Hooks are actions that you want to perform in response to certain events.
- Highlighters — Manipulate how text is shown. These are cumulative. You can add multiple highlighters that all modify how your text is shown.
- Commands — The stuff you actually do, such as highlighting, switching a buffer, opening a file etc.
Scopes
When you open a file in Vim, Emacs or Kakoune, you create a buffer. At least, that is the terminology most of these editors use. You could also create a new buffer not associated with any existing files. In Kakoune, a buffer could have multiple views. These are called windows. Thus you can modify the same buffer using two different windows, each with different configurations. The normal scopes are:
- window — Applies a command to the current window being shown.
- buffer — Apply to current buffer. That means all windows viewing this same buffer will be subject to the same command.
- global — Applies to all open windows
Let us look at an example:
:add-highlighter window/ number-lines
This toggles line numbering for the current window. To toggle for all windows you would write this instead:
:add-highlighter global/ number-lines
Hooks
Hooks are actions performed in response to different events. A simple way to find out what events exists is to use the completion. Here you can see that I have tabbed through the list of possible completions to WinCreate
. This is the event broadcast when a new window is created, for example because you just opened a file.

To learn what the various events are actually for, you can show the documentation for hooks. It lists all the different events. Just type:
:doc hooks
This creates a new buffer containing documentation. How do you close this buffer? There are lots of buffer commands that start with buffer
and which has shortcuts so either of these will work:
:delete-buffer
:db
When a new file is opened, you might want to look at the type and decide on particular highlighters to toggle on. Guess what this hook does:
hook global WinCreate .*\.java %{ add-highlighter number-lines }
To understand this, it helps to look at the general format of the hook command:
hook <scope> <event> <filter> <command>
The .*\.java
part is the filter. It is a regular expression that matches Java source code files.
What needs a bit more explanation is the fact that the command part is given as the somewhat cryptic looking:
%{ add-highlighter number-lines }
It is not readily apparent where the command is enclosed with the %{ }
symbols. Before covering that, though, let’s just cover commands.
Commands
In addition to commands such as :doc
and :buffer-delete
Kakoune also has the ability to use the command you use while editing your text. You can use them as hooks. Here is an example:
:execute-keys xyo<esc>p
This looks really cryptic, but is really just a sequence of keystrokes you would use interactively. It is as if you used:
x
to highlight current line.- Then you used
y
to yank (copy) current selection. o
to insert a new line below.- Get back to command mode by hitting the escape key. Special keys are written with
<>
. Thus escape is<esc>
. - Paste what was previously yanked with
p
.
Command Parsing and Expansion
Kakoune commands don’t work the way a normal programming language works where nested expressions get evaluated in order and substituted. Rather, the way to think about this is in terms of text substitution.
The command echo
in Kakoune will just show what you wrote like an echo in the shell. Thus if I write the command:
:echo Hello World!!!
It will produce the Hello World!!!
text string at the bottom of the text editor. The following line will just show the word data
.
:echo date
But here is the interesting part. You can specify different ways of causing text to be expanded. Think of the Unix shell. If you write *.java
on the shell prompt, that will expand to a list of every file ending with .java
. That is what you Unix command sees. It never sees the *.java
text. We have the same kind of thing happening in Kakoune.
If you write this, then the text string will expand to the output from a shell command before being past to echo
.
:echo %sh{date}
When you run this, you will get the output you see at the bottom of editor. You get the current date Fri Feb 12 17:55:25 CET 2021
which is when I wrote that example.

Kakoune has many different types of expansions. You can read about them by typing:
:doc expansions
I will not cover all of them here. But here are the basics so that you can understand my basic Kakoune configuration. With the %{}
things are just substituted as they are. We can use that to provide text that runs over multiple lines like this example:
hook global InsertCompletionShow .* %{
try %{
execute-keys -draft 'h<a-K>\h<ret>'
map window insert <tab> <c-n>
map window insert <s-tab> <c-p>
hook -once -always window InsertCompletionHide .* %{
map window insert <tab> <tab>
map window insert <s-tab> <s-tab>
}
}
}
This means we can store a text representing a bunch of commands with the hook, to be run later. As this example shows, you can nest expansions. Hence you could put something that expands to something else with a shell command when the hook is run.
InsertCompletionShow Hook Breakdown
So let us look at what is actually going on in the hook I use in my Kakoune config file. The InsertCompletionShow
is triggered when Kakoune shows a completion window. It happens as you are writing and it sees a possible match for something else in the current window.
Let us look at the first part:
hook global InsertCompletionShow .*
This says the hook applies to all windows (global) and to the InsertCompletionShow
event for any file .*
. Next comes the command, which has to be given as one text string. To bundle multiple commands into one text string we use the %{}
. That is a way of quoting everything. It is similar to how you use "hello world"
to quote a text string in the shell to avoid having the space being interpreted as separating two arguments.
Next we have this part:
execute-keys -draft 'h<a-K>\h<ret>'
This runs 'h<a-K>\h<ret>'
key combinations in a separate buffer (the -draft
option). h
moves one character back. <a-K>
means to hold down Alt-Shift-K
. <ret>
is simply the return key.
Let’s move on to the next part:
map window insert <tab> <c-n>
This replaces one key stroke with a series of other key strokes. First we have to give context. window
say this should happen in the current window. insert
says we should do it while in insertion mode. That refers to when you are typing characters into the window. The next part says that whenever you hit <tab>
in insertion mode, this should be replaced by <c-n>
which means Ctrl-N
.
However, we don’t want tab to work this way all the time while being in insertion mode. Hence, as soon as the completion window is closed, we want to go back to normal:
hook -once -always window InsertCompletionHide .* %{
map window insert <tab> <tab>
map window insert <s-tab> <s-tab>
}
This tells Kakoune to map Tab
to Tab
and Shift-Tab
to Shift-Tab
. That means Tab is no longer translating to Ctrl-N
.
Further Exploration
I hope this article helps you grokking Kakoune configuration. All of this is covered in the doc system built into Kakoune. But it can be hard to know where to get started.
While this may seem a bit complex, Kakoune doesn’t go much deeper. There is no built-in script language like in Vim or Emacs. Instead, the simple mechanism shown is intended to allow you to interface with other scripts or Unix commands.