Switching between different keyboard layouts

I thought I’d show how I handle multiple keyboard layouts in my kakoune configuration in case that’s useful to anyone. On my laptop, I alternate between using the built-in Qwerty keyboard, and an external ortholinear keyboard in Dvorak. On Dvorak, I remap H, T, N, S to H, J, K, L., but I also want an easy way to remove those mappings when I switch to Qwerty. To do that:

I create a file with Dvorak-specific bindings at ~/.config/kak/keymaps/dvorak.kak, consisting of only map commands:

set-option global keymap_name "Dvorak"

map global normal l s
map global normal s l
map global normal n k
map global normal k n
...

I also create another empty file at ~/.config/kak/keymaps/qwerty.kak with bindings that only make sense on Qwerty.

Then, to switch between layouts, I use the following :keymap command:

declare-option -docstring "Filepath to the kak file that defines the current keymap" str keymap 
declare-option -docstring "Name of the current keymap" str keymap_name

define-command -params 1 -shell-script-candidates %{
    ls "$kak_config/keymaps/" | grep '\.kak$' | perl -pe 's/^(.*)\.kak$/\1/'
} keymap %{
    # Disable previous keymap
    try %sh{
        cat "$kak_opt_keymap" | sed -e 's/^map/unmap/' -e 's/ -docstring .*//'  
    }
    set global keymap ""

    set global keymap "%val{config}/keymaps/%arg{1}.kak"
    source "%opt{keymap}"
}

Calling :keymap dvorak will source the kak file for Dvorak. Then, calling :keymap qwerty will load the previous keymap file (dvorak.kak), call an unmap for every map, and then source qwerty.kak.

It is also possible to display the current keymap in the status bar like so:

set-option global modelinefmt "%opt{modelinefmt} [%%opt{keymap_name}]"

4 Likes