Files
omarchy/docs/tools/yazi.md
T
Prad Nukala b18729f4a0 Initial import: chezmoi source for Omarchy (Hyprland)
Imported from prdlk/dotfiles master (efdd827), which supersedes the omarchy
branch (3031416). Drops the Umbriel, Noctalia, niri, CachyOS, macOS, and Blume
docs-site layers; docs/ is plain Markdown.
2026-11-02 09:14:11 -05:00

13 KiB

Yazi

Yazi file manager config — layout, openers, bat previews, keymap, plugins, flavors, and the Neovim bridge.

Yazi is a terminal file manager. It is the default way to browse files here: shell keybindings, aliases, and a kitty shortcut all open it, and it hands files to Neovim.

Source prdlk/yazi via .chezmoiexternals/yazi.toml (git-repo, pulled --ff-only every 168h)
Target ~/.config/yazi/ (git checkout; edit in place, commit and push from there)
Files yazi.toml, keymap.toml, init.lua, package.toml, theme.toml, vfs.toml, flavors/{cyberdream,ii-auto}.yazi/flavor.toml, plugins/bunny.yazi/ (vendored)
Helper dot_local/bin/executable_yazi-nvim-open → ~/.local/bin/yazi-nvim-open
Packages yazi plus preview backends ffmpeg, ffmpegthumbnailer, poppler, resvg, imagemagick, 7zip, unzip
Plugins run_onchange_after_install-yazi-plugins.sh.tmpl → ya pkg install

The whole directory is a symlink into the source tree, so edits apply without chezmoi apply.

yazi/
  yazi.toml
  keymap.toml
  init.lua
  package.toml
  theme.toml
  vfs.toml
  flavors/
    cyberdream.yazi/
      flavor.toml
    ii-auto.yazi/
      flavor.toml
  plugins/
    bunny.yazi/

yazi.toml

Plain TOML, not a template. The open opener runs xdg-open.

~/.config/yazi/yazi.toml

[mgr]
ratio = [0, 2, 6]

[opener]
play = [
	{ run = "mpv %s", orphan = true, for = "unix" },
]
edit = [
	{ run = 'yazi-nvim-open %s', block = true, for = "unix" },
]
open = [
	{ run = "xdg-open %s1", desc = "Open" },
]

[open]
prepend_rules = [
	{ url = "*.{md,markdown}", use = [ "fry", "edit", "open" ] },
]

[[plugin.prepend_previewers]]
mime = "text/*"
run = 'piper -- bat -p --color=always --terminal-width=$w "$1"'

[[plugin.prepend_previewers]]
mime = "application/{mbox,javascript,wine-extension-ini}"
run = 'piper -- bat -p --color=always --terminal-width=$w "$1"'
Setting Effect
mgr.ratio = [0, 2, 6] Hides the parent column; the file list takes 2/8 of the width and the preview 6/8.
opener.play mpv, detached from yazi (orphan = true).
opener.edit yazi-nvim-open, blocking, so yazi waits for the editor.
opener.open xdg-open on the first selected file.
open.prepend_rules Markdown files list fry, then edit, then open. No fry opener is defined in this file.
Previewers Text MIME types, plus mbox, JavaScript, and wine .ini, preview through the piper plugin running bat -p --color=always, so previews use the bat cyberdream theme. Markdown falls under text/* too.

Keymap

All bindings in keymap.toml are [[mgr.prepend_keymap]] entries, so they take priority over yazi's defaults and leave the rest of the default keymap intact.

Navigation

Keys Action
l plugin smart-enter: enter a directory, or open a file
g r cd to the git root (git rev-parse --show-toplevel)
g C cd to ~/.local/share/chezmoi
g d cd to ~/Downloads
g D d cd to $GHQ_ROOT/github.com
g D w cd to $GHQ_ROOT/github.com/wltbs
g D p cd to $GHQ_ROOT/github.com/prdlk
g l cd to ~/.local
g p cd to ~/Pictures
g o p cd to ~/Documents/Obsidian/Personal
g o r cd to ~/Documents/Obsidian/Research
g o w cd to ~/Documents/Obsidian/Walletbase
g b Back to the previous directory
g f Forward to the next directory
g m p cd to sftp://gdrive-personal
g m s cd to sftp://gdrive-sonr
g m h cd to sftp://gdrive-hyperauth
; Open the bunny hop menu
' Bunny fuzzy search over hops

$GHQ_ROOT is ~/Code, exported in dot_config/fish/conf.d/10-env.fish, dot_zshrc, and dot_bashrc. The g m bindings need the SFTP services in vfs.toml, which are commented out (see vfs.toml).

Finding and opening

Keys Action
F plugin smart-filter: live filter; enters the directory or opens the file when one match remains
Ctrl+t plugin tv: jump to a file with television
Ctrl+g plugin tv ghq: jump to a ghq repo
Ctrl+d plugin tv dirs: jump to a directory
Ctrl+f plugin tv text: search text and open the match in Neovim at that line
Ctrl+v yazi-nvim-open vsplit on the selection (inside an nvim terminal only)
Ctrl+x yazi-nvim-open split on the selection (inside an nvim terminal only)

The tv plugin shells out to television, which is not in packages.yaml.

Files and session

Keys Action
A Create a directory (create --dir)
N Bulk-create files (bulk_create)
Shift+Tab Drop into $SHELL in the current directory (blocking)
Ctrl+q Quit

In the shell opened by Shift+Tab, the q function (fish, bash, zsh) runs ya emit quit when $YAZI_ID is set, then exits. That closes the parent yazi too instead of returning to it.

Plugins

package.toml pins every plugin to a commit and hash. ~/.config/yazi is the prdlk/yazi checkout, so ya pkg install writes plugins into its plugins/, which that repo's .gitignore excludes (plugins/*, !plugins/bunny.yazi/). The post-apply script reinstalls from the manifest:

run_onchange_after_install-yazi-plugins.sh.tmpl

#!/bin/sh
# Install the yazi plugins pinned in ~/.config/yazi/package.toml whenever it
# changes. ~/.config/yazi is a git-repo external (prdlk/yazi); plugins land in
# its plugins/ dir (gitignored there, except the vendored bunny.yazi).
{{- $pkg := joinPath .chezmoi.homeDir ".config/yazi/package.toml" }}
# package.toml hash: {{ if stat $pkg }}{{ include $pkg | sha256sum }}{{ end }}
set -eu
command -v ya >/dev/null 2>&1 || exit 0
[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/yazi/package.toml" ] || exit 0
# ya's clone cache is disposable and clones made by an older ya can break a
# newer one, so rebuild it once before giving up.
ya pkg install || {
	rm -rf "${XDG_CACHE_HOME:-$HOME/.cache}/yazi/packages"
	ya pkg install
}

The embedded hash makes chezmoi re-run the script whenever package.toml changes.

bunny is not in package.toml: it is vendored at 71b14a3 in plugins/bunny.yazi/ of the yazi repo, because its repo contains a Git symlink to a directory (test/plugins/bunny.yazi -> ../..) that ya pkg cannot materialize. To update it, re-copy the files from upstream.

Plugin Rev Used by
yazi-rs/plugins:smart-filter efa4d79 F
uhs-robert/sshfs a8b8903 require("sshfs"):setup() in init.lua
yazi-rs/plugins:smart-enter efa4d79 l
yazi-rs/plugins:piper efa4d79 bat previewers in yazi.toml
Rolv-Apneseth/starship ea92cf4 Installed; not set up in init.lua
mikavilpas/easyjump.yazi:easyjump 4aa1a06 Installed; not bound in keymap.toml
cap153/tv b6b1f12 Ctrl+t/g/d/f
stelcodes/bunny 71b14a3 (vendored) ; and ', configured in init.lua
coder0x6675/osc7 ae73046 Installed; not referenced in config
WhoSowSee/mdv-previewer ea4732b Installed; not referenced in yazi.toml
yazi-rs/plugins:vcs-files efa4d79 Installed; not bound in keymap.toml
yazi-rs/plugins:git efa4d79 require("git"):setup { order = 1500 }
yazi-rs/plugins:no-status efa4d79 require("no-status"):setup()

[flavor] deps is empty: flavors ship as files in flavors/, not as packages.

init.lua

~/.config/yazi/init.lua

require("sshfs"):setup()
require("bunny"):setup({ hops = { ... }, desc_strategy = "path", ephemeral = true, tabs = true, notify = false, fuzzy_cmd = "fzf" })
require("git"):setup { order = 1500 }
require("no-status"):setup()
  • sshfs: default setup, for mounting remote hosts over SSHFS.
  • git: git status signs in the file list, ordered at 1500 in the linemode.
  • no-status: removes the status bar.
  • bunny: bookmark "hops", with ephemeral hops and tab hops on, no notification after hopping, fzf for fuzzy search, and the path as the label when a hop has no desc.
Hop key Path Label
/ /
t /tmp
~ ~ Home
m ~/Music Music
d ~/Desktop Desktop
D ~/Developer Developer
c ~/.config Config files
l s ~/.local/share Local share
l b ~/.local/bin Local bin
l t ~/.local/state Local state

Theme and flavors

~/.config/yazi/theme.toml

[flavor]
light = "cyberdream"
dark = "cyberdream"
use = "cyberdream"

Cyberdream is active in both light and dark mode, the palette shared with Ghostty, tmux, nvim, and television. Two flavors ship in flavors/:

Flavor Origin Notes
cyberdream.yazi Hand-maintained cyberdream palette Active. Sets syntect_theme = "~/.config/bat/themes/cyberdream.tmTheme", so yazi's built-in code preview shares the bat theme. Cyan cwd (#5ef1ff), green find keyword (#5eff6c), yellow and red copy/cut markers.
ii-auto.yazi Generated by the ii wallpaper theming system ("Do not edit manually") Not selected. Monochrome palette taken from the wallpaper.

To switch, change use (and light/dark) in theme.toml to ii-auto.

Icons

theme.toml also carries a large [icon] table:

  • prepend_dirs: Nerd Font icons for named directories: Applications, Code, Desktop, Developer, github.com, prdlk, wltbs, Shared, Templates, env, go, js, dart, py, rs, tex, md, docs, prad.codes.
  • files and exts: several hundred filename and extension rules, from dotfiles like .gitignore and .zshrc to formats like kicad_pcb and wrangler.toml. Each rule sets a Nerd Font glyph and a foreground color from the Catppuccin Mocha palette (#a6e3a1, #f38ba8, #89b4fa, #cba6f7, #fab387, ...).

Glyphs need a Nerd Font. The terminal uses VictorMono Nerd Font (see Terminal).

vfs.toml

Every line is commented out. The file sketches three SFTP services (gdrive-personal, gdrive-sonr, gdrive-hyperauth) on local ports, meant to be served by a local SFTP bridge to Google Drive. Until they are uncommented and the bridge is running, the g m bindings have nothing to connect to.

Neovim bridge: yazi-nvim-open

~/.local/bin/yazi-nvim-open [vsplit|split|tabedit] file... backs the edit opener and the Ctrl+v/Ctrl+x bindings. It lives on PATH because yazi does not expand $HOME in opener commands.

  1. Parse mode

    A first argument of vsplit, split, or tabedit selects the mode; anything else means edit.

  2. Standalone yazi ($NVIM unset)

    edit runs exec nvim "$@". Split modes do nothing and exit 0.

  3. Inside an nvim terminal ($NVIM set)

    Each file is resolved with realpath, escaped for a Vimscript string, and sent to the host with nvim --server "$NVIM" --remote-expr "v:lua.EditFromYazi(mode, path)". The nvim side opens the file and hides the yazi window.

Set YAZI_OPEN_TRACE to a file path to log each call's $NVIM, mode, and arguments.

Launching yazi

Entry point Behavior
y / yy (fish functions) Run yazi with --cwd-file, then cd to the directory yazi was in on exit. The two are identical apart from y calling command rm.
yy (bash, zsh functions) Same wrapper for bash and zsh.
Ctrl+e / Ctrl+f fish and zsh keybindings that run yy and repaint the prompt.
Ctrl+Shift+f Kitty: yazi in a new tab at the current directory.
Aliases e.y, e.k, e.n, e.f, e.v open config directories in yazi; cdc, cdl, cdw, and ,, (fish only; chezmoi source) cd first, then start yazi.

tmux sets allow-passthrough on so yazi's kitty-protocol image previews work inside tmux. Kitty's tab bar and the tmux window-name map show a folder icon for yazi. See aliases and fish for the shell side.