Skip to content

Configuration

konoma reads a single TOML file:

~/.config/konoma/config.toml

Everything is optional — no config file is required. A missing or broken file never prevents startup; konoma falls back to the defaults described below (invalid values fall back per-key). A fully commented example lives in config.example.toml; copy it as a starting point (a Japanese-annotated copy is at config.example.ja.toml):

Terminal window
mkdir -p ~/.config/konoma
cp config.example.toml ~/.config/konoma/config.toml
[ui]
lang = "en" # UI language ("auto" follows the OS)
wrap = false # no soft-wrap; h/l scroll long lines
line_numbers = true
details = ["size", "modified"]
[ui.theme]
bg = "#282c34"
[keys]
copy_prefix = "y"
Key Default Description
show_hidden false Show dotfiles at startup (toggle at runtime with .).
tabbar "auto" Tab bar visibility: "always" / "auto" (only with 2+ tabs) / "hidden".
icons true Nerd Font icons in the tree, Markdown links and task checkboxes. Set false on terminals without a Nerd Font — konoma falls back to plain ASCII symbols (no tofu).
wrap true Soft-wrap text previews. false = no wrap + horizontal scrolling (h/l, 0/$).
line_numbers false Line-number gutter in code/text previews.
git_gutter true Editor-style git change gutter (green added / blue modified / red deleted) in code/text previews of files with uncommitted changes.
tab_width 4 Tab stop width in code/text previews (0 keeps raw tabs).
syntax_highlight true Syntax highlighting for code previews (false = plain text, fastest).
preview_loading "indicator" First-open wait for heavy code previews: "indicator" (loading screen) or "progressive" (plain text first, colors swap in when ready).
path_style "relative" Title-bar path form: "relative" / "home" (~/...) / "full". Cycle at runtime with p.
keys "vim" Paging-key scheme for previews: "vim" (Ctrl-f/b, Ctrl-d/u) or "less" (f/b, d/u, Space).
lang "auto" UI language for help/hints/messages: "auto" (OS language) / "en" / "jp".
statusbar "split" Status chrome layout: "split" (context top, hints bottom) / "bottom" / "top".
image_render_scale 1.0 Image display scale (0.1–1.0). Smaller = fewer pixels sent to the terminal = faster draws, smaller image.
svg_max_px 800 Max rasterization side (px) for SVG previews. Larger = crisper but heavier.
details [] Metadata columns on tree rows, in order. Available: "size", "modified", "perm", "type", "items" (directory entry count).
graph_max_branches 12 Cap on branches drawn simultaneously in the commit graph (og). 0 = unlimited. Toggle branches at runtime with b inside the graph.
graph_base_branches [] Ordered list of preferred base branches, e.g. ["main", "develop"]. In the graph, the first one that exists becomes the base (pinned to lane 0) and the array order becomes the display priority. A worktree’s diff (o w, then d) treats these as candidates and picks whichever shares the most recent common ancestor with that worktree, so the order only breaks ties.
commit_meta_align "right" Author/date column in git log & graph: "right" (aligned right-edge column) or "inline" (directly after the subject).
confirm_quit true Ask before quitting (q/y/Enter = quit, n/Esc = cancel; qq quits quickly). false = quit immediately.
confirm_jj_sync true Ask before R in the hub lets jj snapshot the working copy — the one thing konoma writes to a jj repository, and only when asked. It exists for what konoma cannot see on its own: a file whose contents changed while its timestamp did not. false = snapshot without asking.
confirm_bookmark_overwrite true Ask before a bookmark key (m) overwrites a different existing path (y/Enter = overwrite, n/Esc = cancel). Re-registering the same path or an unused key never prompts. false = overwrite silently.
csv_rainbow true Rainbow column colors in CSV/TSV table previews. false = monochrome (alignment and navigation unchanged).
filter_mode "fuzzy" How the / tree filter matches: "fuzzy" (ranked subsequence match, fzf-style; space-separated words are AND-ed) or "substring" (the older plain substring test). Case is ignored either way.
follow_view "diff" How follow mode (F) opens a changed file: "diff" (full-screen diff since follow-start — pre-existing uncommitted changes stay hidden; press f in the diff to switch to the full git diff) or "file" (normal preview scrolled to the first changed hunk). Files without a diff and media always open as "file".
busy_indicator true Small spinner + job label at the top-right while background work runs (git-ignored scan, media decode, highlight warm-up, image fetches). Idle shows nothing and costs nothing. A file operation in progress (copy / move / duplicate / delete, with its N/M progress) is always shown regardless of this setting — it is what you are waiting on, not background bookkeeping.
mermaid "image" How mermaid diagrams render. "image" rasterizes them in-process (pure Rust, mermaid.js-quality — no browser/Node): standalone .mmd files show full screen with zoom/pan (zooming re-rasterizes so it stays sharp), and ```mermaid fences in Markdown render inline (Tab focuses a diagram — cyan frame + auto-scroll; +/- zoom in place without moving the layout, hjkl pan while zoomed, 0 fits, Enter opens full screen, q returns). "text" keeps the legacy Unicode box-drawing rendering. Failures and non-graphics terminals degrade to text automatically.
mermaid_theme "dark" Color theme for image-mode diagrams: "dark", "light", "classic", "forest", "neutral". The background is always transparent (blends with the terminal). Has no effect when mermaid_routing = "konoma-orthogonal" — that mode always uses konoma’s own designed palette instead.
mermaid_curve "basis" Curve a flowchart’s edges are drawn in — mermaid’s flowchart.curve (mermaid’s most-requested flowchart feature: a straight/right-angle line instead of a spline, mermaid-js#2817 / #2549). All 13 of mermaid’s own curve names are implemented; an unrecognized value falls back to "basis". "basis" (default) is a smooth spline and never changes the look unless you set this. "linear" draws straight segments; "step" / "stepBefore" / "stepAfter" draw a right angle, differing in where the corner sits (midpoint / vertical-first / horizontal-first). "natural" / "cardinal" / "catmullRom" are smooth splines that pass through every waypoint; "monotoneX" / "monotoneY" never overshoot a waypoint, along the named axis; "bumpX" / "bumpY" draw an S-curve offset on the named axis; "rounded" is straight segments with every corner cut to a small rounded curve (mermaid’s own curve, not part of d3-shape). Three ways to set the curve, weakest first: this setting < the diagram’s own %%{init: {"flowchart": {"curve": "..."}}}%% directive < a linkStyle <n> interpolate <curve> naming one edge. Only a flowchart’s own edges read any of this.
mermaid_routing "splines" How a flowchart’s edges are routed — a konoma-only extension, independent of mermaid_curve above. "splines" (default) is the classic mermaid layout: edges follow the diagram’s own curve (mermaid_curve) — the look never changes unless you set this. "konoma-orthogonal" is konoma’s own orthogonal router (flowchart and stateDiagram-v2; every other diagram kind is unaffected): every edge bends only at 90° with sharp corners (zero radius) and always meets a node or subgraph border head-on. Decision nodes ({}) draw as a chamfered rectangle (6px cut corners) instead of a diamond, so every edge lands on a flat face. Multiple edges on the same side of a node spread across 16px-spaced ports, widening the node on that axis if there isn’t room. A straight-through edge between adjacent ranks aligns to a shared centerline — a true zero-bend straight lane. Where edges cross, the one passing over (a back-edge or detour) opens a 12px gap so the stacking order reads at a glance. Back-edges and detours route around the diagram’s outer lane (16px outside every element; multiple such edges offset 8px apart). A label sits on a plate on the line itself, and its segment is padded to at least the label’s width plus margin — widening the rank gap automatically when it doesn’t fit. Arrowheads are painted the edge’s own color (after linkStyle/classDef) and stop 1px short of the node border. Named after ELK’s edgeRouting: ORTHOGONAL and Graphviz’s splines=ortho; the konoma- prefix marks it as konoma’s own value so it can never collide with a future mermaid-defined "orthogonal". mermaid_curve has no effect in this mode. This mode also switches the diagram to konoma’s own designed palette and style — dark node fill with rounded corners and thin strokes, dashed subgraph frames, and classDef/style colors applied consistently to a node’s border, its edges, arrowheads, and label — so mermaid_theme has no effect here either. An unrecognized value falls back to "splines".
mermaid_rows 24 Upper limit on the height (rows) of an inline mermaid diagram inside Markdown. A diagram is shown at its natural size — matching the surrounding body text — and is never enlarged; it’s only shrunk (aspect preserved) when that natural size exceeds this cap or the available width. Diagrams re-rasterize at the needed density on zoom and stay sharp (the display size itself doesn’t change). The initial view also fits the viewport: shorter windows shrink the diagram further so the whole block is visible. 0/invalid falls back to the default.
math "image" How LaTeX math renders. "image" (default) rasterizes $…$ / $$…$$ in-process via RaTeX (pure Rust, KaTeX quality, no browser/Node) and shows each as an inline image (inline math is always drawn in the running text, like ordinary Markdown — an expression too wide for the line shrinks to fit instead of being lifted onto its own line; display math is centered). "text" leaves the raw LaTeX as plain text. Non-graphics terminals and render failures degrade to the raw LaTeX automatically.
math_color "#d0d0d0" Glyph color for image-mode math. RaTeX paints equations pure black, invisible on a dark terminal; konoma is dark-terminal-first, so equations are recolored to this over a transparent background (the terminal shows through, like mermaid). On a light terminal set a dark color (e.g. "#202020"). Accepts any color usvg parses (#hex, rgb(…), or a CSS color name); an unrecognized or fully-transparent value falls back to the default (a typo can’t silently blank equations).
restore_tabs true Restore the previous tab set per start directory: each tab’s root, tree cursor, and open preview come back on the next launch in the same directory. Saved on tab open/close/switch and on quit under ~/.config/konoma/sessions/. false = always start fresh (nothing is read or written).
restore_single_tab true When restore_tabs is on: also persist/restore a session that has only one tab. false = don’t save single-tab sessions — quitting with a lone tab deletes that directory’s session file, so the next launch starts fresh; sessions with two or more tabs still save/restore.
tree_cursor "origin" Where the cursor lands after moving to the parent directory (h). "origin" puts it back on the directory you just left (the same spirit as q returning from a preview — you land where you came from, not at the top); "top" always lands on the first row (the older behavior). An unrecognized value is treated as "origin". If the left directory isn’t in the parent’s listing (e.g. it’s hidden and show_hidden is off), this falls back to the top. Descending into a directory (l) always starts at the top either way — there is no “came from” row there.
md_task_states [" ", "x"] Task-checkbox states cycled by Space in a Markdown preview, in order. Each entry is exactly one character. E.g. [" ", "/", "x"] adds an Obsidian-style in-progress state (shown as [/]). Invalid configs fall back to the default.
md_autolink true Auto-link bare URLs and emails in Markdown previews (GFM autolink), like GitHub: a plain https://…, www.…, or foo@bar.com becomes a focusable link (Tab to it, Enter opens it). Never applied inside code spans / code fences. false = leave them as plain text.
md_alerts true Render GitHub-style alerts as colored callout boxes (icon + label) instead of plain blockquotes. Markers (case-insensitive, plus common aliases): > [!NOTE] / [!TIP] / [!IMPORTANT] / [!WARNING] / [!CAUTION]. false = ordinary blockquote (marker kept literal).
md_emoji true Convert :shortcode: emoji to real Unicode in Markdown previews, like GitHub (:rocket: → 🚀). Shortcodes with no Unicode equivalent (GitHub-custom like :shipit:) and shortcodes inside code stay literal. false if emoji width upsets column alignment.
md_frontmatter true Recognize leading YAML front matter (------ at the very start) and show it as a compact dim metadata block instead of a rule + raw YAML. false renders it as ordinary Markdown.
md_footnotes true Render GFM footnotes: text[^1] references become superscript numbers and the [^1]: … definitions are collected into a numbered footnotes section at the end. false leaves them literal.
md_inline_html true Render common inline HTML the Markdown engine strips: <del>/<s>/<strike> as strikethrough, <kbd> as an inline-code keycap, <sup>/<sub> as Unicode (when the text maps), <br> as a hard line break. (<mark>/<ins> keep only their text either way.) false strips all of them.
md_details "auto" How <details> blocks start out. "auto" honors the open attribute like GitHub (<details> collapsed, <details open> expanded); "open" always expanded; "closed" always collapsed. Either way Tab focuses the <summary> and Space/Enter toggle it.
md_table_align "left" Where a table sits in a Markdown preview: "left" (the grid starts at the left edge), "center", "right". Moves the whole box — GFM pipe tables and HTML <table> alike, and any image inside a cell travels with it. It does not change alignment within a cell (a column’s :---: and an HTML cell’s align= still decide that). A table as wide as the pane stays flush left.
md_image_align "center" Where a block image sits in a Markdown preview: "left", "center", "right". Covers a standalone ![alt](url), a packed row of badges, and a mermaid fence’s diagram (its caption and focus frame follow it). It does not cover an image inside a table cell (its cell’s alignment places that) or display math (centered by typesetting convention). An image as wide as the pane stays flush left.
Key Default Description
key "name" Sort key: "name" / "size" / "modified" / "ext".
reverse false Descending order.
dirs_first true Group directories before files.

Change at runtime with the s menu (n/s/m/e, r = reverse, . = dirs first).

Colors accept "#rrggbb", color names ("black", "lightblue", …), terminal indexes ("8"), or "none".

Key Default Description
bg "none" App background. "none" keeps the terminal’s default background (terminal transparency keeps working).
code_bg "#2b303b" Background band for Markdown code (inline + blocks). "none" removes it.
code_label_align "right" Code-block language badge position: "right" or "left".
code_label_bg "auto" Language badge background: "auto" (brightened code_bg) / "none" / any color.
code_theme "TwoDark" Syntax-highlight theme (shared by code files and Markdown fences). Others: "OneHalfDark", "Dracula", "Nord", "gruvbox-dark", "Catppuccin Mocha", "Monokai Extended", "Solarized (dark)", "GitHub", … Separators/case are ignored; unknown names fall back to TwoDark.

[[preview.rules]] — what renders each file type

Section titled “[[preview.rules]] — what renders each file type”

konoma’s core model: file format → viewer is declared in TOML. Rules are evaluated top to bottom; the first match wins. A rule matches by glob (file name, case-insensitive) or mime (content sniffing, e.g. "image/*"), and renders via either a built-in renderer or an external command.

Note: if your config defines any [[preview.rules]], your list replaces the built-in defaults — copy the full rule list from config.example.toml and edit, rather than adding a single rule.

Built-in renderers (builtin = "..."):

Name Renders
markdown Decorated Markdown (headings, tables, links, task checkboxes, inline images, ```mermaid fences as diagrams).
mermaid Standalone .mmd/.mermaid files as diagrams. Renders as a real image by default (pure Rust, full-screen zoom/pan); [ui] mermaid = "text" switches to Unicode box-drawing.
image Full-screen image drawn with the terminal’s graphics protocol (zoom/pan; GIFs animate automatically).
svg Rasterized in-process (resvg; pure Rust) and shown as an image.
video A single representative frame, shown as a thumbnail. H.264 and HEVC inside .mp4/.m4v/.mov and .mkv/.webm are decoded natively in Rust — no external tool needed (HEVC covers what an iPhone records by default). Everything else (VP9, AV1, older codecs, the .avi container, and the uncommon profiles — H.264 in 10-bit / 4:2:2 / 4:4:4 / monochrome, HEVC outside Main / Main 10 4:2:0) is extracted with ffmpegthumbnailer/ffmpeg if installed, and shows a hint if not. No in-terminal playback either way — delegate to mpv via command if you want playback.
pdf Pages rasterized natively in Rust (hayro; one page at a time, no external tool needed) — J/K turn any page. On macOS only, a PDF hayro can’t render (encrypted, corrupt, or otherwise unsupported) falls back to the system’s own qlmanage/sips — always present, nothing to install — but those can only produce the first page.
csv / tsv Aligned table with rainbow columns and a cell cursor (hjkl moves, y → copies cell/row/column).
archive Lists entries (name / size / modified) for .zip/.tar/.tar.gz/.tgz in the same aligned-table renderer as CSV/TSV — metadata only, nothing is extracted (hjkl / y → c/r/C copy work the same).
code Syntax-highlighted source (grammar resolved by extension → file name → first line).
text Plain text. Also the automatic fallback for anything that looks like text.

External command delegation:

[[preview.rules]]
glob = "*.{mp4,mov}"
command = "mpv {path}" # {path} = the file, {out} = a temp output path
detached = true # don't block the TUI (opens in a separate process)
[[preview.rules]]
glob = "*.{dot,gv}" # No builtin for Graphviz -- delegate it. (Mermaid needs no rule: konoma
render_as = "image" # renders it natively.) render_as = treat the command's output as an image.
command = "dot -Tpng -o {out}.png {path}" # No shell: write the command as argv, not as a pipeline.

Omitting render_as (or setting it to anything other than "image") captures the command’s output and shows it as plain text through the ordinary windowed reader — a missing/failing command (binary not found, non-zero exit, {out} never produced) degrades safely to [can not preview: <ext>] with the reason attached, instead of crashing.

Mermaid needs no rule of its own. konoma renders .mmd/.mermaid files and ```mermaid fences itself — pure Rust, no Node, no browser — and the [ui] mermaid options above control it. If what you specifically want is the output of mermaid.js itself (the same engine behind mermaid.live and GitHub), you can delegate standalone files to mmdc, the official mermaid CLI:

[[preview.rules]]
glob = "*.{mmd,mermaid}" # replaces the default builtin = "mermaid" rule
render_as = "image"
command = "mmdc -q -i {path} -o {out}.png -t dark -b transparent -s 3"

-i/-o are the input and output files (mmdc picks svg/png/pdf from the output extension), -t is the theme (default / forest / dark / neutral), -b the background color, -s the Puppeteer scale factor (3 renders at 3×, so the PNG still has pixels to spare when you zoom in), and -q keeps mmdc’s progress log out of the error line. {out} deliberately has no extension, so the .png you append in {out}.png is what tells mmdc which format to write — konoma accepts the suffixed file it produces.

Unlike everything else konoma leans on, mmdc is a heavyweight dependency. You install it with npm install -g @mermaid-js/mermaid-cli; it wants Node 18.19+ / 20+, and it drives a real browser through Puppeteer, so the install brings a bundled Chromium with it and every preview starts one — expect a second or two per diagram rather than an instant one (konoma gives any delegated command 30 seconds before it gives up). konoma’s own mermaid path needs none of that. Take the trade deliberately.

Two limits of this rule:

  • It covers standalone files only. ```mermaid fences inside a Markdown document are composited by the markdown renderer and always take konoma’s built-in path — a [[preview.rules]] entry matches whole files, so it cannot reach inside one.
  • Don’t aim it at *.md. Given a Markdown input, mmdc rewrites the whole document (replacing each fence with a generated image file) instead of producing one diagram — not what a preview wants.

If mmdc isn’t installed, the rule degrades exactly like any other missing command, and [external] preview_commands = false switches it off (along with every other delegation) without touching your rule list.

Anything that matches no rule and doesn’t look like text shows a safe [can not preview: <ext>] screen — konoma never crashes on unknown input, and missing optional tools degrade to a hint.

konoma never edits file contents itself; e delegates to your editor.

[editor]
command = "nvim" # global default
[editor.ext]
md = "code -w" # per-extension override (extension without the dot)
rs = "nvim +{line} {path}" # {line} = the preview line you were on

Resolution order: [editor.ext] match → editor.command$VISUAL$EDITORvim. Values are command + args, whitespace-separated; {path} is substituted if present, otherwise the file path is appended.

Opening at the preview line. Pressing e from a windowed preview (plain text, code, or raw Markdown via R) opens the editor at the caret line. Use a {line} token to place it explicitly (code -g {path}:{line}, hx {path}:{line}, nvim +{line} {path}). Without a {line} token, common editors are handled automatically — vim family (+N, plus zt to scroll that line to the top of the window), VS Code (-g path:N), and Sublime/Helix/Zed (path:N); other editors open at the top. Rendered Markdown reflows the source, so e opens at the line whose text is at the top of your view — it searches the source for the on-screen text and lands on it (R gives an exact caret open). If you have Tab-focused an item (link, checkbox, code block) that is on screen, e opens at that item’s line instead. Mermaid and images always open at the top.

Key Default Description
tool "lazygit" External git tool launched with ! inside the changes hub (command + args).
diff "unified" Initial diff layout: "unified" (vertical) / "split" (side by side) / "auto" (by width). Cycle at runtime with s while viewing a diff.
worktree_dir "../" Where n in the worktree list puts a new worktree, resolved against the main worktree so the location doesn’t depend on which worktree you started from. The directory is named after the branch, with / replaced by -. Pointing this inside the repository works, but then that path needs a .gitignore or .git/info/exclude entry of your own — konoma never writes one for you.

Preview. The surface is complete for the tree, diffs and the hub, but jj workspace has no list yet, and jj is pre-1.0 and ships breaking changes monthly. konoma pins nothing: it probes the jj on your machine once and falls back to git if it cannot answer.

Only what has no git counterpart lives here; everything else about a jj repository is decided by [external] vcs and by jj itself. konoma only reads a jj repository — every call carries --ignore-working-copy, so it never snapshots the working copy, and keys that would write are hidden rather than offered.

Key Default Description
tool "lazyjj" External jj tool launched with ! inside the hub, the way [git] tool is for git. A missing binary flashes what could not be launched.

[external] — external process on/off switches

Section titled “[external] — external process on/off switches”

One on/off switch per external process konoma can launch. Every key defaults to true, so an absent [external] section (or an absent field within it) changes nothing.

Key Default Description
git true git integration: status colors, the gutter, the Git views, stage/unstage/commit/checkout/branch (src/git.rs, via the git CLI and the embedded git2/libgit2). false behaves exactly like building with --no-default-features (no git feature) — every read returns empty/None, every write returns an error. o (open the Git view) flashes a message distinct from “not a git repo”, since it may well be one. Whatever this setting says, git integration also turns itself off automatically when no git executable is found on the machine (probed once, on first use); o then says git is not installed rather than blaming the directory.
git_tool true The external git tool launched with ! ([git] tool, default lazygit).
vcs "auto" Which version-control system answers. jj support is a preview — see the git suite guide. "auto" keeps git wherever git can answer, so a repository that already worked shows exactly what it showed before; jj answers only where there is no git repository to ask (jj git init --no-colocate, or a jj workspace). "git" is always git. "jj" uses jj wherever a .jj exists, colocated or not — ask for this when jj is the system you actually work in. With no jj binary on the machine, konoma falls back to git.
pdf true The external fallback rasterizer — macOS’s bundled qlmanage/sips, tried only when the primary renderer (hayro, pure Rust — parses/renders in-process regardless of this flag) fails on page 1 of a given PDF (encrypted, corrupt, or otherwise unsupported). false never launches those tools, but PDF preview itself (page rendering and the page count) keeps working via hayro. On every other platform this flag is effectively a no-op: there is no external PDF tool to launch.
video true The external fallback thumbnail extractors (ffmpegthumbnailer/ffmpeg), tried only when the built-in decoder (pure Rust, in-process regardless of this flag) can’t handle the file — i.e. anything that isn’t H.264 or HEVC in .mp4/.m4v/.mov and .mkv/.webm. false never launches them, but H.264 and HEVC thumbnails from those containers keep working. Same relationship pdf has with hayro above.
remote_images true Fetching http(s):// images referenced from Markdown — the only outbound network call konoma makes. Done in-process via ureq (rustls), not an external tool.
open_links true Opening URLs/files with the OS handler (open on macOS, xdg-open elsewhere) — Markdown links, pasted-path jump (P), etc.
preview_commands true Running a [[preview.rules]] command = "..." delegation. false makes a matching rule behave as if it hadn’t matched (falls through to [can not preview]); builtin renderers (markdown, image, pdf, …) are unaffected.

Disabled mechanisms degrade the same way a missing optional tool already does: PDF/video fall back to the existing “cannot render” hint, a disabled remote image shows the text placeholder instead of the image, and a disabled command rule falls through to [can not preview] — nothing crashes.

Prefer [external] over trying to disable one thing through [[preview.rules]]: as noted above, writing even a single user rule there replaces the entire builtin rule table, so it can’t selectively turn off just PDF or video without also breaking Markdown, images, and CSV.

[ui] lang already has its own explicit-vs-"auto" switch for OS-language detection (via the sys-locale crate — no external process is launched) — setting it explicitly ("en"/"jp") skips that lookup entirely, so there is no separate [external] flag for it.

Every command is rebindable. The model: each screen (“surface”) maps keys to actions, helix-style:

[keys.tree]
"J" = "navigate:half_down" # capital = Shift included
"ctrl-g" = "open_git_view" # ctrl-x / c-x
"space d" = "file_delete" # two tokens = chord (leader + key)
"o" = "noop" # disable a default binding
[keys.global] # inherited by every non-input surface
"Q" = "quit"

Surface names: global, tree, tree_visual, preview_text, preview_text_visual, preview_image, preview_table, table_cell (the full-cell popup opened by Enter in preview_table), sort, bookmarks, tabs, outline, info, help, and (git builds) preview_git_diff, git_changes, git_log, git_graph, git_graph_picker, git_branches, git_worktrees (the linked-worktree list, w in the changes hub), git_detail.

Key tokens: single characters (uppercase = Shift), space, literals like 0 $ ! + - = . / ', modifiers ctrl-<k> (alias c-<k>), named keys tab enter esc backspace delete up down left right home end pageup pagedown. Two whitespace-separated tokens form a chord ("y f" = y then f). Esc/Enter/Tab/arrows and text-input keys are fixed and cannot be rebound.

Action names are snake_case strings — the full annotated list is in config.example.toml. The main groups:

  • Movement: navigate:down|up|top|bottom|page_down|page_up|half_down|half_up|left|right|line_home|line_end
  • Tree: quit, close_tab_or_quit, tree_descend, tree_leave, tree_activate, filter_start, toggle_hidden, refresh, open_sort_menu, toggle_info, request_edit, cycle_path_style, set_anchor, reset_anchor, enter_visual, toggle_select, open_in_new_tab (Ctrl-t: open the entry under the cursor in a new foreground tab)
  • Bookmarks: mark_set (m), mark_jump (' — opens the list; plain letters inside it jump), bookmark_edit (ctrl-e), bookmark_delete (ctrl-d), bookmark_close. m/' are bound in both the tree and previews (a preview bookmarks the shown file).
  • Path copy (y leader): copy_name, copy_relative, copy_full, copy_parent, copy_at_ref (@relative/path for AI chats), copy_code_block (y c — copy the Markdown code block currently focused with Tab; the entry only appears in the menu while one is focused)
  • File management (Space leader): file_create, file_rename, file_delete, file_copy, file_cut, file_paste, file_duplicate (Space→D: duplicate the cursor/selection in place, e.g. note copy.md)
  • Preview: preview_back, search_start, search_next, search_prev, preview_enter_visual (v), preview_enter_visual_line (V), preview_copy_selection, preview_copy_selection_ref (Y = @path#L12-34), toggle_markdown_raw (R), link_focus_next/prev, link_open (Enter = current tab), open_link_new_tab (Ctrl-t = new tab), image_zoom_in/out/reset, pdf_next_page, pdf_prev_page, preview_next_file / preview_prev_file (Ctrl-n / Ctrl-p — page to the next/previous file in tree order, skipping directories, wrapping at the ends)
  • Table (preview_table): table_copy_cell/row/column (y leader), toggle_table_cell (Enter: a full-text popup for the cursor cell — the grid truncates wide cells with , this shows the untruncated value, wrapped and scrollable with j/k/g/G/PageUp/PageDown; q/Esc/Enter close it; [keys.table_cell] covers the popup’s own keys)
  • Agent Watch: toggle_follow (F), toggle_changed_filter (C), jump_next_change (n), jump_prev_change (N), toggle_follow_diff_scope (f, in a follow diff: switch between “since follow start” and the full git diff)
  • Git: open_git_view (o), open_git_diff_cursor (d), git_stage, git_unstage, git_stage_all, git_unstage_all, git_discard, git_commit, git_open_log, git_open_graph, git_open_branches, git_launch_tool (!, in the changes hub), cycle_diff_layout, git_copy_*, branch_*
  • jj (git_changes): jj_sync (R — let jj snapshot the working copy; konoma’s only write to a jj repository, and only after a confirmation. Does nothing in a git repository.)
  • Git graph (git_graph): git_graph_toggle_all (a — show every revision instead of the range the backend considers current; only jj has a narrower one), git_graph_set_base, git_graph_clear_base, git_graph_open_picker (b, opens the branch panel). Inside the branch panel ([keys.git_graph_picker]): git_graph_picker_toggle, git_graph_picker_all, git_graph_picker_current_only, git_graph_picker_move_up, git_graph_picker_move_down
  • Git worktrees (git_worktrees — a linked working tree from git worktree add, a different concept from the “worktree” meant everywhere else on this page, which is always the uncommitted working tree): git_open_worktrees (w, in the changes hub), worktree_filter_start (/, filter by branch name / path), worktree_goto (Enter, fixed key: switch this tab’s root — and open_dir — to the selected worktree; still config-rebindable to another key), worktree_goto_new_tab (Ctrl-t: open the selection in a new tab, leaving this tab as-is), worktree_create (n: open an input dialog for a branch name — new vs. existing is auto-detected, no separate prompt for it — then git worktree add it under [git] worktree_dir (see above) next to the main worktree, and switch this tab into it), worktree_show_changes (d: show the selected worktree’s diff since the base branch — committed and uncommitted content together, since an agent working in a worktree often commits along the way and an uncommitted-only diff would otherwise go blank; falls back to an uncommitted-only diff when there’s no resolvable base or nothing has piled up — see graph_base_branches above), worktree_close (q/Esc). A bare main worktree, a locked/prunable one, or the currently-active one all refuse to switch (a flash explains why); worktree_show_changes still works on the currently-active one.
  • Paste-jump (global): paste_jump (P) — reads a path or GitHub link from the clipboard and jumps there (reveal + preview). Understands local absolute/relative paths, GitHub blob/raw URLs, and #L123 / :123 line anchors; switches root to the target’s repository when it lies outside the current root.
  • Tabs / app (global): tab_new (t), toggle_tab_list (T — tab list; tab_list_close = d inside it), tab_prev/tab_next ([/]), quit (Q), toggle_help (?). tab_close has no default key (closing is q on the tree; rebind with "w" = "tab_close" if you want it back)
  • noop (alias disabled) removes a default binding.

Conflicting bindings that would break essential defaults (stealing a leader prefix, tab keys, …) are detected at startup, reported in the footer, and reverted — a bad config never bricks the UI.

Backward-compatible aliases for path copy also exist at the [keys] top level (copy_prefix, copy_name, copy_relative, copy_full, copy_parent).

Path Contents
~/.config/konoma/config.toml This configuration.
~/.config/konoma/bookmarks.toml Global (uppercase) bookmarks — absolute paths.
~/.config/konoma/bookmarks/<dir>.toml Local (lowercase) bookmarks, one file per start directory.
~/.config/konoma/sessions/<dir>.toml Tab session (restore_tabs), one file per start directory.
~/.cache/konoma/remote-images/ Cache for remote images embedded in Markdown.
  • Images / SVG / Mermaid / LaTeX math / video thumbnails / PDF pages are drawn as real pixels in any terminal that speaks a graphics protocol — kitty graphics (Ghostty, kitty, WezTerm, Konsole), iTerm2, or sixel. konoma has its own compressed transfer for the kitty protocol, so those terminals are the fastest. Anywhere else the picture degrades to a half-block approximation — coarse, but visible. Text previews (Markdown, code, git diffs, CSV, tables) work in any terminal.
  • Icons (ui.icons = true, the default) need Nerd Font glyphs: either add Symbols Nerd Font Mono as a fallback font in your terminal, or use an NF-bundled font (HackGen Console NF, UDEV Gothic NF, …). Without one, set ui.icons = false for plain-symbol fallbacks.
  • Optional tools: ffmpegthumbnailer/ffmpeg (thumbnails for video konoma can’t decode itself — VP9, AV1, the older codecs, .avi), git + lazygit (git suite / external tool). PDF, images, SVG, Markdown, Mermaid, LaTeX math, CSV and H.264/HEVC video thumbnails (.mp4/.m4v/.mov and .mkv/.webm) need nothing extra at all — they are rendered in pure Rust. Everything degrades gracefully when absent.