forked from jaybosamiya/dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdot_zshrc
608 lines (550 loc) · 19.9 KB
/
dot_zshrc
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
# Early direnv initialization, required due to how powerlevel10k's instant prompt
# works. Since direnv may produce output in some directories, we need to do this
# bit early, before the instant prompt is enabled.
(( ${+commands[direnv]} )) && emulate zsh -c "$(direnv export zsh)"
# mise (https://github.com/jdxcode/mise) initialization to support automatically
# setting up different versions of various tools like python, node, etc.
#
# This needs to be run _after_ the direnv activation, but before the
# powerlevel10k instant prompt.
(( ${+commands[mise]} )) && eval "$(mise activate zsh)"
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Actually enable direnv
(( ${+commands[direnv]} )) && emulate zsh -c "$(direnv hook zsh)"
# Need to migrate some settings from old machine
export ZSH=$HOME/.oh-my-zsh
if [[ -f ~/.p10k.zsh ]]; then
ZSH_THEME="powerlevel10k/powerlevel10k"
else
ZSH_THEME="robbyrussell"
fi
plugins=(git command-not-found rust pass just F-Sy-H)
source $ZSH/oh-my-zsh.sh || git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
if command -v nix-index >/dev/null; then source ~/.nix-command-not-found.sh || echo "Might want to stow nix-command-not-found for niceties"; fi
# Make `--help` auto-scrolling on all commands. The `+` is needed to prevent
# `alias` from thinking that the `--help` is part of the arguments to `alias`.
#
# Note: since we are adding a pipe, many programs will detect that it is not a
# TTY anymore, and thus not output things in color; to handle this, we can pass
# `unbuffer` (from `sudo apt install expect`) at the start of the command
# (e.g., `unbuffer foo --help`) to bring back colors. We _could_ handle this via
# `zle` to overwrite `accept-line` but that feels very weird when it happens, so
# I have elected not to keep that part around.
#
# Potentially worth considering: using a suffix alias (for say, `.help`) that runs a
# function that will then do the unbuffer _and_ less pipe stuff; not sure it works though
#alias -g + --help='--help |& less -RF'
# Add a convenient Control-H binding that does useful things for --help
bindkey '^H' __helper_function_for_ctrl_h
__helper_function_for_ctrl_h() {
local initial_spaces="${BUFFER%%[^ ]*}"
BUFFER="${initial_spaces}unbuffer ${BUFFER##$initial_spaces} --help | less -RF"
CURSOR=${#BUFFER}
zle redisplay
}
zle -N __helper_function_for_ctrl_h
# Switch Meta-l back to lower-caseing things, rather than running "ls^J" for whatever reason
bindkey '^[l' down-case-word
# Useful utility function
function _unwrap_or {
default="$1"
shift
case x$# in
x0) echo "$default" ;;
x1) echo "$1" ;;
*) echo "Too many arguments; using '$1'" 1>&2; echo "$1" ;;
esac
}
# Custom aliases
function n {
case ${HOST%%.*} in
eden) function n { nautilus "$(_unwrap_or . "$@")" &! } ;;
Valhalla|asphodel|magmell) function n { explorer.exe "$(_unwrap_or . "$@")" } ;;
arcadia) function n { open "$(_unwrap_or . "$@")" } ;;
*) function n { echo "Unknown machine. n is unbound." } ;;
esac
n "$@"
}
alias units='units -1v' # verbose single line output for GNU units
if [[ "$HOST" == "Valhalla" ]]; then
alias screenperm='sudo /etc/init.d/screen-cleanup start' # Needed for WSL2 when `screen` gives the "Cannot make directory '/run/screen': Permission denied" error
fi
# Make it easier to open things on WSL2
#
# Relevant: `apt install wslu`
#
# Also, `wslview -r` is useful to set up browser stuff
if command -v wslview >/dev/null; then
alias open=wslview
fi
# Get completions for jujutsu if available
if command -v jj >/dev/null; then
source <(jj util completion zsh)
fi
# Make it easy to clear out any existing open SSH sockets
function ssh-clear {
# Ask for confirmation on each file in ~/.ssh/*.sock
rm -i ~/.ssh/*.sock
}
# A convenience function that is both `cat` and `ls`, based upon what is being looked at
function c {
if [ "$1" = "-l" ]; then
local LSEXTRAARGS="-l"
shift
elif [ "$1" = "-al" ]; then
local LSEXTRAARGS="-al"
shift
fi
if [ -e "$1" ]; then
if [ -d "$1" ]; then
ls $LSEXTRAARGS "$1";
else
cat "$1";
fi
else
echo "$1 does not exist" 1>&2;
return 1
fi
}
alias less="less --chop-long-lines"
# Set up zoxide if it exists to make cd easier
#
# Install using `cargo install zoxide --locked`
if command -v zoxide >/dev/null; then
eval "$(zoxide init zsh)"
else
function z () { 1>&2 echo 'No zoxide. Install via `cargo install zoxide --locked`'; return 1 }
function zi () { z }
fi
if command -v rg >/dev/null; then
function rg() {
if [ -t 1 ]; then
command rg -p "$@" | less -RFX
else
command rg "$@"
fi
}
fi
if command -v phd >/dev/null; then
function phd() {
if [ -t 1 ]; then
command phd --color=always "$@" | less -RFX
else
command phd "$@"
fi
}
fi
if command -v cargo >/dev/null; then
function cargo() {
if [ "$1" = "check" ] || [ "$1" = "clippy" ]; then
if [ -t 1 ] && [ -t 2 ]; then
CARGO_TERM_COLOR=always command cargo "$@" |& less -RFX
fi
else
command cargo "$@"
fi
}
fi
# Replace `cat` with `bat` when available
#
# Set up bcat as a quick alias to cat, to quickly access cat if bat doesn't make sense for some use case
if command -v bat >/dev/null; then
alias cat=bat
alias bcat=/bin/cat
fi
# If `jq` exists, add a helper function `jqi` which runs `ijq` (install via `nix-env -iA nixpkgs.ijq`)
# switching around the relevant streams, so that we can get the actual filter usable in jq out
if command -v jq >/dev/null; then
function jqi() {
# ijq prints the output to stdout, and filter to stderr
# We just kill stdout, and move stderr to stdout instead
ijq 2>&1 1>/dev/null "$@"
}
fi
# Upload a file to allow temporary download for 24 hours
function upload_temporary() {
if [ $# -lt 1 ]; then
echo "Usage: $0 [--autodestroy] {filename}" 1>&2
echo " Uploads a file (to oshi.at) to be available for download for 24 hours" 1>&2
echo " --autodestroy causes file to delete itself on first download" 1>&2
return -1
fi
local AUTODESTROY=""
if [ "$1" = "--autodestroy" ]; then
AUTODESTROY="&autodestroy=1"
shift
fi
curl -T "$1" "https://oshi.at/?expire=1440${AUTODESTROY}"
}
# Make it easier to read out what/where commands are after doing a
# `which` on them
function cwhich() {
ls -l $(which "$1");
file $(which "$1");
cat $(which "$1");
}
if command -v delta >/dev/null; then
function diff() {
# Use delta (from `cargo install git-delta`) to better colorize
# output, when at the terminal. Also, automatically enter into a
# pager if needed (done by delta).
if [ -t 1 ]; then
command diff -u "$@" | delta
else
command diff -u "$@"
fi
}
fi
if command -v yt-dlp >/dev/null; then
alias music-dl='yt-dlp --audio-format=mp3 --extract-audio --metadata-from-title "%(artist)s - %(title)s"'
alias twitch-dl="yt-dlp -o '%(id)s-%(title)s.%(ext)s'"
fi
case "$OSTYPE" in
darwin*)
alias ls='ls -h -G --color=auto' # Human readable file sizes, and color :)
;;
linux*)
alias ls='ls -h --color=tty' # Human readable file sizes, and color :)
;;
*)
echo "Unknown OS type $OSTYPE"
;;
esac
# Convenience function to enable coredumps
case "$OSTYPE" in
darwin*)
function enable_coredumps() {
if [ -x "$1" ]; then
if touch "/cores/tmp" && rm "/cores/tmp"; then
local TMP_ENTITLEMENTS="$(mktemp -d)"
/usr/libexec/PlistBuddy -c "Add :com.apple.security.get-task-allow bool true" "$TMP_ENTITLEMENTS/tmp.entitlements" >/dev/null
# Perform ad-hoc signing (not using any specific
# identity; this is quite restrictive, see man
# page for `codesign`, but prob good enough)
codesign --sign - --force --entitlements "$TMP_ENTITLEMENTS/tmp.entitlements" "$1" >/dev/null 2>&1
rm -f "$TMP_ENTITLEMENTS/tmp.entitlements"
rmdir "$TMP_ENTITLEMENTS"
ulimit -c unlimited
echo "[i] Core dumping for '$1' enabled. Cores will be dumped to /cores/."
echo ""
echo " Reminder: clean out that directory semi-regularly, since cores can be massive."
else
echo "[!] Insufficient permissions on /cores. Fix by running:" 1>&2
echo "" 1>&2
echo " sudo chmod 1777 /cores" 1>&2
echo "" 1>&2
echo "[i] To reset back to default, use 0755" 1>&2
return 1
fi
else
echo "Usage: enable_coredumps {executable}" 1>&2
return 1
fi
}
;;
linux*)
function enable_coredumps() {
ulimit -c unlimited
}
;;
*)
echo "Unknown OS type $OSTYPE"
;;
esac
if command -v gdb >/dev/null; then
alias gdb='gdb -q'
alias peda='gdb -q -ex peda'
alias pwngdb='gdb -q -ex pwngdb'
alias pwndbg='gdb -q -ex pwndbg'
alias gef='gdb -q -ex gef'
fi
if command -v docker >/dev/null; then
alias dockerubuntu='docker run --rm -it -v "$(pwd):/connect" --cap-add=SYS_PTRACE ubuntu' # Runs a docker container in current spot, and connects it to /connect ; enables ptrace
fi
# limactl allows nice management of nerdctl docker-like instances
# across different archs on a Mac.
#
# See the `lima` stow to have the right setup for the VMs.
#
# The `--cap-add=SYS_PTRACE` allows ptrace, thereby allowing GDB. The
# `--security-opt seccomp=unconfined` is to allow disabling ASLR
# within GDB.
if command -v limactl >/dev/null; then
alias limax86='limactl shell x86instance nerdctl run --rm -it --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v "$(pwd):/connect"'
alias limaarm='limactl shell default nerdctl run --rm -it --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v "$(pwd):/connect"'
fi
if command -v fzf >/dev/null; then
alias fzf="fzf --layout=reverse-list --multi"
fi
if command -v apt-mark >/dev/null; then
alias manually-installed-to-auto='sudo apt-mark auto'
fi
if command -v asciinema >/dev/null; then
alias record-term='asciinema rec --yes -i 1 --title'
# TODO: Also look into termtosvg
fi
function e() {
if [[ ${HOST%%.*} == "magmell" && ! -L "/run/user/1000/wayland-0" ]]; then
echo "Wayland shenanigans have occurred. Setting it up again..."
ln -s /mnt/wslg/runtime-dir/wayland-0* /run/user/1000/
fi
case "$OSTYPE" in
darwin*)
if [ $# = 0 ]; then
emacsclient --create-frame --no-wait . &!
else
emacsclient --create-frame --no-wait "$@" &!
fi
;;
linux*)
if [ $# = 0 ]; then
emacs . &!
elif [ "$1" = "-nw" ]; then
echo "Don't run 'e -nw'. It'll send it into the background lol."
local choice
if read -q "choice?Press y to open it in foreground: "; then
if [ $# = 1 ]; then
emacs -nw .
else
emacs "$@"
fi
else
echo "" 1>&2
echo "Got '$choice'. Not doing anything..." 1>&2
return 1
fi
else
emacs "$@" &!
fi
;;
*)
echo "Unknown OS type $OSTYPE"
;;
esac
}
export ALTERNATE_EDITOR='emacs' # Opens emacs if no emacs server is already started
if command -v ncdu >/dev/null; then
alias ncdu='ncdu -rx' # Make ncdu safe (no delete) and fast (don't cross FS boundary)
fi
function clip {
case ${HOST%%.*} in
eden) function clip { xclip -selection clipboard "$@" } ;;
Valhalla|asphodel|magmell) function clip { clip.exe "$@" } ;;
arcadia) function clip { pbcopy "$@" } ;;
*) function clip {
echo "Unknown machine. Attempting heuristic to discover clipboard.";
case "$OSTYPE" in
darwin*) pbcopy "$@" ;;
linux*) xclip -selection clipboard "$@" ;;
*) echo "Unknown OS type $OSTYPE" ;;
esac
} ;;
esac
clip "$@"
}
if command -v axel >/dev/null; then
alias axel='axel -a -n 10'
fi
# Make things easy to copy over into markdown/slack :)
function shcopy() {
export PS1='\`\`\`
\`\`\`
$ '
bash
}
function comment_aux() {
if [ "$#" -ne 3 ]; then
echo "Usage: comment_aux {start} {comment-text} {end}"
return 1
fi
figlet "$2" | awk '{print "'$1'" $0 "'$3'"}'
}
function comment_c() { comment_aux '// ' "$(echo "$@")" '' }
function comment_cpp() { comment_aux '/* ' "$(echo "$@")" ' */' }
function comment_ocaml() { comment_aux '(* ' "$(echo "$@")" ' *)' }
function comment_shell() { comment_aux '# ' "$(echo "$@")" '' }
function public-ip() {
curl https://f0xtr0t.xyz/ip
}
function latexmakefile() {
# Drop the super nice Makefile I've written into current directory
wget --no-clobber https://raw.githubusercontent.com/jaybosamiya/latex-paper-template/master/Makefile
}
function dockermakefile() {
# Drop the super nice Makefile I've written into current directory
wget --no-clobber https://git.jaybosamiya.com/build/docker-makefile/raw/branch/master/Makefile
}
function waitmake() {
case ${HOST%%.*} in
eden|Valhalla)
function waitmake() {
while true; do
inotifywait -e modify -r .
make "$@"
sleep 0.1
done
}
waitmake "$@"
;;
arcadia)
function waitmake() {
while true; do
fswatch --one-event --exclude '\.#.*' --exclude '.*~' --recursive .
sleep 0.1 # Give time to kill via Ctrl-C
make "$@"
sleep 0.1
done
}
waitmake "$@"
;;
*)
echo 'Unknown machine. "waitmake" is unbound.'
;;
esac
}
if command -v task >/dev/null; then
alias t='task'
alias ta='task add'
alias tm='task modify'
alias tn='task next'
alias ts='task start'
function _tt() {
task ready 2>/dev/null | \
awk '$1~/^[0-9]+$/{$1="TODO[" $1 "]"; $2=""; print $0}' | \
rev | awk '{$1=""; print $0}' | rev
# TODO: Use the JSON export and write a nicer output
}
function tt() {
_tt || echo "No tasks"
}
function td() {
task done "$@" && tt
}
alias tph='task modify scheduled:"$(date -Iseconds --date='"'"'next hour'"'"')"'
function tpt() {
task modify "$2" scheduled:"$(date -Iseconds --date=$1)"
}
alias tpd='task modify scheduled:tomorrow'
function tpw() {
task modify "$1" scheduled:"$(date -Iseconds --date='next week')"
}
# Show the next set up of tasks upon zsh load, if they exist; but
# don't display of recording
if [ -z "$ASCIINEMA_REC" ]; then
_tt
true # Prevent failure if no task exists
fi
fi
function gitignore() {
curl -L -s --output .gitignore https://www.gitignore.io/api/c++,vim,ocaml,latex,emacs,python,sublimetext,visualstudio,visualstudiocode,linux,mac,windows
}
# Create a temporary directory, with current time until minutes, and
# link /tmp/tempdir to it
function tempdirnew() {
DIR="/tmp/tmp.$(date +%F/%H-%M-%S)"
mkdir -p "$DIR"
if [ -d /tmp/tempdir ]; then
rm -f /tmp/tempdir.old
mv /tmp/tempdir /tmp/tempdir.old
fi
ln -s "$DIR" /tmp/tempdir
cd /tmp/tempdir
echo "$DIR"
}
# Jump to tempdir
function tempdir() {
if [ -d /tmp/tempdir ]; then
cd /tmp/tempdir/$@
else
tempdirnew
fi
}
if command -v wdiff >/dev/null; then
# Colorized wdiff
function cwdiff() {
wdiff -n -w $'\033[1;31m' -x $'\033[0m' -y $'\033[1;32m' -z $'\033[0m' -s "$1" "$2"
}
# Compare two texts, and nicely word-diff them
function 2compare() {
A="$(mktemp /tmp/text1.XXXXXX)"
B="$(mktemp /tmp/text2.XXXXXX)"
echo "Enter text1 (press Enter,Ctrl+D when done):"
cat > "$A"
echo "Enter text2 (press Enter,Ctrl+D when done):"
cat > "$B"
echo "Comparing..."
cwdiff "$A" "$B"
rm -f "$A" "$B"
}
fi
function duplicate-repo() {
USAGE="Usage: duplicate-repo {from} {to}"
[ -z "$1" ] && echo $USAGE && return 1
[ -z "$2" ] && echo $USAGE && return 1
FROM="$1"
TO="$2"
DIR="$(mktemp -d /tmp/tmp-duplicate-XXXXXX)"
git clone --bare "$FROM" "$DIR" || return 2
pushd "$DIR"
git push --mirror "$TO" || (popd; return 3)
popd
rm -rf "$DIR"
echo "Done duplicating repository"
}
# Enable the cod completion daemon
#
# See https://github.com/dim-an/cod
# source <(cod init $$ zsh)
which cod >/dev/null && source <(cod init $$ zsh) || true
# Enable fish like auto-suggestions when available
# Install via [sudo apt install zsh-autosuggestions]
#
# Make sure not to enable them when recording for asciinema, to
# prevent accidental information leakage.
if [ -z "$ASCIINEMA_REC" ]; then
test -f /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh && source /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
test -f ~/.nix-profile/share/zsh-autosuggestions/zsh-autosuggestions.zsh && source ~/.nix-profile/share/zsh-autosuggestions/zsh-autosuggestions.zsh
fi
# Track directories so new tab can open in same directory. Do so only on Windows
# Terminal, which needs this.
#
# Only works properly if the correct profile is selected ("source":
# "Windows.Terminal.Wsl") within Windows Terminal's settings.json as the one for
# Ubuntu (it should NOT have a command line set). Additionally, out of pure
# convenience, it is helpful to bind Ctrl+Shift+T to "Duplicate tab" (I also
# keep it bound to Ctrl+Shift+D which is its default); I also move away "New
# Tab" to be on Ctrl+Alt+Shift+T.
if test -n "$WT_SESSION"; then
# See https://learn.microsoft.com/en-us/windows/terminal/tutorials/new-tab-same-directory
__keep_current_path() { printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")" }
precmd_functions+=(__keep_current_path)
fi
# connect up to cargo
if [ -f ~/.cargo/env ]; then
. "$HOME/.cargo/env"
fi
# If atuin exists, use it
if command -v atuin >/dev/null; then
eval "$(atuin init zsh --disable-up-arrow)"
fi
if [ -d "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/F-Sy-H" ]; then
# We have the F-Sy-H plugin, we'll just use it
else
# We can pull in F-Sy-H
echo "[!] Cloning F-Sy-H..."
git clone https://github.com/z-shell/F-Sy-H.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/F-Sy-H
# Or (commented out right now, but if I decide to move away from F-Sy-H, this exists):
#
# Enable nice syntax highlighting if available
# Install via [sudo apt install zsh-syntax-highlighting]
# NOTE: This MUST be at the end of .zshrc
#test -f /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh && source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
#test -f ~/.nix-profile/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh && source ~/.nix-profile/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
fi
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh