Hello & Some Plugins

:wave: :wave: :wave:

Hey there everyone! After many years of using Vim (and Neovim), writing a couple plugins and coming up with a setup I really liked, I recently came across Kakoune and had to give it a try. Armed with kak-lsp, I instantly knew it was going to be a great fit for the kind of setup I’ve been looking for with Vim.

While I was switching editors I decided to try an experiment and organize my config around a large collection of small plugins, and the only job of my kakrc is to load the plugins via require-module. Since they are pretty small & isolated I added a README and pushed them to their own Github repo for anyone else to use or learn from. Some of the plugins & their motivation are described below.

Kakoune sadly doesn’t have support for splits, at least not the way I prefer to use them. Depending on what I’m working on I might have vertical or horizontal splits; or tabs. I had already setup my preferred terminal emulator (Kitty) to use splits (and there’s no way in hell I’m going back to tmux… way too complex for just needing window management). Since Kakoune already sports great integration with Kitty I decided to take it a little further and implement splits the way Vim does them.

I’m very interested in making my splits plugins a little more reusable between the various window management solutions in the kak community; Kakoune’s terminal API is a little too limited atm to make it fit without some modifications (ie. it doesn’t accept an argument for the split direction). I plan to start a separate discussion around that.

Another thing I missed from (Neo)vim was my Spacemacs-like keyboard shortcut groupings (ie. space+g would present a menu of Git shortcuts, space+f for file-related shortcuts, space+b for buffer-related ones, etc). I was using the vim-which-key plugin to present the menu of shortcuts, but since Kakoune already had that builtin all I had to do was define some usermodes & mappings and everything else just worked.


Regarding split direction, @alexherbo2 showed me a nifty solution of just aliasing either or horizontal or vertical version for the next usage.

alias global terminal tmux-terminal-vertical

As for the groupings, I use a ton of them, by defining my own user-modes. I have user modes for everything from git to spelling!

map global user -docstring "Enable Git keymap mode for next key" G ": enter-user-mode<space>git<ret>"
declare-user-mode git
map global git -docstring "commit - Record changes to the repository" c ": git commit<ret>"
map global git -docstring "blame - Show what revision and author last modified each line of the current file" b ': connect-vertical; connect-terminal tig blame "+%val{cursor_line}" -- "%val{buffile}"<ret>,z'
map global git -docstring "blame - Show what revision and author last modified each line of the current file" B "<esc>,Gb"
map global git -docstring "diff - Show changes between HEAD and working tree" d ": git diff<ret>,z"
map global git -docstring "git - Explore the repository history" g ": repl tig<ret>"
map global git -docstring "github - Copy canonical GitHub URL to system clipboard" h ": github-url<ret>"
map global git -docstring "log - Show commit logs for the current file" l ': repl "tig log -- %val{buffile}"<ret>'
map global git -docstring "status - Show the working tree status" s ': repl "tig status"<ret>'
map global git -docstring "status - Show the working tree status" G ': repl "tig status"<ret>,z'
map global git -docstring "staged - Show staged changes" t ": git diff --staged<ret>"
map global git -docstring "write - Write and stage the current file" w ": write<ret>: git add<ret>: git update-diff<ret>"

Now, you might ask, “why not g?” – because that is for my grep commands

map global user -docstring "Enable grep keymap mode for next key" g ": enter-user-mode<space>grep<ret>"
declare-user-mode grep
map global grep l %{: grep '' %val{bufname} -H<left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left>} -docstring "Local grep"
map global grep g %{<A-i>w"gy<esc>: grep <C-r>g<ret>: try %{delete-buffer *grep*:<C-r>g}<ret> : try %{rename-buffer *grep*:<C-r>g}<ret> : try %{mark-pattern set <C-r>g}<ret>} -docstring "Grep for word under cursor, persist results"
map global grep / ': exec /<ret>\Q\E<left><left>' -docstring 'regex disabled'
map global grep i %{:grep -i ''<left>} -docstring 'case insensitive'
map global grep t %{:grep -i '' -g '*.ts'<left><left><left><left><left><left><left><left><left><left><left>} -docstring 'just typescript'
map global grep k %{:grep -i '' -g '*.kt'<left><left><left><left><left><left><left><left><left><left><left>} -docstring 'just kotlin'
map global grep g %{:grep -i '' -g '*.go'<left><left><left><left><left><left><left><left><left><left><left>} -docstring 'just go'

That’s cool, that is essentially how my plugin works. Since I’m using kitty and the split direction depends on the kitty @ launch command (whereas Kak’s builtin kitty integration uses kitty @ new-window is which doesn’t take split location) I had to create new commands for vertical, horizontal and overlay splits (overlay actually renders on top of the current terminal). I then mapped those commands to space wv & space ws respectively.

This feature is one of my favorites! It saved me so much code that I had in my Vim config (plus the plugin). So nice!

I absolutely adore tmux — as I use it remotely a lot. But locally I often considered playing more with kitty – but at this point it would just be a second one of accomplishing the same thing.

@robertmeta Why not using terminal-mode.kak?

From a mapping, you can use the terminal-set command directly:

terminal-set global tmux tmux-terminal-vertical tmux-focus

Hi Joe! Long time no see!

When I moved from Vim, I configured tmux to intercept ^W and do what Vim used to do, mostly. I went through several iterations of trying to make Kakoune spawn new windows, but I eventually found that it isn’t hard at all to start Kakoune manually, if:

  • You have tmux bindings to make splits, and these start your shell. (I made tmux-ctrlw to emulate what Vim does)
  • You have a little shell wrapper for Kakoune that joins the same session by default.

Then it is just <c-w>|kak<ret> or <c-w>-kak<ret> to make splits.

1 Like

Control + w looks a nice prefix. I’m using Control + Space for now, but I think I will like Control + w more for being single hand.

What do you think of Control + w to keep the mode, and Control + w again to leave?

For the scripts, they look a bit complicated. Why not using a simple tmux config to source from your ~/.tmux.conf, instead of a Bash script? And for Kakoune, using a shell environment variable.


# Environment variables
export KAKOUNE_SESSION=kakoune

# Functions
kamux() {
  KAKOUNE_SESSION=$(tmux display-message -p '#{window_name}') \
  kak-wrapper "$@"

# Aliases
alias kak=kak-wrapper
1 Like

Hey Jason! Great to run into you here :smile:

As I mentioned above, I’m loathe to use tmux again. I know others love it, but it’s just too much for me. Actually, I’ve configured Kitty to work like Vim (C-h, C-l, C-j & C-k to switch windows) and then Kakoune just launches new instances using the kitty @ launch command which takes a location type. I’ve noticed recently though that I can no longer open a split from a split. Might be something I broke, need to look into it when I have a moment.

@alexherbo2 I’m actually making pretty heavy use of connect.kak in my setup, so thanks for that!

1 Like