kort
Fast and safe abbreviation expansion for zsh.
kort pre-validates your abbreviations at compile time — catching conflicts with existing commands before they cause problems — then uses a binary cache for instant expansion at runtime.
Installation
Build from source
Setup
- Generate a config file:
This creates ~/.config/kort/kort.toml.
- Add the zsh integration to your
.zshrc:
- Compile your config:
Configuration
Edit ~/.config/kort/kort.toml to define your abbreviations.
Regular Abbreviations
Expand only at command position (the beginning of a command):
[[]]
= "g"
= "git"
[[]]
= "gc"
= "git commit"
Typing g then pressing Space expands to git . But echo g does not expand, because g is not in command position.
Global Abbreviations
Expand anywhere in the line:
[[]]
= "NE"
= "2>/dev/null"
= true
curl example.com NE expands to curl example.com 2>/dev/null.
Contextual Abbreviations
Expand only when surrounding text matches regex patterns:
[[]]
= "main"
= "main --branch"
= "^git (checkout|switch) "
main expands to main --branch only after git checkout or git switch.
Placeholders
Use {{name}} to mark positions where you want to type after expansion:
[[]]
= "gc"
= "git commit -m '{{message}}'"
gc expands to git commit -m '' with the cursor placed between the quotes. Press Tab to jump to the next placeholder if there are multiple.
Evaluate Mode
Execute a shell command and insert its output:
[[]]
= "TODAY"
= "date +%Y-%m-%d"
= true
= true
TODAY expands to the current date, e.g. 2026-03-08.
Command-Scoped Abbreviations
Expand only after a specific command:
[[]]
= "co"
= "checkout"
= "git"
git co expands to git checkout, but co alone does not expand.
Function Mode
Run expansion as a shell function:
[[]]
= "mf"
= "my_func"
= true
Regex Keywords
Use a regex pattern as the keyword:
[[]]
= "^g[0-9]$"
= "git"
= true
Settings
[]
# prefixes = ["sudo", "doas"] # commands that preserve command position
# remind = false # remind when abbreviation could have been used
Conflict Detection
When you run kort compile, kort scans your $PATH and checks zsh builtins to detect abbreviations that shadow existing commands.
| Conflict Type | Behavior |
|---|---|
Exact match with a command in $PATH |
Error |
zsh builtin (e.g. cd, echo) |
Error |
To allow a specific conflict:
[[]]
= "gs"
= "git status --short"
= true
Key Bindings
The zsh integration sets up the following key bindings:
| Key | Action |
|---|---|
| Space | Expand abbreviation, then insert space |
| Enter | Expand abbreviation, then execute |
| Tab | Jump to next {{placeholder}} (falls back to normal completion) |
| accept-line | Check for abbreviation reminders (when remind = true) |
Prefix Candidates
When you type a partial keyword and press Space, kort shows matching abbreviations as candidates if no exact match is found.
For example, with these abbreviations defined:
[[]]
= "gc"
= "git commit"
[[]]
= "gp"
= "git push"
[[]]
= "gd"
= "git diff"
Typing g then pressing Space displays:
gc → git commit
gp → git push
gd → git diff
Space is not inserted — you continue typing to narrow down the candidates. Typing gc then pressing Space expands to git commit as usual.
Candidates respect abbreviation scope:
- At command position: regular, global, and command-scoped abbreviations are shown
- At argument position: only global and matching command-scoped abbreviations are shown
The prefix index is built automatically during kort compile — no extra configuration needed. Candidates are shown only when 2 or more matches exist.
Adding Abbreviations from the CLI
Instead of editing kort.toml by hand, you can use kort add:
Non-interactive
| Flag | Description |
|---|---|
--global |
Register as a global abbreviation |
--evaluate |
Run expansion as a shell command |
--function |
Run expansion as a shell function |
--regex |
Keyword is a regex pattern |
--command <CMD> |
Only expand as argument of this command |
--allow-conflict |
Allow conflicts with PATH commands |
--context-lbuffer <REGEX> |
Left-buffer regex for context matching |
--context-rbuffer <REGEX> |
Right-buffer regex for context matching |
--config <PATH> |
Use a custom config file path |
Interactive
Run kort add without arguments to enter interactive mode:
You will be prompted for the keyword, expansion, type (regular / global / context), and other options.
Commands
| Command | Description |
|---|---|
kort init config |
Generate a config template at ~/.config/kort/kort.toml |
kort init zsh |
Output zsh integration script (usage: eval "$(kort init zsh)") |
kort add |
Add an abbreviation interactively |
kort add <keyword> <expansion> |
Add an abbreviation with options |
kort erase <keyword> |
Erase an abbreviation from config |
kort rename <old> <new> |
Rename an abbreviation keyword |
kort query <keyword> |
Check if an abbreviation exists (exit code 0 = found) |
kort show [keyword] |
Show abbreviations in re-importable kort add format |
kort compile |
Validate config, detect conflicts, and generate binary cache |
kort check |
Validate config syntax without compiling |
kort list |
Show all registered abbreviations |
kort import aliases |
Import from zsh aliases (stdin) |
kort import fish [file] |
Import from fish abbreviations |
kort import git-aliases |
Import from git aliases |
kort export |
Export abbreviations in kort add format |
kort remind |
Check for abbreviation reminders (called by ZLE) |
kort expand |
Expand an abbreviation (called by the zsh widget) |
kort next-placeholder |
Jump to next placeholder (called by the zsh widget) |
Migrating from Aliases
From zsh aliases
Pipe the output of alias into kort import aliases:
This parses each alias name='expansion' line and appends it to your kort.toml. Aliases that conflict with PATH commands are automatically marked with allow_conflict = true.
From fish abbreviations
From git aliases
Auto-Recompilation
When you edit kort.toml, the next expansion automatically detects the stale cache and recompiles. No manual kort compile needed after config changes.
License
MIT