docs(docs): clarify inline TV picker behavior and update widget/keybinding documentation

This commit is contained in:
Prad Nukala committed 2026-09-30 11:54:55 -04:00
1 parent a5bf3e9194
commit f6e979fa8c
4 files changed
+56 -29

No files matched your search

+25 -16
View File
@@ -55,16 +55,24 @@ Interactive shells only (`[[ $- != *i* ]] && return`). In order:
`keybinds.zsh` ports `fish_user_key_bindings.fish` to zle. Unlike fish, zsh uses the **emacs** keymap: `bindkey -e` pins it so that `$EDITOR=nvim` does not switch zsh into vi mode. `unsetopt flow_control` frees <kbd>ctrl-q</kbd> and <kbd>ctrl-s</kbd> from the terminal. `keybinds.zsh` ports `fish_user_key_bindings.fish` to zle. Unlike fish, zsh uses the **emacs** keymap: `bindkey -e` pins it so that `$EDITOR=nvim` does not switch zsh into vi mode. `unsetopt flow_control` frees <kbd>ctrl-q</kbd> and <kbd>ctrl-s</kbd> from the terminal.
A generic widget `_zle-run` is registered as `run-<cmd>` for `purple`, `clip-last`, `gho`, `pj`, `omp`, `yy`, and `lazygit`. It clears the pending display (`zle -I`), runs the command with the tty on stdin, then `zle reset-prompt`. Widgets run in the shell process, so directory changes made by `gho` and `yy` persist. `tv-git-files` runs `tv git-files` the same way, and `pj-down` handles <kbd>down</kbd>. A generic widget `_zle-run` is registered as `run-<cmd>` for `purple`, `clip-last`, `omp`, `yy`, and `lazygit`. It clears the pending display (`zle -I`), runs the command with the tty on stdin, then `zle reset-prompt`. Widgets run in the shell process, so directory changes made by `gho` and `yy` persist.
The tv pickers have their own widgets, because `tv --inline` opens on the line below the prompt and leaves the cursor there on exit. `zle -I` followed by `zle reset-prompt` redraws the prompt where zle last drew it, wiping anything printed below; `zle -I` alone draws a fresh prompt under the output.
| Widget | Runs | Then |
| --- | --- | --- |
| `tv-git-files` | `tv git-files --inline` | `\033[A`, `reset-prompt` |
| `gho-inline` | `gho` | cwd unchanged: `\033[A`, `reset-prompt`. After a cd: nothing, so the new prompt lands below onefetch |
| `pj-inline`, `pj-down` | `_zle-pj`: `pj` with `PJ_STATE` set to a temp file (`PJ_QUIET=1` for `pj-down`) | `open` (cancelled): `\033[A`, `reset-prompt`. `ran`: nothing, so the task output stays. Empty (no task sources): `reset-prompt` |
| Key | Action | | Key | Action |
| --- | --- | | --- | --- |
| <kbd>ctrl-e</kbd> | `tv git-files` (pick a file, open it in nvim) | | <kbd>ctrl-e</kbd> | `tv-git-files` (pick a file, open it in nvim) |
| <kbd>ctrl-f</kbd> | `yy` | | <kbd>ctrl-f</kbd> | `yy` |
| <kbd>ctrl-b</kbd> | `purple` (an external command; this repo does not provide it) | | <kbd>ctrl-b</kbd> | `purple` (an external command; this repo does not provide it) |
| <kbd>ctrl-y</kbd> | `clip-last` | | <kbd>ctrl-y</kbd> | `clip-last` |
| <kbd>ctrl-o</kbd> | `gho` (`ghq-repos` cable, cd) | | <kbd>ctrl-o</kbd> | `gho-inline` (`ghq-repos` cable, cd) |
| <kbd>ctrl-p</kbd> | `pj` (`pj` cable) | | <kbd>ctrl-p</kbd> | `pj-inline` (`pj` cable) |
| <kbd>ctrl-t</kbd> | tv smart autocomplete (from `tv init zsh`) | | <kbd>ctrl-t</kbd> | tv smart autocomplete (from `tv init zsh`) |
| <kbd>down</kbd> | `pj-down`: `PJ_QUIET=1 pj` on an empty prompt, otherwise `down-line-or-history` (bound to `^[[B` and `^[OB`) | | <kbd>down</kbd> | `pj-down`: `PJ_QUIET=1 pj` on an empty prompt, otherwise `down-line-or-history` (bound to `^[[B` and `^[OB`) |
| <kbd>ctrl-a</kbd> | `omp` | | <kbd>ctrl-a</kbd> | `omp` |
@@ -78,23 +86,24 @@ The fish-only binds <kbd>ctrl-w</kbd> (atuin AI) and <kbd>?</kbd> have no zsh eq
## bash key bindings ## bash key bindings
`keybinds.bash` gives bash the same picker keys as fish and zsh. bash keeps readline's default emacs keymap. `keybinds.bash` gives bash the same picker keys as fish and zsh. bash keeps readline's default emacs keymap. Every picker runs `tv --inline`; when nothing was printed below the prompt, `_kb_up` (`\033[A` on `/dev/tty`) steps back so readline redraws the prompt in place after `bind -x`.
| Key | Action | | Key | Action |
| --- | --- | | --- | --- |
| <kbd>ctrl-o</kbd> | `gho` (`ghq-repos` cable, cd) | | <kbd>ctrl-o</kbd> | Macro `\C-x1\C-x2\C-x3\C-x0` (below): pick from the `ghq-repos` cable and cd |
| <kbd>ctrl-e</kbd> | `tv git-files` | | <kbd>ctrl-e</kbd> | `_kb_git_files`: `tv git-files --inline`, then `_kb_up` |
| <kbd>ctrl-p</kbd> | `pj` (`pj` cable) | | <kbd>ctrl-p</kbd> | `_kb_pj`: `pj` with `PJ_STATE` set to a temp file; `_kb_up` only when the state is `open` (cancelled) |
| <kbd>down</kbd> | `pj` cable on an empty prompt (`PJ_QUIET=1`), otherwise `history-search-forward` | | <kbd>down</kbd> | `PJ_QUIET=1 _kb_pj` on an empty prompt, otherwise `history-search-forward` |
| <kbd>ctrl-t</kbd> | `_kb_tv_autocomplete`: runs `tv --autocomplete-prompt` on the text left of the cursor and inserts the picks there, each `printf %q`-quoted | | <kbd>ctrl-t</kbd> | `_kb_tv_autocomplete`: runs `tv --autocomplete-prompt … --inline` on the text left of the cursor, `_kb_up`, and inserts the picks there, each `printf %q`-quoted |
Each picker key is a readline macro `\C-xN \C-m \C-x0` built by `_kb_bind KEY SLOT COMMAND…`: `bind -x` runs in the shell process, so a `cd` persists, but readline keeps drawing the prompt it started with. <kbd>ctrl-o</kbd> is therefore a macro:
1. `\C-xN` is a `bind -x` for `_kb_run`, which stashes `READLINE_LINE` and runs the command in the shell process, so the `cd` done by `gho` persists. 1. `\C-x1` runs `_kb_gho`: stashes `READLINE_LINE`, runs `tv ghq-repos --inline`, `_kb_up`, and cds into the pick. It does not call the `gho` function. After a cd it empties the line and rebinds `\C-x2` to `accept-line` and `\C-x3` to `bind -x _kb_gho_show`; when cancelled it rebinds both to `redraw-current-line`.
2. `\C-m` accepts the now-empty line, so bash prints a fresh prompt for the new cwd. Nothing reaches history. 2. `\C-x2` accepts the empty line, so bash prints a fresh prompt for the new cwd. Nothing reaches history.
3. `\C-x0` runs `_kb_restore`, which puts the typed text back. 3. `\C-x3` runs `_kb_gho_show` (`clear`, then `onefetch` in git repos); readline redraws the prompt below the output.
4. `\C-x0` runs `_kb_restore`, which puts the typed text back.
<kbd>down</kbd> (`\e[B` and `\eOB`) is the macro `\C-x4\C-x5`. `bind -x` cannot call readline functions, so `_kb_down` (`\C-x4`) rebinds `\C-x5` to `history-search-forward` when the line is non-empty, or runs `pj` and rebinds `\C-x5` to `redraw-current-line`. The slots used are `\C-x0` through `\C-x5`. <kbd>down</kbd> (`\e[B` and `\eOB`) is the macro `\C-x4\C-x5`. `bind -x` cannot call readline functions, so `_kb_down` (`\C-x4`) rebinds `\C-x5` to `history-search-forward` when the line is non-empty, or runs `PJ_QUIET=1 _kb_pj` and rebinds `\C-x5` to `redraw-current-line`.
## Shared aliases: aliases.sh ## Shared aliases: aliases.sh
@@ -141,7 +150,7 @@ Each directory holds one function per file. bash and zsh source every file at st
| `clip-last` | Re-runs the previous history entry (`fc -ln -1 -1`, skipping itself if the line editor already recorded `clip-last`), pipes the output to `wl-copy` or `pbcopy`, and sends a `notify-send -a shell` notification if available | | `clip-last` | Re-runs the previous history entry (`fc -ln -1 -1`, skipping itself if the line editor already recorded `clip-last`), pipes the output to `wl-copy` or `pbcopy`, and sends a `notify-send -a shell` notification if available |
| `ghg <repo>` | `ghg-clone "$@"`, cd into the printed path, `clear && onefetch` | | `ghg <repo>` | `ghg-clone "$@"`, cd into the printed path, `clear && onefetch` |
| `ghn <name>` | `command ghn "$@"`, cd into the printed path | | `ghn <name>` | `command ghn "$@"`, cd into the printed path |
| `gho` | `dir=$(tv ghq-repos)`, return if empty, cd into it, `clear`, and `onefetch` if it is a git repo | | `gho` | `dir=$(tv ghq-repos --inline)`, return if empty, cd into it, `clear`, and `onefetch` if it is a git repo. No cursor handling; bash <kbd>ctrl-o</kbd> does not call it |
| `yy [args]` | `yazi --cwd-file=<tmp>`, then cd to the directory written there if it changed | | `yy [args]` | `yazi --cwd-file=<tmp>`, then cd to the directory written there if it changed |
The `ghg` helper script is named `ghg-clone` because an unrelated cargo binary already uses the name `ghg`. The [Scripts](/shell/scripts#why-some-helpers-are-shell-functions) page explains why these helpers are shell functions and not scripts. The `ghg` helper script is named `ghg-clone` because an unrelated cargo binary already uses the name `ghg`. The [Scripts](/shell/scripts#why-some-helpers-are-shell-functions) page explains why these helpers are shell functions and not scripts.
+18 -7
View File
@@ -179,12 +179,12 @@ The header comment says the file should stay empty, but it holds the following:
| Key | Action | | Key | Action |
| --- | --- | | --- | --- |
| <kbd>ctrl-e</kbd> | `tv git-files`, then repaint: pick a file in the repo and open it in nvim ([television](/tools/television#git-files)) | | <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-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-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-y</kbd> | `clip-last`: re-run the last command and copy its output |
| <kbd>ctrl-o</kbd> | `gho`: pick a ghq repo or Obsidian vault from the `ghq-repos` cable and cd into it | | <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`: task runner on the `pj` cable ([Scripts](/shell/scripts#pj)) | | <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` (the coding agent, see [AI agents](/ai)) | | <kbd>ctrl-a</kbd> | `omp` (the coding agent, see [AI agents](/ai)) |
| <kbd>ctrl-w</kbd> | `atuin ai inline`: natural-language command overlay | | <kbd>ctrl-w</kbd> | `atuin ai inline`: natural-language command overlay |
| <kbd>ctrl-g</kbd> | `lazygit` | | <kbd>ctrl-g</kbd> | `lazygit` |
@@ -201,7 +201,15 @@ Bindings added by tool init scripts:
| <kbd>?</kbd> | default (vi normal) | `_atuin_ai_question_mark`: on an empty buffer, opens `atuin ai inline` | `config.fish` | | <kbd>?</kbd> | default (vi normal) | `_atuin_ai_question_mark`: on an empty buffer, opens `atuin ai inline` | `config.fish` |
| <kbd>ctrl-t</kbd> | insert | `tv_smart_autocomplete` | `tv init 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_QUIET=1 pj`, so pressing down outside a project does nothing and prints no error. `_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.
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`:
| Wrapper | Runs | Then |
| --- | --- | --- |
| `_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) |
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>, <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.
@@ -255,7 +263,10 @@ Every file in `functions/` is autoloaded by name. Several also exist as POSIX sc
| `_nvm_list` | nvm.fish internal: lists installed Node versions plus `system` | | `_nvm_list` | nvm.fish internal: lists installed Node versions plus `system` |
| `_nvm_version_activate` | nvm.fish internal: sets `nvm_current_version` and prepends its `bin` to `PATH` | | `_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` | | `_nvm_version_deactivate` | nvm.fish internal: removes a version's `bin` from `PATH` |
| `_pj_bind_down` | Down-arrow handler: `pj` (tv cable) on an empty idle prompt, else `down-or-search` | | `_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_down` | Down-arrow handler: `_pj_bind --quiet` on an empty idle prompt, else `down-or-search` |
| `_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` | | `ai` | `gum choose` among `claude`, `opencode`, `codex`, `hermes`, `fractal`. `claude` runs with `--dangerously-skip-permissions` |
| `c` | `clear` with no argument, `cd <dir>` with one | | `c` | `clear` with no argument, `cd <dir>` with one |
| `c2p` | fzf-pick a `.hbs` template under `~/.config/code2prompt` and run `code2prompt --template` | | `c2p` | fzf-pick a `.hbs` template under `~/.config/code2prompt` and run `code2prompt --template` |
@@ -272,7 +283,7 @@ Every file in `functions/` is autoloaded by name. Several also exist as POSIX sc
| `gh-sonr-org-migrate` | Script body (see the warning below) that moves every repo from `*sonr*` GitHub orgs into `sonr-io` and deletes the emptied orgs | | `gh-sonr-org-migrate` | Script body (see the warning below) that moves every repo from `*sonr*` GitHub orgs into `sonr-io` and deletes the emptied orgs |
| `ghg <repo>` | `ghg-clone <repo>` (ghq get), cd into the clone, `clear`, `onefetch` | | `ghg <repo>` | `ghg-clone <repo>` (ghq get), cd into the clone, `clear`, `onefetch` |
| `ghn <name>` | Runs `~/.local/bin/ghn` to create and clone a private repo, then cds into it | | `ghn <name>` | Runs `~/.local/bin/ghn` to create and clone a private repo, then cds into it |
| `gho` | `tv ghq-repos` (repo/vault picker); returns if nothing was picked, else cds into the result, `clear`, and `onefetch` inside git repos | | `gho` | `tv ghq-repos --inline` (repo/vault picker); returns if nothing was picked, else cds into the result, `clear`, and `onefetch` inside git repos |
| `git-summary [flags]` | `code2prompt` over the repo root, including only `AGENTS.md` files, using `~/.config/code2prompt/agents-md.hbs`. Extra flags pass through | | `git-summary [flags]` | `code2prompt` over the repo root, including only `AGENTS.md` files, using `~/.config/code2prompt/agents-md.hbs`. Extra flags pass through |
| `gtm [repo]` | Migrates GitHub repos to a prad.codes (Gitea) org with `tea repos migrate`. With no argument, fzf multi-selects from `gh repo list`. You pick the target org and migration options (wiki, issues, labels, pull-requests, releases, milestones, lfs, mirror) with gum, private repos stay private, and it offers to clone the results with `ghg-clone`. Fish only | | `gtm [repo]` | Migrates GitHub repos to a prad.codes (Gitea) org with `tea repos migrate`. With no argument, fzf multi-selects from `gh repo list`. You pick the target org and migration options (wiki, issues, labels, pull-requests, releases, milestones, lfs, mirror) with gum, private repos stay private, and it offers to clone the results with `ghg-clone`. Fish only |
| `launch_omp_livediff_overlay` | Uses `kitty @` to overlay `omp` on the current window with a `livediff` vsplit beside it. Needs `KITTY_LISTEN_ON` | | `launch_omp_livediff_overlay` | Uses `kitty @` to overlay `omp` on the current window with a `livediff` vsplit beside it. Needs `KITTY_LISTEN_ON` |
@@ -281,7 +292,7 @@ Every file in `functions/` is autoloaded by name. Several also exist as POSIX sc
| `mdp` | fzf-pick a Markdown file up to 3 levels deep (mdfried preview) and open it in `mdfried` | | `mdp` | fzf-pick a Markdown file up to 3 levels deep (mdfried preview) and open it in `mdfried` |
| `nvm` | nvm.fish: `install`, `use`, `list`, `list-remote`, `current`, `uninstall`. Reads `.nvmrc`/`.node-version` | | `nvm` | nvm.fish: `install`, `use`, `list`, `list-remote`, `current`, `uninstall`. Reads `.nvmrc`/`.node-version` |
| `y` | yazi with `--cwd-file`, then cd to the directory yazi exited in | | `y` | yazi with `--cwd-file`, then cd to the directory yazi exited in |
| `yy` | Same as `y`. Used by the <kbd>ctrl-e</kbd>/<kbd>ctrl-f</kbd> binds | | `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`, `starship_transient_rprompt_func`, and `_atuin_ai_question_mark` (config.fish).
+2 -2
View File
@@ -266,7 +266,7 @@ A task runner that searches every task source in the project and lets you pick o
**Scanning.** Walks from `$PWD` up to the git toplevel, inclusive. Outside a repo it stops at the first directory that produced tasks. **Scanning.** Walks from `$PWD` up to the git toplevel, inclusive. Outside a repo it stops at the first directory that produced tasks.
**Picker.** `pj` writes the records to a temp file and runs `tv pj --source-command "cat <tmp>" --input-header <project root>`. Rows are tagged with the tool (`npm`, `pnpm`, `bun`, `make`, `just`, `mise`, `poe`, `py`, …), so typing a tool name filters to it. A directory column appears when more than one project contributed tasks. Tasks are sorted by their manifest's mtime, newest first, through `mtime-sort`. The preview shows the task body: the npm script string, the Make recipe, `just --show`, `mise tasks info`, the devbox script, or the pyproject entry. **Picker.** `pj` writes the records to a temp file and runs `tv pj --inline --source-command "cat <tmp>" --input-header <project root>`. Rows are tagged with the tool (`npm`, `pnpm`, `bun`, `make`, `just`, `mise`, `poe`, `py`, …), so typing a tool name filters to it. A directory column appears when more than one project contributed tasks. Tasks are sorted by their manifest's mtime, newest first, through `mtime-sort`. The preview shows the task body: the npm script string, the Make recipe, `just --show`, `mise tasks info`, the devbox script, or the pyproject entry.
**Entry points.** The cable calls back into the script: **Entry points.** The cable calls back into the script:
@@ -278,7 +278,7 @@ A task runner that searches every task source in the project and lets you pick o
**Run.** cds into the task's directory and `exec`s the runner. Extra arguments given to `pj` travel to the task through `$PJ_EXTRA` (shell-quoted), with `--` inserted for `npm run`, `mise`, and `devbox`. Tasks named `dev`, `start`, `serve`, `watch`, or namespaced variants like `dev:web` are wrapped in `openlogs` (found on `PATH`, via `mise which`, or in mise's node installs) for a live log tail. Without openlogs they run unwrapped, with a note. **Run.** cds into the task's directory and `exec`s the runner. Extra arguments given to `pj` travel to the task through `$PJ_EXTRA` (shell-quoted), with `--` inserted for `npm run`, `mise`, and `devbox`. Tasks named `dev`, `start`, `serve`, `watch`, or namespaced variants like `dev:web` are wrapped in `openlogs` (found on `PATH`, via `mise which`, or in mise's node installs) for a live log tail. Without openlogs they run unwrapped, with a note.
**Env.** `PJ_QUIET=1` suppresses the "no task sources found" error (exit status stays 1). The <kbd>down</kbd> bindings use it. **Env.** `PJ_QUIET=1` suppresses the "no task sources found" error (exit status stays 1). The <kbd>down</kbd> bindings use it. `PJ_STATE=FILE` makes `pj` write `open` to `FILE` before launching the picker, and `pj --run` writes `ran`; the file stays empty when there are no task sources. The key bindings read it to tell no tasks, a cancelled picker, and a task that printed output apart and redraw the prompt to match. `pj` itself does no cursor handling, so typing `pj` behaves like any command.
**Launched by:** <kbd>ctrl-p</kbd>, and <kbd>down</kbd> on an empty prompt, in fish, zsh, and bash. **Launched by:** <kbd>ctrl-p</kbd>, and <kbd>down</kbd> on an empty prompt, in fish, zsh, and bash.
+11 -4
View File
@@ -17,15 +17,22 @@ The whole directory is a symlink into the source tree, so edits apply without `c
## config.toml ## config.toml
The UI is minimal: no borders, a hidden status bar, and padding in place of frames.
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| `default_channel` | `files` | | `default_channel` | `files` |
| `ui.theme` | `cyberdream-transparent` | | `ui.theme` | `cyberdream-transparent` |
| `ui.input_bar.position` | `top`, prompt `>` | | `ui.input_bar` | position `top`, prompt `❯`, `border_type = "none"`, padding left 1, right 1, bottom 1 |
| Borders | `rounded` on the input bar, results, and preview | | `ui.status_bar.hidden` | `true` (<kbd>f12</kbd> toggles it) |
| `ui.preview_panel.size` | `50` | | `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` | | `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#key-bindings), [bash and zsh](/shell/bash-zsh)).
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: Global keys added on top of the defaults:
| Key | Action | | Key | Action |
@@ -100,7 +107,7 @@ Both are sorted with `mtime-sort`. The preview is `bat -n` with `BAT_THEME=ansi`
### pj ### pj
Source `pj --list`; tv shows the display column. The preview runs `pj --preview`, the preview panel is 40% wide, and <kbd>enter</kbd> runs `pj --run`. Running `pj` scans the project and opens this cable with its own records. See [pj](/shell/scripts#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#pj).
**Needs:** `pj`, `mtime-sort`. **Needs:** `pj`, `mtime-sort`.