-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathfunctions.fish
More file actions
324 lines (261 loc) · 10.6 KB
/
functions.fish
File metadata and controls
324 lines (261 loc) · 10.6 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
function subl --description 'Open Sublime Text'
if test -d "/Applications/Sublime Text.app"
"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" $argv
else if test -d "/Applications/Sublime Text 2.app"
"/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" $argv
else if test -x "/opt/sublime_text/sublime_text"
"/opt/sublime_text/sublime_text" $argv
else if test -x "/opt/sublime_text_3/sublime_text"
"/opt/sublime_text_3/sublime_text" $argv
else
echo "No Sublime Text installation found"
end
end
function solve_all_conflicts --description 'try to solve all current git conflicts with mergiraf'
set before (git diff --name-only --diff-filter=U | wc -l)
for file in (git diff --name-only --diff-filter=U)
set output (mergiraf solve --keep-backup=false "$file" 2>&1)
echo "$output"
if string match -q -- "*Solved all conflicts*" "$output"
git add "$file"
echo "now all resolved: $file"
end
end
set after (git diff --name-only --diff-filter=U | wc -l)
echo "Conflicted files: $before ==> $after"
end
# git-recent with experimental worktree support
function recent
set -l o (~/code/git-recent/git-recent $argv)
if test -d "$o"
cd $o
else if test -n "$o"
echo $o
end
end
function killprocess --description 'Kill process that user selects in fzf (from ps aux output)'
set -l pid (ps aux | fzf -m --header-lines=1 | awk '{print $2}')
if test -n "$pid"
echo "Killing processes: $pid"
kill -9 $pid
end
end
function killport --description 'Select a port to kill, by pid, port, or command line'
# Function to get the command line for a given PID
function get_command -a pid
ps -p $pid | awk 'NR>1 {for (i=4; i<=NF; i++) {printf "%s ", $i}; print ""}'
end
# Find listening processes, get commands, and format output
lsof -iTCP -sTCP:LISTEN -P | awk '{print $2, $9}' | uniq | tail -n +2 | \
while read -l pid port
set -l command (get_command $pid)
set -l port (string pad -w 8 (string replace 'localhost' '' $port))
set -l pid (string pad --right -w 6 $pid)
echo -e "$pid $port $command" | column
end | \
# Pipe the output to fzf for selection. Grab pid and show pstree
fzf --exact --tac --preview 'pstree -p (echo {} | awk "{print $2}")' --preview-window=down,30% --header "Select a process to kill (PID Command Port):" | \
# Kill the selected process
awk '{print $1}' | xargs -r kill -9
end
# aliases so i can run a cmd somewhere when another one finishes. usage:
# waitfordone && command # in one session
# long_running_command; done # in another
alias done="echo done > /tmp/done_pipe"
alias waitfordone="mkfifo /tmp/done_pipe && read -r line < /tmp/done_pipe"
function clone --description "clone something, cd into it. install it."
git clone --depth=1 $argv[1]
cd (basename $argv[1] | sed 's/.git$//')
yarn install
end
function renameurldecode
for file in *
set -l original $file
set -l decoded (python3 -c "import urllib.parse; print(urllib.parse.unquote_plus('$original'))")
if test "$original" != "$decoded"
mv "$original" "$decoded"
end
end
end
function notif --description "make a macos notification that the prev command is done running"
# osascript -e 'display notification "hello world!" with title "Greeting" sound name "Submarine"'
osascript \
-e "on run(argv)" \
-e "return display notification item 1 of argv with title \"command done\" sound name \"Submarine\"" \
-e "end" \
-- "$history[1]"
end
function beep --description "make two beeps"
echo -e '\a'; sleep 0.1; echo -e '\a';
end
function all_binaries_in_path --description \
"list all binaries available in \$PATH (incl conflicts). pipe it to grep. top-most are what's used, in case of conflicts"
# based on https://unix.stackexchange.com/a/120790/110766. and then made it faster. needs `brew install findutils`
gfind -L $PATH -maxdepth 1 -executable -type f 2>/dev/null
end
function all_binaries_in_path_grep --description "run all_binaries_in_path and grep with your argument"
all_binaries_in_path | grep $argv
end
function list_path --description "list all paths in PATH, top-most wins"
for val in $PATH; echo "$val"; end
end
function stab --description "stabalize a video"
set -l vid $argv[1]
ffmpeg -i "$vid" -vf vidstabdetect=stepsize=32:result="$vid.trf" -f null -;
ffmpeg -i "$vid" -b:v 5700K -vf vidstabtransform=interpol=bicubic:input="$vid.trf" "$vid.mkv"; # :optzoom=2 seems nice in theory but i dont love it. kinda want a combo of 1 and 2. (dont zoom in past the static zoom level, but adaptively zoom out to full when possible)
ffmpeg -i "$vid" -i "$vid.mkv" -b:v 3000K -filter_complex hstack "$vid.stack.mkv"
# vid=Dalton1990/Paultakingusaroundthehouseagai ffmpeg -i "$vid.mp4" -i "$vid.mkv" -b:v 3000K -filter_complex hstack $HOME/Movies/"Paultakingusaroundthehouseagai.stack.mkv"
command rm $vid.trf
end
function md --wraps mkdir -d "Create a directory and cd into it"
command mkdir -p $argv
if test $status = 0
switch $argv[(count $argv)]
case '-*'
case '*'
cd $argv[(count $argv)]
return
end
end
end
# print compression results with a bar chart
function gz --d "Get the gzipped size"
set -l file "$argv[1]"
set -l orig_size (cat "$file" | wc -c)
printf "\e[1;97m%-20s %12s\e[0m\n" "compression method" "bytes"
for method in \
"original" \
# Gzip CLI default is -6, but GH pages only uses -5. Dunno about others.
"gzip (-5)" \
# "gzip (--best)" \
# Default zstd is -3
(test (command -v zstd) && echo "zstd") \
# (test (command -v zstd) && echo "zstd (-19)") \
(test (command -v brotli) && echo "brotli (-q 5)") # brotli is last because its compressor is sloowww
printf "%-20s " "$method"
set -l compressed_size (
switch "$method"
case "original"
cat "$file" | wc -c
case "gzip (-5)"
cat "$file" | gzip -5 -c | wc -c
case "gzip (--best)"
cat "$file" | gzip --best -c | wc -c
case "brotli (-q 5)"
cat "$file" | brotli -c | wc -c
case "zstd"
# If experimenting, could also do --19 or --22 --ultra
cat "$file" | zstd -c - | wc -c
case '*'
echo "Unhandled case. $method"
end
)
set -l wid (math $COLUMNS - 40)
set -l bar_width (math -s0 $compressed_size \* $wid / $orig_size)
printf "%'12.0f %s%s\n" "$compressed_size" (string repeat -n $bar_width '█') (string repeat -n (math -s0 "$wid - $bar_width") '░')
end
end
function sudo!!
eval sudo $history[1]
end
# `shellswitch [bash|zsh|fish]`
function shellswitch
chsh -s (brew --prefix)/bin/$argv
end
function maxcpu100 -d "literally max out all your cores."
echo "To stop the pain run:"
echo "killall yes"
for i in (seq (nproc)); yes >/dev/null & end
end
function copy_modification_date -d "Copies the modification time (and access time) of one file to another"
# Check if the correct number of arguments are provided
if test (count $argv) -ne 2
echo "Usage: cpmodtime <source_file> <target_file>" >&2
echo "Copies the modification time (and access time) from <source_file> to <target_file>." >&2
return 1
end
set -l source_file $argv[1]
set -l target_file $argv[2]
# Check if the source file exists and is a regular file
if not test -f "$source_file"
echo "Error: Source file '$source_file' does not exist or is not a regular file." >&2
return 1
end
# Use 'touch -r' to copy the timestamps (both modification and access)
touch -r "$source_file" "$target_file"
end
# requires my excellent `npm install -g statikk`
function server -d 'Start a HTTP server in the current dir, optionally specifying the port'
# arg can either be port number or extra args to statikk
if test $argv[1]
if string match -qr '^-?[0-9]+(\.?[0-9]*)?$' -- "$argv[1]"
set port $argv[1]
# fancy argv thing to pass all remaining args. eg `server --cors --jsprof`
statikk --open --port $argv[1..-1]
else
statikk --open $argv[1..-1]
end
else
statikk --open
end
end
# straight from the docs
function last_history_item
echo $history[1]
end
abbr -a !! --position anywhere --function last_history_item
# I crafted this lazy init pattern. It's lovely.
# I first did it with functions but it's better with abbr to get completions etc immediately.
function __lazy_init_conda -d 'lazy initialize conda'
abbr --erase conda; functions --erase __lazy_init_conda
eval $(which conda) "shell.fish" "hook" | source
echo "conda"
end
abbr --add conda --function __lazy_init_conda
function __lazy_init_cargo -d 'lazy initialize cargo'
abbr --erase cargo; functions --erase __lazy_init_cargo
sh "$HOME/.cargo/env"
echo "cargo"
end
abbr --add cargo --function __lazy_init_cargo
# NVM doesnt support fish and its stupid to try to make it work there.
# gcloud: Don't need "$HOME/google-cloud-sdk/path.fish.inc" lazyily done because it only adds to PATH which is already done.
function fns --description "Interactively search/preview fish shell functions and aliases"
set -l items
# Gather up all functions w/ descriptions
for fn_name in (functions -n)
set -l description ""
# Get the full function definition output
set -l definition_output (functions $fn_name | string collect) # Collect lines for easier matching
# extract the description, unless its a wrap fn (alias)
if not string match --quiet -- "--wraps*" "$definition_output"
string match --quiet --regex -- '--description\s+(?<desc>[^$^\n]*)' "$definition_output"
end
if test -n "$desc"
set -a items "$fn_name — $desc"
else
set -a items "$fn_name "
end
end
set -l preview_cmd "
set -l line {}
set -l parts (string split ' — ' \"\$line\")
set -l item_name (string trim \$parts[1])
functions \"\$item_name\" | bat --color=always --plain --language=fish --line-range :500
"
set -l chosen_fn (printf "%s\n" $items | fzf \
--height 60% \
--ansi \
--color="hl:#5f87af,hl+:#5fd7ff" \
--layout reverse \
--border rounded \
--header 'fish functions' \
--preview "$preview_cmd" \
--preview-window 'right:60%:wrap')
# on selection, output it.
if test -n "$chosen_fn"
set -l parts (string split ' — ' "$chosen_fn" \ )
set -l item_name (string trim $parts[1])
functions "$item_name" | bat --color=always --plain --language=fish --line-range :500
end
end