A Magit-inspired porcelain for Kakoune. Ships the daily and weekly git verbs as first-class transients, a status buffer, a log browser, blame overlay, interactive rebase, stash/worktree/submodule/bisect sections, and more — keyboard-first, kakoune-native.
Covers ~99% of Magit's daily commands and ~97% of its
weekly commands. 19 self-contained modules; no external dependencies beyond
git, awk, sed, perl (for blame), and a POSIX shell.
via kak-bundle
bundle magit.kak https://github.com/saifulapm/magit.kakkak-bundle recursively sources every .kak file in the repo on load; all
modules live under rc/, so this loads the whole plugin. No keybindings are
defined — magit.kak ships only commands so it never clobbers your keymap.
Add the suggested bindings yourself (next section).
magit.kak intentionally ships no keymap. Copy this block into your
kakrc (or a kak-bundle config block) and customize freely — it puts every
verb under a <space>g (the git) user-mode; kakoune's built-in autoinfo
shows each binding and its docstring when you press <space>g.
declare-user-mode git
map global user g ':enter-user-mode git<ret>' -docstring 'magit'
# --- Top-level entry points ---------------------------------------------
map global git g ':magit-status<ret>' -docstring 'magit status'
map global git l ':magit-log<ret>' -docstring 'log'
map global git L ':magit-reflog<ret>' -docstring 'HEAD reflog'
map global git b ':magit-branch-dispatch<ret>' -docstring 'branches buffer'
# --- Buffer-local operations (gutter, blame, hunk nav, stage-selection) -
map global git n ':magit-next-hunk<ret>' -docstring 'next hunk'
map global git p ':magit-prev-hunk<ret>' -docstring 'previous hunk'
map global git m ':magit-blame-toggle<ret>' -docstring 'toggle blame'
map global git s ':magit-stage-selection<ret>' -docstring 'stage selection'
map global git u ':magit-unstage-selection<ret>' -docstring 'unstage selection'
map global git <ret> ':magit-log-line<ret>' -docstring 'commit for current line'
# --- Diff -----------------------------------------------------------------
map global git d ':magit-diff-dispatch<ret>' -docstring 'diff (menu)'
map global git D ':magit-diff-staged<ret>' -docstring 'diff staged preview'
map global git "'" ':magit-diff-dwim<ret>' -docstring 'diff (context-aware)'
# --- Commit + sequence verbs ---------------------------------------------
map global git c ':magit-commit-dispatch<ret>' -docstring 'commit transient'
map global git P ':magit-push-transient<ret>' -docstring 'push transient'
map global git F ':magit-fetch-transient<ret>' -docstring 'fetch transient'
map global git f ':magit-pull-transient<ret>' -docstring 'pull transient'
map global git M ':magit-merge-transient<ret>' -docstring 'merge transient'
map global git A ':magit-cherry-transient<ret>' -docstring 'cherry-pick transient'
map global git V ':magit-revert-transient<ret>' -docstring 'revert transient'
map global git r ':magit-rebase-transient<ret>' -docstring 'rebase transient'
# --- Repo-scoped transients ----------------------------------------------
map global git t ':magit-tag-transient<ret>' -docstring 'tag transient'
map global git X ':magit-reset-transient<ret>' -docstring 'reset transient'
map global git e ':magit-remote-transient<ret>' -docstring 'remote transient'
map global git z ':magit-stash-transient<ret>' -docstring 'stash (create) transient'
map global git w ':magit-worktree-dispatch<ret>' -docstring 'worktree transient'
map global git o ':magit-submodule-dispatch<ret>' -docstring 'submodule transient'
map global git i ':magit-bisect-dispatch<ret>' -docstring 'bisect transient'
map global git C ':magit-clone-dispatch<ret>' -docstring 'clone transient'
map global git I ':magit-gitignore-dispatch<ret>' -docstring 'gitignore transient'
map global git N ':magit-patch-dispatch<ret>' -docstring 'patch transient (create/apply/am)'
# --- Working-tree helpers -------------------------------------------------
map global git x ':enter-user-mode magit-conflict<ret>' -docstring 'conflict resolve'
map global git . ':magit-file-dispatch<ret>' -docstring 'file dispatch (this file)'
map global git W ':magit-wip-toggle<ret>' -docstring 'toggle WIP auto-snapshot'
declare-user-mode magit-conflict
map global magit-conflict n ': magit-conflict-next<ret>' -docstring 'next conflict'
map global magit-conflict p ': magit-conflict-prev<ret>' -docstring 'previous conflict'
map global magit-conflict o ': magit-conflict-ours<ret>' -docstring 'keep ours'
map global magit-conflict t ': magit-conflict-theirs<ret>' -docstring 'keep theirs'
map global magit-conflict b ': magit-conflict-both<ret>' -docstring 'keep both'After install:
- Open kakoune inside a git worktree.
- Press
<space>g g→*magit-status*opens. - Press
<space>g(and hold) to see every binding in autoinfo.
All under the <space>g user-mode.
| Key | Action |
|---|---|
g |
magit status |
l / L |
log / reflog |
b |
branches buffer |
d / D / ' |
diff (menu / staged / context-aware) |
c |
commit transient |
P / F / f |
push / fetch / pull |
M / A / V / r |
merge / cherry-pick / revert / rebase |
t / X / e / z |
tag / reset / remote / stash |
w / o / i |
worktree / submodule / bisect |
C / I / N |
clone / gitignore / patch |
x |
conflict resolve |
. |
file dispatch (current buffer) |
m |
toggle blame |
s / u |
stage / unstage selection |
n / p |
next / previous hunk |
W |
toggle WIP auto-snapshot |
<ret> |
commit for current line |
Inside *magit-status*: s/u stage/unstage at cursor, <a-k>/K discard,
<tab> fold, t section-jump menu, V reverse to worktree.
Inside *magit-log*: <ret> view commit, O log another ref, T filter,
~ toggle margin, V revert at cursor.
Inside blame overlay: s cycle display style, B recursive blame, <ret>
jump to commit.
Press ? inside any magit buffer to see an autoinfo listing of every
buffer-local binding with its docstring — no need to memorize.
Full details: see each module's header comment under rc/.
magit.kak adds effectively nothing to Kakoune startup. The transient engine
(magit-transients, the one heavy module) is lazy-loaded — it is required on
the first push / pull / fetch / merge / cherry-pick / revert / rebase / tag /
reset / remote / stash transient (or first diff/log/commit transient), then
stays loaded for the rest of the session. The first such command therefore
pays a one-time ~250 ms load; everything else, including *magit-status*, is
available immediately at launch.
Enable autoreload so file buffers refresh automatically when magit operations
(rebase / stash apply / revert / reset) mutate the worktree:
set-option global autoreload trueWithout this, kakoune warns "file changed on disk" on the next keystroke in
any affected buffer; you then must :edit! to reload.
magit.kak shows a per-line VCS gutter (added / modified / deleted markers,
diffed against HEAD) in every tracked-file buffer automatically — no
keymap or setup required. It installs four global hooks under the
magit-gutter group:
| Hook | Effect |
|---|---|
WinDisplay |
show + populate the gutter when a buffer is first displayed |
FocusIn |
refresh on window focus |
BufReload |
refresh after an external reload |
BufWritePost |
refresh after save |
The check for "is this a tracked file in a git repo" lives inside
magit-gutter-update, so the hooks are safe on scratch / non-git buffers
(they no-op). Markers are colored with kakoune's built-in faces: green
added, blue modified, red deleted.
Customize the marker glyphs (defaults shown):
set-option global magit_gutter_add_char '▏' # added lines
set-option global magit_gutter_mod_char '▏' # modified lines
set-option global magit_gutter_del_char '_' # deleted lines
set-option global magit_gutter_top_char '‾' # deletion at top of fileControl it manually:
magit-gutter-hide/magit-gutter-show— toggle for the current buffer.magit-gutter-update— force a refresh.magit-next-hunk/magit-prev-hunk— jump between changed hunks (bound to<space>g n/<space>g pin the suggested keymap).- To disable the auto-gutter entirely, remove the hook group after load:
remove-hooks global magit-gutter.
33/51 Magit 4.5.0 transients implemented, plus:
- Status buffer with full sectioning + folding + section-jump menu.
- Commit transient with extend / amend / reword / fixup / squash / instant-fixup / instant-squash.
- Interactive rebase with reword batching (single-buffer edit of N messages) and edit-verb pause/continue.
- Blame overlay with recursive walk, blob blame from show buffer, style cycle.
- Merge preview / nocommit / editmsg variants.
- Log with graph, SHA linemap, filters, other-ref prompt, author+age margin.
- Stash section + create transient with
--include-untracked/--all/--keep-index/--staged/ branch-from-stash. - Worktree + submodule + bisect transients, each with a status-buffer section.
- WIP auto-snapshots to
refs/wip/wtree/<branch>on every save. - 2-way and diff3 conflict-marker helpers.
- Patch transient (format-patch / apply / am with --continue/--abort).
- Clone transient (regular / shallow / bare / mirror / sparse).
- Gitignore transient (top / subdir / .git/info/exclude) with pre-fill.
magit-dispatchpopup — kakoune's built-in user-mode autoinfo covers it.- Ediff — replaced by
<space>g xconflict helpers. - Dired / bookmark / autorevert — Emacs-specific.
- Subtree / bundle / notes / sparse-checkout standalone / list-repositories / absorb / request-pull — niche; open an issue if you need one.
- Magit by Jonas Bernoulli and contributors — the reference design.
- Kakoune community for
provide-module,flag-lines, transient-as-user-mode, and%sh{}patterns that make this possible in ~4k lines of kakscript.
MIT. See LICENSE.