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.
This commit is contained in:
Prad Nukala committed 2026-11-02 09:14:11 -05:00
commit b18729f4a0
163 files changed
+12685

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
# Tools
CLI and TUI tools the repo installs and configures, with the settings applied to each.
This section covers the command-line and terminal-UI tools outside the shell, terminal, and desktop layers. Every tool here is universal: none of it is gated by machine role, so `desktop`, `laptop`, and `server` machines all get it (see [Installation](../installation.md)).
Packages come from `.chezmoidata/packages.yaml` and are installed by `run_onchange_before_10-packages.sh.tmpl` (pacman plus yay for the AUR). See [chezmoi scripts](../chezmoi/scripts.md).
## Configured tools
| Page | Tool | Source in repo | Theme |
| --- | --- | --- | --- |
| [Git](git.md) | git, delta, diffnav, git-split-diffs | `dot_gitconfig.tmpl` | delta colors hand-tuned (dark) |
| [GitHub CLI](github-cli.md) | gh, gh extensions, gh-dash | `dot_config/gh/`, `dot_config/gh-dash/` | gh-dash defaults |
| [Neovim](neovim.md) | nvim (AstroNvim) | external repo via `.chezmoiexternal.toml` | managed in the nvim repo |
| [Yazi](yazi.md) | yazi file manager | external repo via `.chezmoiexternals/yazi.toml` | cyberdream flavor (ii-auto flavor shipped) |
| [Lazygit](lazygit.md) | lazygit | `dot_config/lazygit/` | cyberdream colors (ii theme file shipped) |
| [Lazydocker](lazydocker.md) | lazydocker | `dot_config/lazydocker/config.yml` | cyberdream colors |
| [bat](bat.md) | bat | `dot_config/bat/` | cyberdream tmTheme |
| [Topgrade](topgrade.md) | topgrade | `dot_config/topgrade.toml` | n/a |
| [Hunk](hunk.md) | hunk diff viewer | `dot_config/hunk/config.toml` | `auto` |
| [drydock](drydock.md) | drydock repo fleet view | `dot_config/drydock/config.toml` | n/a |
| [television](television.md) | tv fuzzy picker, custom cables | external repo via `.chezmoiexternals/television.toml` | `cyberdream-transparent` |
| [LeetCode](leetcode.md) | leetcode CLI, `lc-elir` | `dot_leetcode/` | n/a |
- [Git](git.md): Identity from chezmoi data, diff pagers, gh credential helper.
- [Yazi](yazi.md): Keymap, plugins, bookmarks, and the Neovim bridge.
- [Lazygit](lazygit.md): GUI options, delta renderer, custom gh commands.
- [GitHub CLI](github-cli.md): Aliases, extensions, and the gh-dash dashboard.
## Other packaged CLI tools
These packages are declared in `.chezmoidata/packages.yaml` but have no config file in the repo. The "Wired in" column lists where the repo actually uses them.
| Tool | Role | Wired in |
| --- | --- | --- |
| `fzf` | Fuzzy finder | `FZF_DEFAULT_OPTS` in `dot_config/fish/conf.d/10-env.fish` (rounded border, cyberdream colors: highlight `#5ef1ff`, pointer `#ffaecf`, marker `#5eff6c`). Used by fish functions `c2p`, `cp-appid`, `fab`, `gtm`, `mdp`, `lc-elir`, by `~/.local/bin` scripts (`lc-elir`), and as `fuzzy_cmd` of the yazi bunny plugin. The shell pickers (`gho`, `pj`, <kbd>ctrl-e</kbd>) use [television](television.md). |
| `fd` | File finder | `c2p`, `cp-appid`, `extract_agents`, `mdp`, `lc-elir`, `conf.d/pnpm-filter.fish`. |
| `ripgrep` | Content search | `cp-appid`, `gtm`, `gh-sonr-org-migrate` fish functions. |
| `zoxide` | Frecency `cd` | `zoxide init fish` in `conf.d/40-tools.fish`; the `cd` function in fish/bash/zsh falls back to `zoxide query` when the argument is not a directory, and `ghg-clone` registers new clones. |
| `eza` | `ls` replacement | Interactive shells alias `ls` to `eza --icons` (fish `conf.d/20-aliases.fish`, `~/.config/shell/aliases.sh`). |
| `jq` | JSON processor | `fab`, `gtm`, `gh-sonr-org-migrate`, `pnpm-filter`. |
| `duf` | Disk usage overview | Not referenced by any config. |
| `btop` | Resource monitor | Waybar modules launch it on click (`omarchy-launch-or-focus-tui btop`); kitty tab bar shows an icon for it. |
| `fastfetch` | System info | Not referenced by any config. |
| `gum` | Shell prompts and pickers | `gdc` (confirm before `git reset --hard`), `ghn` (host and org pickers), `gtm`, `ai`, `pnpm-filter`, nvm activation messages. |
| `glow` | Markdown renderer | Kitty tab-bar icon only. |
| `micro` | Terminal editor | Alias `sm` = `sudo micro`. |
| `ffmpeg`, `ffmpegthumbnailer`, `poppler`, `resvg`, `imagemagick`, `7zip`, `unzip` | Media, PDF, SVG, image, and archive backends | Grouped in the manifest as yazi preview dependencies. See [Yazi](yazi.md). |
| `wget` | HTTP downloads | Not referenced by any config. |
| `zsh-syntax-highlighting` | zsh highlighting | Sourced by the zsh setup. See [Shell](../shell/README.md). |
| `ttf-victor-mono-nerd` / `font-victor-mono-nerd-font` | Nerd Font | Terminal font. See [Terminal](../terminal/README.md). |
| `suvadu`, `mandible`, `worktrunk` | Declared under `packages.shared.cargo` | Installed by [`15-tools`](../chezmoi/scripts.md#15-tools), which installs rustup first when `cargo` is missing. `mandible` backs the tmux-palette "mandible" item via `~/.local/bin/mandible-pick`. `worktrunk` is the `wt` git-worktree CLI for parallel agent workflows. |
Tools with their own pages in other sections: [fish](../shell/fish.md), [starship](../shell/starship.md), and [atuin](../shell/atuin.md) under Shell; [kitty](../terminal/kitty.md) and [tmux](../terminal/tmux.md) under Terminal.
> [!NOTE]
> `topgrade` comes from the AUR. See the individual pages for per-tool package details.
+74
View File
@@ -0,0 +1,74 @@
# bat
bat with the cyberdream tmTheme, an external PureScript syntax, and automatic cache rebuilds on apply.
[bat](https://github.com/sharkdp/bat) is a `cat` replacement with syntax highlighting and git gutter marks. The repo sets its theme to cyberdream, adds a PureScript grammar, and rebuilds bat's cache whenever those inputs change.
| | |
| --- | --- |
| Sources | `dot_config/bat/config`, `dot_config/bat/themes/cyberdream.tmTheme` |
| External | `.config/bat/syntaxes/sublime-purescript-syntax` in `.chezmoiexternal.toml` |
| Targets | `~/.config/bat/config`, `~/.config/bat/themes/cyberdream.tmTheme`, `~/.config/bat/syntaxes/sublime-purescript-syntax/` |
| Packages | `bat` (pacman) |
## config
bat's config file holds default command-line flags. One is active:
**~/.config/bat/config**
```sh
--theme="cyberdream"
```
The file also carries bat's stock commented examples (`--italic-text=always`, `--paging=never`, a mouse-enabled `--pager`, `--map-syntax`); none are enabled.
## Theme
`cyberdream.tmTheme` is a TextMate theme named "Cyberdream". Base settings:
| Key | Color |
| --- | --- |
| `background` | `#16181a` |
| `foreground`, `caret` | `#ffffff` |
| `lineHighlight`, `selection` | `#3c4048` |
| `findHighlight` | `#5ef1ff` |
| `activeGuide` | `#ffbd5e` |
| `bracketsForeground` | `#ff5ea0` (underlined) |
| Comments | `#7b8496` |
The same file is also used outside bat:
- The [yazi](yazi.md) cyberdream flavor points `syntect_theme` at `~/.config/bat/themes/cyberdream.tmTheme`.
- Yazi text previews run `bat -p --color=always` through the piper plugin, so they get this theme via the config file.
## PureScript syntax
**.chezmoiexternal.toml**
```toml
[".config/bat/syntaxes/sublime-purescript-syntax"]
type = "git-repo"
url = "https://github.com/tellnobody1/sublime-purescript-syntax.git"
[".config/bat/syntaxes/sublime-purescript-syntax".pull]
args = ["--ff-only"]
```
chezmoi clones the Sublime grammar when it is missing. With no `refreshPeriod`, it only pulls (`--ff-only`) on `chezmoi apply --refresh-externals`. See [externals and ignore rules](../chezmoi/externals-and-ignore.md).
## Cache rebuilds
bat only sees custom themes and syntaxes after `bat cache --build`. Two scripts run it:
| Script | When it runs |
| --- | --- |
| `run_onchange_after_build-bat-cache.sh.tmpl` | Embeds SHA-256 hashes of `cyberdream.tmTheme` and `config`, so it re-runs whenever either file changes. Exits quietly if `bat` is missing. |
| `.chezmoiscripts/run_onchange_after_40-post.sh.tmpl` | Post-apply housekeeping (also runs `fc-cache` on Linux). Runs `bat cache --build` when its own rendered content changes, which includes the first apply. |
> [!NOTE]
> Neither hash covers the PureScript external. If the grammar updates, run `bat cache --build` by hand.
## Other consumers
- `lc-elir` previews candidate files with `bat --color=always --line-range=:40` inside fzf. See [LeetCode](leetcode.md).
- The kitty tab bar shows a book icon while `bat` runs.
+23
View File
@@ -0,0 +1,23 @@
# drydock
drydock fleet view of uncommitted, unpushed, and unreleased work, scanning the ghq root.
drydock lists what is uncommitted, unpushed, and unreleased across every repo under its roots.
| | |
| --- | --- |
| Source | `dot_config/drydock/config.toml` |
| Target | `~/.config/drydock/config.toml` (holds live beside it in `holds.toml`, unmanaged) |
| Packages | Not declared in `packages.yaml`; installed with cargo (`~/.cargo/bin/drydock`) |
## config.toml
**~/.config/drydock/config.toml**
```toml
roots = ["~/Code"]
```
Only `roots` is set; everything else stays at drydock's defaults (`drydock config show` prints the effective config). The root is the ghq root, where repos sit at `<host>/<owner>/<repo>`, within the default `max_depth = 4`. `~/Projects` would find nothing: it holds only symlinks (made by [`projects-sync`](../shell/scripts.md#projects-sync)), and drydock does not follow symlinks by default (`follow_symlinks = false`).
`drydock --root <path>` replaces the configured roots for one run.
+114
View File
@@ -0,0 +1,114 @@
# Git
Global git config with templated identity, three diff pagers, an nvim difftool, and gh/tea credential helpers.
Git's global config is a single chezmoi template. It sets the commit identity from chezmoi data, routes diffs through diffnav and git-split-diffs, styles delta for the tools that call it, and delegates HTTPS credentials to `gh` and `tea`.
| | |
| --- | --- |
| Source | `dot_gitconfig.tmpl` |
| Target | `~/.gitconfig` |
| Type | Template (rendered, so it is written as a regular file, not a symlink) |
| Packages | `git`, `git-delta`, `diffnav` (pacman) |
> [!WARNING]
> `git-split-diffs` (the `core.pager`) is not declared in `packages.yaml`; install it separately.
## Identity
**~/.gitconfig**
```ini
[user]
email = {{ .email }}
name = {{ .name }}
```
`.name` and `.email` are prompted once by `.chezmoi.toml.tmpl` on the first `chezmoi init` and stored in the local chezmoi config. No role or OS condition changes this file.
## Pagers
Three pagers are configured, each for a different path:
| Setting | Value | Applies to |
| --- | --- | --- |
| `pager.diff` | `diffnav` | `git diff`: file-tree diff viewer built on delta |
| `core.pager` | `git-split-diffs --color`, piped into `less -+LFX` | Every other paged command (`git log -p`, `git show`, ...) |
| `[split-diffs] min-line-width` | `40` | git-split-diffs side-by-side threshold |
| `[split-diffs] theme-name` | `dark` | git-split-diffs theme |
`less -+LFX` resets the `-L`, `-F`, and `-X` flags, so less always takes over the screen and never exits early on short output.
### delta styling
The `[delta]` section is not a pager setting; delta reads it whenever it runs. Here that means diffnav and [lazygit](lazygit.md), which renders diffs with `delta --dark --paging=never`.
| Option | Value |
| --- | --- |
| `dark` | `true` |
| `tabs` | `2` |
| `file-style` / `file-decoration-style` | `omit` / `none` (no file header) |
| `line-numbers-left-format` | `"{nm:>4} "` |
| `line-numbers-right-format` | `"│ {np:>4} "` |
| `line-numbers-left-style` | `white dim` |
| `line-numbers-right-style` | `"#1f2335" dim` |
| `line-numbers-zero-style`, `-plus-style`, `-minus-style` | `white dim` |
| `wrap-left-symbol`, `wrap-right-symbol`, `wrap-right-prefix-symbol` | a single space each (wrap markers hidden) |
| `plus-style` | `syntax "#0e250e"` |
| `plus-emph-style` | `syntax "#103610"` |
| `minus-style` | `syntax "#402a26"` |
| `minus-emph-style` | `syntax "#45221c"` |
| `hunk-label` | a Nerd Font glyph |
| `hunk-header-line-number-style` | `"#10233A"` |
| `hunk-header-style` | `"#868E99"` |
| `hunk-header-file-style` | `"#868E99" dim` |
| `hunk-header-decoration-style` | `"#163050" ol ul` |
Added and removed lines keep syntax highlighting (`syntax` foreground) on dark green and dark red backgrounds.
## Difftool
**~/.gitconfig**
```ini
[diff]
tool = codediff
[difftool "codediff"]
cmd = nvim \"$LOCAL\" \"$REMOTE\" +\"CodeDiff file $LOCAL $REMOTE\"
```
`git difftool` opens both versions in [Neovim](neovim.md) and runs the `:CodeDiff` command, which comes from the external nvim config. Lazygit's `openDiffTool` binding (`<c-t>`) uses the same tool.
## Remotes and push
| Setting | Value | Effect |
| --- | --- | --- |
| `url "git@github.com:".pushInsteadOf` | `https://github.com/` | Remotes cloned over HTTPS push over SSH; fetches stay on HTTPS. |
| `push.autoSetupRemote` | `true` | First `git push` on a new branch sets its upstream automatically. |
| `advice.addIgnoredFile` | `false` | Silences the hint when `git add` touches an ignored path. |
| `beads.role` | `maintainer` | Role read by the beads (`bd`) issue tracker. |
## Credential helpers
Each host block first sets an empty `helper =`, which clears any helper inherited from system config, then adds one helper:
| Host | Helper | Notes |
| --- | --- | --- |
| `https://github.com` | `!gh auth git-credential` | Uses the token from `gh auth login`. See [GitHub CLI](github-cli.md). |
| `https://gist.github.com` | `!gh auth git-credential` | Same as above, for gists. |
| `https://prad.codes` | `!tea login helper` | Self-hosted Gitea; uses the login stored by the `tea` CLI. |
No credentials are stored in the file itself.
## Related helpers
These git-adjacent commands live in `~/.local/bin` and the shell function directories. See [shell scripts](../shell/scripts.md) for the full set.
| Command | What it does |
| --- | --- |
| `gdc` | Asks for confirmation with `gum confirm`, then runs `git reset --hard HEAD` and `git clean -fd`. |
| `gop` | Opens a repo's web page for any forge whose layout is `https://<host>/<owner>/<repo>`; defaults to `origin`, then `upstream`. Also the <kbd>ctrl-b</kbd> action of the `ghq-repos` [television](television.md#ghq-repos) cable. |
| `git-summary` | Aggregates every `AGENTS.md` in the current repo through `code2prompt`. |
| `ghg` / `ghg-clone` | `ghq get` a repo and `cd` into the clone; sets up a prad.codes pull mirror (your GitHub repos) or GitHub push mirror (prad.codes repos) when none exists. |
| `ghn` | Creates a private repo on prad.codes (via `tea`) or github.com (via `gh`), clones it with ghq, and `cd`s into it. |
| `gho` | Picks a ghq repo or Obsidian vault with the `ghq-repos` [television](television.md#ghq-repos) cable and `cd`s into it. |
+159
View File
@@ -0,0 +1,159 @@
# GitHub CLI
gh config and aliases, the four gh extensions installed on apply, and the gh-dash dashboard layout.
`gh` is GitHub's official CLI. The repo manages its global config, installs a fixed set of extensions, and configures [gh-dash](https://github.com/dlvhdr/gh-dash), a TUI dashboard for pull requests, issues, and notifications.
| | |
| --- | --- |
| Sources | `dot_config/gh/private_config.yml`, `dot_config/gh-dash/config.yml` |
| Targets | `~/.config/gh/config.yml` (mode `0600`, from the `private_` prefix), `~/.config/gh-dash/config.yml` |
| Packages | `github-cli` (pacman) |
| Extensions | `packages.shared.gh_extensions` in `.chezmoidata/packages.yaml` |
> [!NOTE]
> Authentication is per machine: run `gh auth login` once. Tokens live in gh's `hosts.yml` or the system keyring, which the repo does not manage.
## gh config
| Key | Value | Effect |
| --- | --- | --- |
| `version` | `1` | Config schema version. |
| `git_protocol` | `https` | gh clones and adds remotes over HTTPS. Pushes still go over SSH because of the `pushInsteadOf` rewrite in [Git](git.md). |
| `editor` | empty | Falls back to the environment; fish exports `EDITOR=nvim`. |
| `prompt` | `enabled` | Interactive prompts on. |
| `prefer_editor_prompt` | `disabled` | Prompts inline instead of opening an editor. |
| `pager` | empty | Falls back to the environment. |
| `http_unix_socket` | empty | Default transport. |
| `browser` | empty | Falls back to the environment. |
| `color_labels` | `disabled` | Labels are not drawn in their RGB colors. |
| `accessible_colors` | `disabled` | |
| `accessible_prompter` | `disabled` | |
| `spinner` | `enabled` | Animated progress spinner. |
### Aliases
| Alias | Expands to |
| --- | --- |
| `gh co` | `gh pr checkout` |
## Extensions
| Extension | Command | Purpose |
| --- | --- | --- |
| `davidraviv/gh-clean-branches` | `gh clean-branches` | Deletes local branches that no longer have a remote counterpart. |
| `prdlk/gh-commit` | `gh commit` | The owner's commit helper; lazygit binds it as "Smart commit with AI". |
| `dlvhdr/gh-dash` | `gh dash` | PR, issue, and notification dashboard (configured below). |
| `meiji163/gh-notify` | `gh notify` | Notification viewer. |
`.chezmoiscripts/run_onchange_after_20-gh-extensions.sh.tmpl` installs them. It is a fish script, so fish's config is sourced first and `PATH` and `GITHUB_TOKEN` match a fish session:
1. **Re-run trigger**
The rendered script embeds a SHA-256 of the `gh_extensions` list, so chezmoi re-runs it whenever the list changes.
2. **Guards**
If `gh` is missing, or `gh auth status` fails, it prints a warning and exits 0. Run `gh auth login`, then `chezmoi apply` again.
3. **Install**
Reads `gh extension list` and runs `gh extension install` only for entries not already present.
See [chezmoi scripts](../chezmoi/scripts.md) for the full script order.
## gh-dash
Launched with `gh dash`, or <kbd>Ctrl</kbd>+<kbd>d</kbd> in lazygit's files panel.
### Sections
### Pull requests
| Title | Filter |
| --- | --- |
| My Pull Requests | `is:open author:@me` |
| Needs My Review | `is:open review-requested:@me` |
| Involved | `is:open involves:@me -author:@me` |
### Issues
| Title | Filter |
| --- | --- |
| My Issues | `is:open author:@me` |
| Assigned | `is:open assignee:@me` |
| Involved | `is:open involves:@me -author:@me` |
### Notifications
| Title | Filter |
| --- | --- |
| All | (none) |
| Created | `reason:author` |
| Participating | `reason:participating` |
| Mentioned | `reason:mention` |
| Review Requested | `reason:review-requested` |
| Assigned | `reason:assign` |
| Subscribed | `reason:subscribed` |
| Team Mentioned | `reason:team-mention` |
### Defaults
| Key | Value |
| --- | --- |
| `defaults.view` | `prs` |
| `defaults.preview.open` / `width` | `true` / `0.45` |
| `defaults.prsLimit`, `issuesLimit`, `notificationsLimit` | `20` each |
| `defaults.prApproveComment` | `LGTM` |
| `defaults.refetchIntervalMinutes` | `30` |
| `repo.branchesRefetchIntervalSeconds` | `30` |
| `repo.prsRefetchIntervalSeconds` | `60` |
| `repoPaths` | empty |
| `confirmQuit` | `false` |
| `showAuthorIcons` | `true` |
| `smartFilteringAtLaunch` | `true` |
| `includeReadNotifications` | `true` |
| `theme.ui.sectionsShowCount` | `true` |
| `theme.ui.table.showSeparator` / `compact` | `true` / `false` |
### Column layout
| View | Column | Width | Hidden |
| --- | --- | --- | --- |
| PRs | `updatedAt`, `createdAt` | 5 | no |
| PRs | `repo` | 20 | no |
| PRs | `author` | 15 | no |
| PRs | `authorIcon` | | no |
| PRs | `assignees` | 20 | yes |
| PRs | `base` | 15 | yes |
| PRs | `lines` | 15 | no |
| Issues | `updatedAt`, `createdAt` | 5 | no |
| Issues | `repo` | 15 | no |
| Issues | `creator` | 10 | no |
| Issues | `creatorIcon` | | no |
| Issues | `assignees` | 20 | yes |
### Keybindings
| View | Key | Command |
| --- | --- | --- |
| PRs | <kbd>T</kbd> | `gh enhance -R {{.RepoName}} {{.PrNumber}}` |
`gh enhance` is a gh extension that is not in the managed extension list; install it separately for this binding to work.
### Pager
**~/.config/gh-dash/config.yml**
```yaml
pager:
diff: "hunk pager"
```
PR diffs open in [Hunk](hunk.md).
## Other integrations
- [Lazygit](lazygit.md) custom commands call `gh repo sync && gh clean-branches --force`, `gh commit`, `gh pr create --fill -w`, `gh dash`, and `gh browse`.
- `ghn` creates github.com repos with `gh`, and `gh-sonr-org-migrate` scripts gh for an org migration.
- The tmux window-name map gives `gh` its own Nerd Font icon.
+62
View File
@@ -0,0 +1,62 @@
# Hunk
Hunk terminal diff viewer settings, used as the gh-dash diff pager.
[Hunk](https://github.com/modem-dev/hunk) is a review-first terminal diff viewer aimed at agent-authored changes. In this setup it is the diff pager for [gh-dash](github-cli.md#gh-dash).
| | |
| --- | --- |
| Sources | `dot_config/hunk/config.toml`, `dot_config/hunk/private_state.json` |
| Targets | `~/.config/hunk/config.toml`, `~/.config/hunk/state.json` (mode `0600`) |
| Packages | Not declared in `packages.yaml`; install hunk separately |
## config.toml
**~/.config/hunk/config.toml**
```toml
theme = "auto"
mode = "auto"
vcs = "git"
watch = false
exclude_untracked = true
line_numbers = true
tab_width = 4
wrap_lines = false
menu_bar = true
agent_notes = true
prompt_save_view_preferences = false
transparent_background = true
```
| Key | Value | Effect |
| --- | --- | --- |
| `theme` | `auto` | Picks a built-in theme to match the terminal. |
| `mode` | `auto` | Chooses split or stacked layout from the window width (alternatives: `split`, `stack`). |
| `vcs` | `git` | Git backend (alternatives: `jj`, `sl`). |
| `watch` | `false` | Does not reload on file changes. |
| `exclude_untracked` | `true` | Untracked files are left out of working-tree diffs. |
| `line_numbers` | `true` | Shows line numbers. |
| `tab_width` | `4` | Tab stops every 4 columns. |
| `wrap_lines` | `false` | Long lines are not wrapped. |
| `menu_bar` | `true` | Shows the top menu bar. |
| `agent_notes` | `true` | Shows agent notes when a review opens (off by default in hunk). |
| `prompt_save_view_preferences` | `false` | Does not ask to persist view changes. |
| `transparent_background` | `true` | Uses the terminal background instead of the theme's. |
No `[pager]` or per-command sections are set, so pager sessions use these top-level values.
## state.json
`private_state.json` is hunk's runtime state: the state-file `version` and `lastSeenCliVersion`, which hunk updates on its own. It holds no preferences. The `private_` prefix gives it mode `0600`.
## Integrations
**~/.config/gh-dash/config.yml**
```yaml
pager:
diff: "hunk pager"
```
gh-dash pipes PR diffs into `hunk pager`. Plain `git diff` does not use hunk; it goes through diffnav (see [Git](git.md)).
+47
View File
@@ -0,0 +1,47 @@
# Lazydocker
Lazydocker with rounded borders and the CherryBlossom border and selection colors shared with lazygit.
[Lazydocker](https://github.com/jesseduffield/lazydocker) is a terminal UI for Docker containers, images, volumes, and compose projects. The config only restyles it to match [lazygit](lazygit.md).
| | |
| --- | --- |
| Source | `dot_config/lazydocker/config.yml` |
| Target | `~/.config/lazydocker/config.yml` |
| Packages | `lazydocker` (pacman) |
## Settings
**~/.config/lazydocker/config.yml**
```yaml
gui:
border: rounded
theme:
activeBorderColor:
- "#cf716f"
inactiveBorderColor:
- "#a6958f"
selectedLineBgColor:
- "#453130"
optionsTextColor:
- "#a6958f"
```
| Key | Value | Palette |
| --- | --- | --- |
| `gui.border` | `rounded` | |
| `activeBorderColor` | `#cf716f` | CherryBlossom primary |
| `inactiveBorderColor` | `#a6958f` | CherryBlossom on-surface-variant |
| `selectedLineBgColor` | `#453130` | CherryBlossom selection (primary 20% over surface) |
| `optionsTextColor` | `#a6958f` | CherryBlossom on-surface-variant |
Everything else (keybindings, commands, log settings) is left at lazydocker's defaults.
## Launching
| Entry point | Behavior |
| --- | --- |
| `dd` | Alias for `lazydocker` in fish, bash, and zsh. It shadows the coreutils `dd` binary wherever the aliases are loaded; use `command dd` for the real one. |
tmux-resurrect lists `lazydocker` among the processes it restores, and the kitty tab bar shows a Docker icon while it runs.
+282
View File
@@ -0,0 +1,282 @@
# Lazygit
Lazygit with CherryBlossom colors, delta diffs, a full keybinding map, and custom commands wired to gh and helper scripts.
[Lazygit](https://github.com/jesseduffield/lazygit) is a terminal UI for git. The config sets CherryBlossom colors, renders diffs with delta, turns on background fetching and a whole-graph log, and adds custom commands that call `gh`.
| | |
| --- | --- |
| Source | `dot_config/lazygit/config.yml`, `dot_config/lazygit/ii-theme.yml` |
| Target | `~/.config/lazygit/config.yml`, `~/.config/lazygit/ii-theme.yml` |
| Packages | `lazygit` (pacman) |
| Ignored | `.config/lazygit/.omc/**` (agent tooling state) |
## Launching
| Entry point | Behavior |
| --- | --- |
| `gg` | Alias for `lazygit` (all shells) |
| <kbd>Ctrl</kbd>+<kbd>g</kbd> | fish and zsh keybinding |
| <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>g</kbd> | [Kitty](../terminal/kitty.md): lazygit as an overlay on the current window. The tmux-host kitty config opens it in a 90% `tmux display-popup` instead. |
tmux-resurrect lists `lazygit` among the processes it restores.
## GUI
Colors come from the CherryBlossom palette, shared with Ghostty, tmux, and omp:
| Theme key | Color |
| --- | --- |
| `activeBorderColor` | `#cf716f` |
| `inactiveBorderColor` | `#a6958f` |
| `searchingActiveBorderColor` | `#c17e4a` |
| `optionsTextColor` | `#a6958f` |
| `selectedLineBgColor` | `#453130` |
| `cherryPickedCommitBgColor` | `#453130` |
| `cherryPickedCommitFgColor` | `#ad6756` |
| `unstagedChangesColor` | `#ae825f` |
| `defaultFgColor` | `#dcc1b7` |
| `authorColors."*"` | `#dcc1b7` (every author the same color) |
| Option | Value |
| --- | --- |
| `border` | `rounded` |
| `scrollHeight` / `scrollPastBottom` | `2` / `true` |
| `scrollOffMargin` / `scrollOffBehavior` | `2` / `margin` |
| `mouseEvents` | `true` |
| `skipDiscardChangeWarning` | `true` |
| `skipStashWarning` | `true` |
| `skipNoStagedFilesWarning` | `false` |
| `skipRewordInEditorWarning` | `false` |
| `sidePanelWidth` | `0.4` |
| `expandFocusedSidePanel` / `expandedSidePanelWeight` | `true` / `2` |
| `mainPanelSplitMode` | `horizontal` |
| `enlargedSideViewLocation` | `left` |
| `language` | `auto` |
| `timeFormat` / `shortTimeFormat` | `02 Jan 06` / `3:04PM` |
| `commitLength.show` | `true` |
| `showListFooter` | `true` |
| `showFileTree` | `true` |
| `showRandomTip` | `false` |
| `showCommandLog` / `commandLogSize` | `true` / `4` |
| `showBottomLine` | `false` (keybinding hint line hidden) |
| `showPanelJumps` | `false` |
| `showIcons`, `nerdFontsVersion`, `showFileIcons` | `true`, `"3"`, `true` |
| `commitAuthorShortLength` / `commitAuthorLongLength` | `2` (initials) / `17` |
| `commitHashLength` | `8` |
| `showBranchCommitHash` | `true` |
| `showDivergenceFromBaseBranch` | `arrowAndNumber` |
| `splitDiff` | `auto` |
| `screenMode` | `normal` |
| `animateExplosion` | `true` |
| `portraitMode` | `auto` |
| `filterMode` | `fuzzy` |
| `spinner.frames` / `spinner.rate` | ASCII bar (`\|`, `/`, `-`, `\`) / `50` ms |
| `statusPanelView` | `allBranchesLog` |
## Git
| Option | Value |
| --- | --- |
| `diffRenderers` | `delta --dark --paging=never` with `colorArg: always`. delta also reads the `[delta]` section of `~/.gitconfig`; see [Git](git.md). |
| `commit.signOff` | `false` |
| `commit.autoWrapCommitMessage` / `autoWrapWidth` | `true` / `72` |
| `merging.manualCommit` / `args` | `false` / empty |
| `merging.squashMergeMessage` | `Squash merge {{selectedRef}} into {{currentBranch}}` |
| `mainBranches` | `develop` |
| `skipHookPrefix` | `WIP` (a message starting with `WIP` skips pre-commit hooks) |
| `autoFetch` / `autoRefresh` / `fetchAll` | `true` / `true` / `true` |
| `branchLogCmd` | `git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --` |
| `allBranchesLogCmds` | `git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium` |
| `overrideGpg` | `false` |
| `disableForcePushing` | `false` |
| `commitPrefix` / `branchPrefix` | empty |
| `parseEmoji` | `true` |
| `log.order` / `showGraph` / `showWholeGraph` | `topo-order` / `always` / `true` |
| `truncateCopiedCommitHashesTo` | `8` |
## Refresh, updates, and OS
| Option | Value |
| --- | --- |
| `update.method` / `days` | `background` / `14` |
| `refresher.refreshInterval` | `10` s |
| `refresher.fetchInterval` | `60` s |
| `confirmOnQuit` | `false` |
| `quitOnTopLevelReturn` | `true` (<kbd>Esc</kbd> at top level quits) |
| `disableStartupPopups` | `true` |
| `notARepository` | `skip` (opens the most recent repo) |
| `promptToReturnFromSubprocess` | `false` |
| `os.edit`, `editAtLine`, `editAtLineAndWait`, `openDirInEditor`, `editPreset`, `open` | empty (lazygit defaults, which follow `$EDITOR` = nvim) |
| `os.openLink` | `bash -C` running `~/.local/share/omarchy/bin/omarchy-launch-webapp {{link}}` (absolute path in the file) |
| `os.copyToClipboardCmd` / `readFromClipboardCmd` | `wl-copy` / `wl-paste` |
> [!NOTE]
> The link opener and the `wl-copy`/`wl-paste` clipboard commands are Wayland/Omarchy-specific. On a `server` role machine they are unavailable, so opening links and clipboard actions fail there.
## Custom commands
| Key | Context | Command | Output |
| --- | --- | --- | --- |
| <kbd>Ctrl</kbd>+<kbd>i</kbd> | global | `gitv {{.Repository.Owner}}/{{.Repository.Name}}` | terminal |
| <kbd>Ctrl</kbd>+<kbd>w</kbd> | global | `gwm` | terminal |
| <kbd>Ctrl</kbd>+<kbd>a</kbd> | global | `wrkflw` | terminal |
| <kbd>Ctrl</kbd>+<kbd>p</kbd> | global | `github prs` | terminal |
| <kbd>F</kbd> | files | `gh repo sync && gh clean-branches --force` ("Sync repo and clean branches, update DuckDB cache") | log |
| <kbd>A</kbd> | files | `gh commit` ("Smart commit with AI") | terminal |
| <kbd>C</kbd> | files | `gh commit` ("Smart commit with AI") | terminal |
| <kbd>a</kbd> | files | `git add` the file if it has unstaged changes, else `git reset` it ("Toggle file staged") | |
| <kbd>L</kbd> | files | `livediff` | terminal |
| <kbd>Ctrl</kbd>+<kbd>d</kbd> | files | `gh dash` | terminal |
| <kbd>Ctrl</kbd>+<kbd>o</kbd> | files | `gh browse` | |
| <kbd>o</kbd> | localBranches | `gh pr create --fill -w` ("start ai pull request") | |
| <kbd>C</kbd> | localBranches | `gh repo sync && gh clean-branches --force` | log |
| <kbd>O</kbd> | commits | `hub browse -- "commit/{{.SelectedLocalCommit.Hash}}"` | |
`gh commit`, `gh clean-branches`, and `gh dash` are managed gh extensions (see [GitHub CLI](github-cli.md)). `gitv`, `gwm`, `wrkflw`, `github`, `livediff`, and `hub` are not installed by this repo.
> [!WARNING]
> Several custom keys share a key with a built-in binding in the same context: <kbd>C</kbd> and <kbd>a</kbd> in files (`commitChangesWithEditor`, `toggleStagedAll`), <kbd>Ctrl</kbd>+<kbd>w</kbd>, <kbd>Ctrl</kbd>+<kbd>p</kbd>, <kbd>Ctrl</kbd>+<kbd>d</kbd>, <kbd>Ctrl</kbd>+<kbd>o</kbd> against universal bindings, and <kbd>O</kbd> in commits. <kbd>Ctrl</kbd>+<kbd>i</kbd> is the same keycode as <kbd>Tab</kbd> in most terminals.
## Keybindings
The file writes out the full keybinding map. Most values match lazygit's defaults; they are listed so the file is the single reference.
### Universal
| Action | Key |
| --- | --- |
| `quit` / `quit-alt1` | <kbd>q</kbd> / <kbd>Ctrl</kbd>+<kbd>q</kbd> |
| `return` | <kbd>Esc</kbd> |
| `quitWithoutChangingDirectory` | <kbd>Q</kbd> |
| `togglePanel` | <kbd>Tab</kbd> |
| `prevItem` / `nextItem` | <kbd>Up</kbd> / <kbd>Down</kbd> |
| `prevItem-alt` / `nextItem-alt` | <kbd>k</kbd> / <kbd>j</kbd> |
| `prevPage` / `nextPage` | <kbd>,</kbd> / <kbd>.</kbd> |
| `scrollLeft` / `scrollRight` | <kbd>H</kbd> / <kbd>L</kbd> |
| `gotoTop` / `gotoBottom` | `<` / `>` |
| `toggleRangeSelect` | <kbd>v</kbd> |
| `rangeSelectDown` / `rangeSelectUp` | <kbd>Shift</kbd>+<kbd>Down</kbd> / <kbd>Shift</kbd>+<kbd>Up</kbd> |
| `prevBlock` / `nextBlock` | <kbd>Left</kbd> / <kbd>Right</kbd> |
| `prevBlock-alt` / `nextBlock-alt` | <kbd>h</kbd> / <kbd>l</kbd> |
| `nextBlock-alt2` / `prevBlock-alt2` | <kbd>Tab</kbd> / <kbd>Shift</kbd>+<kbd>Tab</kbd> |
| `jumpToBlock` | <kbd>1</kbd>–<kbd>5</kbd> |
| `nextMatch` / `prevMatch` | <kbd>n</kbd> / <kbd>N</kbd> |
| `startSearch` | <kbd>/</kbd> |
| `optionMenu` | <kbd>?</kbd> |
| `select` | <kbd>Space</kbd> |
| `goInto` / `confirm` | <kbd>Enter</kbd> |
| `confirmInEditor` | <kbd>Alt</kbd>+<kbd>Enter</kbd> |
| `remove` | <kbd>d</kbd> |
| `new` | <kbd>n</kbd> |
| `edit` | <kbd>e</kbd> |
| `openFile` | <kbd>o</kbd> |
| `scrollUpMain` / `scrollDownMain` | <kbd>PgUp</kbd> / <kbd>PgDn</kbd> |
| `scrollUpMain-alt1` / `scrollDownMain-alt1` | <kbd>K</kbd> / <kbd>J</kbd> |
| `scrollUpMain-alt2` / `scrollDownMain-alt2` | <kbd>Ctrl</kbd>+<kbd>u</kbd> / <kbd>Ctrl</kbd>+<kbd>d</kbd> |
| `createRebaseOptionsMenu` | <kbd>m</kbd> |
| `pushFiles` / `pullFiles` | <kbd>P</kbd> / <kbd>p</kbd> |
| `refresh` | <kbd>R</kbd> |
| `createPatchOptionsMenu` | <kbd>Ctrl</kbd>+<kbd>p</kbd> |
| `nextTab` / `prevTab` | <kbd>]</kbd> / <kbd>[</kbd> |
| `nextScreenMode` / `prevScreenMode` | <kbd>+</kbd> / <kbd>_</kbd> |
| `undo` / `redo` | <kbd>z</kbd> / <kbd>Ctrl</kbd>+<kbd>z</kbd> |
| `filteringMenu` | <kbd>Ctrl</kbd>+<kbd>s</kbd> |
| `diffingMenu` / `diffingMenu-alt` | <kbd>W</kbd> / <kbd>Ctrl</kbd>+<kbd>e</kbd> |
| `copyToClipboard` | <kbd>Ctrl</kbd>+<kbd>o</kbd> |
| `openRecentRepos` | <kbd>Ctrl</kbd>+<kbd>r</kbd> |
| `submitEditorText` | <kbd>Enter</kbd> |
| `extrasMenu` | <kbd>@</kbd> |
| `toggleWhitespaceInDiffView` | <kbd>Ctrl</kbd>+<kbd>w</kbd> |
| `increaseContextInDiffView` / `decreaseContextInDiffView` | `}` / `{` |
| `increaseRenameSimilarityThreshold` / `decrease...` | <kbd>)</kbd> / <kbd>(</kbd> |
| `openDiffTool` | <kbd>Ctrl</kbd>+<kbd>t</kbd> (runs the nvim `codediff` difftool) |
| `newWorktree` | <kbd>w</kbd> |
### Status
| Action | Key |
| --- | --- |
| `checkForUpdate` | <kbd>u</kbd> |
| `recentRepos` | <kbd>Enter</kbd> |
| `allBranchesLogGraph` | <kbd>a</kbd> |
### Files
| Action | Key |
| --- | --- |
| `commitChanges` | <kbd>c</kbd> |
| `commitChangesWithoutHook` | <kbd>w</kbd> |
| `amendLastCommit` | <kbd>E</kbd> |
| `commitChangesWithEditor` | <kbd>C</kbd> |
| `findBaseCommitForFixup` | <kbd>Ctrl</kbd>+<kbd>f</kbd> |
| `confirmDiscard` | <kbd>x</kbd> |
| `ignoreFile` | <kbd>i</kbd> |
| `refreshFiles` | <kbd>r</kbd> |
| `stashAllChanges` / `viewStashOptions` | <kbd>s</kbd> / <kbd>S</kbd> |
| `toggleStagedAll` | <kbd>a</kbd> |
| `viewResetOptions` | <kbd>D</kbd> |
| `fetch` | <kbd>f</kbd> |
| `toggleTreeView` | `` ` `` |
| `openMergeOptions` | <kbd>M</kbd> |
| `openStatusFilter` | <kbd>Ctrl</kbd>+<kbd>b</kbd> |
| `copyFileInfoToClipboard` | <kbd>y</kbd> |
### Branches
| Action | Key |
| --- | --- |
| `createPullRequest` | <kbd>1</kbd> |
| `viewPullRequestOptions` | <kbd>O</kbd> |
| `copyPullRequestURL` | <kbd>Ctrl</kbd>+<kbd>y</kbd> |
| `checkoutBranchByName` | <kbd>c</kbd> |
| `forceCheckoutBranch` | <kbd>F</kbd> |
| `rebaseBranch` | <kbd>r</kbd> |
| `renameBranch` | <kbd>R</kbd> |
| `mergeIntoCurrentBranch` | <kbd>M</kbd> |
| `viewGitFlowOptions` | <kbd>i</kbd> |
| `fastForward` / `fetchRemote` | <kbd>f</kbd> |
| `createTag` / `pushTag` | <kbd>T</kbd> / <kbd>P</kbd> |
| `setUpstream` | <kbd>u</kbd> |
| `sortOrder` | <kbd>s</kbd> |
### Commits
| Action | Key |
| --- | --- |
| `squashDown` | <kbd>s</kbd> |
| `renameCommit` / `renameCommitWithEditor` | <kbd>r</kbd> / <kbd>R</kbd> |
| `viewResetOptions` | <kbd>g</kbd> |
| `markCommitAsFixup` / `createFixupCommit` | <kbd>f</kbd> / <kbd>F</kbd> |
| `squashAboveCommits` | <kbd>S</kbd> |
| `moveDownCommit` / `moveUpCommit` | <kbd>Ctrl</kbd>+<kbd>j</kbd> / <kbd>Ctrl</kbd>+<kbd>k</kbd> |
| `resetCommitAuthor` | <kbd>a</kbd> |
| `pickCommit` | <kbd>p</kbd> |
| `revertCommit` | <kbd>t</kbd> |
| `cherryPickCopy` / `pasteCommits` | <kbd>C</kbd> / <kbd>V</kbd> |
| `markCommitAsBaseForRebase` | <kbd>B</kbd> |
| `tagCommit` | <kbd>T</kbd> |
| `checkoutCommit` | <kbd>Space</kbd> |
| `resetCherryPick` | <kbd>Ctrl</kbd>+<kbd>c</kbd> |
| `copyCommitAttributeToClipboard` | <kbd>y</kbd> |
| `openLogMenu` | <kbd>Ctrl</kbd>+<kbd>l</kbd> |
| `openInBrowser` | <kbd>o</kbd> |
| `viewBisectOptions` | <kbd>b</kbd> |
| `startInteractiveRebase` | <kbd>i</kbd> |
### Other panels
| Panel | Action | Key |
| --- | --- | --- |
| amendAttribute | `resetAuthor` / `setAuthor` / `addCoAuthor` | <kbd>a</kbd> / <kbd>A</kbd> / <kbd>c</kbd> |
| stash | `popStash` / `renameStash` | <kbd>g</kbd> / <kbd>r</kbd> |
| commitFiles | `checkoutCommitFile` | <kbd>c</kbd> |
| main | `toggleSelectHunk` / `pickBothHunks` / `editSelectHunk` | <kbd>a</kbd> / <kbd>b</kbd> / <kbd>E</kbd> |
| submodules | `init` / `update` / `bulkMenu` | <kbd>i</kbd> / <kbd>u</kbd> / <kbd>b</kbd> |
| commitMessage | `commitMenu` | <kbd>Ctrl</kbd>+<kbd>o</kbd> |
## ii-theme.yml
`ii-theme.yml` is generated by the ii wallpaper theming system and holds only a `gui.theme` block: white active border (bold), grey `#8F9192` inactive border, `#1F1F1F` selection and cherry-pick backgrounds, `#FFF17B` marked base commit, `#FF9BAD` unstaged changes, `#DFE3E3` default text.
Nothing in the repo loads it, so `config.yml`'s cyberdream colors are what lazygit uses. To apply it, pass both files: `LG_CONFIG_FILE="$HOME/.config/lazygit/config.yml,$HOME/.config/lazygit/ii-theme.yml" lazygit`.
+89
View File
@@ -0,0 +1,89 @@
# LeetCode
LeetCode CLI workspace config, its tracked state files, and the lc-elir helper that sends solutions to omp.
The repo tracks the state directory of a terminal LeetCode client, plus a helper that feeds solution files to omp prompt commands. The `~/.leetcode` layout (workspaces with `collab.json`, `timer.json`, and `snapshots/`) matches [night-slayer18/leetcode-cli](https://github.com/night-slayer18/leetcode-cli), which is invoked as `leetcode`.
| | |
| --- | --- |
| Source | `dot_leetcode/` |
| Target | `~/.leetcode/` |
| Packages | The CLI is not declared in `packages.yaml`; install it separately |
| Alias | `lc` = `leetcode` (fish, bash, zsh) |
```text
dot_leetcode/
workspaces.json
star-prompt.json
version-cache.json
workspaces/
default/
config.json
collab.json
timer.json
snapshots/
.keep
```
## Workspaces
`workspaces.json` lists one workspace, `default`, and marks it active.
**~/.leetcode/workspaces/default/config.json**
```json
{
"workDir": "/home/prad/Code/github.com/prdlk/leetcode/work/1",
"lang": "python3",
"site": "leetcode.com",
"editor": "nvim",
"syncRepo": "https://github.com/prdlk/leetcode.git"
}
```
| Key | Value | Effect |
| --- | --- | --- |
| `workDir` | `~/Code/github.com/prdlk/leetcode/work/1` (absolute path in the file) | Where problem files are written. It sits inside the ghq checkout of the solutions repo, under `$GHQ_ROOT`. |
| `lang` | `python3` | Default solution language. |
| `site` | `leetcode.com` | Target site. |
| `editor` | `nvim` | Opens problems in [Neovim](neovim.md). |
| `syncRepo` | `https://github.com/prdlk/leetcode.git` | Repo that solutions sync to. |
The path is absolute, so on a machine with a different username or `$GHQ_ROOT`, edit `workDir`.
The other workspace files start empty: `collab.json` has `"session": null`, `timer.json` has no solve times and no active timer, and `snapshots/` holds only a `.keep` placeholder.
## Tracked state files
| File | Contents |
| --- | --- |
| `star-prompt.json` | Counter for the CLI's "star the repo" prompt: accepted-submission total, milestones already shown, submissions since the last prompt, timestamps, and a `dismissed` flag. |
| `version-cache.json` | Last update check time, latest known version, and whether it has breaking changes. |
These are runtime files. In chezmoi's symlink mode, non-template, non-private files are symlinks into the source directory, so the CLI writes these straight into the repo working tree. Expect them to show up as diffs.
## lc-elir
`lc-elir [root]` picks LeetCode solution files with fzf and runs the omp `/leetcode-eli5` command on each one.
| | |
| --- | --- |
| Sources | `dot_local/bin/executable_lc-elir` (POSIX sh), `dot_config/fish/functions/lc-elir.fish` (fish port) |
| Targets | `~/.local/bin/lc-elir`, `~/.config/fish/functions/lc-elir.fish` |
| Needs | `fd`, `fzf`, `bat`, `omp` |
1. **Find candidates**
`fd --type f '^\d+\..+\.(js|ts)$'` under `root` (default `.`) matches numbered problem files such as `1365.some-slug.js`.
2. **Pick**
`fzf --multi` with prompt `eli5> `, showing the last three path segments (`--delimiter=/ --with-nth=-3..`). The right-hand 60% preview shows the first 40 lines through `bat --color=always --line-range=:40`.
3. **Run**
For each selected file it prints a separator line, then runs `omp -p "/leetcode-eli5 <file>"`. It exits 1 if nothing was picked.
## omp commands
`lc-elir` runs the `/leetcode-eli5` omp command, which lives in `~/.omp/agent/commands/` and is not managed by this repo.
+56
View File
@@ -0,0 +1,56 @@
# Neovim
Neovim config pulled from its own repository as a chezmoi external, plus the editor hooks the dotfiles wire into it.
Neovim is the default editor everywhere in this setup. Its configuration (AstroNvim-based, per the repo README) lives in a separate repository, [prdlk/nvim](https://github.com/prdlk/nvim). This repo only clones it and wires other tools to it; the Lua config itself is not documented here.
| | |
| --- | --- |
| Source | `.chezmoiexternal.toml` entry `.config/nvim` |
| Target | `~/.config/nvim` (a git checkout) |
| Remote | `https://github.com/prdlk/nvim.git` |
| Packages | `neovim` (pacman) |
## How the external works
**.chezmoiexternal.toml**
```toml
[".config/nvim"]
type = "git-repo"
url = "https://github.com/prdlk/nvim.git"
[".config/nvim".pull]
args = ["--ff-only"]
```
- `type = "git-repo"`: chezmoi runs `git clone` when `~/.config/nvim` does not exist, so a fresh machine gets the config on first apply.
- No `refreshPeriod` is set, so a normal `chezmoi apply` never pulls. The local checkout always wins; commit and push nvim changes from `~/.config/nvim` directly.
- A forced refresh (`chezmoi apply --refresh-externals`) runs `git pull --ff-only`, which refuses to merge if local history has diverged.
See [externals and ignore rules](../chezmoi/externals-and-ignore.md) for how chezmoi handles externals in general.
### Ignored runtime paths
`.chezmoiignore.tmpl` keeps chezmoi away from state that tools write inside the checkout:
| Path | Why |
| --- | --- |
| `.config/nvim/lazy-lock.json` | lazy.nvim lockfile, rewritten on plugin updates |
| `.config/nvim/.git`, `.config/nvim/.git/**` | the checkout's own git metadata |
| `.config/nvim/.omc/**` | agent tooling state |
| `.config/nvim/.crush/**` | agent tooling state |
| `.config/nvim/.understand-anything/**` | agent tooling state |
## Integrations in this repo
| Where | What |
| --- | --- |
| `dot_config/fish/conf.d/10-env.fish` | `EDITOR=nvim`. [gh](github-cli.md) falls back to it because its `editor` key is empty. |
| [Aliases](../shell/aliases.md) | `e` = `nvim`; `e.v` opens `~/.config/nvim/lua` in yazi; `e.t` opens the tmux config in nvim. |
| [Kitty](../terminal/kitty.md) | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>e</kbd> opens nvim in the current directory in a 50/50 vertical split. Kitty's `listen_on` socket lets nvim hand <kbd>Ctrl</kbd>+<kbd>h/j/k/l</kbd> at a window edge back to kitty. |
| [Yazi](yazi.md) | The `edit` opener and <kbd>Ctrl</kbd>+<kbd>v</kbd> / <kbd>Ctrl</kbd>+<kbd>x</kbd> call `~/.local/bin/yazi-nvim-open`. Inside an nvim terminal (`$NVIM` set) files open in the host instance through the nvim-side `EditFromYazi` Lua function; otherwise a blocking `nvim` starts. |
| [Git](git.md) | `git difftool` runs `nvim "$LOCAL" "$REMOTE" +"CodeDiff file $LOCAL $REMOTE"`. |
| [LeetCode](leetcode.md) | The default workspace sets `"editor": "nvim"`. |
> [!NOTE]
> `yazi-nvim-open` depends on `_G.EditFromYazi`, which the nvim repo defines (its header points at `lua/config/yazi_session.lua`). If that function is missing, the remote call fails and nothing opens.
+182
View File
@@ -0,0 +1,182 @@
# television
tv config symlinked from the repo, a transparent cyberdream theme, and the custom cables behind gho, pj, and ctrl-e in fish, zsh, and bash.
[television](https://github.com/alexpasmantier/television) (`tv`) is a fuzzy picker built on "cables": TOML files that define a source command, a preview, and actions. Every shell picker in the repo runs on a tv cable, with the same keys in fish, zsh, and bash.
| | |
| --- | --- |
| Source | [prdlk/television](https://github.com/prdlk/television) via `.chezmoiexternals/television.toml`: `config.toml`, `cable/*.toml`, `themes/cyberdream-transparent.toml` |
| Target | `~/.config/television/` |
| Install | Not listed in `.chezmoidata/packages.yaml`; install separately |
`~/.config/television` is a `git-repo` checkout (pulled `--ff-only` every 168h), so edits apply immediately; commit and push them from there. `cable/` holds tv's stock cables plus the repo's own and overridden ones.
## config.toml
The UI is minimal: no borders, a hidden status bar, and padding in place of frames.
| Key | Value |
| --- | --- |
| `default_channel` | `files` |
| `ui.theme` | `cyberdream-transparent` |
| `ui.input_bar` | position `top`, prompt `❯`, `border_type = "none"`, padding left 1, right 1, bottom 1 |
| `ui.status_bar.hidden` | `true` (<kbd>f12</kbd> toggles it) |
| `ui.results_panel` | `border_type = "none"`, padding left 1, right 1 |
| `ui.preview_panel` | `size = 50`, `scrollbar = false`, `border_type = "none"`, padding left 2, right 1 |
| `ui.help_panel.hidden` | `true` |
tv 0.15 has no config key for inline mode (`--inline` and `--height` are CLI-only), so every call site passes `--inline`: `gho` (`tv ghq-repos --inline`), `pj` (`tv pj --inline …`), <kbd>ctrl-e</kbd> (`tv git-files --inline`), and bash <kbd>ctrl-t</kbd> (`tv --autocomplete-prompt … --inline`). Actions that re-exec tv pass it too: `files` (`tv files .. --inline`), `dirs` (`tv dirs .. --inline`), and `channels` (`tv {} --inline`). `tv --inline` opens on the line below the prompt and leaves the cursor there on exit; the shell key bindings move the prompt back ([fish](../shell/fish.md#key-bindings), [bash and zsh](../shell/bash-zsh.md)).
A channel that sets its own `[ui.preview_panel]` replaces the whole table with tv's defaults (rounded border, scrollbar). The stock cables that override it (`alias`, `cargo-commands`, `crontab`, `env`, `fonts`, `gh-issues`, `journal`, `man-pages`, `npm-scripts`, `opencode-sessions`, `ports`, `tea-issues`, `tea-prs`, `text`, `todo-comments`) therefore repeat `border_type = "none"`, `scrollbar = false`, and padding left 2, right 1.
Global keys added on top of the defaults:
| Key | Action |
| --- | --- |
| <kbd>ctrl-e</kbd> | `actions:edit`: the channel's `edit` action |
| <kbd>ctrl-h</kbd> | `actions:goto_parent_dir`; the help panel loses <kbd>ctrl-h</kbd> |
| <kbd>end</kbd> | `go_to_input_end` (unchanged) |
## Theme
`themes/cyberdream-transparent.toml` is a separate file because tv 0.15's builtin `cyberdream` shadows a user theme of the same name and paints an opaque `#16181a` background. This theme omits `background`, so kitty's translucent background shows through (tv 0.15 rejects `background = 'none'`).
| Key | Color |
| --- | --- |
| `border_fg` | `#3c4048` |
| `text_fg`, `input_text_fg`, `result_value_fg` | `#ffffff` |
| `dimmed_text_fg` | `#7b8496` |
| `result_name_fg` | `#5ea1ff` |
| `result_line_number_fg` | `#f1ff5e` |
| `match_fg` | `#5ef1ff` |
| `selection_fg` / `selection_bg` | `#5eff6c` on `#3c4048` |
| `preview_title_fg` | `#ffaecf` |
| `result_count_fg` | `#ffbd5e` |
| `channel_mode_bg` | `#5ef1ff` on `#16181a` |
| `remote_control_mode_bg` | `#5eff6c` on `#16181a` |
| `action_picker_mode_bg` | `#bd5eff` on `#16181a` |
## Sorting
Every custom cable except `agents` (a fixed list, see [agents](#agents)), `omp-sessions` (sorted by [`omp-session`](../shell/scripts.md#omp-session) itself), and `jobs` (fish's job order) pipes its source through [`mtime-sort`](../shell/scripts.md#mtime-sort), which orders lines newest-first by the mtime of the path in the line's last tab-separated field (`--repo` stats `<path>/.git/index` first). tv then ranks match quality and frecency on top of that order. All custom cables set `shell = "bash"`, because `$SHELL` is fish.
## Custom cables
| Cable | File | Opened by |
| --- | --- | --- |
| [`ghq-repos`](#ghq-repos) | `cable/ghq-repos.toml` | <kbd>ctrl-o</kbd> (`gho`) |
| [`git-files`](#git-files) | `cable/git-files.toml` | <kbd>ctrl-e</kbd> |
| [`pj`](#pj) | `cable/pj.toml` | <kbd>ctrl-p</kbd>, <kbd>down</kbd> on an empty prompt (`pj`) |
| [`files`](#files) | `cable/files.toml` | `tv`, <kbd>ctrl-t</kbd> autocomplete |
| [`obsidian`](#obsidian) | `cable/obsidian.toml` | `tv obsidian` |
| [`agents`](#agents) | `cable/agents.toml` | `tv agents` |
| [`omp-sessions`](#omp-sessions) | `cable/omp-sessions.toml` | `tv omp-sessions`, <kbd>ctrl-a</kbd> (`omp-session`) when it has nothing to resume |
| [`jobs`](#jobs) | `cable/jobs.toml` | <kbd>ctrl-z</kbd> in fish (`_jobs_bind`) with two or more background jobs |
| [`kitty-days`](#kitty-days) | `cable/kitty-days.toml` | `tv kitty-days` |
The keys are bound in fish (`fish_user_key_bindings.fish`), zsh (`keybinds.zsh`), and bash (`keybinds.bash`); bash has no <kbd>ctrl-a</kbd> binding, and <kbd>ctrl-z</kbd> is fish only. See [fish](../shell/fish.md#key-bindings) and [bash and zsh](../shell/bash-zsh.md).
### ghq-repos
Entries are `name<TAB>path`: tv shows and matches the name and prints the path. <kbd>ctrl-s</kbd> cycles between the two sources.
| Source | Entries | Sort |
| --- | --- | --- |
| Repos | `ghq list` under `ghq root`, plus two checkouts outside it: the chezmoi source (`~/.local/share/chezmoi`) and the nvim config (`~/.config/nvim`) as `github.com/prdlk/nvim`. Those two win over a ghq clone with the same name | `mtime-sort --repo` |
| Vaults | Every directory under `~/Documents/Obsidian` (depth 3) that contains `.obsidian`, named relative to that directory | `mtime-sort` |
**Preview.** Two commands; <kbd>ctrl-f</kbd> cycles. The default is the commit graph for git directories: `git log --graph --all`, newest 300 commits, as short hash, relative date, subject and refs. The second is `onefetch --no-art`. Non-git directories show `eza --tree --level 2` (falling back to `ls -la`) in both.
[serie](https://github.com/lusingander/serie) cannot draw inside the preview pane: it is a fullscreen TUI that paints its graph with kitty images and has no print mode. <kbd>ctrl-g</kbd> opens it instead.
| Key | Action |
| --- | --- |
| <kbd>enter</kbd> | Print the path. The `gho` function cds into it, clears, and runs `onefetch` in git repos |
| <kbd>ctrl-e</kbd> | `edit`: `cd <path> && nvim .` on `/dev/tty` |
| <kbd>ctrl-b</kbd> | `browse`: `cd <path> && gop` in fork mode, so tv stays open ([gop](../shell/scripts.md#gop)) |
| <kbd>ctrl-g</kbd> | `history`: `serie` on `/dev/tty` in fork mode for git directories; <kbd>q</kbd> returns to the picker |
**Needs:** `ghq`, `fd`, `git`, `serie`, `onefetch`, `mtime-sort`.
### git-files
| Source | Entries |
| --- | --- |
| Tracked | `git ls-files` of the whole repo (from the toplevel), or `fd -t f` outside a repo |
| All | `fd -t f -H -E .git` |
Both are sorted with `mtime-sort`. The preview is `bat -n` with `BAT_THEME=ansi`. <kbd>enter</kbd> runs `edit`: `nvim {}` on `/dev/tty`.
**Needs:** `git`, `fd`, `bat`, `mtime-sort`.
### pj
Source `pj --list`; tv shows the display column. The preview runs `pj --preview` in the global 50% panel, and <kbd>enter</kbd> runs `pj --run`. Running `pj` scans the project and opens this cable with its own records. See [pj](../shell/scripts.md#pj).
**Needs:** `pj`, `mtime-sort`.
### files
Overrides tv's stock `files` cable. Sources `Default` (`fd -t f`) and `Hidden` (`fd -t f -H`), both piped through `mtime-sort`. The `edit` action opens the selection in `nvim` on `/dev/tty`, so it also works from <kbd>ctrl-t</kbd>, where the shell captures tv's stdout.
**Needs:** `fd`, `bat`, `mtime-sort`.
### obsidian
Entries are `name<TAB>path` for every directory under `~/Documents/Obsidian` (depth 3) that contains `.obsidian`, named relative to that directory (nested vaults show as `Research/Sonr`) and sorted with `mtime-sort`. The preview is `eza --tree --level 2`.
| Key | Action |
| --- | --- |
| <kbd>enter</kbd> | `open`: `xdg-open obsidian://open?path=<path>`, detached with `setsid -f` because the generic `xdg-open` stays in the foreground |
| <kbd>ctrl-e</kbd> | `edit`: `cd <path> && nvim .` |
`obsidian://open?path=` only resolves vaults listed in `~/.config/obsidian/obsidian.json`, and Obsidian reads that file once at startup and rewrites it from memory. So when the vault is not listed and Obsidian is closed, `open` adds `{path, ts}` under a random 16-hex id first. When Obsidian is running, it sends a notification and opens the vault switcher (`obsidian://choose-vault`) for **Open folder as vault**.
**Needs:** `fd`, `jq`, `eza`, `obsidian`, `xdg-open`, `mtime-sort`.
### agents
The source is a table of known agent CLIs in the cable, `binary|launch command|description`, kept in table order (`omp` first). A row is listed only when `command -v <binary>` resolves, so agents appear and disappear as they are installed. Entries are `<name description><TAB><launch command><TAB><binary>`; the description is part of the matched text, so `openai` finds `codex`.
| Agents in the table | Launch |
| --- | --- |
| `omp`, `claude`, `codex`, `opencode`, `crush`, `pi`, `cursor-agent`, `copilot`, `gemini`, `agy`, `grok`, `muse`, `ori`, `hermes`, `amp`, `droid`, `qwen`, `kimi`, `goose`, `aider`, `auggie`, `kiro-cli`, `cn`, `fractal` | The binary, except `claude --dangerously-skip-permissions` (same as `ai`) |
The preview shows the launch command, the path on `PATH`, its `readlink -f` target, and, for the `~/.local/bin` wrappers that install the agent through mise on first run, the mise tool. It never runs the agent, since some wrappers take seconds to answer `--version`.
<kbd>enter</kbd> runs `launch` in execute mode: tv exits and the launch command runs in its place, in the current directory.
**Needs:** nothing beyond the agents themselves.
### omp-sessions
Source `omp-session --list`: the omp sessions of the current git repo, newest first, as `<age> <branch> <title>[ · <subdir>]<TAB><session file>`. tv shows and matches the display column, so typing a branch name filters to its sessions. The branch is the one HEAD was on when the session was last written, from the reflog; see [omp-session](../shell/scripts.md#omp-session).
The preview runs `omp-session --preview`: title, last-write time and cwd, then the text of every user and assistant message. <kbd>enter</kbd> runs `resume` in execute mode, `omp-session --resume <file>`, which `exec`s `omp --resume <file>`. <kbd>ctrl-n</kbd> runs `new`, `omp-session --new`, which starts a fresh `omp` session. In this cable <kbd>ctrl-n</kbd> no longer moves to the next entry; <kbd>down</kbd> and <kbd>ctrl-j</kbd> still do.
**Needs:** `omp-session`, `omp`.
### jobs
The current fish shell's background jobs, stopped or running, newest first. tv runs as a child process and cannot read the shell's job table, so `_jobs_bind` ([fish](../shell/fish.md#key-bindings)) writes it to a temp file named by `$TV_JOBS` and the source just `cat`s that file; opened any other way the list is empty. Entries are `%<id> <state> <command><TAB><id><TAB><pgid>`; <kbd>enter</kbd> prints the id and the binding runs `fg %<id>`.
The preview finds the job's processes by process group (procps `ps -g` matches sessions, so it filters `ps -e -o pgid,pid`) and shows the first process's cwd and start time, then `ps --forest` with PID, STAT (`T` = stopped), elapsed time, CPU, RSS, and arguments. The preview script avoids `{`/`}` because tv would parse them as templates and leave `{split:…}` unexpanded.
| Key | Action |
| --- | --- |
| <kbd>enter</kbd> | Print the job id; `_jobs_bind` runs `fg` on it |
| <kbd>ctrl-d</kbd> | `kill` then `reload_source`: SIGTERM to the job's process group, then SIGCONT so a stopped job receives it. Once the group is gone (polled up to 1 s) the row is removed from `$TV_JOBS`, so the reloaded list drops it; a job that ignores SIGTERM stays listed. Fish reports the termination at the next prompt |
**Needs:** `ps`, fish.
### kitty-days
Lists the daily kitty sessions that `~/.config/kitty/day_session.py` saves under `~/.local/share/kitty-sessions/<monday>/<day>.kitty-session` ([kitty daily sessions](../terminal/kitty.md#daily-sessions)). Entries are `<day> <weekday> week of <monday> <n> tabs<TAB><session file>`, through `mtime-sort`. The preview parses the session file with an inline `python3` script (written without braces, which tv would treat as templates): each tab, then each window's cwd and the program it restores, with the last 6 lines of its saved scrollback in color.
| Key | Action |
| --- | --- |
| <kbd>enter</kbd> | `open`: `setsid -f kitty --session <file>`, a new kitty with that day's tabs, scrollback and programs. Past days are read-only snapshots; today's file comes back as the live day if no kitty owns it |
| <kbd>ctrl-e</kbd> | `edit`: the session file in `nvim` |
**Needs:** `kitty`, `python3`, `mtime-sort`.
+72
View File
@@ -0,0 +1,72 @@
# Topgrade
Topgrade config for Omarchy (Arch) machines, with yay as the package manager, chezmoi re-add before upgrades, and post-upgrade hooks.
[Topgrade](https://github.com/topgrade-rs/topgrade) runs every updater on the machine in one pass: system packages, cargo, firmware, git repos, flatpak, and custom commands. The config is written for an Omarchy (Arch) box running fish; most keys are left at topgrade's defaults.
| | |
| --- | --- |
| Source | `dot_config/topgrade.toml` |
| Target | `~/.config/topgrade.toml` |
| Packages | `topgrade` (AUR, via yay) |
> [!NOTE]
> The file's comments say topgrade on the owner's machine is cargo-installed, and that `cargo install-update` keeps it current. That is why self-update is off.
## [misc]
| Key | Value | Why |
| --- | --- | --- |
| `pre_sudo` | `true` | Caches sudo credentials up front so an unattended run does not stop at a password prompt partway through. |
| `no_self_update` | `true` | The `[cargo]` step already updates the topgrade binary; two updaters would fight over it. |
| `cleanup` | `true` | Runs distro cleanup afterwards (paccache needs `pacman-contrib`; skipped if absent). |
| `show_distribution_summary` | `true` | Surfaces `*.pacnew` / `*.pacsave` files to merge. |
| `disable` | `["containers", "config_update"]` | Skips pulling `:latest` for every local container image, and skips topgrade's config-update step. |
| `ignore_failures` | `["uv", "containers"]` | Failures in these steps do not fail the run. |
The Python pip/conda steps stay off (topgrade's default), which protects a pinned ROCm build of torch from blind upgrades. A `remote_topgrades` entry for another host is present but commented out.
## [linux]
| Key | Value | Why |
| --- | --- | --- |
| `arch_package_manager` | `"yay"` | Pins Omarchy's AUR helper so topgrade does not fall back to bare `pacman`, which would skip the AUR. |
| `show_arch_news` | `true` | Prints archlinux.org news before upgrading; Omarchy tracks Arch, so manual-intervention notices still apply. |
## Other steps
| Section | Key | Value | Effect |
| --- | --- | --- | --- |
| `[cargo]` | `git` | `true` | Also updates git-sourced cargo installs, not only crates.io ones. Needs `cargo-update`. |
| `[firmware]` | `upgrade` | `false` | fwupd updates are listed, not flashed, so firmware is reviewed before applying. |
| `[git]` | (none active) | | Predefined repos are still pulled; custom `repos` and `arguments` are commented out to avoid tripping over dirty working trees. |
| `[flatpak]` | (none active) | | User-scope flatpaks update without sudo; `use_sudo` is commented out. |
## Pre- and post-commands
Pre-commands run before any upgrade step:
| Name | Command | Purpose |
| --- | --- | --- |
| Chezmoi Re-Add | `chezmoi re-add` | Pulls local edits to managed dotfiles back into the chezmoi source repo before anything changes them. Only re-adds files chezmoi already manages; review and commit in `~/.local/share/chezmoi` afterwards. |
| GHQ Update | see below | Updates every ghq-managed repo. |
**~/.config/topgrade.toml**
```toml
[pre_commands]
"Chezmoi Re-Add" = "chezmoi re-add"
"GHQ Update" = "ghq list | ghq get -u -s"
```
Post-commands run after everything else:
| Name | Command |
| --- | --- |
| Hermes Update | `hermes update --backup --yes` |
| Herdr Update | `herdr update` |
The post-commands assume the owner's own CLIs (`hermes`, `herdr`); on machines without them those steps fail. omp has no post-command: it is a global mise tool, so topgrade's built-in mise step (`mise upgrade`) updates it, and `omp update` would overwrite the binary inside mise's install directory.
> [!NOTE]
> `chezmoi re-add` does not overwrite templates, so edits made directly to rendered files such as `~/.gitconfig` are not captured; change the `.tmpl` source instead.
+270
View File
@@ -0,0 +1,270 @@
# Yazi
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`, `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`.
```text
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**
```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](bat.md) 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 |
| --- | --- |
| <kbd>l</kbd> | `plugin smart-enter`: enter a directory, or open a file |
| <kbd>g</kbd> <kbd>r</kbd> | cd to the git root (`git rev-parse --show-toplevel`) |
| <kbd>g</kbd> <kbd>C</kbd> | cd to `~/.local/share/chezmoi` |
| <kbd>g</kbd> <kbd>d</kbd> | cd to `~/Downloads` |
| <kbd>g</kbd> <kbd>D</kbd> <kbd>d</kbd> | cd to `$GHQ_ROOT/github.com` |
| <kbd>g</kbd> <kbd>D</kbd> <kbd>w</kbd> | cd to `$GHQ_ROOT/github.com/wltbs` |
| <kbd>g</kbd> <kbd>D</kbd> <kbd>p</kbd> | cd to `$GHQ_ROOT/github.com/prdlk` |
| <kbd>g</kbd> <kbd>l</kbd> | cd to `~/.local` |
| <kbd>g</kbd> <kbd>p</kbd> | cd to `~/Pictures` |
| <kbd>g</kbd> <kbd>o</kbd> <kbd>p</kbd> | cd to `~/Documents/Obsidian/Personal` |
| <kbd>g</kbd> <kbd>o</kbd> <kbd>r</kbd> | cd to `~/Documents/Obsidian/Research` |
| <kbd>g</kbd> <kbd>o</kbd> <kbd>w</kbd> | cd to `~/Documents/Obsidian/Walletbase` |
| <kbd>g</kbd> <kbd>b</kbd> | Back to the previous directory |
| <kbd>g</kbd> <kbd>f</kbd> | Forward to the next directory |
| <kbd>g</kbd> <kbd>m</kbd> <kbd>p</kbd> | cd to `sftp://gdrive-personal` |
| <kbd>g</kbd> <kbd>m</kbd> <kbd>s</kbd> | cd to `sftp://gdrive-sonr` |
| <kbd>g</kbd> <kbd>m</kbd> <kbd>h</kbd> | cd to `sftp://gdrive-hyperauth` |
| <kbd>;</kbd> | Open the bunny hop menu |
| <kbd>'</kbd> | 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 |
| --- | --- |
| <kbd>F</kbd> | `plugin smart-filter`: live filter; enters the directory or opens the file when one match remains |
| <kbd>Ctrl</kbd>+<kbd>t</kbd> | `plugin tv`: jump to a file with television |
| <kbd>Ctrl</kbd>+<kbd>g</kbd> | `plugin tv ghq`: jump to a ghq repo |
| <kbd>Ctrl</kbd>+<kbd>d</kbd> | `plugin tv dirs`: jump to a directory |
| <kbd>Ctrl</kbd>+<kbd>f</kbd> | `plugin tv text`: search text and open the match in Neovim at that line |
| <kbd>Ctrl</kbd>+<kbd>v</kbd> | `yazi-nvim-open vsplit` on the selection (inside an nvim terminal only) |
| <kbd>Ctrl</kbd>+<kbd>x</kbd> | `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 |
| --- | --- |
| <kbd>A</kbd> | Create a directory (`create --dir`) |
| <kbd>N</kbd> | Bulk-create files (`bulk_create`) |
| <kbd>Shift</kbd>+<kbd>Tab</kbd> | Drop into `$SHELL` in the current directory (blocking) |
| <kbd>Ctrl</kbd>+<kbd>q</kbd> | Quit |
In the shell opened by <kbd>Shift</kbd>+<kbd>Tab</kbd>, 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:
**run_onchange_after_install-yazi-plugins.sh.tmpl**
```sh
#!/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` | <kbd>F</kbd> |
| `uhs-robert/sshfs` | `a8b8903` | `require("sshfs"):setup()` in `init.lua` |
| `yazi-rs/plugins:smart-enter` | `efa4d79` | <kbd>l</kbd> |
| `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` | <kbd>Ctrl</kbd>+<kbd>t</kbd>/<kbd>g</kbd>/<kbd>d</kbd>/<kbd>f</kbd> |
| `stelcodes/bunny` | `71b14a3` (vendored) | <kbd>;</kbd> and <kbd>'</kbd>, 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**
```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 |
| --- | --- | --- |
| <kbd>/</kbd> | `/` | |
| <kbd>t</kbd> | `/tmp` | |
| <kbd>~</kbd> | `~` | Home |
| <kbd>m</kbd> | `~/Music` | Music |
| <kbd>d</kbd> | `~/Desktop` | Desktop |
| <kbd>D</kbd> | `~/Developer` | Developer |
| <kbd>c</kbd> | `~/.config` | Config files |
| <kbd>l</kbd> <kbd>s</kbd> | `~/.local/share` | Local share |
| <kbd>l</kbd> <kbd>b</kbd> | `~/.local/bin` | Local bin |
| <kbd>l</kbd> <kbd>t</kbd> | `~/.local/state` | Local state |
## Theme and flavors
**~/.config/yazi/theme.toml**
```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](bat.md) 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/README.md)).
## 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 <kbd>g</kbd> <kbd>m</kbd> 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 <kbd>Ctrl</kbd>+<kbd>v</kbd>/<kbd>Ctrl</kbd>+<kbd>x</kbd> 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. |
| <kbd>Ctrl</kbd>+<kbd>e</kbd> / <kbd>Ctrl</kbd>+<kbd>f</kbd> | fish and zsh keybindings that run `yy` and repaint the prompt. |
| <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>f</kbd> | [Kitty](../terminal/kitty.md): 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.md) 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.md) and [fish](../shell/fish.md) for the shell side.