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
|
# This file defines the key bindings for bb
# The format is: <key>(,<key>)*:[ ]*#<description>(\n[ ]+script)+
Section: BB Commands
?,F1: # Show Help menu
bbcmd help
q,Q: # Quit
bbcmd quit
Ctrl-c: # Send interrupt signal
kill -INT $PPID
Ctrl-z: # Suspend
kill -TSTP $PPID
Ctrl-\: # Quit and generate core dump
kill -QUIT $PPID
Section: File Navigation
j,Down: # Next file
bbcmd move:+1
k,Up: # Previous file
bbcmd move:-1
h,Left: # Parent directory
bbcmd cd:..
l,Right: # Enter directory
if [ -d "$BBCURSOR" ]; then bbcmd cd:"$BBCURSOR"; fi
Ctrl-f: # Search for file
file="$(
if [ $BBDOTFILES ]; then find -mindepth 1 -printf '%P\0';
else find -mindepth 1 ! -path '*/.*' -printf '%P\0';
fi | pick "Find: "
)" && bbcmd goto:"$file"
/: # Pick a file
file="$(find -mindepth 1 -maxdepth 1 -printf '%P\0' | pick "Pick: ")" || exit
expr "$file" : "\..*" >/dev/null && ! [ "$BBDOTFILES" ] && bbcmd dotfiles
bbcmd goto:"$file"
Ctrl-g: # Go to directory
ask goto "Go to directory: " && bbcmd cd:"$goto"
m: # Mark this directory
mkdir -p "$XDG_CONFIG_HOME/bb/marks"
ln -sT "$2" "$XDG_CONFIG_HOME/bb/marks/$1" 2>/dev/null
ask mark "Mark: " && ln -s "$PWD" "$XDG_CONFIG_HOME"/bb/marks/"$mark"
': # Go to a marked directory
[ -d "$XDG_CONFIG_HOME"/bb/marks ] || exit
mark="$(find "$XDG_CONFIG_HOME"/bb/marks/ -mindepth 1 -type l -printf '%P\0' | pick "Jump to: ")" &&
bbcmd cd:"$(readlink -f "$XDG_CONFIG_HOME"/bb/marks/"$mark")"
-,Backspace: # Go to previous directory
[ "$BBPREVPATH" ] && bbcmd cd:"$BBPREVPATH"
;: # Show selected files
bbcmd cd:'<selection>'
0: # Go to intitial directory
bbcmd cd:"$BBINITIALPATH"
g,Home: # Go to first file
bbcmd move:0
G,End: # Go to last file
bbcmd move:100%n
PgDn: # Page down
bbcmd scroll:+100%
PgUp: # Page up
bbcmd scroll:-100%
Ctrl-d: # Half page down
bbcmd scroll:+50%
Ctrl-u: # Half page up
bbcmd scroll:-50%
Mouse wheel down: # Scroll down
bbcmd scroll:+3
Mouse wheel up: # Scroll up
bbcmd scroll:-3
Section: File Selection
v,V,Space: # Toggle selection at cursor
bbcmd toggle
Escape: # Clear selection
bbcmd deselect
S: # Select pattern
ask patt "Select: " && eval bbcmd select: "$patt"
U: # Unselect pattern
ask patt "Unselect: " && eval bbcmd deselect: "$patt"
Ctrl-s: # Save the selection
[ $# -gt 0 ] && ask savename "Save selection as: " || exit 1
mkdir -p "$XDG_DATA_HOME"/bb
if ! expr "$savename" : ".*\.sel" >/dev/null; then savename="$savename.sel"; fi
printf '%s\0' "$@" > "$XDG_DATA_HOME"/bb/"$savename"
Ctrl-o: # Open a saved selection
[ -d "$XDG_DATA_HOME"/bb ] || exit
[ $# -gt 0 ] && ! confirm "The current selection will be discarded. " && exit 1
loadpath="$(find "$XDG_DATA_HOME"/bb/ -mindepth 1 -name '*.sel' -printf '%P\0' | pick "Load selection: ")" &&
cat "$XDG_DATA_HOME"/bb/"$loadpath" | bbcmd deselect select:
J: # Spread selection down
bbcmd spread:+1
K: # Spread selection up
bbcmd spread:-1
Shift-Home: # Spread the selection to the top
bbcmd spread:0
Shift-End: # Spread the selection to the bottom
bbcmd spread:100%n
Ctrl-a: # Select all files here
bbcmd select
Section: File Actions
Left click: # Move cursor to file
if [ "$BBCLICKED" = "<column label>" ]; then
bbcmd sort:"~$BBMOUSECOL"
elif [ "$BBCLICKED" -a "$BBMOUSECOL" = "*" ]; then
bbcmd toggle:"$BBCLICKED"
elif [ "$BBCLICKED" ]; then
bbcmd goto:"$BBCLICKED"
fi
Enter,Double left click: # Open file/directory
if [ -d "$BBCURSOR" ]; then bbcmd cd:"$BBCURSOR";
elif [ "$(uname)" = "Darwin" ]; then
if expr "$(file -bI "$BBCURSOR")" : '\(text/\|inode/empty\)' >/dev/null; then $EDITOR "$BBCURSOR";
else open "$BBCURSOR"; fi
else
if expr "$(file -bi "$BBCURSOR")" : '\(text/\|inode/x-empty\)' >/dev/null; then $EDITOR "$BBCURSOR";
else xdg-open "$BBCURSOR"; fi
fi
e: # Edit file in $EDITOR
$EDITOR "$BBCURSOR" || pause
d,Delete: # Delete a file
printf "\033[1mDeleting \033[33m$BBCURSOR\033[0;1m...\033[0m " && confirm &&
rm -rf "$BBCURSOR" && bbcmd deselect:"$BBCURSOR" refresh
D: # Delete all selected files
[ $# -gt 0 ] && printf "\033[1mDeleting the following:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | unscroll | more &&
confirm && rm -rf "$@" && bbcmd deselect refresh
Ctrl-v: # Move files here
printf "\033[1mMoving the following to here:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | unscroll | more &&
confirm && printf "\033[1G\033[KMoving..." && mv -i "$@" . && printf "done." &&
bbcmd deselect refresh && for f; do bbcmd sel:"$(basename "$f")"; done
c: # Copy a file
printf "\033[1mCreating copy of \033[33m$BBCURSOR\033[0;1m...\033[0m " &&
confirm && cp -ri "$BBCURSOR" "$BBCURSOR.copy" && bbcmd refresh
C: # Copy all selected files here
[ $# -gt 0 ] && printf "\033[1mCopying the following to here:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | unscroll | more &&
confirm && printf "\033[1G\033[KCopying..." &&
for f; do if [ "./$(basename "$f")" -ef "$f" ]; then
cp -ri "$f" "$f.copy" || break;
else cp -ri "$f" . || break; fi; done; printf 'done.' && bbcmd refresh
Ctrl-n: # New file/directory
case "$(printf '%s\0' File Directory | pick "Create new: ")" in
File)
ask name "New File: " || exit
touch "$name"
;;
Directory)
ask name "New Directory: " || exit
mkdir "$name"
;;
*) exit
;;
esac && bbcmd goto:"$name" refresh || pause
p: # Page through a file with `less`
less -XK "$BBCURSOR"
r,F2: # Rename a file
ask newname "Rename $(printf "\033[33m%s\033[39m" "$(basename "$BBCURSOR")"): " "$(basename "$BBCURSOR")" || exit
r="$(dirname "$BBCURSOR")/$newname" || exit
[ "$r" = "$BBCURSOR" ] && exit
[ -e "$r" ] && printf "\033[31;1m$r already exists! It will be overwritten.\033[0m " &&
confirm && { rm -rf "$r" || { pause; exit; }; }
mv "$BBCURSOR" "$r" && bbcmd refresh &&
while [ $# -gt 0 ]; do "$1" = "$BBCURSOR" && bbcmd deselect:"$BBCURSOR" select:"$r"; shift; done &&
bbcmd goto:"$r" || { pause; exit; }
R: # Rename all selected files
for f; do
ask newname "Rename $(printf "\033[33m%s\033[39m" "$(basename "$f")"): " "$(basename "$f")" || break;
r="$(dirname "$f")/$newname";
[ "$r" = "$f" ] && continue;
[ -e "$r" ] && printf "\033[31;1m$r already exists! It will be overwritten.\033[0m "
&& confirm && { rm -rf "$r" || { pause; exit; }; }
mv "$f" "$r" || { pause; exit; }
bbcmd deselect:"$f" select:"$r";
[ "$f" = "$BBCURSOR" ] && bbcmd goto:"$r";
done;
bbcmd refresh
Ctrl-r: # Regex rename files
command -v rename >/dev/null ||
{ printf '\033[31;1mThe `rename` command is not installed. Please install it to use this key binding.\033[0m\n'; pause; exit; };
ask patt "Replace pattern: " && ask rep "Replacement: " &&
printf "\033[1mRenaming:\n\033[33m$(if [ $# -gt 0 ]; then rename -nv "$patt" "$rep" "$@"; else rename -nv "$patt" "$rep" *; fi)\033[0m" | unscroll | more &&
confirm || exit 1
if [ $# -eq 0 ]; then set -- *; ! [ -e "$1" ] && exit; fi
rename -i "$patt" "$rep" "$@"
bbcmd deselect refresh
Section: Shell Commands
:: # Run a command
ask cmd ':' && sh -c "$BBSHELLFUNC$cmd" -- "$@"; bbcmd refresh; pause
|: # Pipe selected files to a command
ask cmd '|' && printf '%s\n' "$@" | sh -c "$BBSHELLFUNC$cmd"; bbcmd refresh; pause
>: # Open a shell
tput rmcup; tput cvvis; $SHELL; bbcmd refresh
f: # Resume suspended process
bbcmd fg
Section: Viewing Options
s: # Sort by...
ask1 sort "Sort (n)ame (s)ize (m)odification (c)reation (a)ccess (r)andom (p)ermissions: " &&
bbcmd sort:"~$sort"
---,#: # Set columns
ask columns "Set columns (*)selected (a)ccessed (c)reated (m)odified (n)ame (p)ermissions (r)andom (s)ize: " &&
bbcmd col:"$columns"
.: # Toggle dotfile visibility
bbcmd dotfiles
i: # Toggle interleaving files and directories
bbcmd interleave
F5: # Refresh view
bbcmd refresh
Ctrl-b: # Bind a key to a script
ask1 key "Press key to bind..." && echo && ask script "Bind script: " &&
bbcmd bind:"$key":"{ $script; } || pause" || pause
Section: User Bindings
|