Repository navigation
Expand file tree
/
Copy path.zshrc
More file actions
651 lines (529 loc) · 19.9 KB
/
Copy path.zshrc
File metadata and controls
651 lines (529 loc) · 19.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
# THIS FILE IS AUTO-GENERATED. DO NOT EDIT THIS FILE DIRECTLY.
#!/usr/bin/env zsh
# Capture the real hostname before anything (shadowenv/dev) can clobber $HOST.
# Ghostty's shell integration uses $HOST in OSC 7 CWD reporting; if shadowenv
# sets HOST to a dev-internal service hostname, Ghostty rejects the update
# ("OSC 7 host must be local") and new tabs get stuck at a stale directory.
typeset -g __real_host="$HOST"
# pnpm
export PNPM_HOME="$HOME/.local/share/pnpm"
# PATH — set once, at the top
export PATH=\
$PNPM_HOME:\
$HOME/.atuin/bin:\
/opt/homebrew/bin:/opt/homebrew/sbin:\
$HOME/bin/:$HOME/.local/bin:$HOME/bin:\
$HOME/.kube-plugins:\
${KREW_ROOT:-$HOME/.krew}/bin:\
$HOME/.cargo/bin:\
$HOME/go/bin:\
/usr/bin/local:\
/usr/local/opt/coreutils/libexec/gnubin:\
/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin:\
/opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin/:\
$PATH
zmodload zsh/zprof
STARTTIME=0
if command -v gdate &>/dev/null; then
STARTTIME=$(($(gdate +%s%3N)))
else
STARTTIME=$(($(date +%s%3N)))
fi
# Plugin directory — XDG data (not config; not stowed)
export ZSH_PLUGIN_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/zsh/plugins"
# fpath — must come before compinit
fpath=($HOME/.config/zsh/completions $fpath)
[[ -d "$ZSH_PLUGIN_DIR/zsh-completions/src" ]] && \
fpath=("$ZSH_PLUGIN_DIR/zsh-completions/src" $fpath)
# Homebrew completions (macOS) — must also be before compinit
[[ -d /opt/homebrew/share/zsh/site-functions ]] && \
fpath=(/opt/homebrew/share/zsh/site-functions $fpath)
case "$OSTYPE" in
darwin*)
# macOS
bindkey '^[b' backward-word
bindkey '^[f' forward-word
;;
linux*)
# Linux
bindkey '^[[1;5D' backward-word
bindkey '^[[1;5C' forward-word
;;
esac
### TEMPLATES ###
# base template
BASE_SCRIPT="yes"
setopt INC_APPEND_HISTORY
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE
HISTTIMEFORMAT="%d/%m/%y %T "
HISTSIZE=20000
HISTFILESIZE=20000
# base template end
# zsh-config template (compinit, completion styles, key bindings — replaces oh-my-zsh framework)
ZSH_CONFIG_SCRIPT="yes"
# Completion system
autoload -Uz compinit
zcompdump="${ZDOTDIR:-$HOME}/.zcompdump"
# Invalidate stale compdump cache when zshrc changes (fixes completions for newly added tools like zoxide)
if [[ -f "$zcompdump" && "$HOME/.zshrc" -nt "$zcompdump" ]]; then
rm -f "$zcompdump" "$zcompdump.zwc" 2>/dev/null
fi
compinit -d "$zcompdump"
zmodload -i zsh/complist
WORDCHARS=''
unsetopt menu_complete flowcontrol
setopt auto_menu complete_in_word always_to_end
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' 'r:|=*' 'l:|=* r:|=*'
zstyle ':completion:*' special-dirs true
zstyle ':completion:*' list-colors ''
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'
zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm -w -w"
zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories
zstyle ':completion:*' use-cache yes
zstyle ':completion:*' cache-path "${ZDOTDIR:-$HOME}/.zsh_cache"
# History additions (base.sh.erb already sets HISTSIZE/HISTFILESIZE/INC_APPEND_HISTORY etc.)
[ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history"
SAVEHIST=10000
setopt extended_history hist_expire_dups_first hist_verify share_history
# Key bindings
bindkey -e
autoload -U up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey '^[[A' up-line-or-beginning-search
bindkey '^[[B' down-line-or-beginning-search
if (( ${+terminfo[kcuu1]} )); then bindkey "${terminfo[kcuu1]}" up-line-or-beginning-search; fi
if (( ${+terminfo[kcud1]} )); then bindkey "${terminfo[kcud1]}" down-line-or-beginning-search; fi
bindkey '^r' history-incremental-search-backward # fallback; Atuin overrides when installed
bindkey ' ' magic-space
bindkey '^f' forward-word
if (( ${+terminfo[khome]} )); then bindkey "${terminfo[khome]}" beginning-of-line; fi
if (( ${+terminfo[kend]} )); then bindkey "${terminfo[kend]}" end-of-line; fi
if (( ${+terminfo[kdch1]} )); then bindkey "${terminfo[kdch1]}" delete-char; fi
# Bracketed paste (existing behaviour preserved)
pasteinit() {
OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
zle -N self-insert url-quote-magic
}
pastefinish() {
zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish
# zsh-config template end
# plugins — direct sources (no framework)
# evalcache — provides _evalcache; must come before any _evalcache call
[[ -f "$ZSH_PLUGIN_DIR/evalcache/evalcache.plugin.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/evalcache/evalcache.plugin.zsh"
# zsh-autosuggestions
export ZSH_AUTOSUGGEST_USE_ASYNC="true"
export ZSH_AUTOSUGGEST_STRATEGY=(history completion)
[[ -f "$ZSH_PLUGIN_DIR/zsh-autosuggestions/zsh-autosuggestions.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/zsh-autosuggestions/zsh-autosuggestions.zsh"
# git plugin (from OMZ repo, sourced as a data file — not as a framework)
[[ -f "$ZSH_PLUGIN_DIR/ohmyzsh/plugins/git/git.plugin.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/ohmyzsh/plugins/git/git.plugin.zsh"
# colored-man-pages
[[ -f "$ZSH_PLUGIN_DIR/ohmyzsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/ohmyzsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh"
# colorize (ccat / cless)
[[ -f "$ZSH_PLUGIN_DIR/ohmyzsh/plugins/colorize/colorize.plugin.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/ohmyzsh/plugins/colorize/colorize.plugin.zsh"
# fzf — key bindings and completion; Atuin supersedes only history Ctrl-R.
[ -f "$HOME/.fzf.zsh" ] && source "$HOME/.fzf.zsh"
# Atuin — shell history sync/search. Keep Up/Down prefix search from zsh-config.
if command -v atuin &>/dev/null; then
export ATUIN_NOBIND="true"
eval "$(atuin init zsh)"
bindkey '^r' atuin-search
fi
# kubectl completion
[[ -f "$ZSH_PLUGIN_DIR/kubectl-autocomplete/kubectl-autocomplete.plugin.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/kubectl-autocomplete/kubectl-autocomplete.plugin.zsh"
# herdr-automatic-rename — real-time tab naming for herdr (plugin-installed hook)
for _f in ${HOME}/.config/herdr/plugins/github/herdr-automatic-rename-*/shell/hook.zsh(N); do
source "$_f"
break
done
# fast-syntax-highlighting — MUST be sourced last
[[ -f "$ZSH_PLUGIN_DIR/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh" ]] && \
source "$ZSH_PLUGIN_DIR/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh"
# aliases template
ALIAS_SCRIPT="yes"
export EDITOR="nvim"
alias edit="nvim"
alias e="nvim"
alias nv="neovide"
# terminal multiplexers
alias tmux='tmux -CC'
# file manipulations
alias cpv='rsync -ah --info=progress2'
alias mnt='mount | grep -E ^/dev | column -t'
alias cl='clear'
alias psg='ps -ef | grep'
alias myip='curl ip.me'
alias cprof='curl -s -o /dev/null -w "time_namelookup: %{time_namelookup}s\n time_connect: %{time_connect}s\n time_appconnect: %{time_appconnect}s\n time_pretransfer: %{time_pretransfer}s\n time_redirect: %{time_redirect}s\n time_starttransfer: %{time_starttransfer}s\n ----------\n time_total: %{time_total}s\n"'
alias acceloff='defaults write -g com.apple.mouse.scaling -1'
alias cdiff='code -d'
alias ipseek='/Users/kalindu/.dev/go/1.17/bin/ipseek'
alias hs="history"
alias pf="promformat <(pbpaste | sed 's/\$__rate_interval/100M/g') | sed 's/100M/\$__rate_interval/g' | pbcopy"
alias lg='lazygit'
alias ls='ls --color=auto'
# aliases template end
# git template
export GPG_TTY=$(tty)
GIT_SCRIPT="yes"
alias g='git'
alias gd='git dunk'
alias gpull='git pull origin $(git rev-parse --abbrev-ref HEAD)'
alias grpull='git pull --rebase origin $(git rev-parse --abbrev-ref HEAD)'
GIT_PROJECTS_PATH="$HOME/src/github.com/"
unalias grb
grb() {
count="${1:=2}"
git rebase -i $(git rev-parse --abbrev-ref HEAD)~$count
}
gfp() {
git push origin +$(git rev-parse --abbrev-ref HEAD)
}
gacp() {
if [[ $# -eq 2 ]]; then
printf "adding \`$1\` and commiting with \`$2\`\n"
git add $1
git commit -m $2
fi
if [[ $# -eq 1 ]]; then
printf "commiting with $1\n"
git commit -m $1
fi
git push origin $(git rev-parse --abbrev-ref HEAD)
}
unalias gp
alias gp='gacp'
# functions
gitcd() {
dir=""
if [[ $# -gt 0 ]]; then
dir=$(ls -a $GIT_PROJECTS_PATH | grep $@ | sed 's/\x1b\[[0-9;]*m//g' | head -n 1)
[[ -z $dir ]] && printf "Could not find matching directory\n" || printf "Found matching directory: $dir\n"
fi
cd "${GIT_PROJECTS_PATH}${dir}"
}
ghopen() {
url_to_open="$(git remote get-url origin)"
printf "$url_to_open\n"
open "$url_to_open"
}
gfix() {
# Check if there's a previous commit to squash into
if ! git rev-parse --verify "HEAD~1" >/dev/null 2>&1; then
echo "Error: No previous commit to squash into"
return 1
fi
# Check for uncommitted changes
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "Error: You have uncommitted changes. Please commit or stash them first."
git status --short
return 1
fi
echo "Marking last commit as fixup..."
# Create temp script to automatically mark last commit as fixup
temp_script=$(mktemp)
cat > "$temp_script" << 'EOF'
#!/bin/bash
sed -i.bak '2s/^pick/fixup/' "$1"
EOF
chmod +x "$temp_script"
# Run the exact same rebase as your manual process
GIT_SEQUENCE_EDITOR="$temp_script" git rebase -i $(git rev-parse --abbrev-ref HEAD)~2
# Clean up
rm -f "$temp_script"
echo "Last commit fixed up into previous commit!"
}
# git template end
# functions template
FUNC_SCRIPT="yes"
reload() {
exec zsh
}
# functions template end
# kubernetes template
KUBERNETES_SCRIPT="yes"
export KUBE_EDITOR="nvim"
compdef kubecolor=kubectl
alias kubectl=kubecolor
alias k='kubectl'
alias kcl='kubectl'
alias kngx='kubectl ingress-nginx --deployment nginx-ingress-controller'
alias kevents="kubectl get events --sort-by='.lastTimestamp'"
alias kgc="kubectl config get-contexts -o name | fzf --exact -m --height=40% | tr -d '\n' | pbcopy; pbpaste; echo ''"
alias kclgc="kubectl config get-contexts -o name | fzf --exact -m --height=40% | tr -d '\n' | pbcopy; pbpaste; echo ''"
alias klog="stern $@"
alias kcls="kubectl config get-contexts -o name | grep -e "
kdebug() {
local host_net=false
local positional=()
# Parse flags
for arg in "$@"; do
case $arg in
--host-network) host_net=true ;;
*) positional+=("$arg") ;;
esac
done
cluster=${positional[1]}
if [[ -z "$cluster" ]] then
cluster=$(kubectl config get-contexts -o name | fzf)
if [[ -z "$cluster" ]] then
echo "Please select a valid cluster"
return -1
fi
fi
namespace=${positional[2]}
if [[ -z $namespace ]] then
namespace=$(kubectl --context $cluster get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | fzf)
if [[ -z "$namespace" ]] then
echo "Please select a valid namespace"
return -1
fi
fi
echo "Using $cluster and $namespace for a debug pod"
image_to_use="gcr.io/shopify-docker-images/cloud/debug-container"
fallback_image="docker.io/nicolaka/netshoot"
local overrides=""
if [[ "$host_net" == true ]]; then
echo "Enabling hostNetwork (pod will use node's network stack incl. IPv6 if available)"
overrides='--overrides={"spec":{"hostNetwork":true,"dnsPolicy":"ClusterFirstWithHostNet"}}'
fi
kubectl --context "$cluster" -n "$namespace" delete pod "$USER-test" --ignore-not-found
if ! kubectl --context "$cluster" -n "$namespace" run -ti --rm $USER-test --image "$image_to_use" ${=overrides} -- bash; then
echo "Falling back to $fallback_image"
kubectl --context "$cluster" -n "$namespace" run -ti --rm $USER-test --image "$fallback_image" ${=overrides} -- bash
fi
}
kcerts() {
cluster=$1
if [[ -z "$cluster" ]] then
cluster=$(kubectl config get-contexts -o name | fzf)
if [[ -z "$cluster" ]] then
echo "Please select a valid cluster"
return -1
fi
fi
namespace=$2
if [[ -z $namespace ]] then
namespace=$(kubectl --context $cluster get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | fzf)
if [[ -z "$namespace" ]] then
echo "Please select a valid namespace"
return -1
fi
fi
secret=$3
if [[ -z $secret ]] then
secret=$(kubectl --context $cluster -n $namespace get secrets -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | fzf)
if [[ -z "$secret" ]] then
echo "Please select a valid secret"
return -1
fi
fi
echo "Using $cluster, $namespace and $secret"
kubectl --context $cluster --namespace $namespace get secrets $secret -o json | jq -r '.data["tls.crt"]' | base64 --decode | openssl x509 -noout -text
}
kclcn() {
context=$1
shift
namespace=$1
shift
kubectl --namespace $namespace --context $context $@
}
kcla() {
kubectl $@ -A
}
kexec() {
cluster=$1
if [[ -z "$cluster" ]] then
cluster=$(kubectl config get-contexts -o name | fzf)
if [[ -z "$cluster" ]] then
echo "Please select a valid cluster"
return -1
fi
fi
namespace=$2
if [[ -z $namespace ]] then
namespace=$(kubectl --context $cluster get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | fzf)
if [[ -z "$namespace" ]] then
echo "Please select a valid namespace"
return -1
fi
fi
deploy=$3
if [[ -z $deploy ]] then
deploy=$(kubectl --context $cluster -n $namespace get deploy -o name | fzf)
if [[ -z "$namespace" ]] then
echo "Please select a valid namespace"
return -1
fi
fi
echo "Using $cluster, $namespace and $deploy for exec"
kubectl --context $cluster -n $namespace exec -it $deploy -- bash
}
export KUBECONFIG=$(printf '%s:' $HOME/.kube/*config*(N.) | sed 's/:$//')
# kubernetes template end
# agents template
AGENTS_SCRIPT="yes"
# Add other AI agent configurations here
# agents template end
# misc template
if [[ "$(uname)" == "Linux" ]]; then
# Use xclip to copy/paste to clipboard
alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'
fi
# Arch Linux: go-task package provides 'go-task' binary, alias to 'task'
if [[ -f /etc/arch-release ]]; then
alias task='go-task'
fi
# misc template end
### TEMPLATES END ###
# Homebrew (macOS)
# Cached via _evalcache: brew shellenv output is deterministic per-install.
# To refresh after a Homebrew upgrade or prefix change, run `_evalcache_clear`.
[[ -x /opt/homebrew/bin/brew ]] && _evalcache /opt/homebrew/bin/brew shellenv
# starship prompt
# Cached via _evalcache: starship init output is deterministic per starship
# version. If you upgrade starship, run `_evalcache_clear` to refresh.
_evalcache starship init zsh
# zoxide (replaces enhancd)
if command -v zoxide &>/dev/null; then
# Cached via _evalcache: zoxide init output is deterministic per version +
# flags. Run `_evalcache_clear` after a zoxide upgrade.
_evalcache zoxide init zsh --cmd cd
# Override zoxide's default zsh completion:
# 1. `cd <TAB>` (no prefix) completes only local directories.
# 2. `cd que<TAB>` completes local directories first; if no local match,
# falls back to zoxide database matches.
# Using `compadd -U` allows zoxide's substring matches (e.g. "que"
# matching "pi-quests") to appear even though they don't prefix-match.
# When `-U` candidates don't share a prefix with the typed text, zsh's
# longest-common-prefix auto-insert would clobber the typed text (e.g.
# `cd t<TAB>` -> `cd `). We set `compstate[insert]=menu` to disable
# LCP auto-insert and require menu selection instead, which preserves
# the typed prefix.
# 3. `cd foo<SPACE><TAB>` triggers interactive fzf selection and inserts
# the chosen path using `compadd -U` instead of the fragile upstream
# DSR escape-sequence hack that breaks on many terminals
# (see zoxide issues #737, #778, #1043).
function __zoxide_z_complete() {
[[ "${#words[@]}" -eq "${CURRENT}" ]] || return 0
# cd <TAB> with absolutely no prefix -> only local directories
if [[ "${#words[@]}" -eq 2 && "${words[-1]}" == '' ]]; then
_cd -/
return 0
fi
# cd foo<SPACE><TAB> -> interactive fzf via zoxide
if [[ "${words[-1]}" == '' ]]; then
__zoxide_result="$(\command zoxide query --exclude "$(__zoxide_pwd || \builtin true)" --interactive -- ${words[2,-1]})" || __zoxide_result=''
if [[ -n "${__zoxide_result}" ]]; then
compadd -U -S '' -- "${__zoxide_result}"
fi
return 0
fi
# cd que<TAB> -> local dirs first; zoxide fuzzy matches only if no local match
local -i nm_before=compstate[nmatches]
_cd -/
if (( compstate[nmatches] == nm_before )); then
local -a zdirs znames
zdirs=(${(f)"$(\command zoxide query --list -- ${words[2,-1]} 2>/dev/null | head -30)"})
znames=(${(u)${zdirs:t}})
if (( ${#znames} )); then
compadd -U -S '' -a znames
# Prevent LCP auto-insert from clobbering the typed prefix when -U
# candidates don't share a common prefix with it (e.g. `cd t<TAB>`).
compstate[insert]=menu
fi
fi
}
if (( ${+functions[compdef]} )); then
compdef __zoxide_z_complete cd 2>/dev/null || true
fi
fi
# felix (TUI file manager) — shell integration for LWD (last working directory)
# Cached via _evalcache: the init output only depends on $XDG_RUNTIME_DIR/$TMPDIR,
# which are stable across shells for a given user session.
if command -v fx &>/dev/null; then _evalcache fx --init; fi
# direnv
if command -v direnv &>/dev/null; then _evalcache direnv hook zsh; fi
# pyenv
# Pass `--no-rehash` to skip `command pyenv rehash` on every shell start
# (~70ms saving). Rehashing is only needed after installing a new Python
# version or a gem/package that provides a new shim — in those cases run
# `pyenv rehash` manually.
if [[ -d "$HOME/.pyenv" ]]; then
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH"
_evalcache pyenv init - --no-rehash
fi
# fnm (Fast Node Manager — replaces nvm)
if command -v fnm &>/dev/null; then
eval "$(fnm env --use-on-cd --shell zsh)"
fi
# rbenv (lazy-load)
if command -v rbenv &>/dev/null; then
export PATH="$HOME/.rbenv/bin:$PATH"
rbenv() {
unfunction rbenv
eval "$(command rbenv init -)"
rbenv "$@"
}
fi
# Shopify dev
[[ -f /opt/dev/sh/chruby/chruby.sh ]] && \
{ type chruby >/dev/null 2>&1 || chruby() { source /opt/dev/sh/chruby/chruby.sh; chruby "$@"; }; }
if [[ $- == *i* ]] && [[ -f /opt/dev/dev.sh ]]; then source /opt/dev/dev.sh; fi
# Nix
if [ -e $HOME/.nix-profile/etc/profile.d/nix.sh ]; then
. $HOME/.nix-profile/etc/profile.d/nix.sh
fi
# tec agent
[[ -x $HOME/.local/state/tec/profiles/base/current/global/init ]] && \
eval "$($HOME/.local/state/tec/profiles/base/current/global/init zsh)"
# Ruby gem bin. Runs after Nix and tec put their Ruby on PATH, so GEM_HOME
# belongs to the Ruby that actually runs, not macOS's system Ruby.
if command -v ruby &>/dev/null; then
export GEM_HOME="$(ruby -e 'puts Gem.user_dir')"
export PATH="$GEM_HOME/bin:$PATH"
fi
# .env
if [[ -s $HOME/.env ]]; then
set -a
source $HOME/.env
set +a
fi
ENDTIME=0
if command -v gdate &>/dev/null; then
ENDTIME=$(($(gdate +%s%3N)))
else
ENDTIME=$(($(date +%s%3N)))
fi
# Ghostty CWD fix — override _ghostty_report_pwd to use the real hostname
# captured at shell startup instead of $HOST (which shadowenv overwrites).
# _ghostty_deferred_init runs on the first precmd, so we schedule our
# one-shot fixer to run after it.
if [[ -n "$GHOSTTY_RESOURCES_DIR" ]]; then
__ghostty_fix_cwd_host() {
if (( ${+functions[_ghostty_report_pwd]} )); then
_ghostty_report_pwd() {
builtin print -nu $_ghostty_fd '\e]7;kitty-shell-cwd://'"$__real_host""$PWD"'\a'
}
fi
# Remove this one-shot hook
precmd_functions=(${precmd_functions:#__ghostty_fix_cwd_host})
}
precmd_functions+=(__ghostty_fix_cwd_host)
fi
# Tools that read the environment through `zsh -ilc` (bb, editors) parse stdout, so report only to a terminal.
if [[ -t 1 ]]; then
printf 'Start time %.4fs\n' $(echo "($ENDTIME - $STARTTIME)/1000" | bc -l)
fi