Robustness fixes and cleanups across prompt functions#14
Conversation
If rbenv is installed but no Ruby version is configured for the current directory, rbenv version-name returns empty and the prompt would show no version at all. Clear ruby_version at the start of each invocation and, after the rbenv branch, fall back to ruby --version whenever ruby_version is still empty (in addition to the existing path-changed check).
On systems without a python2-era `python` binary (e.g. macOS where only `python3` is shipped), _prompt_virtualenv returned early outside of a virtualenv and the Python version was missing from the prompt entirely. Inside a venv it worked because venvs provide a `python` symlink. Probe for `python` first, then `python3`, and use whichever exists for both the existence check and the --version call.
Previously the cached RUST_VERSION was only invalidated when the last history entry contained `rustup default`. Other rustup invocations that also change the active rustc — `rustup update`, `rustup toolchain install`, `rustup override` — left a stale version in the prompt. Broaden the match to any `rustup` subcommand, and use `string match` instead of `echo | grep` to drop the per-prompt subshell + fork.
`git symbolic-ref HEAD` returns nothing when HEAD points at a tag or arbitrary commit, so _git_branch_name produced an empty string and _prompt_git returned early — the entire git block disappeared from the prompt the moment you ran `git checkout <tag-or-sha>`. Fall back to `git rev-parse --short HEAD` and prefix it with `:` so the prompt still shows the current commit and the format makes the detached state visually distinct from a regular branch name.
_git_ahead_count piped `git log` through `grep '^commit'` and `wc -l` to count commits ahead of a remote — three forked processes per remote per prompt rendering, plus a `tr -d ' '` to strip wc's padding. `git rev-list --count <remote>/<branch>..HEAD` returns the same number directly with a single process and no trailing whitespace, so the echo wrapper and tr call drop out too.
The hardcoded origin|upstream filter is intentional — random remotes
(forks, mirrors, etc.) shouldn't pollute the prompt — but the previous
implementation shelled out to an external grep with a regex alternation
per prompt rendering.
Replace the pipe with fish's contains builtin and a continue guard.
Same filter, no fork, and the intent ("only these two remotes") is
spelled out as data rather than buried in a regex.
_prompt_pwd was the only _prompt_* function that hard-coded its color (`set_color -o cyan`) instead of accepting it as an argument, so the palette in fish_prompt was no longer the single source of truth — a theme tweak meant editing two places. Add a color parameter, declare bold cyan alongside the other palette variables, and pass it in at both call sites.
`echo '|'` appended a newline mid right-prompt. Fish was getting away with it visually, but a stray newline in the right-prompt buffer is fragile — a future refactor or terminal quirk could surface it as a broken layout. Use `printf '|'` to emit just the character, matching how every other glyph in this function is written.
The function signature declared a sixth parameter `append` that was never referenced anywhere in the body. Dead since at least the move into functions/. Drop it so the signature reflects what the function actually uses.
The pipeline ended in `tr -d '\n'`, presumably to strip a trailing newline. But `echo -n` (used at the start of the same pipeline) doesn't emit one in the first place, so the tr invocation was a no-op fork per prompt rendering.
The empty lines that separated logical groups of statements within _git_dirty_remotes, _prompt_versions, fish_prompt, and fish_title were inconsistent across the file (some functions had them, others didn't) and added scroll height without aiding readability. Collapse them so the bodies match the tighter style already used elsewhere.
|
@pedrosnk Pedrão! Can I be lucky and get you to review this PR? Things worth flagging, in order of "could bite you if wrong":
History was rewritten a couple times (filter-branch passes for lowercase-after-colon and to clean backticks), so commit-by-commit review is fine but the bottom-line diff is what matters. TIA :-* |
There was a problem hiding this comment.
Pull request overview
This PR improves the scorphish Fish prompt’s robustness and reduces external-process usage by hardening language version detection, refining Git-state display (including detached HEAD), and adding an option to show command duration in the right prompt.
Changes:
- Make Ruby/Python/Rust version detection more resilient (fallbacks, python3-only systems, rustup refresh triggers).
- Improve Git prompt behavior/performance (detached HEAD short SHA,
rev-list --count, fishcontainsfiltering). - Cleanup/consistency updates across prompt functions and docs (config option,
_prompt_pwdcolor parameter,printfvsecho).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| README.md | Documents new right-prompt duration toggle option. |
| functions/fish_title.fish | Enhances terminal title to include host and improved virtualenv naming. |
| functions/fish_right_prompt.fish | Adds configurable duration vs time display and avoids newline issues. |
| functions/fish_prompt.fish | Robustifies version detection, improves Git info display/perf, and aligns prompt layout with new right-prompt toggle. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function _prompt_rubies -a color -d 'Display current Ruby (rvm/rbenv)' | ||
| type -q ruby; or return | ||
| [ "$theme_display_ruby" = 'no' ]; and return | ||
| set -gx ruby_version |
| set venv_name (basename "$VIRTUAL_ENV") | ||
| test $venv_name = ".venv"; and set venv_name (basename (dirname "$VIRTUAL_ENV")) | ||
| [ -n "$VIRTUAL_ENV" ]; and echo -n -s '@'$venv_name |
| type -q rustc; or return | ||
| [ "$theme_display_rust" != 'yes' ]; and return | ||
| if echo $history[1] | grep -q 'rustup default'; or not set -q RUST_VERSION | ||
| if string match -q 'rustup *' $history[1]; or not set -q RUST_VERSION |
| set -l git_branch (_git_branch_name) | ||
| test -z $git_branch; and return | ||
| set git_branch (string replace -ar '(\.?[^/]{1})[^/]*/' '$1/' $git_branch) |
| * To display command duration in right prompt: | ||
|
|
||
| ```fish | ||
| set -g theme_display_command_duration_in_right_prompt yes | ||
|
|
||
| ``` |
Summary
Version detection robustness
ruby --versionwhen rbenv reports no versionpython3exists (e.g. recent macOS)rustupsubcommand, not onlyrustup defaultGit info
:) instead of the git block disappearing_git_ahead_countusesrev-list --countinstead oflog | grep '^commit' | wc -l | tr -d ' '_git_dirty_remotesfilter via fish'scontainsbuiltin instead of an externalgrepCleanup
_prompt_pwdtakes its color as a parameter (palette-consistent with the other_prompt_*functions)_prompt_versionsdrops an unusedappendparameter and a redundanttr -d '\n'fish_right_promptusesprintf '|'instead ofecho '|'(no stray newline mid right-prompt)Test plan