Skip to content

Commit baff678

Browse files
committed
Modernize shell setup across fish, zsh, and Ghostty
1 parent 39a5439 commit baff678

21 files changed

+501
-323
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ You'll be prompted for these values (stored locally, never committed):
5757
#### 3. What happens automatically
5858

5959
- **Homebrew** is installed if missing (with Apple Silicon detection)
60-
- **Packages** are installed via Brewfile — shell tools, editors, language managers, 1Password CLI, Ghostty
60+
- **Packages** are installed via Brewfile — shell tools, editors, `mise`, 1Password CLI, Ghostty
61+
- **Runtimes** are installed via `mise` — global Node/Python defaults plus a Node 20 fallback for older repos
6162
- **Configs** are templated and written to `~` — git, zsh, fish, starship, editors, terminal, tmux, SSH
6263
- **TPM** (tmux plugin manager) is cloned if not present
6364
- **Post-setup checklist** runs and flags anything that still needs manual attention
@@ -114,17 +115,17 @@ fish-check-deps # fish prompt/tooling dependencies installed
114115
<tr><td><b>Git</b></td><td>gpg signing, graphite, conditional work includes, aliases</td></tr>
115116
<tr><td><b>Tmux</b></td><td>tmux + TPM, dracula theme</td></tr>
116117
<tr><td><b>Files</b></td><td>yazi (Ctrl+y picker), ranger</td></tr>
117-
<tr><td><b>Languages</b></td><td>nvm, pyenv, rbenv (all lazy-loaded), bun</td></tr>
118+
<tr><td><b>Languages</b></td><td>mise (Node/Python with legacy version-file support), bun</td></tr>
118119
<tr><td><b>Security</b></td><td>1Password CLI (<code>op://</code> URIs), GPG commit signing</td></tr>
119120
<tr><td><b>Theme</b></td><td>Catppuccin Macchiato (ghostty, zed, starship, fzf, fsh) / Dracula (alacritty, iterm2, nvim, tmux)</td></tr>
120121
</table>
121122

122123
### Highlights
123124

124125
<details>
125-
<summary><b>Lazy-loaded version managers</b></summary>
126+
<summary><b>Mise-managed runtimes</b></summary>
126127
<br/>
127-
NVM, pyenv, and rbenv are wrapped so they only initialize when first called. NVM also auto-switches Node versions when you <code>cd</code> into a directory with an <code>.nvmrc</code>.
128+
<code>mise</code> manages Node, Python, and Ruby from one config while still honoring legacy project files like <code>.nvmrc</code>, <code>.python-version</code>, and <code>.ruby-version</code>. The global config pins the default Node/Python versions, and bootstrap installs an extra Node 20 runtime for repos that still declare <code>v20</code>.
128129
</details>
129130

130131
<details>
@@ -201,7 +202,7 @@ Run <code>zsh-check-deps</code> to verify required tools (starship, fzf) and opt
201202
│ │ ├── 10-options.zsh # shell options & history
202203
│ │ ├── 20-plugins.zsh # antidote + starship init
203204
│ │ ├── 30-completion.zsh # fzf-tab, bookmarks
204-
│ │ ├── 40-tools.zsh # lazy nvm/pyenv/rbenv
205+
│ │ ├── 40-tools.zsh # mise activation, fzf, zoxide
205206
│ │ ├── 50-functions.zsh.tmpl # yazi, nx wrapper
206207
│ │ ├── 70-keybindings.zsh # Ctrl+y, arrow keys
207208
│ │ └── 99-local.zsh.tmpl # machine-specific
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const { createRequire } = require("node:module");
2+
3+
const requireFromWorkspace = createRequire(`${process.cwd()}/package.json`);
4+
const { createProjectGraphAsync, readProjectsConfigurationFromProjectGraph } = requireFromWorkspace("nx/src/devkit-exports");
5+
6+
(async () => {
7+
const graph = await createProjectGraphAsync();
8+
const projects = readProjectsConfigurationFromProjectGraph(graph).projects;
9+
const result = Object.fromEntries(
10+
Object.entries(projects)
11+
.sort(([left], [right]) => left.localeCompare(right))
12+
.map(([name, config]) => [
13+
name,
14+
Object.keys(config.targets || {}).sort((left, right) => left.localeCompare(right)),
15+
])
16+
);
17+
18+
process.stdout.write(JSON.stringify(result));
19+
})().catch((error) => {
20+
console.error(error);
21+
process.exit(1);
22+
});
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# =============================================================================
2+
# Nx Completions
3+
# =============================================================================
4+
5+
function __braden_nx_completion_enabled
6+
set -l phoenix_root "$HOME/Development/Phoenix"
7+
test -x "$phoenix_root/node_modules/.bin/nx"
8+
end
9+
10+
function __braden_nx_cache_dir
11+
echo "$HOME/.cache/fish/nx"
12+
end
13+
14+
function __braden_nx_cache_is_fresh --argument-names file_path
15+
test -f "$file_path"; or return 1
16+
17+
set -l now (date +%s)
18+
set -l modified_at (stat -f %m "$file_path" 2>/dev/null)
19+
or return 1
20+
21+
test (math "$now - $modified_at") -lt 300
22+
end
23+
24+
function __braden_nx_refresh_completion_cache
25+
__braden_nx_completion_enabled; or return 1
26+
27+
set -l cache_dir (__braden_nx_cache_dir)
28+
set -l projects_file "$cache_dir/projects.txt"
29+
set -l targets_file "$cache_dir/targets.txt"
30+
set -l mapping_file "$cache_dir/project-targets.tsv"
31+
32+
if __braden_nx_cache_is_fresh "$projects_file"
33+
and __braden_nx_cache_is_fresh "$targets_file"
34+
and __braden_nx_cache_is_fresh "$mapping_file"
35+
return 0
36+
end
37+
38+
set -l phoenix_root "$HOME/Development/Phoenix"
39+
set -l helper_script "$HOME/.config/fish/completions/_braden_nx_workspace.js"
40+
41+
mkdir -p "$cache_dir"
42+
43+
set -l temp_json (mktemp)
44+
set -l temp_projects (mktemp)
45+
set -l temp_targets (mktemp)
46+
set -l temp_mapping (mktemp)
47+
48+
env PATH="$PATH" HOME="$HOME" bash -c '
49+
cd "$1" || exit 1
50+
shift
51+
node "$@"
52+
' bash "$phoenix_root" "$helper_script" >"$temp_json" 2>/dev/null
53+
or begin
54+
rm -f "$temp_json" "$temp_projects" "$temp_targets" "$temp_mapping"
55+
return 1
56+
end
57+
58+
jq -r 'keys[]' "$temp_json" >"$temp_projects"
59+
or begin
60+
rm -f "$temp_json" "$temp_projects" "$temp_targets" "$temp_mapping"
61+
return 1
62+
end
63+
64+
jq -r 'to_entries[] | .key as $project | .value[] | [$project, .] | @tsv' "$temp_json" | sort -u >"$temp_mapping"
65+
or begin
66+
rm -f "$temp_json" "$temp_projects" "$temp_targets" "$temp_mapping"
67+
return 1
68+
end
69+
70+
jq -r '[.[] | .[]] | unique[]' "$temp_json" >"$temp_targets"
71+
or begin
72+
rm -f "$temp_json" "$temp_projects" "$temp_targets" "$temp_mapping"
73+
return 1
74+
end
75+
76+
mv "$temp_projects" "$projects_file"
77+
and mv "$temp_targets" "$targets_file"
78+
and mv "$temp_mapping" "$mapping_file"
79+
80+
rm -f "$temp_json"
81+
end
82+
83+
function __braden_nx_projects
84+
__braden_nx_refresh_completion_cache; or return 1
85+
cat (__braden_nx_cache_dir)/projects.txt
86+
end
87+
88+
function __braden_nx_targets
89+
__braden_nx_refresh_completion_cache; or return 1
90+
cat (__braden_nx_cache_dir)/targets.txt
91+
end
92+
93+
function __braden_nx_project_target_pairs
94+
__braden_nx_refresh_completion_cache; or return 1
95+
cat (__braden_nx_cache_dir)/project-targets.tsv
96+
end
97+
98+
function __braden_nx_known_subcommands
99+
printf "%s\n" \
100+
add \
101+
affected \
102+
configure-ai-agents \
103+
connect \
104+
daemon \
105+
download-cloud-client \
106+
exec \
107+
fix-ci \
108+
format:check \
109+
format:write \
110+
generate \
111+
graph \
112+
import \
113+
init \
114+
list \
115+
login \
116+
logout \
117+
mcp \
118+
migrate \
119+
record \
120+
release \
121+
repair \
122+
report \
123+
reset \
124+
run \
125+
run-many \
126+
show \
127+
start-agent \
128+
start-ci-run \
129+
stop-all-agents \
130+
sync \
131+
sync:check \
132+
view-logs \
133+
watch
134+
end
135+
136+
function __braden_nx_subcommands_with_desc
137+
printf "%s\t%s\n" \
138+
affected "Run targets for affected projects" \
139+
daemon "Inspect or start the Nx daemon" \
140+
exec "Run an arbitrary command as an Nx target" \
141+
format:check "Check formatting across the workspace" \
142+
format:write "Write formatting fixes across the workspace" \
143+
generate "Generate or update source code" \
144+
graph "Open the dependency graph" \
145+
list "List installed or available plugins" \
146+
release "Run versioning and publishing flows" \
147+
repair "Repair outdated Nx configuration" \
148+
report "Print Nx environment details" \
149+
reset "Clear Nx cache and daemon state" \
150+
run "Run a target for one project" \
151+
run-many "Run a target for multiple projects" \
152+
show "Show workspace project information" \
153+
sync "Run workspace sync generators" \
154+
sync:check "Check whether sync generators would change files" \
155+
watch "Watch projects and run commands"
156+
end
157+
158+
function __braden_nx_targets_with_desc
159+
__braden_nx_targets | awk '{ printf "%s\tWorkspace target\n", $0 }'
160+
end
161+
162+
function __braden_nx_run_specs
163+
__braden_nx_project_target_pairs | awk -F '\t' '{ printf "%s:%s\t%s target for %s\n", $1, $2, $2, $1 }'
164+
end
165+
166+
function __braden_nx_projects_for_target --argument-names target_name
167+
__braden_nx_project_target_pairs | awk -F '\t' -v target_name="$target_name" '$2 == target_name { print $1 }'
168+
end
169+
170+
function __braden_nx_non_option_args
171+
for token in (commandline -pxc)[2..-1]
172+
if string match -qr '^-' -- $token
173+
continue
174+
end
175+
176+
echo $token
177+
end
178+
end
179+
180+
function __braden_nx_first_non_option_arg
181+
set -l args (__braden_nx_non_option_args)
182+
test (count $args) -gt 0; or return 1
183+
echo $args[1]
184+
end
185+
186+
function __braden_nx_is_target_command
187+
set -l first_arg (__braden_nx_first_non_option_arg)
188+
or return 1
189+
190+
contains -- $first_arg (__braden_nx_known_subcommands)
191+
and return 1
192+
193+
contains -- $first_arg (__braden_nx_targets)
194+
end
195+
196+
function __braden_nx_projects_for_first_target
197+
set -l first_arg (__braden_nx_first_non_option_arg)
198+
or return 1
199+
200+
__braden_nx_projects_for_target $first_arg
201+
end
202+
203+
function __braden_nx_previous_token_is
204+
set -l tokens (commandline -opc)
205+
test (count $tokens) -gt 0; or return 1
206+
contains -- $tokens[-1] $argv
207+
end
208+
209+
function __braden_nx_csv_candidates --argument-names candidate_type
210+
set -l prefix (string replace -r '[^,]*$' '' -- (commandline -ct))
211+
set -l candidates
212+
213+
switch $candidate_type
214+
case projects
215+
set candidates (__braden_nx_projects)
216+
case targets
217+
set candidates (__braden_nx_targets)
218+
case '*'
219+
return 1
220+
end
221+
222+
for candidate in $candidates
223+
echo "$prefix$candidate"
224+
end
225+
end
226+
227+
complete -c nx -e
228+
229+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_use_subcommand' -a '(__braden_nx_subcommands_with_desc)'
230+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_use_subcommand' -a '(__braden_nx_targets_with_desc)'
231+
232+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run; and __fish_is_nth_token 2' -a '(__braden_nx_run_specs)'
233+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_is_nth_token 2; and __braden_nx_is_target_command' -a '(__braden_nx_projects_for_first_target)'
234+
235+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many affected' -s t -xa '(__braden_nx_csv_candidates targets)' -d 'Targets to run'
236+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many affected' -l target -xa '(__braden_nx_csv_candidates targets)' -d 'Targets to run'
237+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many affected' -l targets -xa '(__braden_nx_csv_candidates targets)' -d 'Targets to run'
238+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many affected; and __braden_nx_previous_token_is -t --target --targets' -a '(__braden_nx_csv_candidates targets)'
239+
240+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many' -s p -xa '(__braden_nx_csv_candidates projects)' -d 'Projects to run'
241+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many' -l projects -xa '(__braden_nx_csv_candidates projects)' -d 'Projects to run'
242+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many affected' -l exclude -xa '(__braden_nx_csv_candidates projects)' -d 'Projects to exclude'
243+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many; and __braden_nx_previous_token_is -p --projects' -a '(__braden_nx_csv_candidates projects)'
244+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from run-many affected; and __braden_nx_previous_token_is --exclude' -a '(__braden_nx_csv_candidates projects)'
245+
246+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from show; and __fish_is_nth_token 2' -a "project\tShow resolved configuration for a project"
247+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from show; and __fish_is_nth_token 2' -a "projects\tShow workspace projects"
248+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from show; and __fish_seen_subcommand_from project; and __fish_is_nth_token 3' -a '(__braden_nx_projects)'
249+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from show; and __fish_seen_subcommand_from projects' -l with-target -xa '(__braden_nx_csv_candidates targets)' -d 'Only show projects with a target'
250+
complete -f -c nx -n '__braden_nx_completion_enabled; and __fish_seen_subcommand_from show; and __fish_seen_subcommand_from projects; and __braden_nx_previous_token_is --with-target' -a '(__braden_nx_csv_candidates targets)'

dot_config/fish/conf.d/00-env.fish

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ set -gx HOMEBREW_REPOSITORY $HOMEBREW_PREFIX
1414

1515
# Keep PATH ordering aligned with the existing zsh setup.
1616
fish_add_path -gPm "$HOMEBREW_PREFIX/bin" "$HOMEBREW_PREFIX/sbin"
17+
fish_add_path -gPm "$HOME/.local/share/mise/shims"
1718
fish_add_path -gPm "$HOME/.cargo/bin"
1819
fish_add_path -gPm "$HOME/.bun/bin"
1920
fish_add_path -gPm "$HOME/.antigravity/antigravity/bin"
@@ -25,6 +26,15 @@ if set -q MANPATH[1]
2526
set -gx MANPATH "" $MANPATH
2627
end
2728

29+
# Prefer a terminal-provided startup timestamp. Fall back to Fish init timing.
30+
if status is-interactive; and not set -q __BRADEN_SHELL_START_REAL
31+
if command -q perl
32+
set -gx __BRADEN_SHELL_START_REAL (command perl -MTime::HiRes=time -e 'printf "%.6f\n", time')
33+
else if command -q python3
34+
set -gx __BRADEN_SHELL_START_REAL (command python3 -c 'import time; print(f"{time.time():.6f}")')
35+
end
36+
end
37+
2838
if test -d /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
2939
set -gx JAVA_HOME /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
3040
end
@@ -35,9 +45,4 @@ end
3545

3646
if status is-interactive
3747
set -gx GPG_TTY (tty)
38-
39-
# Reuse the existing Starship startup-time module across zsh and fish.
40-
if command -q python3
41-
set -gx __BRADEN_SHELL_START_REAL (command python3 -c 'import time; print(f"{time.time():.6f}")')
42-
end
4348
end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# =============================================================================
2+
# Fish Syntax Highlighting
3+
# =============================================================================
4+
5+
set -g fish_color_normal cad3f5
6+
set -g fish_color_command a6da95 --bold
7+
set -g fish_color_keyword c6a0f6 --bold
8+
set -g fish_color_quote a6da95
9+
set -g fish_color_redirection b7bdf8
10+
set -g fish_color_end f5bde6
11+
set -g fish_color_error ed8796 --bold
12+
set -g fish_color_param cad3f5
13+
set -g fish_color_comment 8087a2 --italics
14+
set -g fish_color_option c6a0f6
15+
set -g fish_color_operator 8bd5ca
16+
set -g fish_color_escape f5a97f --bold
17+
set -g fish_color_autosuggestion 6e738d
18+
set -g fish_color_cancel ed8796 --reverse
19+
set -g fish_color_selection cad3f5 --background=363a4f
20+
set -g fish_color_search_match a6da95 --background=494d64
21+
set -g fish_color_history_current --bold
22+
set -g fish_color_valid_path a6da95 --underline
23+
set -g fish_color_match a6da95 --background=363a4f
24+
25+
set -g fish_pager_color_completion ed8796
26+
set -g fish_pager_color_description a5adcb
27+
set -g fish_pager_color_prefix a6da95 --bold
28+
set -g fish_pager_color_progress 6e738d
29+
set -g fish_pager_color_secondary_completion ed8796
30+
set -g fish_pager_color_secondary_description 8087a2
31+
set -g fish_pager_color_secondary_prefix a6da95
32+
set -g fish_pager_color_selected_background --background=363a4f
33+
set -g fish_pager_color_selected_completion ed8796 --bold
34+
set -g fish_pager_color_selected_description cad3f5
35+
set -g fish_pager_color_selected_prefix a6da95 --bold

0 commit comments

Comments
 (0)