> **⚠️️ this guide is written as of Kakoune v2022.10.31, future versions may not be compatible with parts of this guide anymore ⚠️** When I first started seriously learning to program, I used a mixture of text-editors and IDE's and really whatever I could get my hands on. I didn't quite know what I was doing. ## A rough timeline of me first using text editors - I used [Atom](https://atom.io) *(rest in peace, you were loved by some)*. - I saw someone using [Sublime Text](https://www.sublimetext.com/) and thought it looked very pretty. - Sublime costs money. Never-mind I'm broke. - What's this, [Brackets](https://brackets.io/) is *gorgeous* (this is something I maintain to this day. Brackets is the most beautiful text editor but no one knows it). - Oh, Brackets is unmaintained and doesn't work with new frameworks very well :\[ `EDIT: It is now maintained again, go check it out` - Maybe I want to be an iOS developer? omg it takes seven hours to install [Xcode](https://developer.apple.com/xcode/) (5 of those are just opening the app) - Never-mind, [Swift](https://www.swift.org/) isn't fun anymore, and Xcode serves no other purpose to me. - Woah, this guy in this one YouTube tutorial is using *the terminal* to edit. How is that even possible? - Oh! It must be [Nano](https://www.nano-editor.org/). Team Nano! - Wait.. this looks different and there's no syntax highlighting :\[ - Never-mind, not team Nano anymore. - Ohhh it was [Vim](https://www.vim.org/). Let's open it up, can't be too hard to use right? - *One vim-quitting-induced OS reinstall later* - Ok, let's not do that. - What's this hot new thing? [VSCode](https://code.visualstudio.com/)? I've used [Visual Studio](https://visualstudio.microsoft.com/) before, but idk what this is. Let's try it, why not. And there I was, yet another VSCode dev. To be clear, there's absolutely nothing wrong with this. The themes are great, the editor runs smoothly (for me), extensions do all the hard work, it's a mostly good experience. But something in me yearned for more, I needed something new. ## To [Vim](https://www.vim.org/), [Neovim](https://neovim.io), etc. A video by [ThePrimeagen](https://www.youtube.com/@ThePrimeagen) on YouTube was the final catalyst for me, watching him duck and weave through files, never touching the mouse and editing at the speed of thought was inspiring. - I set out to learn Vim. - I quickly switched to [Neovim](https://neovim.io/), but eventually gave up and returned to VSCode I wasn't quite ready for the world of configuration and text file customization. My sudden introduction to it scared me away. Eventually, I stumbled across [Helix](https://helix-editor.com/) configuring Helix is dead-simple. In fact, here's my Helix config right here: ```toml theme = "everforest_dark" [editor] middle-click-paste = false line-number = "relative" auto-save = true auto-format = false bufferline = "always" color-modes = true shell = ["zsh", "-c"] [editor.statusline] mode.normal = "NORMAL" mode.insert = "INSERT" mode.select = "SELECT" left = ["mode", "file-name", "version-control"] center = ["spinner", "position-percentage", "file-encoding"] right = ["diagnostics", "primary-selection-length", "position", "file-type"] [editor.lsp] auto-signature-help = false display-signature-help-docs = false # Remaps [keys.normal] A-F = ":fmt" esc = ["collapse_selection", "keep_primary_selection", ":w"] C-r = [":reload"] "{" = "goto_prev_paragraph" "}" = "goto_next_paragraph" [keys.normal.space] space = "goto_next_buffer" m = "goto_previous_buffer" q = ":buffer-close" [keys.select] "{" = "goto_prev_paragraph" "}" = "goto_next_paragraph" [keys.insert] A-F = ":fmt" esc = ["normal_mode", ":w"] ``` > Not very complicated, all things considered I used Helix for a while, I really liked it a lot. Eventually, I got good at the keybindings and was a whizz at getting through files just like I had dreamt of. But the 'batteries included' nature of Helix eventually got to me. It did nearly everything I needed, but the lack of customization via plugins really killed it for me eventually. Not to mention, the beta software state meant that Helix had a lot of little quirks and bugs that sometimes made using it a pain in the ass. ## To [Kakoune](https://kakoune.org/) I knew [Kakoune](https://kakoune.org/) was the inspiring editor for Helix, and I really did love the keybindings for Helix, so I decided to give it a try. Well, it was damn good! Using Kakoune was a much smoother experience, Kakoune was obviously more mature, thought out, and performance-wise I could feel noticeable lag going back to Helix. The only problem; configuration. Eventually, I figured it out. I used a combination of other people's config files, trial and error, and reading some of the source code for Kakoune, but eventually I understood the configuration layout well enough to write a config file of my own that serves me well. ## Small disclaimer This guide is for those who already know keybindings in Kakoune, and want a nice configuration file. I'm not going to be going over actually using the editor in detail. ## Writing a nice configuration file Here's what Kakoune looks like by default ![default kakrc](https://i.imgur.com/DArA8Jy.png) > pretty damn ugly if I do say so myself Here's what my current config looks like ![default kakrc](https://i.imgur.com/h3wlERq.png) > That's a marked improvement for me at least ## Step-by-step ### The basic-basics When ran, `kak` will search for the autoload folder(s) and recursively load all `.kak` files in it. The `autoload` dir is usually `~/.config/kak/autoload/`. Then, `kak` will search for a `kakrc` file in your configuration folder (usually `~/.config/kak/kakrc`), and load it up. Let's set that up ```bash mkdir -p ~/.config/kak kak ~/.config/kak/kakrc ``` > yes, we're using Kakoune to edit it's own config ### Tips Kakoune has a lot of detailed documentation, it's just not very easy to read. The `:doc` command gives instant access to every article, it's just not super easy to find what you're for. All the actual docs files can be found on GitHub [here](https://github.com/mawww/kakoune/tree/master/doc) ### Color scheme Obviously, the most important thing about a text-editor is it's themes. Let's get something nice going for Kakoune. In Kakoune, the `colorscheme` command set's the terminal. You can type `:colorscheme ` and `` around to find something you like. `kakrc` ```vim colorscheme gruvbox-dark ``` > that should make things nicer You can reload your `kakrc` by running `:source kakrc`. When that doesn't work, just `:wq` and open it right back up, no biggie. *How's the new color-scheme look?* **Let's take a quick detour to talk about scopes** ### Scopes > `global/` First, `:doc scopes` According to the docs, there's three options for scopes. `global`, `buffer`, and `window` ##### Global The `global` scope refers to every linked instance of `kak` currently running (you can spawn new 'linked' instances of Kakoune with the `:new` command). Changes you make to the `global` scope will be available everywhere. If you edit your `kakrc`, changes will only be available in new session from then on. ##### Buffer A buffer is in most cases, just the raw file that is opened. Kakoune has a neat feature called `:new` that I won't get into, but it allows multiple instances of the same file to be edited at the same time which is wicked cool. Objects in the `buffer` scope will affect every instance of that file open in `kak` ##### Window The `window` scope is the logical subset of the `buffer` scope. Where the `window` scope affects all instances of `kak` with that buffer open, `window` refers to *this* instance of *this* buffer open. Make sure you understand this to the best of your abilities, `scopes` are *very* handy in Kakoune ### Line numbers Something very useful in any sort of text editor is line numbers, fortunately Kakoune offers line numbers as a builtin feature. Kakoune offers most visual customization through the `add-highlighter`command, the docs are at `:doc highlighters`. #### Syntax `add-highlighter [-override] / ...` In Kakoune, you can think of highlighters as literal unique objects in the editor, each highlighter is a unique instance with it's own unique scope. Here's how to add line numbers to Kakoune ```vim add-highlighter global/ number-lines ``` Let's go over that word-by-word - `add-highlighter` - the root command to add 'highlighters' to the editor - `global/` - the scope of this command - `number-lines` - the builtin highlighter to apply to the Kakoune look But wait, did you notice that `global` has a trailing `/`? That's actually another very neat feature of Kakoune. In `kak` each `highlighter` is it's own unique object with it's own ID. This means that the alternate command `remove-highlighter` exists, you'll see how useful this can be later in this article. How to use `remove-highlighter` is an exercise left to the reader for now (`:doc` is your friend). #### Great, but what about `/`? In Kakoune, you can set the name of a `highlighter` , or just let `kak` pick one for you automagically. Setting a custom name in Kakoune is what the `/` is for. For example, here's the equivalent command but with a custom name: ```vim add-highlighter global/number-lines-highlighter number-lines ``` In this case, our highlighter will be named `number-lines-highlighter` and that allows us to refer to it in the future. Unless you know you'll need to refer to a `highlighter`, I recommend letting Kakoune pick names for you since it will eliminate the risk of accidental name collision. The trailing `/` is how you tell Kakoune to pick a name for you. #### Getting gnarly In Kakoune, some `highlighters` have optional arguments that can be passed to them. The `:docs` will always explain this. Here's the options for `number-lines`: ```text -relative show line numbers relative to the main cursor line -hlcursor highlight the cursor line with a separate face -separator specify a string to separate the line numbers column from the rest of the buffer (default is '|') -cursor-separator identical to -separator but applies only to the line of the cursor (default is the same value passed to -separator) -min-digits always reserve room for at least num digits, so text doesn’t jump around as lines are added or removed (default is 2) ``` Let's apply some of those; ```vim add-highlighter global/ number-lines -hlcursor -relative -separator " " -cursor-separator " |" ``` Try adding each of those flags one at a time to see what happens. After that you can customize it to your liking. #### Going deeper To read a much more extensive and informative article on `highlighters`, see [here](https://zork.net/~st/jottings/Intro_to_Kakoune_highlighters.html) ### Matching braces `kak` has another useful feature and that's to highlight matching brackets, braces, parentheses, quotes, etc. The command is ```vim add-highlighter global/ show-matching ``` Here's a before-and-after to illustrate what that does: **Before** ![show-matching-before](https://i.imgur.com/oZotdaR.png) **After** ![show-matching-before](https://i.imgur.com/5A6A4XY.png) Notice how the other bracket was highlighted blue in the second photo. This feature can be super useful in large codebases, or situations where there's nested blocks in your code. ### Pit Stop Ok, here's our `kakrc` so far ```vim # custom theme colorscheme gruvbox-dark ## highlighting # display line numbers add-highlighter global/ number-lines -hlcursor -relative -separator " " -cursor-separator " |" # show matching symbols add-highlighter global/ show-matching ``` > pretty simple so far ### Set-option `:doc options` #### Syntax `set-option [-add|-remove] ...` #### Tab-width Most settings in `kak` can be accessed though the `set-options` command. For example, I like my tabs to be 2 spaces wide, so I'm going to add that to my config like this: ```vim #command #scope #name #value set-option global tabstop 2 set-option global indentwidth 2 ``` > Options don't get names in `kak`, that's why there's no `/` after the `global`scope. #### Scroll-off In Kakoune, you can specify a margin around the cursor. This is useful because it lets you see the text around a cursor even when editing text at the edges of the window. ```vim # always keep eight lines and three columns displayed around the cursor set-option global scrolloff 8,3 ``` ### Keybindings `:doc mapping` The `map` command is really quite simple. You tell it `key a`, and `keys b` and then whenever you type `key a`, Kakoune will just pretend you typed `keys b` instead. A bit like an alias. #### Syntax `map [switches] ` Everything here should be straightforwards except possibly ``. I'm not going to get into `modes` here, since those are something you should already understand if you know `vim/kak` keybindings. Here are the modes defined in `:doc mapping` ```text insert insert mode normal normal mode prompt prompts, such as when entering a command through :, or a regex through / menu mode entered when a menu is displayed with the 'menu' command user mode entered when the user prefix is hit (default: '') goto mode entered when the goto key is hit (default: 'g') view mode entered when the view key is hit (default: 'v') object mode entered when an object selection is triggered (e.g. '') ``` #### `normal` mode maps ##### `qwe` Normally, to navigate word-by-word you'd use the `w`, `b`, and `e` keys to move around. However, I find it more convenient to remap the `b` to `q`. That way the keys are `qwe` and are next to each other on my keyboard. Here's how to do that ```vim # remap b to q map global normal q b # variations of b map global normal Q B map global normal map global normal ``` Kakoune doesn't have a `select` mode like Vim or Helix, so we only need to map from `normal` mode. ##### Clear selection on`` In `kak`, pressing `` doesn't clear any highlighted text or collapse cursors which doesn't feel intuitive to me. Let's fix that; ```vim # unselect on map global normal ";," ``` `;` un-highlights text, and `,` gets rid of multiple cursors. ##### Auto-comment lines I like to map `` (control+v) to the `:comment-line` command in Kakoune. This lets me toggle lines really quickly when debugging or refactoring code. ```vim # comment lines map global normal ":comment-line" ``` > `` tells Kakoune to execute the commadn Normally, I'd map `` to this, but in Kakoune certain key-mappings don't work because of compatibility features (i think), and control+c is one of them. More info [here](https://github.com/mawww/kakoune/issues/797#issuecomment-649494417). #### `user` mode maps `user` mode is really neat, it allows you to setup a little menu of commands that you access by typing `` and then the mapping. ##### Buffer control Some utilities for navigating buffers ```vim map -docstring "close current buffer" global user b ": db" map -docstring "goto previous buffer" global user n ": bp" map -docstring "goto next buffer" global user m ": bn" ``` > `-docstring` is just the help-text shown for the mapping in the menu Now, by typing `m`, `n`, and `b` I can go one buffer forwards, back, and close the current buffer respectively. The more astute among you may have noticed that the commands in that mapping have a space separating the `:` colon and the actual command. In older versions Kakoune we did this when we didn't want the command saved in the history (access the history by typing `:` and pressing the up/down arrows). Current and future versions of Kakoune do this automatically, so we don't need to worry about the ``. ##### Some more misc. mappings ```vim # fancy insert newline map -docstring "insert newline above" global user [ "Oj" map -docstring "insert newline below" global user ] "ok" # spellcheck (requires aspell) map -docstring "check document for spelling" global user w ": spell" map -docstring "clear document spelling" global user q ": spell-clear" ``` ##### And one more ```vim # copy to system pboard [MAC ONLY] map -docstring "copy to system pboard" global user y " pbcopy" ``` - `` - the *pipe-to* command - `pbcopy` - a shell tool available on macs to manipulate the clipboard #### Insert mode autosave I like it when text-editors autosave. Neovim has this awesome autosave plugin that prints a little log message each time it saves and I want to implement something similar to that as a `map`. First, the most basic ```vim map -docstring "save current buffer" global user s ": w" ``` But there's no log :( Also, later we're going to make this something that happens automatically when the user presses `` in `insert` mode. So let's take a really quick detour to the `define-command` command, essentially functions in `kak`. ### Custom commands `:doc commands declaring-new-commands` ```text New commands can be defined using the define-command command: define-command [] commands is a string containing the commands to execute, and switches can be any combination of the following parameters: -params the command accepts a num parameter, which can be either a number, or of the form .., with both and omittable -override allow the new command to replace an existing one with the same name -hidden do not show the command in command name completions -docstring define the documentation string for the command -menu -file-completion -client-completion -buffer-completion -command-completion -shell-completion -shell-script-completion -shell-script-candidates old-style command completion specification, function as-if the switch and its eventual parameter was passed to the complete-command command (See Configuring command completion) The use of those switches is discouraged in favor of the complete-command command. Using shell expansion allows defining complex commands or accessing Kakoune's state: # create a directory for current buffer if it does not exist define-command mkdir %{ nop %sh{ mkdir -p $(dirname $kak_buffile) } } ``` Overall, it's a lot like `map`. Define a command name, and then some other commands that will be ran. #### Save-buffer Here's my `save-buffer` command: ```vim define-command save-buffer -docstring "save current buffer and show info" %{ write info "file saved at %sh{date}" } ``` - `write` - save the current buffer (the same thing as `:w`) - `info - `info` logs a little snipped to the user, try `:info "hello, world!"` to see for yourself. - `'file saved at %sh{date}'` - `kak` will first expand `%sh{date}` into the output of the `date` shell command, and then interpolate that with `file saved at ` before passing it to the `info` command. The reason we don't need the `:` in the `%{}` block is that Kakoune treats the commands there as just that - commands. The `map` command simulates those actual keypresses, so we need to tell the editor to go to `prompt` mode. #### A more complicated example ```vim # open tutor (needs curl) define-command trampoline -docstring "open a tutorial" %{ evaluate-commands %sh{ tramp_file=$(mktemp -t "kakoune-trampoline.XXXXXXXX") echo "edit -fifo $tramp_file *TRAMPOLINE*" curl -s https://raw.githubusercontent.com/mawww/kakoune/master/contrib/TRAMPOLINE -o "$tramp_file" } } ``` > found on the [Kakoune forums](https://discuss.kakoune.com/) Figuring out how this works is an exercise left to the reader. ### Plugins The main reason I switched from Helix to Kakoune was plugins. Helix does not yet have support for plugins, where Kakoune has an incredible ecosystem. Albeit a much smaller one than Vim/Neovim, but personally, I think `kak` extensions are much easier to write, In Kakoune, any `.kak` files in the `~/.config/kak/autoload` directory will be loaded, so one way to install extensions is to just clone git repos there. **However** Kakoune has an extremely well made package manager that I highly recommend. It's called [plug.kak](https://github.com/andreyorst/plug.kak). According to the site there's a few ways to install it, but here's how I like to do it: ```bash mkdir -p $HOME/.config/kak/plugins git clone https://github.com/andreyorst/plug.kak.git $HOME/.config/kak/plugins/plug.kak ``` Before we start using it, you should go read the `README` on the tool's [GitHub](https://github.com/andreyorst/plug.kak). #### Initializing `plug.kak` `plug.kak` has to be loaded by `plug.kak`! Kinda trippy I know. Here's the line to do that: ```vim source "%val{config}/plugins/plug.kak/rc/plug.kak" plug "andreyorst/plug.kak" noload ``` This should go before your other plugins in your `kakrc`. - `source` just tells `kak` where to find `plug.kak` - `plug` is a special command that `plug.kak` provides that tells it to make that plugin available to Kakoune, among other things. #### Loading plugins Whenever you add a plugin, you need to reload your `kakrc`, then you can run the `:plug-install` command. Read the `plug.kak` [README](https://github.com/andreyorst/plug.kak) for a better explanation of all this. #### Our first plugin - more themes I like Gruvbox, I do, but I don't quite like running it 24/7, the colors hurt my eyes. Luckily, the amazing `anhsirk0` made a huge collection of amazing themes for Kakoune. Here's the repo for that [GitHub](https://github.com/anhsirk0/kakoune-themes). Unfortunately, the structure of that repo makes it not work super well with `plug.kak`. Luckily, I made a fork of it that preserves all the themes and makes it work with `plug`. [Link here](https://github.com/secondary-smiles/kakoune-themes). Now, let's get it 'installed'. ```vim # themes plug "secondary-smiles/kakoune-themes" theme config %{ colorscheme pastel } ``` > Woah, there's a lot going on there. - `plug "secondary-smiles/kakoune-themes"` - `plug.kak` will automagically search github for a plugin if you just provide a *username/repo* string. - `theme` - this tells `plug.kak` that this extension is actually a pack of themes, or just one theme. It will treat the files differently because of that. - `config` - this is some `Kakscript` that will be ran only once `plug.kak` has loaded this extension. - `%{ colorscheme pastel }` - this will be run once `plug.kak` loads the extension, it works in a pair with the `config` keyword. (blocks in Kakoune are defined with `%[optional directive]{}`). Well, try and reload your config now, see what you think! Oh, we should probably remove that `colorscheme gruvbox-dark` from earlier too, we don't need two themes racing each-other to be dominant in the editor. #### Auto-pairs I might be the weird one out, but I really like auto-pairs when typing. That's where typing a matched character like `(`, `[`, `<`, etc. the editor automatically inserts the opposite character (`)`, `]`, `>`, etc.). Luckily, a plugin exists for just that! ```vim # autopairs plug "alexherbo2/auto-pairs.kak" config %{ enable-auto-pairs } ``` `enable-auto-pairs` is a command provided by `auto-pairs.kak`. You can, of course, disable it with `:disable-auto-pairs`. #### Fuzzy-finder Having a builtin file picker is really useful in any editor. [`fzf.kak`](https://github.com/andreyorst/fzf.kak) is a really superb implementation of this with a lot of customization abilities. ```vim # fzf plug "andreyorst/fzf.kak" config %{ require-module fzf require-module fzf-grep require-module fzf-file } defer fzf %{ set-option global fzf_highlight_command "lat -r {}" } defer fzf-file %{ set-option global fzf_file_command "fd . --no-ignore-vcs" } defer fzf-grep %{ set-option global fzf_grep_command "fd" } ``` If you read the `plug.kak` `README`, you'd already understand this. Let's go over it anyways though. `fzf.kak` provides several modules to further customize the plugin. In the first `config` block, we `require` those modules so that they get loaded. Then, we use the `defer ` block to run more commands only *after* that module is loaded by `plug.kak`. In this case, I'm using [`lat`](https://github.com/secondary-smiles/lat) (*shameless plug*) as my default file viewer, and [`fd`](https://github.com/sharkdp/fd) as my grepper. I also like to set `f` to enter fuzzy-finder mode: ```vim map -docstring "open fzf" global user f ": fzf-mode" ``` #### Powerline The default Kakoune status-bar leaves a lot to be desired. This plugin adds a lot more customizability. Read the [README](https://github.com/andreyorst/powerline.kak) for more info on customization ```vim plug "andreyorst/powerline.kak" defer kakoune-themes %{ powerline-theme pastel } defer powerline %{ powerline-format global "git lsp bufname filetype mode_info lsp line_column position" set-option global powerline_separator_thin "" set-option global powerline_separator "" } config %{ powerline-start } ``` #### Enhanced selection In Helix, pressing `x` will select the entire line. Subsequent `x`'s will keep expanding the selection line-by-line. In Kakoune, Subsequent `x`'s do nothing. [byline.kak](https://github.com/evanrelf/byline.kak) does exactly that. In fact, pressing `x` will shrink the selection by a line! Very useful. ```vim plug "evanrelf/byline.kak" config %{ require-module "byline" } ``` #### Luar Some Kakoune plugins are written in Lua, this plugin will allow those ones to run. Adding this plugin is a nice future-proof against plugins randomly break because you forgot this one. ```vim plug "gustavo-hms/luar" %{ require-module luar } ``` #### LSP I Kakoune has autocomplete out-of-the-box, but now that LSP's are standard, it makes a lot of sense to use them. There's an extension for that! ```vim plug "kak-lsp/kak-lsp" do %{ cargo install --locked --force --path . # optional: if you want to use specific language servers # mkdir -p ~/.config/kak-lsp # cp -n kak-lsp.toml ~/.config/kak-lsp/ } ``` - The `do` directive tells `plug.kak` to run those shell commands only when first installing the plugin. However, `kak-lsp` requires a bit more configuration to work properly. First, read the `kak-lsp` [README](https://github.com/kak-lsp/kak-lsp) (always read the README for everything). Before finishing `lsp`, let's learn about `hooks`; ### Hooks `:doc hooks` Hooks in `kak` are like Events in Javascript, or `autocmd` in Vim/Neovim. Basically, you give Kakoune some commands to run, and a trigger. When `kak` detects that trigger happening, it'll run your commands. #### Autosave Let's finally finish that autosave feature we were working on. Here's a simple hook to do that: ```vim hook global ModeChange pop:insert:.* %{ save-buffer } ``` - `ModeChange` - the hook for whenever the user goes from `user` to `insert` or any combination of other modes - `ModeChange` accepts a string formatted as `[push|pop]::` - `pop:insert:.*` - this is the filter for the `ModeChange` hook, let's go over that - `pop` - this is the *kind* of mode-change. The options here are `pop`, `push`, and `.*`. - `pop` - refers to moving out of a mode and into the next one. - `push` - *push*ing a command into a mode, for example, pressing `;` escapes `normal` mode for a single command. - `.*` - wildcard for all - `insert` - the **from** mode, or the mode that we're leaving. - `.*` - the **to** mode, or the mode that we're going to. This is set to *any*, as we want to save anytime we exit `insert` mode - `save-buffer` - our custom command to save the buffer and log the time. #### Soft-wrap in markdown files Another hook I have enabled is soft-wrapping text in `.md` files. I find that it makes it a lot easier to edit text (not code) when I can see everything at once and don't have to horizontally-scroll. ```vim hook global WinSetOption filetype=markdown %{ add-highlighter -override global/markdown-wrap wrap -word hook -once -always window WinSetOption filetype=.* %{ remove-highlighter global/markdown-wrap } } ``` > Yeah, you can nest `hooks` 😎 Figuring out what the nested `hook` does is an exercise left to the reader. #### Lsp II If you read the `kak-lsp` [README](https://github.com/kak-lsp/kak-lsp), then this part is going to make a lot of sense. While it's possible to just blindly enable `kak-lsp` for everything, I prefer so set hooks for the specific filetypes that I want to be editing. ```vim hook global WinSetOption filetype=(rust|javascript|typescript|c) %{ lsp-enable-window lsp-inlay-diagnostics-enable global } ## enable syntax highlighting for each lang # c hook global WinSetOption filetype=c %{ hook window -group semantic-tokens BufReload .* lsp-semantic-tokens hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens hook -once -always window WinSetOption filetype=.* %{ remove-hooks window semantic-tokens } } # rust hook global WinSetOption filetype=rust %{ hook window -group semantic-tokens BufReload .* lsp-semantic-tokens hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens hook -once -always window WinSetOption filetype=.* %{ remove-hooks window semantic-tokens } } # typescript hook global WinSetOption filetype=typescript %{ hook window -group semantic-tokens BufReload .* lsp-semantic-tokens hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens hook -once -always window WinSetOption filetype=.* %{ remove-hooks window semantic-tokens } } # javascript hook global WinSetOption filetype=javascript %{ hook window -group semantic-tokens BufReload .* lsp-semantic-tokens hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens hook -once -always window WinSetOption filetype=.* %{ remove-hooks window semantic-tokens } } ``` > If you read the comments, you'll also notice that we enabled better syntax highlighting for each of those filetypes as well. I also like to set a mapping to `user` mode to let me access the `lsp` menu really quickly: ```vim map -docstring "open lsp" global user l ": enter-user-mode lsp" ``` - Some extensions create their own special menus like the one that `` creates. We access those with the `:enter-user-mode` command. - Now, `lf` will perform lsp-assisted formatting! #### Tab completion I don't like the ``, `` convention for selecting autocomplete items. This is the recommended hook (according to the Kakoune wiki) for enabling `` and `` selections. ```vim # tabs for autocomplete hook global InsertCompletionShow .* %{ try %{ # this command temporarily removes cursors preceded by whitespace; # if there are no cursors left, it raises an error, does not # continue to execute the mapping commands, and the error is eaten # by the `try` command so no warning appears. execute-keys -draft 'h\h' map window insert map window insert hook -once -always window InsertCompletionHide .* %{ unmap window insert unmap window insert } } } ``` #### LSP III To learn more about creating custom completion tools in Kakoune see [here](https://zork.net/~st/jottings/Intro_to_Kakoune_completions.html). ### Goodbye clippy You probably noticed that clippy appears a lot in Kakoune ```text ╭──╮ │ │ @ @ ╭ ││ ││ │ ││ ││ ╯ │╰─╯│ ╰───╯ ``` > this mf Well, a not-so-secret easter egg in Kakoune is that it's possible to change the assistant! Here's how to remove clippy altogether ```vim set-option global ui_options terminal_assistant=none ``` > Available options are `clippy`, `dilbert`, `cat`, and `none`. Try setting each of those, something interesting might happen ;D ## Wrapping up My current, mostly up-to-date `kakrc` can be found on my github [.dots](https://github.com/secondary-smiles/.dots/blob/main/pkg/kakoune/kakrc). Kakoune is an incredible editor, I've really never had this much fun in a text editor, and for me it just feels so good using a [punk-rock editor](https://zork.net/~st/jottings/kakoune-a-punk-rock-text-editor.html). This article isn't an introduction to terminal-editors, but if you're interested in the field, YouTube is a great starting place. Also check out the [Kakoune Forums](https://discuss.kakoune.com/) for infinite `kak` tips and tricks. Thanks for reading!