Skip to content
dots
Esc
↑↓navigate↵open⌘Jpreview
On this page

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 dot_config/yazi/
Target ~/.config/yazi/
Files yazi.toml.tmpl, keymap.toml, init.lua, package.toml, theme.toml, vfs.toml, flavors/{cyberdream,ii-auto,noctalia}.yazi/flavor.toml
Helper dot_local/bin/executable_yazi-nvim-open → ~/.local/bin/yazi-nvim-open
Packages yazi plus preview backends ffmpeg, ffmpegthumbnailer, poppler, resvg, imagemagick, 7zip (sevenzip on macOS), unzip
Plugins run_onchange_after_install-yazi-plugins.sh.tmpl → ya pkg install
  • dot_config/yazi/
    • yazi.toml.tmpl
    • keymap.toml
    • init.lua
    • package.toml
    • theme.toml
    • vfs.toml
    • flavors/
      • cyberdream.yazi/
        • flavor.toml
      • ii-auto.yazi/
        • flavor.toml
      • noctalia.yazi/
        • flavor.toml

yazi.toml

The only template in the directory. The one OS condition is the open opener: macOS uses open, everything else uses xdg-open.

[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 = "{{ if eq .chezmoi.os "darwin" }}open{{ else }}xdg-open{{ end }} %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 open (macOS) or 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.

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. 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/plugins/** is in .chezmoiignore.tmpl, so chezmoi never manages the installed code. The post-apply script reinstalls from the manifest:

#!/bin/sh
# package.toml hash: {{ include "dot_config/yazi/package.toml" | sha256sum }}
set -eu
command -v ya >/dev/null 2>&1 || exit 0
[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/yazi/package.toml" ] || exit 0
ya pkg install

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

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 ; 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

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

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

Cyberdream is active in both light and dark mode. Three 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.
noctalia.yazi Noctalia palette Not selected. Full theme: manager, status, mode, input, tabs, completion, tasks, which, spotter, help, notify, and MIME-based file colors.

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

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.

Parse mode

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

Standalone yazi ($NVIM unset)

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

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.

Was this page helpful?