perf(shell): lazy-init version managers and cache op completion - #24
Merged
Conversation
Defer nodenv, rbenv, and goenv shell initialization to first use in both bash and fish. Shims remain on PATH eagerly so managed runtimes resolve immediately without spawning a subprocess at startup. The shell function for each manager is a placeholder that runs the real init on first invocation. Cache `op completion fish` output to disk and regenerate only when the op binary is newer than the cached file, avoiding a subprocess on every interactive shell start. Also pass an explicit shell name to `brew shellenv` in bash and fish, and remove the now-redundant Intel-Mac Homebrew fallback from bashrc. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves shell startup performance by deferring version manager initialization and caching generated 1Password CLI fish completions while preserving runtime shim availability.
Changes:
- Lazy-initializes
nodenv,rbenv, andgoenvin bash and fish while eagerly adding shims toPATH. - Caches
op completion fishoutput under fish completions. - Passes explicit shell names to
brew shellenv.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
private_dot_config/private_fish/private_conf.d/private_20-config-op.fish.tmpl |
Adds cached op fish completion generation. |
private_dot_config/private_fish/private_conf.d/private_00-path-ruby.fish.tmpl |
Defers fish rbenv initialization until first use. |
private_dot_config/private_fish/private_conf.d/private_00-path-node.fish.tmpl |
Defers fish nodenv initialization until first use. |
private_dot_config/private_fish/private_conf.d/private_00-path-golang.fish.tmpl |
Defers fish goenv initialization until first use. |
private_dot_config/private_fish/private_conf.d/private_00-path-base.fish.tmpl |
Calls brew shellenv with explicit fish shell. |
private_dot_bashrc.d/private_tools/private_ruby.bash.tmpl |
Defers bash rbenv initialization until first use. |
private_dot_bashrc.d/private_tools/private_node.bash.tmpl |
Defers bash nodenv initialization until first use. |
private_dot_bashrc.d/private_tools/private_golang.bash.tmpl |
Defers bash goenv initialization until first use. |
private_dot_bashrc |
Calls brew shellenv with explicit bash shell and changes Homebrew fallback handling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Avoid truncating the cached op.fish before generation succeeds. Write to a mktemp file and mv into place only on success; clean up the temp file on failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a version manager is installed via Homebrew without a user root directory, *ENV_ROOT may be unset, causing "$NODENV_ROOT/shims" etc. to expand to "/shims" and prepend a bogus entry to PATH. Guard the fish_add_path/path_prepend call in all three version managers (bash and fish) so shims are only added when the variable is set and the directory exists. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the directory-existence check with an unconditional default:
export RBENV_ROOT="${RBENV_ROOT:-$HOME/.rbenv}" # bash
set -q RBENV_ROOT; or set -x RBENV_ROOT $HOME/.rbenv # fish
*ENV_ROOT is now always set to a well-formed path before the shims
entry is added to PATH, so the tool being Homebrew-installed without
an explicit root directory can no longer produce a bogus /shims entry.
The directory-existence guard introduced in the previous commit is
removed as it is no longer necessary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
*ENV_ROOT now always expands to a well-formed path, but the shims directory itself may not exist when the tool is installed but no versions have been installed yet. Add -d guards to path_prepend/ fish_add_path calls in all three version managers (bash and fish) to match the pattern used for other conditional path entries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
initon first explicit invocation, deferring all subprocess cost to when it's actually needed.*ENV_ROOTis set via default-value expansion (${RBENV_ROOT:-$HOME/.rbenv}in bash,set -q RBENV_ROOT; or set -x …in fish) so the variable always expands to a well-formed path. Shims are then added toPATHeagerly — but only when the shims directory exists — so managed runtimes resolve immediately without a subprocess and no bogus path entries are added on a fresh install before any versions have been installed.op completion fishto~/.config/fish/completions/op.fishand regenerate only when theopbinary is newer than the cache, eliminating a subprocess on every interactive fish shell start; output is written to a temp file and moved into place only on success to avoid leaving a broken cache if generation fails or is interruptedbrew shellenv(brew shellenv bash/brew shellenv fish) in both bash and fish configs; remove redundant Intel-Mac Homebrew fallback from bashrcTest plan
node,ruby, andgoresolve to the correct nodenv/rbenv/goenv-managed versionsnodenv version,rbenv version, andgoenv versionto confirm lazy init fires correctly on first useopsubcommand and confirm completions work; verify~/.config/fish/completions/op.fishwas createdbrew shellenvstill setsHOMEBREW_PREFIXcorrectly in both shells🤖 Generated with Claude Code