code / bb

Lines2.7K C1.8K Shell331 YAML273 Markdown197 make44
(303 lines)
1 #!/bin/sh
2 # This file defines the key bindings for bb. It works by a very hacky script on
3 # the line below that prints out the rest of this file, converted into `bbcmd
4 # bind:` commands. Thanks to the hackiness, the code below is also valid shell
5 # code, so syntax highlighting should work normally.
6 #
7 # The format is: ## <key>(,<key>)*:[ ]+<description>(\n script)+
8 #
9 # May God have mercy on my soul for creating this abomination:
10 awk 'NR<='$LINENO'{next} /^##/{sub(/: /, ":# "); sub(/^## /,"\0bind:")} /./{print}' "$0" | bbcmd; exit
12 ## Section: BB Commands
13 ## ?,F1: Show Help menu
14 bbcmd help
16 ## q,Q: Quit
17 bbcmd quit
19 ## Ctrl-c: Send interrupt signal
20 kill -INT $PPID
22 ## Ctrl-z: Suspend
23 kill -TSTP $PPID
25 ## Ctrl-\: Quit and generate core dump
26 kill -QUIT $PPID
28 ## +: Run a bb command
29 bbcmd "$(bbask '+')"
30 bbcmd refresh
32 ## Section: File Navigation
33 ## j,Down: Next file
34 bbcmd move:+1
36 ## k,Up: Previous file
37 bbcmd move:-1
39 ## h,Left: Parent directory
40 bbcmd cd:..
42 ## l,Right: Enter directory
43 if [ -d "$BB" ]; then bbcmd cd:"$BB";
44 elif [ -L "$BB" ]; then bbcmd goto:"$(readlink -f "$BB")"; fi
46 ## Ctrl-f: Search for file
47 file="$(find . -mindepth 1 -printf '%P\0' | bbpick "Find: ")"
48 bbcmd goto:"$file"
50 ## /: Pick a file
51 file="$(printf "%s\0" $BBGLOB | bbpick "Pick: ")"
52 bbcmd goto:"$file"
54 ## *: Set the glob
55 glob="$(bbask "Show files matching: ")"
56 bbcmd glob:"$glob"
58 ## Ctrl-g: Go to directory
59 dir="$(bbask "Go to directory: ")"
60 bbcmd cd:"$dir"
62 ## m: Mark this directory
63 mkdir -p "$XDG_CONFIG_HOME/bb/marks"
64 ln -sT "$2" "$XDG_CONFIG_HOME/bb/marks/$1" 2>/dev/null
65 mark="$(bbask "Mark: ")"
66 ln -s "$PWD" "$XDG_CONFIG_HOME"/bb/marks/"$mark"
68 ## ': Go to a marked directory
69 [ -d "$XDG_CONFIG_HOME"/bb/marks ]
70 mark="$(find "$XDG_CONFIG_HOME"/bb/marks/ -mindepth 1 -type l -printf '%P\0' | bbpick "Jump to: ")"
71 mark="$(readlink -f "$XDG_CONFIG_HOME"/bb/marks/"$mark")"
72 bbcmd cd:"$mark"
74 ## [,Backspace: Go to previous directory
75 bbcmd cd:-
77 ## ]: Go to next directory
78 bbcmd cd:+
80 ## ;: Show selected files
81 printf '%s\n' "$@" | less
83 ## g,Home: Go to first file
84 bbcmd move:0
86 ## G,End: Go to last file
87 bbcmd move:100%n
89 ## PgDn: Page down
90 bbcmd scroll:+100%
92 ## PgUp: Page up
93 bbcmd scroll:-100%
95 ## Ctrl-d: Half page down
96 bbcmd scroll:+50%
98 ## Ctrl-u: Half page up
99 bbcmd scroll:-50%
101 ## Mouse wheel down: Scroll down
102 bbcmd scroll:+3
104 ## Mouse wheel up: Scroll up
105 bbcmd scroll:-3
108 ## Section: File Selection
109 ## v,V,Space: Toggle selection at cursor
110 bbcmd toggle:"$BB"
112 ## Escape: Clear selection
113 bbcmd deselect
115 ## S: Select pattern
116 patt="$(bbask "Select: ")"
117 bbcmd select: $patt
119 ## U: Unselect pattern
120 patt="$(bbask "Unselect: ")"
121 bbcmd deselect: $patt
123 ## Comma: Save the current settings
124 bbconfirm "Save the current settings? "
125 echo "bbcmd glob:'$BBGLOB' sort:'$BBSORT' columns:'$BBCOLUMNS' $BBINTERLEAVE" > "$XDG_DATA_HOME"/bb/settings.sh
127 ## Ctrl-s: Save the selection
128 savename="$(bbask "Save selection as: ")"
129 savedir="$XDG_DATA_HOME/bb/${savename%.sel}.sel"
130 ! [ -d "$savedir" ] || bbconfirm "Do you want to overwrite the existing save? "
131 rm -rf "$savedir"
132 [ $# -gt 0 ] && mkdir -p "$savedir"
133 for f; do ln -sT "$f" "$savedir/${f##*/}" || exit 1; done
134 echo "Saved."
135 bbpause
137 ## Ctrl-o: Open a saved selection
138 [ -d "$XDG_DATA_HOME"/bb ]
139 [ $# -gt 0 ] && bbconfirm "The current selection will be discarded. "
140 loadpath="$(find "$XDG_DATA_HOME"/bb/ -mindepth 1 -maxdepth 1 -name '*.sel' -printf '%P\0' | bbpick "Load selection: ")"
141 find "$XDG_DATA_HOME/bb/$loadpath" -mindepth 1 -maxdepth 1 -printf '%l\0' | bbcmd deselect select:
142 bbcmd goto sort:'+*' interleave
144 ## J: Spread selection down
145 bbcmd spread:+1
147 ## K: Spread selection up
148 bbcmd spread:-1
150 ## Shift-Home: Spread the selection to the top
151 bbcmd spread:0
153 ## Shift-End: Spread the selection to the bottom
154 bbcmd spread:100%n
156 ## Ctrl-a: Select all files here
157 bbcmd select
160 ## Section: File Actions
161 ## Left click: Move cursor to file
162 if [ "$BBCLICKED" = "<column label>" ]; then
163 bbcmd sort:"~$BBMOUSECOL"
164 elif [ "$BBCLICKED" -a "$BBMOUSECOL" = "*" ]; then
165 bbcmd toggle:"$BBCLICKED"
166 elif [ "$BBCLICKED" ]; then
167 bbcmd goto:"$BBCLICKED"
170 ## Enter,Double left click: Open file/directory
171 if [ -d "$BB" ]; then bbcmd cd:"$BB"
172 elif [ "$(uname)" = "Darwin" ]; then
173 if expr "$(file -bI "$BB")" : '\(text/\|inode/empty\)' >/dev/null; then $EDITOR "$BB"
174 else open "$BB"; fi
175 else
176 if expr "$(file -bi "$BB")" : '\(text/\|inode/x-empty\)' >/dev/null; then $EDITOR "$BB"
177 else xdg-open "$BB"; fi
180 ## e: Edit file in $EDITOR
181 $EDITOR "$BB"
183 ## Ctrl-v: Move files here
184 printf "\033[1mMoving the following to here:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | bbunscroll | more
185 bbconfirm
186 printf "\033[1G\033[KMoving..."
187 mv -i "$@" .
188 printf "done."
189 bbcmd deselect refresh
190 bbcmd sel: "${@##*/}"
192 ## c: Copy a file
193 [ $# -gt 0 ]
194 printf "\033[1mCopying the following to here:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | bbunscroll | more
195 bbconfirm
196 printf "\033[1G\033[KCopying..."
197 for f; do
198 if [ "./${f##*/}" -ef "$f" ]; then
199 cp -ri "$f" "$f.copy" || break
200 else cp -ri "$f" . || break; fi
201 done
202 printf 'done.'
203 bbcmd refresh
205 ## Ctrl-n: New file/directory
206 case "$(printf '%s\0' File Directory | bbpick "Create new: ")" in
207 File)
208 name="$(bbask "New File: ")" && printf '' >"$name"
210 Directory)
211 name="$(bbask "New Directory: ")" && mkdir -- "$name"
213 *) exit
215 esac
216 bbcmd goto:"$name" refresh
218 ## Section: Shell Commands
219 ## Colon: Run a command
220 cmd="$(bbask ':')"
221 sh -c "$cmd" -- "$@" || true
222 bbpause
223 bbcmd refresh
225 ## |: Pipe selected files to a command
226 cmd="$(bbask '|')"
227 if [ $# -eq 0 ]; then set -- "$BB"; fi
228 printf '%s\n' "$@" | sh -c "$cmd" || true
229 bbpause
230 bbcmd refresh
232 ## @: Pass selected files as args to a command
233 cmd="$(bbask '@')"
234 if [ $# -eq 0 ]; then set -- "$BB"; fi
235 sh -c "$cmd \"\$@\"" -- "$@" || true
236 bbpause
237 bbcmd refresh
239 ## $: Pass the cursor as an argument to a command
240 cmd="$(bbask '$')"
241 sh -c "$cmd \"\$1\"" -- "$BB" || true
242 bbpause
243 bbcmd refresh
245 ## >: Open a shell
246 tput rmcup; tput cvvis
247 $SHELL || true
248 bbcmd refresh
250 ## f: Resume suspended process
251 bbcmd fg
254 ## Section: Viewing Options
255 ## s: Sort by...
256 new_sort="$(bbask -1 "Sort (n)ame (s)ize (m)odification (c)reation (a)ccess (r)andom (p)ermissions: ")"
257 bbcmd sort:"~$new_sort"
259 ## ---,#: Set columns
260 columns="$(bbask "Set columns (*)selected (a)ccessed (c)reated (m)odified (n)ame (p)ermissions (r)andom (s)ize: ")"
261 bbcmd col:"$columns"
263 ## .: Toggle dotfile visibility
264 if [ "$BBGLOB" = ".* *" ]; then
265 bbcmd glob:"*"
266 else
267 bbcmd glob:".* *"
270 ## i: Toggle interleaving files and directories
271 bbcmd interleave
273 ## F5,Ctrl-l,Ctrl-r: Refresh view
274 bbcmd refresh
276 ## Ctrl-b: Bind a key to a script
277 key="$(bbask -1 "Press key to bind...")"
278 echo
279 script="$(bbask "Bind script: ")"
280 bbcmd bind:"$key":"{ $script; } || bbpause"
282 ## 1: Run action on files
283 missing_cursor() {
284 for f; do
285 if [ "$f" = "$BB" ]; then return 1; fi
286 done
288 if [ $# -gt 0 ]; then
289 if missing_cursor "$@"; then
290 intended="$(printf '%s\0' 'Cursor file' 'Selected files' 'Both' | bbpick 'Which do you mean? ')"
291 case "$intended" in
292 Cursor*) set -- "$BB";;
293 Selected*) ;;
294 Both) set -- "$BB" "$@" ;;
295 *) exit 1;;
296 esac
298 else
299 set -- "$BB"
301 picked=$(sed -n 's/^## *//p' /etc/bb/bbactions | fzf --height=1)
302 [ -n "$picked" ] || exit 1
303 sh -c "$(bp "$picked"'\(\n braces)' /etc/bb/bbactions)" -- "$@" || bbpause