main
1# Prompt — computed in precmd, no subshell forks
2# Variables are set in the hook, PROMPT just references them
3
4__prompt_precmd() {
5 local last_status=$?
6
7 __ps_err='' __ps_dir='' __ps_git='' __ps_nix='' __ps_kube=''
8
9 # Exit status
10 (( last_status )) && __ps_err="%F{red}?${last_status} "
11
12 # Directory with smart shortening (inline, no fork)
13 local dir="${PWD/#$HOME/~}"
14 local prefix=""
15 [[ "$dir" == */.local/share/worktrees/* ]] && prefix="🌿 "
16 [[ "$dir" == ~/desktop* ]] && prefix="🖥️ "
17
18 if (( ${#dir} > 50 )); then
19 local parts=("${(@s:/:)dir}")
20 local i
21 for (( i=1; i <= ${#parts[@]} - 2; i++ )); do
22 (( ${#dir} <= 50 )) && break
23 (( ${#parts[$i]} <= 2 )) && continue
24 if [[ "${parts[$i]}" == .* ]]; then
25 parts[$i]=".${parts[$i]:1:1}"
26 else
27 parts[$i]="${parts[$i]:0:1}"
28 fi
29 dir="${(j:/:)parts}"
30 done
31 fi
32 __ps_dir="${prefix}${dir}"
33
34 # Git: single call for branch + dirty state
35 local gstatus branch dirty
36 if gstatus=$(GIT_OPTIONAL_LOCKS=0 git status --porcelain=v2 -b --no-ahead-behind 2>/dev/null); then
37 branch=${gstatus#*branch.head }
38 branch=${branch%%$'\n'*}
39 if [[ -n $branch && $branch != "# "* ]]; then
40 [[ $gstatus == *$'\n'[^#]* ]] && dirty='*'
41 __ps_git=" %F{76}${branch}${dirty}%f"
42 fi
43 fi
44
45 # Nix shell indicator
46 if (( ${+IN_NIX_SHELL} )); then
47 if [[ -n $NIX_SHELL_PACKAGES ]]; then
48 __ps_nix=" %F{yellow}❄{$NIX_SHELL_PACKAGES}%f"
49 else
50 __ps_nix=" %F{yellow}❄%f"
51 fi
52 fi
53
54 # Kubeconfig indicator
55 if [[ -n $KUBECONFIG ]]; then
56 __ps_kube=" %F{134}k8s:${KUBECONFIG:t:r}%f"
57 fi
58}
59
60autoload -Uz add-zsh-hook
61add-zsh-hook precmd __prompt_precmd
62
63setopt PROMPT_SUBST
64PROMPT='${__ps_err}%F{111}%m%f:%F{2}${__ps_dir}%f${__ps_git}${__ps_nix}${__ps_kube} %(!.#.$) '
65RPROMPT=""