shiki (私記)
Reference

Documentation

Every keybinding, every CLI command, the full config.toml schema, note format, and included themes — the complete reference for how shiki actually behaves, kept accurate to the current release rather than a marketing summary.

Layout (3 panels, Yazi-inspired)

shiki — personal/Book recommendations.md
shiki's real three-pane layout: Notebooks, Notes, Preview

Panels behind the current focus collapse to a thin strip (Miller-columns style, like Yazi): browsing NOTEBOOKS shows all three panels at their normal width; moving into NOTES collapses NOTEBOOKS down; moving into PREVIEW collapses both NOTEBOOKS and NOTES so the note has (almost) the full width to read comfortably.

This layout is responsive to the terminal's actual size, not just one fixed arrangement:

Modes (vi-like)

ModeDescription
NORMALNavigation, single-key shortcuts
INSERTTyping in search / input
EDITInline editor active (tui-textarea)
VISUALMulti-note selection

Keybindings

Keybindings aren't one flat list — they're scoped to what's focused, so the same physical key can mean something different (but locally sensible) in each panel. Navigation is hardcoded (not configurable, since it behaves the same everywhere); everything else lives in its own editable config.toml table: [keybindings.global] (needs the leader key first), [keybindings.notebooks], [keybindings.notes], [keybindings.preview].

Navigation (hardcoded, works everywhere)

KeyAction
j / k / / Navigate lists (down / up); scrolls the note while PREVIEW is focused
PageDown / PageUpJump 10 at a time — same lists/scroll as j/k, just a bigger step
Home / EndJump to the first/last notebook or note, or the top/bottom of the note in PREVIEW
l / / enterGo one level deeper (Yazi-style): NOTEBOOKS → NOTES → PREVIEW
h / Go back one level (Yazi-style)
tabCycle focus between panels
?Which-key — near-full-screen list of every binding, doubling as a command palette: type to filter (by key, action, or scope), //PageUp/PageDown/Home/End move the selection, enter runs the highlighted action immediately, Esc just closes
qQuit
EscBack to NORMAL / close popup / cancel leader

PageUp/PageDown/Home/End also work inside every scrollable modal (which-key, logs, global search, tree view) using the same list/selection they already navigate with j/k.

[keybindings.global] — press leader (default space), then:

KeyAction
cPick a theme — modal, live preview while browsing, Enter confirms
gSearch all notes (title + body, every notebook) — modal, Enter/click to jump
TTags panel — j/k browse tags, Enter/l drills into the notes carrying one, Enter/l there jumps to it, h/Esc goes back a level
lLogs — persistent scrollback of every status-bar message (survives restarts, ~/.config/shiki/shiki.log), including errors that already scrolled past; j/k scroll, y/c copies the whole log to the clipboard (OSC 52), x clears all logs (confirmation required), Esc/q closes
bNotebook drawer — left-side sidebar, every notebook's git status in color (dirty/ahead/behind); j/k or click a row to jump to it, n/click "New" to create a notebook, i/click "Import" to clone from a pasted URL, Esc/b again closes
eToggle general.use_favorite_editor on/off and persist it immediately — no need to hand-edit config.toml. The footer always shows which mode is active: the resolved editor name (e.g. nvim) when on, native (the built-in inline editor) when off
UCheck for updates — modal; checks GitHub Releases in the background (never blocks the UI), shows "update available" if there's a newer version, and Enter downloads, verifies (against GitHub's own per-asset checksum), installs, and automatically relaunches into it
uUndo the last delete — restores the most recently deleted note/folder (or whole batch, from a Visual-mode delete) from the trash (~/.config/shiki/trash/) back to exactly where it came from. A single level of undo, not a full history: only the most recent delete is restorable this way; an older one is still on disk in the trash, just no longer reachable from here. With nothing to undo, reports that instead of doing anything

[keybindings.notebooks] — active while NOTEBOOKS is focused

KeyAction
aNew notebook. If the name entered is a git URL (https://, git@host:..., ssh://, git://) instead of a plain name, the notebook name is derived from the repo instead, and the notebook is created, its remote set, and pulled immediately — importing an existing repo is just a + paste URL + Enter
rRename notebook
dDelete notebook (with confirmation)
sGit sync — commit (message auto-built from the diff, naming files directly for a small change, e.g. "shiki: added (First note.md)"), + push if the resolved policy's auto_push is on
uSync and always push, regardless of auto_push/auto_sync — the explicit "do it now" override
pGit pull (fetch + fast-forward merge from the configured remote)
PGit pull for every notebook that has a remote configured
RSet the notebook's git remote (URL or local path)

Beyond manual s, a notebook can sync itself in the background: [git] auto_sync = true (off by default) syncs automatically every auto_sync_every note changes (new/edited/renamed/deleted/moved), not just on manual s. auto_push, auto_sync, and auto_sync_every can all be overridden per notebook under [notebooks.<name>], falling back to the global [git] values for anything left unset. A failed push never blocks or loses anything — the commit already happened locally either way, and the next sync attempt just tries the push again.

[keybindings.notes] — active while NOTES is focused

KeyAction
aNew note (empty title stamps today's date). After the title, a template picker opens — every .md file in ~/.config/shiki/templates/ plus a "blank" option; j/k browse, Enter picks one and jumps straight to editing ({{title}}/{{date}} already substituted), Esc/q cancels the note entirely
fNew folder — empty name cancels rather than creating something unnamed. Created at the current breadcrumb depth, so it can be nested arbitrarily by descending first
rRename note
dDelete the selected note or folder (with confirmation) — a folder deletes everything inside it too. In v select mode, deletes every selected item at once. Moved to the trash rather than permanently removed, so leader+u can undo it
iEdit inline (or the OS favorite editor if general.use_favorite_editor)
EEdit externally ($EDITOR)
/Fuzzy-jump to a note by title anywhere in the current notebook (any folder depth)
tNew/open today's daily note
mMove the selected note or folder — prompts for a notebook/path/within/it target, prefilled with the current one; edit the trailing segments to move within the same notebook (missing folders are created), or replace the first segment to move to a different (existing) notebook. In v select mode, moves every selected item at once
oCycle sort order (filename / title A-Z / date newest-first)
TTree view — every folder and note in the notebook, fully expanded, in one scrollable overview; j/k move, enter/l jumps straight to the selected note, esc/q closes
DToggle each note's date next to its title in the list (off by default)
vSelect mode (Mode::Visual) — anchors a multi-select range at the current item; j/k extend/shrink it, v/Esc cancels. d/m (above) act on the whole range instead of one item
ySelect-mode only: copies every selected note/folder to a prompted target (same notebook/path syntax as m), leaving the originals in place

[keybindings.preview] — active while PREVIEW is focused

KeyAction
iEdit inline (or the OS favorite editor if general.use_favorite_editor)
EEdit externally ($EDITOR)
HNote history — every commit that changed this specific note, newest first, real git history (not a separate versioning system). j/k/PageUp/PageDown/Home/End move, Enter views a revision's full content (frontmatter included, since that's what's actually in the commit), r reverts to the highlighted (or currently-viewed) revision — behind a confirmation, since it overwrites the current content. The revert itself doesn't commit; it shows up as a normal pending change, picked up by s/u/auto_sync like any other edit. The footer shows the count while reading a note ({n} changes)
LLinks — the selected note's outgoing [[wikilinks]] (resolved against every note in the notebook, any folder depth) plus every other note that links back to it ("Outgoing"/"Backlinks" sections; a section with nothing in it is omitted). j/k/PageUp/PageDown/Home/End move, Enter jumps to the selected note (an unresolved outgoing link reports that instead of jumping), Esc/q closes

CLI commands

shiki                     # launch TUI
shiki new <title>         # create note + open $EDITOR
shiki daily               # create/open today's daily note
shiki list                # list notes in the default notebook
shiki list -n work        # list notes in "work"
shiki show <note>         # show rendered content (ANSI)
shiki edit <note>         # edit with $EDITOR
shiki search <query>      # search and show results
shiki sync                # git commit+push default notebook
shiki sync -n work        # git sync in "work"
shiki config              # show config path
shiki notebook create <name>
shiki notebook list
shiki notebook rename <old> <new>
shiki theme list          # list built-in themes, marking the active one
shiki theme set <name>    # switch theme (persisted to config.toml)
shiki theme create [--from <name>]  # scaffold all 19 color overrides from a real palette
shiki doctor              # environment health check (works even with a broken config)

Filesystem layout

Data (~/.local/share/shiki/)

~/.local/share/shiki/
├── personal/              # one notebook = one directory
│   ├── .git/              # independent git repo per notebook
│   ├── 2026-07-22-daily.md
│   ├── meeting-q3-planning.md
│   ├── rust-ideas.md
│   └── projects/          # notebooks nest folders arbitrarily deep, like `nb` —
│       └── website/       # the NOTES panel browses them one level at a time
│           └── todo.md    # (l/→/enter opens a folder, h/← goes back up)
├── work/
│   ├── .git/
│   ├── sprint-review.md
│   └── architecture.md
└── projects/
    └── ...

Frontmatter is optional on read: a plain .md file with no --- block (from nb, an existing repo, or anywhere else) still shows up as a note — its title comes from the first # heading or the filename, its date from the file's mtime. It only gains real frontmatter once you touch it through shiki (rename/edit); until then it's left exactly as it was on disk.

Config (~/.config/shiki/)

~/.config/shiki/
├── config.toml            # general configuration
├── keybindings.toml       # custom shortcuts (optional)
├── theme.toml             # custom theme (optional)
├── shiki.log              # persistent status/log history (leader+l to view, x to clear)
├── trash/                 # deleted notes/folders, restorable with leader+u (see below)
│   └── <notebook>/
└── templates/             # templates
    ├── default.md
    ├── daily.md
    └── meeting.md

Deleting a note or folder (d in NOTES scope) moves it here instead of removing it outright, so leader+u can put it right back. Same collision reasoning as shiki.log: this lives in the config dir, not the data dir, since the data dir's top level is the set of notebooks themselves (user-named directories), so a fixed name placed there could collide with one.

Note format (Markdown + YAML frontmatter)

---
title: My note
date: 2026-07-22
tags: [rust, tui, ideas]
notebook: personal
links: [[another-note]], [[third-link]]
template: default
---

# My note

Content in **markdown**.

- List of items
- Code: `let x = 1;`

[[wikilink]] to another note — navigable from the TUI.

Included themes

Each theme defines 19 configurable color slots: bg, fg, accent, selection, border, statusbar, highlight, error, warning, success, inactive, scrollbar, tab_active, tab_inactive, panel_title, cursor, link, tag, muted. Slots accept #rrggbb hex, the terminal's native ANSI names (red, blue, cyan, darkgray, …), or "reset" to inherit the terminal's own default for that slot. See the live theme switcher on the home page.

Full config.toml reference

[general]
default_notebook = "personal"
editor = "nvim"
daily_template = "daily"
# When true, `i` opens the OS's detected favorite editor (env $VISUAL/$EDITOR,
# then the desktop's default text/plain handler) instead of the inline editor.
use_favorite_editor = false

[keybindings]
leader = "space"
quit = "q"

[keybindings.global]
theme_picker = "c"
global_search = "g"
tags_panel = "T"
logs = "l"
toggle_favorite_editor = "e"
check_update = "U"
drawer = "b"
undo_delete = "u"

[keybindings.notebooks]
new = "a"
rename = "r"
delete = "d"
sync = "s"
pull = "p"
pull_all = "P"
set_remote = "R"

[keybindings.notes]
new = "a"
new_folder = "f"
rename = "r"
delete = "d"
edit_inline = "i"
edit_external = "E"
search = "/"
daily_note = "t"
move_to_notebook = "m"
sort = "o"
tree_view = "T"
toggle_dates = "D"
visual = "v"
copy_entries = "y"

[keybindings.preview]
edit_inline = "i"
edit_external = "E"
history = "H"
links = "L"

[theme]
name = "gruvbox-dark"
# Every one of a theme's 19 color slots can be overridden individually —
# accent, bg, fg, selection, border, statusbar, highlight, error, warning,
# success, inactive, scrollbar, tab_active, tab_inactive, panel_title,
# cursor, link, tag, muted. Override as many or as few as you want; anything
# left unset falls back to `name`'s own value for that slot. A couple of
# examples:
# accent = "blue"
# bg = "#1e1e2e"
# fg = "#cdd6f4"
#
# `shiki theme create [--from ]` scaffolds *all 19* here at once,
# copied from a real palette (defaulting to whichever theme is active) —
# a starting point to edit slot-by-slot instead of hand-typing hex codes
# from scratch with no example to copy from.

[git]
auto_commit = true
auto_push = false
commit_prefix = "shiki: "
remote = "origin"
branch = "main"
sign_commits = false
auto_sync = false
auto_sync_every = 5
# Auto-configures a notebook's remote on creation (plain name, not a pasted
# URL) — "{notebook}" is replaced with the new notebook's name. The remote
# still has to already exist on that server; this doesn't create one via
# any hosting provider's API. Empty (the default) means don't auto-configure
# anything.
remote_template = ""
# remote_template = "git@git.example.com:notes/{notebook}.git"

# Optional per-notebook overrides of [git] — anything left unset here falls
# back to the global values above.
[notebooks.work]
auto_sync = true
auto_sync_every = 3
auto_push = true

Every default shown above matches the current release — if this page and a fresh shiki install ever disagree, trust the install.