-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbashrc
More file actions
362 lines (312 loc) · 12.4 KB
/
Copy pathbashrc
File metadata and controls
362 lines (312 loc) · 12.4 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
#!/bin/bash
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
export BASH_SILENCE_DEPRECATION_WARNING=1
#-------------------------------------------------------------------------------
# ENVIRONMENT VARIABLES
#-------------------------------------------------------------------------------
export EDITOR='nvim'
export GOPATH=$HOME/go
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LESSCHARSET='utf-8'
export FTP_PASSIVE=1
# export CDPATH=.:~:~/src
export MANPAGER='nvim +Man!'
path_remove() {
local dir entry new_path
dir="$1"
[ -n "$dir" ] || return
local IFS=:
for entry in $PATH; do
[ "$entry" = "$dir" ] && continue
new_path="${new_path:+$new_path:}$entry"
done
PATH="$new_path"
}
path_prepend() {
local dir i
for (( i=$#; i>=1; i-- )); do
dir="${!i}"
[ -n "$dir" ] || continue
path_remove "$dir"
PATH="$dir${PATH:+:$PATH}"
done
export PATH
}
path_append() {
local dir
for dir in "$@"; do
[ -n "$dir" ] || continue
path_remove "$dir"
PATH="${PATH:+$PATH:}$dir"
done
export PATH
}
path_prepend_args=("$HOME/.dotfiles/bin")
if [[ "$OSTYPE" == darwin* ]]; then
path_prepend_args+=(
"/opt/homebrew/bin"
"/opt/homebrew/sbin"
"/opt/homebrew/opt/curl/bin"
"/opt/homebrew/opt/node@24/bin"
)
fi
path_prepend_args+=("$HOME/.nix-profile/bin" "$HOME/.local/bin" "$HOME/bin" "$GOPATH/bin")
path_prepend "${path_prepend_args[@]}"
unset path_prepend_args
path_append "/usr/local/go/bin"
# For xterm titles
export PROMPT_COMMAND='echo -ne "\033]0;${HOSTNAME}: ${PWD/$HOME/~}\007"'
# LS_COLORS
export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:'
#-------------------------------------------------------------------------------
# BASH HISTORY
#-------------------------------------------------------------------------------
# Preserve bash history in multiple terminal windows
# from http://unix.stackexchange.com/a/48113
export HISTCONTROL=ignoredups:erasedups # no duplicate entries
export HISTSIZE=10000000 # big big history
export HISTFILESIZE=10000000 # big big history
export SHELL_SESSION_HISTORY=0
shopt -s histappend # append to history, don't overwrite it
# Keep cross-session sync while avoiding full reload each prompt
export PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
#-------------------------------------------------------------------------------
# SHELL PROMPT
#-------------------------------------------------------------------------------
GRAY="\[\033[1;30m\]"
LIGHT_GRAY="\[\033[0;37m\]"
CYAN="\[\033[0;36m\]"
LIGHT_CYAN="\[\033[1;36m\]"
NO_COLOR="\[\033[0m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RED="\[\033[1;31m\]"
shorten_path() {
# Replace the home directory with ~ (handles logical/physical path mismatch)
local path home_path home_real pwd_real
path="$PWD"
home_path="$HOME"
home_real="$(cd "$home_path" 2>/dev/null && pwd -P)"
pwd_real="$(pwd -P 2>/dev/null)"
if [[ "$path" == "$home_path" ]]; then
path="~"
elif [[ "$path" == "$home_path/"* ]]; then
path="~/${path#"$home_path/"}"
elif [ -n "$home_real" ] && [[ "$path" == "$home_real" ]]; then
path="~"
elif [ -n "$home_real" ] && [[ "$path" == "$home_real/"* ]]; then
path="~/${path#"$home_real/"}"
elif [ -n "$home_real" ] && [ -n "$pwd_real" ] && [[ "$pwd_real" == "$home_real" ]]; then
path="~"
elif [ -n "$home_real" ] && [ -n "$pwd_real" ] && [[ "$pwd_real" == "$home_real/"* ]]; then
path="~/${pwd_real#"$home_real/"}"
fi
if [ "$path" = "/" ]; then
echo -n "/"
return
fi
local IFS="/"
local -a parts
read -r -a parts <<< "$path"
local new_path=""
local len=${#parts[@]}
for (( i=0; i<len; i++ )); do
if [[ $i == $((len-1)) ]]; then
# If it's the last element, add the full name
new_path+="${parts[$i]}"
else
# Else, add the first character followed by a /
new_path+="${parts[$i]:0:1}/"
fi
done
echo -n "$new_path"
}
get_git_branch() {
# Check if the current directory is in a git repository
if git -c core.useBuiltinFSMonitor=false rev-parse --git-dir > /dev/null 2>&1; then
# Echo the branch name
echo -n "[$(git -c core.useBuiltinFSMonitor=false branch --show-current)]"
fi
}
export PS1="$GRAY($YELLOW\u$GRAY@$CYAN\h$GRAY)--($LIGHT_CYAN\$(shorten_path)$GRAY)--(\A)$( echo -n " $GRAY\$(get_git_branch)$GRAY")\n$WHITE\$$NO_COLOR "
#-------------------------------------------------------------------------------
# ALIASES
#-------------------------------------------------------------------------------
alias base64decode="perl -mMIME::Base64 -e 'while(<>){print MIME::Base64::decode_base64(\$_)}'"
alias base64encode="perl -mMIME::Base64 -e 'while(<>){print MIME::Base64::encode_base64(\$_)}'"
c() { MAX_THINKING_TOKENS=0 claude --dangerously-skip-permissions --no-session-persistence -p "$*" --model haiku; }
copus() { claude --dangerously-skip-permissions --no-session-persistence -p "$*" --model opus; }
alias cc='claude --effort xhigh'
alias ccd='claude --dangerously-skip-permissions --effort xhigh'
alias ccm='claude --effort max'
alias ccdm='claude --dangerously-skip-permissions --effort max'
cx() {
command codex --profile shared -c 'model_reasoning_effort="xhigh"' "$@"
}
cxd() {
command codex --profile shared -c 'model_reasoning_effort="xhigh"' --dangerously-bypass-approvals-and-sandbox "$@"
}
# Codex has no "max" effort; max is the closest equivalent.
cxm() {
command codex --profile shared -c 'model_reasoning_effort="max"' "$@"
}
cxdm() {
command codex --profile shared -c 'model_reasoning_effort="max"' --dangerously-bypass-approvals-and-sandbox "$@"
}
alias ocdm='opencode --auto'
alias unicodedecode="sed 's/.*/\"&\"/' | jq -r ."
alias curlheader='curl -s -D - -o /dev/null'
alias grep="grep --exclude-dir vendor --color=auto"
alias less='less -r'
alias p='perl'
alias python='python3'
alias pythonserver='python3 -m http.server'
alias sova="source .venv/bin/activate"
alias tmux='tmux -2'
alias urldecode="perl -MCGI::Util=unescape -e'while(<>){chop;print unescape(\$_).\"\\n\";}'"
alias urlencode="perl -MCGI::Util=escape -e'while(<>){chop;print escape(\$_).\"\\n\";}'"
alias v='vi $(find . -path "./.git*" -prune -o -print | peco)'
alias vi='nvim'
alias vi_nofmt='vim --cmd "let g:go_fmt_autosave = 0"'
alias xml_pp='xmllint --format -'
brewdump() {
{
brew tap | sed 's/^/tap "/' | sed 's/$/"/'
brew leaves | sed 's/^/brew "/' | sed 's/$/"/'
brew list --cask | sed 's/^/cask "/' | sed 's/$/"/'
}
}
alias brewup='brew bundle --file=~/.dotfiles/Brewfile'
#-------------------------------------------------------------------------------
# KEYBINDINGS
#-------------------------------------------------------------------------------
set -o vi
bind -m vi-insert "\C-l":clear-screen
bind -m vi-insert "\C-p":previous-history
bind -m vi-insert "\C-n":next-history
#-------------------------------------------------------------------------------
# SHELL EXTENSIONS (Completion, FZF, etc.)
#-------------------------------------------------------------------------------
# Bash Completion
if [[ "$OSTYPE" =~ ^darwin ]]; then
BREWPATH=/opt/homebrew/bin/brew
if [[ "$(arch)" == "i386" ]]; then
BREWPATH=/usr/local/bin/brew
fi
if [ ! -x "$BREWPATH" ] && command -v brew >/dev/null 2>&1; then
BREWPATH="$(command -v brew)"
fi
if [ -x "$BREWPATH" ]; then
BREW_PREFIX="$("$BREWPATH" --prefix)"
if [ -f "$BREW_PREFIX/etc/bash_completion" ]; then
# shellcheck source=/dev/null
. "$BREW_PREFIX/etc/bash_completion"
fi
fi
else
if [ -f "$HOME/.bash-completion/bash_completion" ]; then
# shellcheck source=/dev/null
. "$HOME/.bash-completion/bash_completion"
fi
fi
# FZF (load exactly one source to avoid duplicate key bindings/completion)
if [[ "$OSTYPE" == darwin* ]] && [ -d "/opt/homebrew/opt/fzf/shell" ]; then
[ -f "/opt/homebrew/opt/fzf/shell/key-bindings.bash" ] && source "/opt/homebrew/opt/fzf/shell/key-bindings.bash"
[ -f "/opt/homebrew/opt/fzf/shell/completion.bash" ] && source "/opt/homebrew/opt/fzf/shell/completion.bash"
elif [ -f "$HOME/.fzf.bash" ]; then
# shellcheck source=/dev/null
source "$HOME/.fzf.bash"
elif [ -f "$HOME/.fzf/shell/key-bindings.bash" ] || [ -f "$HOME/.fzf/shell/completion.bash" ]; then
[ -f "$HOME/.fzf/shell/key-bindings.bash" ] && source "$HOME/.fzf/shell/key-bindings.bash"
[ -f "$HOME/.fzf/shell/completion.bash" ] && source "$HOME/.fzf/shell/completion.bash"
else
[ -f "$HOME/.nix-profile/share/fzf/key-bindings.bash" ] && source "$HOME/.nix-profile/share/fzf/key-bindings.bash"
[ -f "$HOME/.nix-profile/share/fzf/completion.bash" ] && source "$HOME/.nix-profile/share/fzf/completion.bash"
fi
# Cargo
if [[ -f "$HOME/.cargo/env" ]]; then
. "$HOME/.cargo/env"
fi
# zoxide
if command -v zoxide >/dev/null 2>&1; then
eval "$(zoxide init bash)"
alias cd=z
fi
# eza
if command -v eza >/dev/null 2>&1; then
alias ls='eza --no-git --no-quotes --color=auto'
export EZA_CONFIG_DIR=~/.config/eza
else
alias ls='ls --color=auto'
fi
#-------------------------------------------------------------------------------
# OS-SPECIFIC CONFIGURATION
#-------------------------------------------------------------------------------
if [[ "$OSTYPE" =~ ^darwin ]]; then
# GNU Coreutils
if [ -d "/usr/local/opt/coreutils/libexec/gnubin" ]; then
path_prepend "/usr/local/opt/coreutils/libexec/gnubin"
export MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"
elif [ -d "/opt/homebrew/opt/coreutils/libexec/gnubin" ]; then
path_prepend "/opt/homebrew/opt/coreutils/libexec/gnubin"
export MANPATH="/opt/homebrew/opt/coreutils/libexec/gnuman:$MANPATH"
fi
# Homebrew
if [ -n "$BREWPATH" ] && [ -x "$BREWPATH" ]; then
eval "$("$BREWPATH" shellenv)"
fi
# ls alias for macOS
# alias ls='/bin/ls -G'
fi
#-------------------------------------------------------------------------------
# NIX & HOME-MANAGER
#-------------------------------------------------------------------------------
home-manager-update() {
if [ -z "$1" ]; then
echo "Usage: home-manager-update <macbook|office>"
return 1
fi
[[ $(ulimit -n) -lt 65536 ]] && ulimit -n 65536
(
cd ~/.config/home-manager || exit 1
rm -rf /homeless-shelter && nix flake update && rm -rf /homeless-shelter && home-manager switch --flake ".#$1"
)
}
nix-cache-clear() {
rm -rf ~/.cache/nix/flake-registry.json ~/.cache/nix/fetcher-cache-v2
echo "Nix flake cache cleared"
}
alias home-manager-diff="nix profile diff-closures --profile ~/.local/state/nix/profiles/home-manager"
home-manager-gc() {
home-manager expire-generations "-1 days" && nix-collect-garbage --delete-older-than 1d
}
nix-darwin-update() {
(
cd ~/.config/nix-darwin || exit 1
nix flake update && sudo nix run nix-darwin -- switch --flake .#mac
)
}
#-------------------------------------------------------------------------------
# LOCAL SECRETS
#-------------------------------------------------------------------------------
if [ -f "$HOME/.bashrc.secrets" ]; then
# shellcheck source=/dev/null
source "$HOME/.bashrc.secrets"
fi
#-------------------------------------------------------------------------------
# LOCAL/HOSTNAME-SPECIFIC OVERRIDES
#-------------------------------------------------------------------------------
if [ -f "$HOME/.bashrc.$(hostname -s)" ]; then
# shellcheck source=/dev/null
source "$HOME/.bashrc.$(hostname -s)"
fi
#-------------------------------------------------------------------------------
# When called by LLM
#-------------------------------------------------------------------------------
if [ -n "$CURSOR_AGENT" ]; then
unset HISTFILE
export PS1="$ "
unalias ls
fi