--- title: Yazi description: Yazi file manager config — layout, openers, bat previews, keymap, plugins, flavors, and the Neovim bridge. --- [Yazi](https://yazi-rs.github.io) 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](https://github.com/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` (`sevenzip` on macOS), `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 one OS difference is the `open` opener, which yazi itself picks with `for`: `xdg-open` on Linux, `open` on macOS. ```toml ~/.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", for = "linux" }, { run = "open %s1", desc = "Open", for = "macos" }, ] [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` (Linux) or `open` (macOS) 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](/tools/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](#vfstoml)). ### 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](https://github.com/alexpasmantier/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](https://github.com/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: ```sh 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 ```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 ```toml ~/.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](/tools/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](/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. A first argument of `vsplit`, `split`, or `tabedit` selects the mode; anything else means `edit`. `edit` runs `exec nvim "$@"`. Split modes do nothing and exit 0. 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](/terminal/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](/terminal/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](/shell/aliases) and [fish](/shell/fish) for the shell side.