diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cac15a8..cf29deb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,11 @@ jobs: - name: clippy run: cargo clippy --all-targets -- -D warnings + # tests/hook.rs evaluates the emitted snippet in each shell `vanadis hook` claims, and + # refuses to skip a shell when `CI` is set. + - name: shells + run: sudo apt-get update && sudo apt-get install -y zsh fish + - name: test run: cargo test --all-targets diff --git a/docs/examples/config.toml b/docs/examples/config.toml index 489bd47..98ba332 100644 --- a/docs/examples/config.toml +++ b/docs/examples/config.toml @@ -80,10 +80,12 @@ name = "starship" template = "templates/starship/starship.toml.in" output = "~/.config/starship.toml" -# fzf reads these colours from the environment, so the shell has to be replaced for a change -# to show. `exec zsh` replaces the user's shell and vanadis runs as a child process, so it -# cannot be a reload command. +# fzf reads these colours from the environment, so a write is not enough on its own: the +# shell has to source the file again. No `reload` can do that, because the shell that needs +# fixing is vanadis's parent. `shell` marks the target instead, and the prompt hook that +# `eval "$(vanadis hook zsh)"` registers sources the file again whenever it changes. [[targets]] name = "zsh" template = "templates/zsh/palette.zsh.in" output = "~/.config/zsh/palette.zsh" +shell = "zsh" diff --git a/docs/hook.md b/docs/hook.md index f39527e..08bd42d 100644 --- a/docs/hook.md +++ b/docs/hook.md @@ -41,6 +41,13 @@ Prints a snippet to stdout, to be evaluated by the shell it names: eval "$(vanadis hook zsh)" ``` +fish reads it the way fish reads every tool in this shape, because `eval` there would need the +output collected into one argument first: + +```fish +vanadis hook fish | source +``` + The snippet sources the outputs of the targets that name that shell, once at evaluation, and registers a prompt hook that sources each of them again when its file has changed. This is the shape `direnv hook zsh`, `mise activate zsh`, `starship init zsh` and `zoxide init zsh` already @@ -211,6 +218,13 @@ alone does not; and the exit status of the command before the prompt survives. This is also what fixes the versions claimed. `path mtime` is not in every fish that is installed anywhere, and the fish CI runs on is the fish this document claims. +**fish needs a terminal before any of that can be asked.** It emits `fish_prompt` only while +drawing a prompt, and it draws none when its input is a pipe, `-i` or not, so a piped fish +answers every prompt question with the state the evaluation itself left. zsh and bash run +`precmd` and `PROMPT_COMMAND` either way. The fish run is therefore given one, and what comes +back carries the prompt and the echo of what was typed around what the script printed, which is +why the assertion reads its marker out of the text rather than off the start of a line. + ## Rejected alternatives The state file as the signal, a top-level table naming shell targets, and a config read at diff --git a/skills/vanadis/SKILL.md b/skills/vanadis/SKILL.md index 835d6ac..d73bbb4 100644 --- a/skills/vanadis/SKILL.md +++ b/skills/vanadis/SKILL.md @@ -63,6 +63,7 @@ not travel with it. | `vanadis get --json` | the whole resolved theme, flat, keyed by token path | | `vanadis render