.profile 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. # Shell Profile/Config File
  2. # NOTE: symlinked to multiple files to apply in multiple shells/scenarios; see install.sh
  3. ###############################################################################
  4. # Non-interactive shell configuration
  5. ###############################################################################
  6. # utils used below
  7. [ "$ZSH_VERSION" ] && get_bin(){ whence -p "$1"; } || get_bin(){ which "$1"; }
  8. has_bin(){ get_bin "$1" >/dev/null; }
  9. get_func(){ typeset -f "$1"; }
  10. has_func(){ get_func "$1" >/dev/null; }
  11. is_num(){ [[ "$1" =~ ^[0-9]+$ ]]; }
  12. as_num(){ is_num "$1" && echo "$1"; }
  13. OS=$(uname -s)
  14. # Add user-specific bin dirs to PATH
  15. export PATH="$PATH:$HOME/.local/bin:$HOME/bin"
  16. # Setup user-specific Python overrides
  17. _PY_BASE_DIR="$HOME/Library/Python/";
  18. if [ "$OS" = "Darwin" ] && [ -d "$_PY_BASE_DIR" ]; then
  19. for PY_DIR in "$HOME/Library/Python/"*/; do
  20. export PATH="$PY_DIR/bin:$PATH"
  21. done
  22. fi
  23. # Homebrew
  24. if [ "$OS" = "Darwin" ]; then
  25. export PATH="$PATH:$HOME/homebrew/bin" # maybe keep? will this help on family laptops?
  26. if [ "${BREW_BIN:=$(get_bin brew)}" ] && [ "${BREW_PREFIX:=$(brew --prefix)}" ]; then
  27. export HOMEBREW_CASK_OPTS="--appdir=$HOME/Applications --require-sha"
  28. export HOMEBREW_NO_INSECURE_REDIRECT=1
  29. # help build tools find all the brew-based bits
  30. export CFLAGS="-I$BREW_PREFIX/include/"
  31. export CXXFLAGS="-I$BREW_PREFIX/include/"
  32. export LDFLAGS="-L$BREW_PREFIX/lib/"
  33. fi
  34. fi
  35. # Default editor
  36. export EDITOR="vim"
  37. # Configure go lang
  38. if [ "$OS" = "Darwin" ]; then
  39. export GOROOT="$BREW_PREFIX/opt/go/libexec"
  40. else
  41. export GOROOT="$HOME/golang"
  42. fi
  43. export PATH="$PATH:$GOROOT/bin"
  44. export GOPATH="$HOME/go"
  45. export PATH="$PATH:$GOPATH/bin"
  46. # Configure less allow colors
  47. export LESS="-FRXM --use-color" #NOTE: --mouse nearly works but selection breaks which is probably more important
  48. # If not running interactively, don't do anything else
  49. [ "$PS1" ] || return
  50. ###############################################################################
  51. # Interactive shell configuration
  52. ###############################################################################
  53. # tweak history behavior a bit
  54. HISTSIZE=100000
  55. if [ ! "$ZSH_VERSION" ]; then
  56. HISTFILESIZE=$HISTSIZE
  57. HISTCONTROL="ignoreboth"
  58. shopt -s histappend
  59. PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
  60. else
  61. SAVEHIST=$HISTSIZE
  62. setopt EXTENDED_HISTORY # Write the history file in the ':start:elapsed;command' format.
  63. setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
  64. setopt APPEND_HISTORY # append to history file
  65. setopt SHARE_HISTORY # Share history between all sessions.
  66. setopt HIST_EXPIRE_DUPS_FIRST # Expire a duplicate event first when trimming history.
  67. setopt HIST_IGNORE_SPACE # Do not record an event starting with a space.
  68. setopt HIST_IGNORE_DUPS # Do not record an event that was just recorded again.
  69. setopt HIST_IGNORE_ALL_DUPS # Delete an old recorded event if a new event is a duplicate.
  70. setopt HIST_FIND_NO_DUPS # Do not display a previously found event.
  71. setopt HIST_SAVE_NO_DUPS # Do not write a duplicate event to the history file.
  72. setopt HIST_VERIFY # Do not execute immediately upon history expansion.
  73. setopt HIST_NO_STORE # Don't store history commands
  74. fi
  75. # Auto fetch and ask to pull if outdated once every 30 days
  76. DOTFILES_DIR="$HOME/.dotfiles"
  77. DOTFILES_GIT_DIR="$DOTFILES_DIR/.git"
  78. DOTFILES_GIT_FETCH_HEAD_PATH="$DOTFILES_GIT_DIR/FETCH_HEAD"
  79. DOTFILES_CHECK_DAYS=30
  80. if [ -d "$DOTFILES_GIT_DIR" ] && [[ ! -f "$DOTFILES_GIT_FETCH_HEAD_PATH" || $(( $(date +%s) - $(date -r "$DOTFILES_GIT_FETCH_HEAD_PATH" +%s) )) -gt $(( $DOTFILES_CHECK_DAYS * 24 * 60 * 60 )) ]]; then
  81. # auto fetch repo
  82. git -C "$DOTFILES_DIR" fetch || :
  83. # complain if branch is outdated and ask to update
  84. COMMITS_BEHIND=$(git -C "$DOTFILES_DIR" rev-list --count HEAD..@{u})
  85. if [ "$COMMITS_BEHIND" -gt 0 ]; then
  86. echo "😅 Outdated dotfiles repo!"
  87. echo "🧐 Review via: git -C \"\$DOTFILES_DIR\" log HEAD..@{u} --oneline --reverse"
  88. echo "👍 Update via: git -C \"\$DOTFILES_DIR\" pull"
  89. fi
  90. fi
  91. # Enable auto-switching by adding mise-aware tool shims to PATH (which resolves tool versions lazily and avoids issues caused by other approaches)
  92. ! has_bin mise || export PATH="$HOME/.local/share/mise/shims:$PATH"
  93. # Custom shell aliases
  94. if [ "$OS" = "Darwin" ]; then
  95. export CLICOLOR=1
  96. else
  97. alias ls="ls --color=auto"
  98. alias pbcopy="xclip -selection clipboard"
  99. alias pbpaste="xclip -selection clipboard -o"
  100. fi
  101. alias la="ls -Fa"
  102. alias ll="ls -Fla"
  103. alias l="ls -FC"
  104. alias d="l"
  105. alias tree="tree -C -F"
  106. alias grep="grep --color"
  107. alias man='LESS_TERMCAP_md=$(tput bold && tput setaf 4 || :) LESS_TERMCAP_me=$(tput sgr0 || :) LESS_TERMCAP_mb=$(tput blink || :) LESS_TERMCAP_us=$(tput setaf 2 || :) LESS_TERMCAP_ue=$(tput sgr0 || :) LESS_TERMCAP_so=$(tput smso || :) LESS_TERMCAP_se=$(tput rmso || :) PAGER="${commands[less]:-$PAGER}" man'
  108. alias vi=vim
  109. ! has_bin nvim || alias vim=nvim
  110. # aliases for node
  111. alias node-print="node -e 'let [,f=\".\",e=\"this\"]=process.argv,ctx=require(fs.existsSync(f)?path.resolve(f):f); eval(\`(async function(){ with(this) return (\${e}); })\`).call(ctx).then(console.log,e=>{console.error(e);process.exit(1)})'"
  112. alias node-print-json="node -e 'let [,f=\".\",e=\"this\"]=process.argv,ctx; try{ctx=require(f)}catch{ctx=require(path.resolve(f))}; eval(\`(async function(){ with(this) return (\${e}); })\`).call(ctx).then(o=>console.log(JSON.stringify(o,null,2)),e=>{console.error(e);process.exit(1)})'"
  113. alias node-print-table="node -e 'let [,f=\".\",e=\"this\"]=process.argv,ctx; try{ctx=require(f)}catch{ctx=require(path.resolve(f))}; eval(\`(async function(){ with(this) return (\${e}); })\`).call(ctx).then(console.table,e=>{console.error(e);process.exit(1)})'"
  114. alias node-print-deep="node -e 'let [,f=\".\",e=\"this\"]=process.argv,ctx; try{ctx=require(f)}catch{ctx=require(path.resolve(f))}; eval(\`(async function(){ with(this) return (\${e}); })\`).call(ctx).then(o=>console.log(require(\"util\").inspect(o,{depth:process.env.DEPTH||Infinity})),e=>{console.error(e);process.exit(1)})'"
  115. alias node-print-repl="node -e 'let [,f=\".\",e=\"this\"]=process.argv,ctx; try{ctx=require(f)}catch{ctx=require(path.resolve(f))}; eval(\`(async function(){ with(this) return (\${e}); })\`).call(ctx).then((r)=>(console.log(r,\`\n = \\\$1\`),repl.start().context.\$1=r),e=>{console.error(e);process.exit(1)})'"
  116. alias env-ts-node="TS_NODE_FILES=true NODE_OPTIONS=\"-r ts-node/register \$NODE_OPTIONS\""
  117. alias ts-node-print="env-ts-node node-print"
  118. # colorized cat using bat
  119. if [ "${BAT_BIN:=$(get_bin bat)}" ]; then
  120. alias cat="$BAT_BIN -p"
  121. # Customize theme (note also used by delta)
  122. export BAT_THEME="$(defaults read -globalDomain AppleInterfaceStyle &>/dev/null && echo 'Visual Studio Dark+' || echo GitHub)"
  123. #TODO: the VSCode theme in bat is not showing markdown italics, code blocks, or fenced code blocks
  124. #TODO: enable --italic-text=always via here? or put config in my dotfiles…
  125. # colorized ripgrep using batgrep
  126. if [ "${BATGREP_BIN:=$(get_bin batgrep)}" ] && [ "${RG_BIN:=$(get_bin rg)}" ]; then
  127. rg(){
  128. if [ $# -ne 1 ] || [ "[$1]" = "[--help]" ]; then
  129. "$RG_BIN" "$@";
  130. else
  131. "$BATGREP_BIN" --search-pattern "$1";
  132. #TODO: -- can the pager be automatic instead of always while still keeping search-pattern (or similar)?
  133. fi
  134. }
  135. fi
  136. #TODO: batman is currently worse/different than my current alias but change the color scheme
  137. # use bat for help
  138. #TODO: I assume this fails if last arg… I should try to fix that first…
  139. if [ "$ZSH_VERSION" ]; then
  140. alias -g -- -h='-h 2>&1 | bat -p -l=help'
  141. alias -g -- --help='--help 2>&1 | bat -p -l=help'
  142. fi
  143. # monkeypatch tail to use bat to colorize things
  144. if [ "${TAIL_BIN:=$(get_bin tail)}" ]; then
  145. tail(){
  146. LAST_ARG=${@[-1]}
  147. if [ "$LAST_ARG" ]; then
  148. LAST_FILE=$(ls -1 "$LAST_ARG" | "$TAIL_BIN" -n1)
  149. "$TAIL_BIN" "$@" | "$BAT_BIN" -Pp --file-name="$LAST_FILE"
  150. else
  151. "$TAIL_BIN" "$@"
  152. fi
  153. }
  154. fi
  155. # monkeypatch head to use bat to colorize things
  156. if [ "${HEAD_BIN:=$(get_bin head)}" ]; then
  157. head(){
  158. LAST_ARG=${@[-1]}
  159. if [ "$LAST_ARG" ]; then
  160. LAST_FILE=$(ls -1 "$LAST_ARG" | "$TAIL_BIN" -n1)
  161. "$HEAD_BIN" "$@" | "$BAT_BIN" -Pp --file-name="$LAST_FILE"
  162. else
  163. "$HEAD_BIN" "$@"
  164. fi
  165. }
  166. fi
  167. # monkeypatch git to use bat to colorize things
  168. if [ "${GIT_BIN:=$(get_bin git)}" ]; then
  169. git(){
  170. case "$1" in
  171. log)
  172. # A gross hack for git log until this is fixed: https://github.com/sharkdp/bat/issues/1632
  173. # NOTE: forcing `--decorate` since piping disables it; `bat` won't highlight those lines properly but the info is too useful to omit
  174. "$GIT_BIN" "$@" --decorate | "$BAT_BIN" -p -l=gitlog
  175. ;;
  176. show)
  177. # Use bat to colorize showing files in other branches
  178. if [[ "$2" =~ ^.+:.+ ]]; then
  179. "$GIT_BIN" "$@" | "$BAT_BIN" -p --file-name "${2##*:}"
  180. else
  181. "$GIT_BIN" "$@";
  182. fi
  183. ;;
  184. *)
  185. "$GIT_BIN" "$@";
  186. ;;
  187. esac
  188. }
  189. fi
  190. fi
  191. if [ "${GH_BIN:=$(get_bin gh)}" ]; then
  192. # monkeypatch gh to customize some of the templates
  193. gh(){
  194. case "$1 $2" in
  195. "search prs" | "pr list")
  196. "$GH_BIN" "$@" \
  197. --json="url,title,author,updatedAt" \
  198. --template='
  199. {{tablerow "URL" "TITLE" "AUTHOR" "UPDATED"}}
  200. {{range .}}{{tablerow (.url | autocolor "blue") .title .author.login .updatedAt}}{{end}}
  201. '
  202. ;;
  203. *)
  204. "$GH_BIN" "$@";
  205. ;;
  206. esac
  207. }
  208. fi
  209. # color theme setup for bat (not aliased to cat directly because it's a bit slow)
  210. ! has_bin bat || export BAT_THEME="$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo 'Visual Studio Dark+' || echo GitHub)"
  211. # color diffs
  212. ! has_bin colordiff || alias diff="colordiff"
  213. #TODO: alias doesn't quite work here for delta because it breaks "diff -u" ... luckily -u is the default and I never want the other format so maybe ignore -u and move on?? 🙄
  214. #! has_bin delta || alias diff="delta" #TODO: make this part of the above …has_bin delta… checks
  215. # color json
  216. ! has_bin json || alias json="json -o inspect"
  217. # fancy shell prompts
  218. if [ "$ZSH_VERSION" ]; then
  219. # use emacs-style for most defaults
  220. bindkey -e
  221. # jump more like bash did with Alt + Left/Right arrow
  222. bindkey "^[f" vi-forward-word
  223. bindkey "^[b" vi-backward-word
  224. # bindings for if you're not using Options as Meta key in Terminal (e.g., VSCode)
  225. bindkey "∑" vi-backward-kill-word # Alt + w
  226. bindkey "ƒ" vi-forward-word # Alt + f
  227. bindkey "∫" vi-backward-word # Alt + b
  228. bindkey "≥" insert-last-word # Alt + .
  229. # editor
  230. autoload -z edit-command-line
  231. zle -N edit-command-line
  232. bindkey "^X^E" edit-command-line
  233. # enable completion menu
  234. zstyle ':completion:*' menu select
  235. # allow trailing slashes on ".."
  236. zstyle ':completion:*' special-dirs true
  237. # enable inline comments since other shells allow it and sometimes they're nice to have
  238. setopt interactive_comments
  239. # ensure proper ls-style colors in completion
  240. zstyle ':completion:*' list-colors 'di=34:ln=35:so=32:pi=33:ex=31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30'
  241. # setup zgenom and plugins for zsh
  242. ZGENOM_DIR="${HOME}/.zgenom"
  243. [ -d "$ZGENOM_DIR" ] || git clone https://github.com/jandamm/zgenom.git "$ZGENOM_DIR"
  244. source "$ZGENOM_DIR/zgenom.zsh"
  245. zgenom autoupdate
  246. if ! zgenom saved; then
  247. echo "Creating a zgenom save ..."
  248. zgenom loadall <<EOF
  249. sindresorhus/pure
  250. zsh-users/zsh-autosuggestions
  251. zsh-users/zsh-syntax-highlighting
  252. EOF
  253. zgenom save
  254. fi
  255. ZSH_AUTOSUGGEST_IGNORE_WIDGETS+=(backward-kill-word)
  256. # My Visual Studio Dark+ zsh-syntax-highlighting theme
  257. [[ $COLORTERM =~ (24bit|truecolor) ]] || zmodload zsh/nearcolor # use nearest for 256-color terminals
  258. typeset -A ZSH_HIGHLIGHT_STYLES
  259. export ZSH_HIGHLIGHT_STYLES
  260. ZSH_HIGHLIGHT_HIGHLIGHTERS+=(brackets cursor regexp)
  261. # zsh-syntax-highlighting: main
  262. ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#F44747'
  263. ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#C586C0' # if, for, then, etc.
  264. ZSH_HIGHLIGHT_STYLES[alias]='fg=#DCDCAA'
  265. ZSH_HIGHLIGHT_STYLES[suffix-alias]='fg=#DCDCAA'
  266. ZSH_HIGHLIGHT_STYLES[global-alias]='fg=#DCDCAA'
  267. ZSH_HIGHLIGHT_STYLES[builtin]='fg=#DCDCAA'
  268. ZSH_HIGHLIGHT_STYLES[function]='fg=#DCDCAA' # foo in foo(){}
  269. ZSH_HIGHLIGHT_STYLES[command]='fg=#DCDCAA' # date in $(date)
  270. ZSH_HIGHLIGHT_STYLES[precommand]='fg=#DCDCAA,italic' # builtin, command, exec
  271. ZSH_HIGHLIGHT_STYLES[commandseparator]='fg=#D4D4D4' # ;, &&, ||
  272. ZSH_HIGHLIGHT_STYLES[hashed-command]='fg=#FF0000' # what's this?
  273. ZSH_HIGHLIGHT_STYLES[autodirectory]='fg=#6A9955,italic'
  274. ZSH_HIGHLIGHT_STYLES[path]='fg=#CE9178'
  275. ZSH_HIGHLIGHT_STYLES[path_pathseparator]='fg=#FF79C6'
  276. ZSH_HIGHLIGHT_STYLES[path_prefix]='fg=#CE9178'
  277. ZSH_HIGHLIGHT_STYLES[path_prefix_pathseparator]='fg=#FF79C6'
  278. ZSH_HIGHLIGHT_STYLES[globbing]='fg=#569CD6'
  279. ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#BD93F9'
  280. ZSH_HIGHLIGHT_STYLES[command-substitution]='fg=#CE9178'
  281. ZSH_HIGHLIGHT_STYLES[command-substitution-unquoted]='fg=#CE9178'
  282. ZSH_HIGHLIGHT_STYLES[command-substitution-quoted]='fg=#CE9178'
  283. ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]='fg=#CE9178'
  284. ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter-unquoted]='fg=#CE9178' # $( … ) -- not the …
  285. ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter-quoted]='fg=#CE9178' # "$( … )" -- not the …
  286. ZSH_HIGHLIGHT_STYLES[process-substitution]='fg=???'
  287. ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]='fg=#CE9178'
  288. ZSH_HIGHLIGHT_STYLES[arithmetic-expansion]='fg=#CE9178' # $(( … )) -- not the …
  289. ZSH_HIGHLIGHT_STYLES[single-hyphen-option]='fg=#9CDCFE' # -h
  290. ZSH_HIGHLIGHT_STYLES[double-hyphen-option]='fg=#9CDCFE' # --help
  291. ZSH_HIGHLIGHT_STYLES[back-quoted-argument]='fg=#BD93F9'
  292. ZSH_HIGHLIGHT_STYLES[back-quoted-argument-unclosed]='fg=#F44747'
  293. ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]='fg=#CE9178'
  294. ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=#CE9178'
  295. ZSH_HIGHLIGHT_STYLES[single-quoted-argument-unclosed]='fg=#F44747'
  296. ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=#CE9178'
  297. ZSH_HIGHLIGHT_STYLES[double-quoted-argument-unclosed]='fg=#F44747'
  298. ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#CE9178'
  299. ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument-unclosed]='fg=#F44747'
  300. ZSH_HIGHLIGHT_STYLES[rc-quote]='fg=#CE9178'
  301. ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]='fg=#9CDCFE'
  302. ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]='fg=#D7BA7D' # "\\"" -- only the \\"
  303. ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]='fg=#D4D4D4'
  304. ZSH_HIGHLIGHT_STYLES[assign]='fg=#9CDCFE' # X=123 -- the X=
  305. ZSH_HIGHLIGHT_STYLES[redirection]='fg=#D4D4D4'
  306. ZSH_HIGHLIGHT_STYLES[comment]='fg=#6A9955'
  307. ZSH_HIGHLIGHT_STYLES[named-fd]='fg=#D4D4D4'
  308. ZSH_HIGHLIGHT_STYLES[numeric-fd]='fg=#D4D4D4'
  309. ZSH_HIGHLIGHT_STYLES[arg0]='fg=#DCDCAA'
  310. ZSH_HIGHLIGHT_STYLES[default]='fg=#D4D4D4'
  311. # zsh-syntax-highlighting: brackets
  312. ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=#D7BA7D' # [[[ -- but only the 1st
  313. ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=#C586C0' # [[[ -- but only the 2nd
  314. ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=#FFB86C' # [[[ -- but only the 3rd
  315. # zsh-syntax-highlighting: cursor
  316. ZSH_HIGHLIGHT_STYLES[cursor]='standout'
  317. # zsh-syntax-highlighting: regexp
  318. typeset -A ZSH_HIGHLIGHT_REGEXP
  319. #TODO: bug: highlighting unfound vars with same color… ideally undefined vars would be red or dimmed or something
  320. ZSH_HIGHLIGHT_REGEXP+=('[$][0-9]' fg=#9CDCFE) # $… -- non-quoted dollar-argument
  321. ZSH_HIGHLIGHT_REGEXP+=('[$][a-zA-Z_][a-zA-Z0-9_]*' fg=#9CDCFE) # $… -- non-quoted dollar-argument
  322. # ZSH_HIGHLIGHT_REGEXP+=('[$]{[a-zA-Z_][a-zA-Z0-9_]*[:-=/#}]{1,2}' fg=#9CDCFE) # $… -- brace-wrapped dollar-argument
  323. ZSH_HIGHLIGHT_REGEXP+=(' -[^= ]*' fg=#9CDCFE) # -xyz
  324. ZSH_HIGHLIGHT_REGEXP+=(' --[^= ]*' fg=#9CDCFE) # --flags=
  325. ZSH_HIGHLIGHT_REGEXP+=('[#][ ]?[A-Z]{3,13}:' ${ZSH_HIGHLIGHT_STYLES[comment]},bold) # #TODO: <-- comment leaders
  326. ZSH_HIGHLIGHT_REGEXP+=(' [^ ]+://[^ ?&#]*' ${ZSH_HIGHLIGHT_STYLES[assign]},bold) # proto://some/path <-- URL-like strings
  327. # Enable zsh completions from brew
  328. ZSH_SITE_FUNC_DIR="$BREW_PREFIX/share/zsh/site-functions"
  329. FPATH="$ZSH_SITE_FUNC_DIR:$FPATH"
  330. # Auto fetch some community completions
  331. RERUN_ZCOMP=
  332. for ID in _node _yarn; do
  333. F="$ZSH_SITE_FUNC_DIR/$ID"; [ -f "$F" ] || curl -s -o "$ZSH_SITE_FUNC_DIR/$ID" "https://raw.githubusercontent.com/zsh-users/zsh-completions/master/src/$ID" && RERUN_ZCOMP=1
  334. done
  335. # Setup for bun
  336. if has_bin bun; then
  337. F="$ZSH_SITE_FUNC_DIR/_bun"; [ -f "$F" ] || curl -s -o "$F" "https://raw.githubusercontent.com/oven-sh/bun/refs/heads/main/completions/bun.zsh"
  338. source "$F"
  339. fi
  340. # Setup for rustup
  341. if [ "${RUSTUP_BIN:=$(get_bin rustup)}" ]; then
  342. # Add rustup completions
  343. F="$ZSH_SITE_FUNC_DIR/_rustup"; [ -f "$F" ] && ! [ "$RUSTUP_BIN" -nt "$F" ] || rustup completions zsh > "$F"
  344. source "$F"
  345. fi
  346. # Setup for cargo
  347. F="$HOME/.cargo/env"; ! [ -f "$F" ] || source "$F"
  348. if [ "${CARGO_BIN:=$(get_bin cargo)}" ]; then
  349. # Add cargo completions
  350. F="$ZSH_SITE_FUNC_DIR/_cargo"; [ -f "$F" ] && ! [ "$CARGO_BIN" -nt "$F" ] || rustup completions zsh cargo > "$F"
  351. # source "$F" -- TODO: fix this… it's not working on my zsh for some reason
  352. fi
  353. # Setup for dprint
  354. if [ "${DPRINT_BIN=$(get_bin dprint)}" ]; then
  355. # Add dprint completions
  356. F="$ZSH_SITE_FUNC_DIR/_dprint"; [ -f "$F" ] && ! [ "$DPRINT_BIN" -nt "$F" ] || dprint completions zsh > "$F"
  357. source "$F"
  358. fi
  359. # recompile completions
  360. [ -z "$RERUN_ZCOMP" ] || compinit
  361. else
  362. # check window size after each command
  363. shopt -s checkwinsize
  364. # tab completion FTW
  365. if [ "$OS" = "Darwin" ]; then
  366. F="$BREW_PREFIX/etc/bash_completion"; ! [ -f "$F" ] || source "$F"
  367. F="$(xcode-select -p)/usr/share/git-core/git-completion.$SHELL_NAME"; ! [ -f "$F" ] || source "$F"
  368. else
  369. F="/etc/bash_completion"; ! [ -f "$F" ] || source "$F"
  370. fi
  371. F="$HOME/.liquidprompt/liquidprompt"; ! [ -f "$F" ] || source "$F"
  372. fi
  373. # gimme gimme
  374. [ -d "$HOME/.gimme" ] || curl -fsSL "https://github.com/KylePDavis/gimme/raw/master/gimme" | bash -
  375. # Remove any PATH duplicates for simplicity
  376. export PATH="$(echo "$PATH" | tr : '\n' | awk '!has[$0]++' | tr '\n' :)"
  377. # gimme completions
  378. F="$HOME/.gimme/gimme"; ! [ -f "$F" ] || source "$F"