keybinding.kdl
Rebind koshi's keys — leader, chord timeouts, key grammar, and the normal and locked mode blocks.
User bindings are applied over the built-in ones. A user binding wins for the same key; every key you do not mention keeps its built-in action.
The file sits directly in the config directory. Each terminal reads it for itself when it attaches, so two terminals on one session can use different shortcuts.
Any error drops the whole file. Run koshi keys conflicts after editing, and
koshi keys list to see what is actually active.
Top-level settings
version is required. Every other setting is optional and may appear at most
once, beside the mode blocks.
| Key | Value | Default | Since |
|---|---|---|---|
chord-timeout-ms | integer — ambiguity delay when one sequence is both a complete binding and the prefix of a longer binding | 500 | ≥ 0.1.0 |
which-key-delay-ms | integer — ms before the hint bar appears | 300 | ≥ 0.1.0 |
max-chord-depth | integer 0–255 — most keys one shortcut may chain. A shortcut longer than this can never fire, and koshi keys conflicts reports it | 4 | ≥ 0.1.0 |
leader | string — what <leader> stands for: a modifier run like "C-", or a single chord like "<Space>" | "C-" | ≥ 0.1.0 |
unlock-alternative | string — the chord that leaves locked mode, in place of <C-l> | none | ≥ 0.1.0 |
Key grammar
Keys use angle brackets. Spaces join keys into a sequence.
| Written | Means |
|---|---|
<C-t> | Ctrl+t. Modifiers are C Ctrl, A Alt, S Shift |
<Tab> <CR> <Esc> <BS> | Named keys |
<leader>p | The leader, then p |
Always bracket named keys. A bare word like Tab is read as one chord per
character — T, then a, then b.
With leader "C-", <leader>p is <C-p>. With leader "<Space>" it becomes
<Space> then p. Explicit keys such as <A-f> never move when the leader
changes.
mode blocks
A mode block holds the bindings for one mode: "normal" is the usual one,
"locked" passes keys straight to the program except the unlock chord.
| Node | Meaning |
|---|---|
bind "<key>" "core:action" | Two strings: the key sequence and the full, namespaced action |
remove "<key>" | Void a key in this mode so lower layers no longer bind it |
A bare action name like new-tab is rejected with a hint — write
core:new-tab. A bind takes no arguments: a fixed choice lives in the action
name (core:new-pane-left), an open value lives in the CLI. Run
koshi actions list for every name you can bind to.
core:quit leaves the session; it does not end one. See
Actions.
The complete default keymap
// keybinding.kdl — the complete default keymap.
version 1
chord-timeout-ms 500
which-key-delay-ms 300
max-chord-depth 4
leader "C-" // the leader = the Ctrl modifier run (default)
// unlock-alternative "<A-u>" // replaces <C-l>; also bind it to core:unlock in "locked"
mode "normal" {
// reserved lock/unlock chord — explicit, never moves with the leader
bind "<C-l>" "core:lock"
// leader-relative — rebind `leader` and all of these move together
bind "<leader>q" "core:quit"
bind "<leader>g" "core:mouse-select"
bind "<leader>p n" "core:new-pane" // <C-p> n with the default leader
bind "<leader>p h" "core:new-pane-left"
bind "<leader>p j" "core:new-pane-down"
bind "<leader>p k" "core:new-pane-up"
bind "<leader>p l" "core:new-pane-right"
bind "<leader>p x" "core:close-pane-tree"
bind "<leader>p <Left>" "core:focus-pane-left"
bind "<leader>p <Down>" "core:focus-pane-down"
bind "<leader>p <Up>" "core:focus-pane-up"
bind "<leader>p <Right>" "core:focus-pane-right"
bind "<leader>s <Left>" "core:resize-pane-left"
bind "<leader>s <Down>" "core:resize-pane-down"
bind "<leader>s <Up>" "core:resize-pane-up"
bind "<leader>s <Right>" "core:resize-pane-right"
bind "<leader>t n" "core:new-tab" // <C-t> n with the default leader
bind "<leader>t x" "core:close-tab"
// explicit chords — they never move with the leader
bind "<A-f>" "core:toggle-pane-fullscreen"
bind "<Tab>" "core:next-tab"
bind "<S-Tab>" "core:previous-tab"
}
mode "locked" {
// locked mode passes every other key straight to the program.
bind "<C-l>" "core:unlock"
bind "<leader>q" "core:quit"
bind "<leader>g" "core:mouse-select"
}Checking your work
koshi keys validate ~/.config/koshi/keybinding.kdl # before adopting it
koshi keys conflicts # clashes and dead shortcuts
koshi keys describe "<C-p> l" # what one sequence does
koshi keys list --scope user # only what you added