mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-02 11:32:42 +00:00
docs(docs): add iris docs and update shell documentation for iris integration
This commit is contained in:
1 parent
0692ae332b
commit
e0cdcd6159
9 files changed
+134
-92
No files matched your search
+26
-24
@@ -3,7 +3,7 @@ title: fish
|
||||
description: The primary interactive shell — conf.d layout, environment, vi-mode key bindings, the cyberdream theme, completions, and every autoloaded function.
|
||||
---
|
||||
|
||||
fish is the primary interactive shell. The config is split into autoloaded files: `conf.d/` for startup snippets, `functions/` for one function per file, `completions/` for completion scripts, and `themes/` for the color theme. `config.fish` runs last and holds the prompt and atuin setup.
|
||||
fish is the primary interactive shell. The config is split into autoloaded files: `conf.d/` for startup snippets, `functions/` for one function per file, `completions/` for completion scripts, and `themes/` for the color theme. `config.fish` runs last and holds the prompt setup and the [iris](/shell/iris) launch.
|
||||
|
||||
| Source (repo) | Target |
|
||||
| --- | --- |
|
||||
@@ -19,7 +19,7 @@ None of these files are templates. chezmoi runs in symlink mode, so each target
|
||||
|
||||
## Installation
|
||||
|
||||
`fish` is in `.chezmoidata/packages.yaml` under `packages.arch.pacman` and `packages.darwin.brew`. `.chezmoiscripts/run_onchange_before_10-packages.sh.tmpl` installs it with pacman on Arch and Homebrew on macOS. The tools that fish initializes (starship, zoxide, atuin, fzf, eza, gum, yazi) come from the same manifest. mise, television, hishtory, envman, and the Bun, Go, Android, and Foundry toolchains are not in the manifest; fish initializes each one only if it is present.
|
||||
`fish` is in `.chezmoidata/packages.yaml` under `packages.arch.pacman` and `packages.darwin.brew`. `.chezmoiscripts/run_onchange_before_10-packages.sh.tmpl` installs it with pacman on Arch and Homebrew on macOS. The tools that fish initializes (starship, zoxide, fzf, eza, gum, yazi) come from the same manifest. mise, television, hishtory, envman, iris, and the Bun, Go, Android, and Foundry toolchains are not in the manifest; fish initializes each one only if it is present.
|
||||
|
||||
### Plugins
|
||||
|
||||
@@ -43,7 +43,6 @@ fish sources `conf.d/*.fish` in name order and then `config.fish`. The numbered
|
||||
| `30-ssh-agent.fish` | One ssh-agent shared across shells |
|
||||
| `40-tools.fish` | mise, television, starship, zoxide, entire, hishtory, unsloth |
|
||||
| `50-terminal-title.fish` | tmux/screen window name from `$PWD` |
|
||||
| `atuin.env.fish` | Sources `~/.atuin/bin/env.fish` (puts atuin's install dir on `PATH`) |
|
||||
| `inir-env.fish` | `INIR_VENV` and `ILLOGICAL_IMPULSE_VIRTUAL_ENV` → `~/.local/state/quickshell/.venv` |
|
||||
| `inir-path.fish` | Prepends `~/.local/bin` to `PATH` if missing |
|
||||
| `nvm.fish` | nvm.fish plugin events and default-version activation |
|
||||
@@ -133,7 +132,7 @@ Interactive shells without `SSH_AUTH_SOCK` source `~/.ssh/agent.env.fish` and pr
|
||||
5. Source `~/.hishtory/config.fish` if present.
|
||||
6. Activate the unsloth studio venv (`~/.unsloth/studio/unsloth_studio/bin/activate.fish`) if present.
|
||||
|
||||
atuin is initialized later, in `config.fish`, and binds <kbd>ctrl-r</kbd> itself.
|
||||
Under [iris](/shell/iris), <kbd>ctrl-r</kbd> never reaches fish: iris takes it to switch its menu between spec and history mode.
|
||||
|
||||
### 50-terminal-title.fish
|
||||
|
||||
@@ -169,10 +168,14 @@ The header comment says the file should stay empty, but it holds the following:
|
||||
2. **Bottom-pinned prompt.** In interactive shells with `FISH_BOTTOM_PROMPT=1`, `tput cup $LINES 0` moves the cursor to the last row. The comment calls `1` the default, but `10-env.fish` sets `0`, so the prompt stays at the top unless you export `FISH_BOTTOM_PROMPT=1`.
|
||||
3. `fish_add_path ~/.grok/bin` (grok installer block).
|
||||
4. Sources `~/.config/envman/load.fish` if it is non-empty.
|
||||
5. **atuin.** Interactive shells run `atuin init fish | source` and `atuin ai init fish | source`. See [atuin](/shell/atuin).
|
||||
6. `fish_add_path ~/.cmux/bin` and `~/.cache/.bun/bin`.
|
||||
7. Sources the first readable `~/.config/herdr/plugins/github/herdr-automatic-rename-*/shell/hook.fish`. This is herdr's automatic pane-rename hook ([herdr](/terminal/herdr)).
|
||||
8. A copy of the `_atuin_ai_question_mark` function that `atuin ai init fish` emits, followed by `bind "?" _atuin_ai_question_mark`.
|
||||
5. `fish_add_path ~/.cmux/bin` and `~/.cache/.bun/bin`.
|
||||
6. Sources the first readable `~/.config/herdr/plugins/github/herdr-automatic-rename-*/shell/hook.fish`. This is herdr's automatic pane-rename hook ([herdr](/terminal/herdr)).
|
||||
7. `brew shellenv fish` for `/home/linuxbrew/.linuxbrew`.
|
||||
8. **iris.** If iris is installed: in an interactive fish that iris is not already running (no `IRIS_PID`, no `IRIS_RESCUE`), export `fish_features=no-query-term`, then `iris init fish | source`. The first half of the init `exec`s iris from an interactive fish; iris starts a second fish inside its pty, which runs this whole config again, and there the second half installs iris's cwd and command hooks and turns off fish autosuggestions. `IRIS_RESCUE=1 fish` starts a plain fish. See [iris](/shell/iris).
|
||||
|
||||
`no-query-term` turns off fish's terminal capability query. In kitty that query switches on kitty's keyboard protocol, which sends keys as `CSI u` escape sequences iris cannot parse, so its menu never opened. Feature flags are read at startup, so the export has to happen before `exec iris`; the fish iris starts inherits it.
|
||||
|
||||
atuin is not used in fish: it fought iris for <kbd>up</kbd> and <kbd>ctrl-r</kbd>. bash still initializes it ([atuin](/shell/atuin)).
|
||||
|
||||
## Key bindings
|
||||
|
||||
@@ -181,16 +184,14 @@ The header comment says the file should stay empty, but it holds the following:
|
||||
| Key | Action |
|
||||
| --- | --- |
|
||||
| <kbd>ctrl-e</kbd> | `_tv_inline git-files`, then repaint: pick a file in the repo and open it in nvim ([television](/tools/television#git-files)) |
|
||||
| <kbd>ctrl-f</kbd> | `yy`: yazi, then cd to the directory yazi exited in |
|
||||
| <kbd>ctrl-b</kbd> | `purple`, then repaint (an external command; this repo does not provide it) |
|
||||
| <kbd>ctrl-y</kbd> | `clip-last`: re-run the last command and copy its output |
|
||||
| <kbd>ctrl-f</kbd> | `_bind_run yy`: yazi, then cd to the directory yazi exited in |
|
||||
| <kbd>ctrl-b</kbd> | `_bind_run purple` (an external command; this repo does not provide it) |
|
||||
| <kbd>ctrl-y</kbd> | `_bind_run clip-last`: re-run the last command and copy its output |
|
||||
| <kbd>ctrl-o</kbd> | `_gho_bind`: `gho` (pick a ghq repo or Obsidian vault from the `ghq-repos` cable and cd into it), then repaint |
|
||||
| <kbd>ctrl-p</kbd> | `_pj_bind`: `pj`, the task runner on the `pj` cable ([Scripts](/shell/scripts#pj)), then repaint |
|
||||
| <kbd>ctrl-a</kbd> | `omp-session`, then repaint: resume or start omp for the current repo by branch and session age, opening the `omp-sessions` cable only when nothing qualifies ([Scripts](/shell/scripts#omp-session)) |
|
||||
| <kbd>ctrl-w</kbd> | `atuin ai inline`: natural-language command overlay |
|
||||
| <kbd>ctrl-a</kbd> | `_bind_run omp-session`: resume or start omp for the current repo by branch and session age, opening the `omp-sessions` cable only when nothing qualifies ([Scripts](/shell/scripts#omp-session)) |
|
||||
| <kbd>ctrl-z</kbd> | `_jobs_bind`: with one background job, `fg` it; with several, pick one from the `jobs` cable ([television](/tools/television#jobs)) and `fg` that; with none, nothing. While a job holds the terminal, ctrl-z is still the tty's suspend, so the key toggles suspend and resume |
|
||||
| <kbd>ctrl-g</kbd> | `lazygit` |
|
||||
| <kbd>down</kbd> | `_pj_bind_down`: opens the `pj` cable on an idle, empty prompt, otherwise fish's `down-or-search` |
|
||||
| <kbd>ctrl-g</kbd> | `_bind_run lazygit` |
|
||||
| <kbd>ctrl-c</kbd> | Clears the command line, runs `clear` (screen and kitty scrollback), repaints |
|
||||
| <kbd>ctrl-q</kbd> | `exit` |
|
||||
|
||||
@@ -198,12 +199,12 @@ Bindings added by tool init scripts:
|
||||
|
||||
| Key | Mode | Action | Source |
|
||||
| --- | --- | --- | --- |
|
||||
| <kbd>ctrl-r</kbd> | default and insert | `_atuin_search` | `atuin init fish` |
|
||||
| <kbd>up</kbd> | default and insert | `_atuin_bind_up` (atuin history, directory filter) | `atuin init fish` |
|
||||
| <kbd>?</kbd> | default (vi normal) | `_atuin_ai_question_mark`: on an empty buffer, opens `atuin ai inline` | `config.fish` |
|
||||
| <kbd>up</kbd> / <kbd>down</kbd> | default and insert | fish presets (`up-or-search`, `down-or-search`); under iris the keys never reach fish | fish |
|
||||
| <kbd>ctrl-t</kbd> | insert | `tv_smart_autocomplete` | `tv init fish` |
|
||||
|
||||
`_pj_bind_down` hands the key to `down-or-search` when the buffer is non-empty, the completion pager is open, or history search is active. Otherwise it runs `_pj_bind --quiet` (`PJ_QUIET=1`), so pressing down outside a project does nothing and prints no error.
|
||||
Under iris, <kbd>tab</kbd>, <kbd>shift-tab</kbd>, <kbd>ctrl-r</kbd>, <kbd>up</kbd>, and <kbd>down</kbd> belong to iris and never reach fish, so fish's tab completion, history keys, and the `tv init fish` <kbd>ctrl-r</kbd> history binding are shadowed. Every other key above reaches fish.
|
||||
|
||||
A program started by a key binding never fires `fish_preexec`/`fish_postexec`, so iris would keep handling keys as if the prompt were idle while tv, yazi, or lazygit owned the screen: it swallowed arrows and <kbd>tab</kbd> and could draw its menu over them. Every binding that runs a program therefore tells iris with `_iris_busy start` / `_iris_busy stop`, the same `IRIS_CMD_START` / `IRIS_CMD_STOP` messages iris's own hooks send (a no-op outside iris). `_bind_run CMD` wraps a command that way and repaints; `_tv_inline`, `_gho_bind`, and `_pj_bind` call `_iris_busy` themselves.
|
||||
|
||||
The pickers run `tv --inline`, which opens on the line below the prompt and leaves the cursor there when it exits. The wrappers put the prompt back before `commandline -f repaint`, writing the cursor moves to `/dev/tty`:
|
||||
|
||||
@@ -211,14 +212,14 @@ The pickers run `tv --inline`, which opens on the line below the prompt and leav
|
||||
| --- | --- | --- |
|
||||
| `_tv_inline ARGS` | `tv ARGS --inline` | `\033[A` (cursor up), returns tv's status |
|
||||
| `_gho_bind` | `gho` | `\033[A` if the cwd did not change; `\n` after a cd, so the prompt lands below onefetch |
|
||||
| `_pj_bind [--quiet]` | `pj` with `PJ_STATE` set to a temp file | `\033[A` for `open` (cancelled) or empty (no task sources); `\n` for `ran` (the task printed output) |
|
||||
| `_pj_bind` | `pj` with `PJ_STATE` set to a temp file | `\033[A` for `open` (cancelled) or empty (no task sources); `\n` for `ran` (the task printed output) |
|
||||
| `_jobs_bind` | `fg` of the only job, or `jobs` with `TV_JOBS` set to a temp file holding the job table | `\033[A` (via `_tv_inline`) when the picker is cancelled |
|
||||
|
||||
`_jobs_bind` runs `fg` by replacing the command line with ` __jobs_bind_fg <id>` (leading space: kept out of history) and executing it, not from inside the binding. A binding runs while fish's reader still owns the terminal with extended keys on, so a job started with `&` that had never held the terminal got ctrl-z and ctrl-c as escape sequences instead of signals. `__jobs_bind_fg` erases the echoed prompt line (`\033[A\033[2K` on `/dev/tty`) and runs `fg` with its "Send job … to foreground" message sent to `/dev/null`, so resuming leaves nothing on screen. Text already typed is put back at the next prompt by a one-shot `fish_prompt` handler.
|
||||
|
||||
`omp-session` (<kbd>ctrl-a</kbd>) does its own `\033[A` when its `omp-sessions` picker is cancelled, so the binding only repaints.
|
||||
|
||||
zsh and bash bind <kbd>ctrl-o</kbd>, <kbd>ctrl-e</kbd>, <kbd>ctrl-p</kbd>, <kbd>down</kbd>, and <kbd>ctrl-t</kbd> the same way ([bash and zsh](/shell/bash-zsh)). Inside television, <kbd>ctrl-e</kbd> runs the channel's `edit` action and <kbd>ctrl-h</kbd> its `goto_parent_dir` action (`television/config.toml`). The config and cables are on the [television](/tools/television) page.
|
||||
zsh and bash bind <kbd>ctrl-o</kbd>, <kbd>ctrl-e</kbd>, <kbd>ctrl-p</kbd>, and <kbd>ctrl-t</kbd> the same way, and zsh also <kbd>ctrl-z</kbd> ([bash and zsh](/shell/bash-zsh)). Inside television, <kbd>ctrl-e</kbd> runs the channel's `edit` action and <kbd>ctrl-h</kbd> its `goto_parent_dir` action (`television/config.toml`). The config and cables are on the [television](/tools/television) page.
|
||||
|
||||
:::note
|
||||
Under kitty, <kbd>ctrl-g</kbd> (lazygit overlay), <kbd>ctrl-y</kbd> (yazi split), and <kbd>ctrl-h/j/k/l</kbd> (split navigation) are mapped in `kitty.conf` and never reach fish. The fish binds for those keys only apply in other terminals. See [kitty](/terminal/kitty).
|
||||
@@ -271,9 +272,10 @@ Every file in `functions/` is autoloaded by name. Several also exist as POSIX sc
|
||||
| `_nvm_version_activate` | nvm.fish internal: sets `nvm_current_version` and prepends its `bin` to `PATH` |
|
||||
| `_nvm_version_deactivate` | nvm.fish internal: removes a version's `bin` from `PATH` |
|
||||
| `_gho_bind` | <kbd>ctrl-o</kbd> handler: `gho`, then cursor fix and repaint (see [Key bindings](#key-bindings)) |
|
||||
| `_pj_bind` | <kbd>ctrl-p</kbd> handler: `pj` with `PJ_STATE`, then cursor fix and repaint. `--quiet` sets `PJ_QUIET=1` |
|
||||
| `_pj_bind` | <kbd>ctrl-p</kbd> handler: `pj` with `PJ_STATE`, then cursor fix and repaint |
|
||||
| `_jobs_bind` | <kbd>ctrl-z</kbd> handler: `fg` the only job or pick one from the `jobs` cable (see [Key bindings](#key-bindings)) |
|
||||
| `_pj_bind_down` | Down-arrow handler: `_pj_bind --quiet` on an empty idle prompt, else `down-or-search` |
|
||||
| `_bind_run` | Runs `$argv` between `_iris_busy start` and `stop`, then repaints. Used by the <kbd>ctrl-a</kbd>, <kbd>ctrl-b</kbd>, <kbd>ctrl-f</kbd>, <kbd>ctrl-g</kbd>, and <kbd>ctrl-y</kbd> bindings |
|
||||
| `_iris_busy` | `start`/`stop`: writes `IRIS_CMD_START` / `IRIS_CMD_STOP:0` to `$IRIS_FD` so iris stands down while a binding's program runs. No-op outside iris |
|
||||
| `_tv_inline` | `tv $argv --inline`, then moves the cursor up one line on `/dev/tty` |
|
||||
| `ai` | `gum choose` among `claude`, `opencode`, `codex`, `hermes`, `fractal`. `claude` runs with `--dangerously-skip-permissions` |
|
||||
| `c` | `clear` with no argument, `cd <dir>` with one |
|
||||
@@ -302,7 +304,7 @@ Every file in `functions/` is autoloaded by name. Several also exist as POSIX sc
|
||||
| `y` | yazi with `--cwd-file`, then cd to the directory yazi exited in |
|
||||
| `yy` | Same as `y`. Used by the <kbd>ctrl-f</kbd> bind |
|
||||
|
||||
Functions defined inside `conf.d/` and `config.fish` rather than `functions/`: `q` (20-aliases), `terminal_title` (50-terminal-title), the `pnpmf*` helpers and `__pnpm_pick_pkg` (pnpm-filter), the `_nvm_install`/`_nvm_update`/`_nvm_uninstall` event handlers (nvm), and `starship_transient_prompt_func`, `starship_transient_rprompt_func`, and `_atuin_ai_question_mark` (config.fish).
|
||||
Functions defined inside `conf.d/` and `config.fish` rather than `functions/`: `q` (20-aliases), `terminal_title` (50-terminal-title), the `pnpmf*` helpers and `__pnpm_pick_pkg` (pnpm-filter), the `_nvm_install`/`_nvm_update`/`_nvm_uninstall` event handlers (nvm), and `starship_transient_prompt_func` and `starship_transient_rprompt_func` (config.fish). Under iris, `iris init fish` adds `_iris_fish_prompt`, `_iris_fish_preexec`, and `_iris_fish_postexec`.
|
||||
|
||||
:::warning[gh-sonr-org-migrate]
|
||||
`functions/gh-sonr-org-migrate.fish` is a script, not a function definition. Running `gh-sonr-org-migrate` in fish autoloads the file, which runs the whole fish migration flow. Because the file defines no function of that name, fish then falls through to the bash port at `~/.local/bin/gh-sonr-org-migrate` and starts a second run. Cancel the second run at its first `gum` prompt, or call the bash script by its full path.
|
||||
|
||||
Reference in new issue
Block a user