I've been using Kakoune as my primary text editor for a few years. After using Vim for over a decade, I wanted to try some of the features listed on Kakoune's home page, like multiple selections and the object-verb editing language — and yeah, those are great. However, those aren't what's kept me using Kakoune. Instead, there's something about the overall design and values that I find satisfying.
I had a hard time explaining exactly what it was I liked about Kakoune, until one day I described it to someone as "very punk rock". I didn't have a specific analogy in mind, and I really only had a vague pop-culture idea of what punk was about, but it seemed worth digging into more deeply.
DISCLAIMER: I haven't actually talked about Kakoune with anyone who identifies as part of the punk community, or talked about punk rock with mawww or anybody else who's worked on Kakoune. Any misunderstandings or misrepresentations are entirely mine.
Wikipedia has a bunch of pages about the punk subculture, so here's some choice quotes from the introduction:
It is largely characterised by anti-establishment views, the promotion of individual freedom, DIY ethics, and is centred on a loud, aggressive genre of rock music called punk rock.
The punk ethos is primarily made up of beliefs such as non-conformity, anti-authoritarianism, anti-corporatism, a do-it-yourself ethic, anti-consumerist, anti-corporate greed, direct action and not "selling out".
[...]
Punk aesthetics determine the type of art punks enjoy, which typically has underground, minimalist, iconoclastic and satirical sensibilities.
That's a very intellectual summary, but I don't know how to convey a more emotional understanding in just a few words. Before going any further, I recommend watching the classic interview with Iggy Pop where he talks about hating the term punk rock, and his motivations. Beyond that, hit play on Never Mind The Bollocks... or The Clash and let's go.
Before we even get into the design or implementation of Kakoune, I want to talk about the licence.
Most open-source licences work within copyright law to grant users permissions that copyright normally restricts. Kakoune's "licence" is different, though — it uses the Unlicence. Rather than working within copyright law, the Unlicence states that the software is in the public domain, i.e. that copyright law does not apply.
Can you just straight-up declare that a particular law doesn't apply to you? The exact answer to that question doesn't really matter: the legal profession is all about limiting legal risk, so any uncertainty makes this a terrible idea from a legal standpoint. Using the BSD or ISC licences would have the same practical effect, and put you on much firmer legal ground, so that's the path every lawyer would prefer. For example, Google's guidelines on using "public domain" code say:
Public domain is a complex topic that requires legal analysis on a case by case basis.
[...]
It is non-trivial to place software in the public domain. While an explicit disclaimer of copyright protection is required, that is not necessarily sufficient.
...and their rules for what projects Googlers can contribute patches to specifically forbids the Unlicence.
Meanwhile, the Unlicence website says things like:
Why Use the Unlicense?
Because you have more important things to do than enriching lawyers or imposing petty restrictions on users of your code.
While there may be ways to make the Unlicence more palatable to Google's lawyers, I get the impression that the creators of the Unlicence are perfectly happy the way it is now.
Going back to Wikipedia's list of punk values, we see things like "non-conformity", "anti-corporate greed", and "not selling out". I think the Unlicence is very punk-rock. It might not swear as much as the WTFPL, but it's setting out to offend lawyers, not 1970s tabloid readers.
Some popular text editors provide a polished, platform-native user-interface. Others build their interface on a web-browser rendering engine, giving them a completely custom interface that's highly portable. Kakoune does neither of these things, it only runs inside a terminal emulator.
In some ways this is incredibly limiting —
everything is aligned to a character grid,
you can't display any symbols or decorations that aren't text,
and a terminal's keyboard handling is much more primitive
than that of graphical toolkits.
On the other hand,
the terminal is vastly, vastly simpler than other output methods,
and it's pretty easy to make something
that looks about as good as any other terminal application.
Today in October 2020,
Kakoune uses the ncurses
library for managing terminal output,
but there's a branch in development that drops the external dependency
and does all the terminal management manually —
for a net decrease of 13 lines of code.
I think Kakoune's terminal-based interface is a lot like the traditional punk aesthetic of ripped clothes repaired with safety pins, or slogans hastily painted onto jackets. It's cheap to buy a new shirt from a store, it's easy to learn to sew enough to patch a hole, but literally anyone can slash a shirt and safety pin it together in under thirty seconds. In the same way, every platform has robust native widgets and lots of people know HTML and CSS, but literally anyone can add colours and formatting to a terminal-based "hello world" app in under thirty seconds. "Direct action" and "do-it-yourself ethic" are on Wikipedia's list of punk values, and it's hard to name a computer interface more egalitarian than the humble terminal.
I also want to point out another detail you'll quickly encounter when using Kakoune. As you can see in the screenshots on the website, Kakoune frequently displays help-text for the next key press or the syntax for its built-in command line. By default, Kakoune displays the image of a helpful paperclip next to such messages, satirising the less-than-helpful Microsoft Office Assistant. Sure enough, "satirical sensibilities" are on Wikipedia's list of punk values too.
No tool can completely cover every possible use, especially in a field as broad as text editing. Like many other editors, Kakoune can be extended with user-created scripts. However, Kakoune's scripting has some interesting twists of its own.
Let's say we're auditing an online payment system, and want to check that it doesn't log customers' credit-card numbers. Let's also assume this code-base consistently uses the abbreviation "ccn" for "credit-card number", so we want to find locations where the word "ccn" appears inside a call to the logging function. To do this interactively, a user might type something like:
%slog\(<ret>m<a-k>\bccn\b<ret>
...where <ret>
means the Return key,
and <a-k>
means Alt+K.
This basically means
"find all the calls to the logging function,
select the arguments,
then focus on argument lists that include the word 'ccn'".
That's not a 100% bullet-proof validation,
but it's a quick way to find the most glaring problems.
Doing that interactively is reasonable on a single file, but our code-base probably contains many, many files. We ought to script this functionality so we can quickly repeat it on many files. In Kakoune's scripting language, the easiest way to perform these actions on demand is:
execute-keys %slog\(<ret>m<a-k>\bccn\b<ret>
Yes, that's just the keys you'd type interactively,
used almost verbatim
as a parameter to the execute-keys
command.
Sometimes,
people familiar with more sophisticated text editors
or general-purpose programming languages
find this to be unreadably grotesque,
and they ask if there's a way
they can script Kakoune more like this:
select-buffer
find-all 'log\('
extend-selection-to-matching-bracket
for-each-selection {
if not find-any '\bccn\b' {
drop-selection
}
}
This is definitely more readable for somebody new to Kakoune, especially somebody with programming experience. However, there's a cost to this scheme most people don't think about: while it's a lot easier to look at this code and guess what it does, it's much harder to look at the keys you'd press interactively and guess what the equivalent script would be.
Now, there's a school of thought that says that code is read more often than it's written, so easy-to-read is more important than easy-to-write. That school of thought comes from computing's military and commercial origins, where non-technical users would ask programmers to solve a problem for them, and then the programmers would have to keep the solution working forever. On the other hand, the punk do-it-yourself safety-pins-and-painted-slogans ethos says that users shouldn't need a pack of programmers, writing scripts should be easy for everybody. It doesn't matter if it's hard to maintain an old script if writing a new one is fast and cheap. And therefore, Kakoune's scripting system optimises for writing, not reading.
There's also another reason the "readable" script above can't be written today: Kakoune's "scripting" does not support loops or if-statements. It's not really a scripting language in the traditional sense, it's pretty much straight-line imperative instructions.
(I'm not going to claim that Kakoune's scripting language is Turing-incomplete. I suspect it's intended to be incomplete, but Turing-completeness can be tricky, so who knows, really.)
If you want to do any kind of processing, you need to shell out to an external program — and I mean "shell out" literally. Kakoune has a special syntax for marking a block of text as a POSIX shell-script, and replacing the block with the output of that shell-script. Let's say you want to make Kakoune display an info box (the one with a picture of Clippy) if current line begins with the word "Dear". The core decision-making part of the code might wind up looking like this:
evaluate-commands %sh{
if [ "Dear " = "$kak_selection" ]; then
echo 'info "It looks like you'"'"'re writing a letter"'
fi
}
If you're like most software engineers, you probably had a pretty violent reaction to the above example. Having to launch an external process just for a conditional? Having to dynamically generate and evaluate code instead of just writing it? Having to deal with multiple layers of quoting? And all this in POSIX shell, widely regarded as one of the ugliest and most treacherous languages in common use? Surely this is a terrible idea!
And yet, there are some distinct advantages. Some people know C, some people know JavaScript, but everybody has to know at least a little bit of shell to get by. Some languages are designed to be embedded into a host application, some languages are designed to stand alone, but every language can take command-line arguments and print to standard output. Even if other languages are better at expressing logic, or at processing data, integrating different programs requires plumbing them together, and shell is great at that. So even if POSIX shell itself is one of the worst languages, for integration purposes it is every language.
It's still pretty ugly, of course, and some might consider it downright offensive, but punk has never shied away from offending mainstream tastes — in fact, quite the opposite. Not that Kakoune was designed primarily to offend, but it was definitely designed, and if the end result causes an uproar in the tabloids, they're more than welcome to spend column-inches talking about it.
Kakoune does not support plugins,
in the sense that the word "plugin" (or any variation) does not appear
anywhere in the editor's source-code.
Instead,
at startup Kakoune just loads
all the *.kak
files it can find
in ~/.config/kak/autoload/
.
As a result, there's a really smooth gradient of modularity
from sticking something in your kakrc
,
to splitting it into a separate file in your autoload
directory,
to giving a copy to your friend to stick in their autoload
directory.
At no point do you have to write a metadata file,
conform to a directory structure,
or sign up for a developer account.
It's all just a natural progression
from scratching your own itch
to helping others.
You can go further and add a README
or put your plugin in a Git repository to help people keep it up-to-date,
set things up so it gets listed on the official website,
but that's entirely optional —
you can do it if you want
or don't if you don't.
I've already mentioned the punk values of "direct action" and "do-it-yourself", but I think this is an excellent demonstration of those ideas. Kakoune's whole scripting system is designed to make it as quick and painless as possible to go from doing a thing manually to automating it and sharing that automation with others.
I confess, I'm not really a fan of punk rock myself. The music is very loud, and aggressive, and I just don't have that inner reserve of frustration and anger that the Sex Pistols tapped into in 1977. However, I respect the time and effort that goes into creating punk rock (or any other creative outlet), I have sympathy for ideas like anti-consumerism and non-conformity, and I absolutely love punk's radical accessibility, encouraging and empowering everybody to express themselves.
In the same way, although Kakoune has design limitations that annoy me, and there's occasional bugs or things that are confusingly documented, I love Kakoune's radical accessibility. I'd rather use rough, unpolished software with that philosophy than beautiful, powerful software that only provided the functionality the creators thought I should have. More to the point, I'd rather be part of the team working in and around the software I use than part of the politely-applauding audience.
But that's just me. That's who I am, and the kinds of things I value. Other people value different things, and would probably hate using Kakoune. That's OK, the world's big enough for multiple viewpoints.
But if you do like punk rock, I recommend trying Kakoune as your text editor.
Thanks to cjv, avalenn, and the rest of the folks in #kakoune on irc.freenode.org for reviewing drafts of this essay.
Thanks Screwtapello for the link and tips, I'll give it a try :)
Is this Hashmap used both for keypress event and
execute-keys
parsing ? Like what would happen if I rename the keyi
to<insert>
?