319 lines
7.7 KiB
Bash
Executable File
319 lines
7.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# This file defines the key bindings for bb. It works by a very hacky script on
|
|
# the line below that prints out the rest of this file, converted into `bbcmd
|
|
# bind:` commands. Thanks to the hackiness, the code below is also valid shell
|
|
# code, so syntax highlighting should work normally.
|
|
#
|
|
# The format is: ## <key>(,<key>)*:[ ]+<description>(\n script)+
|
|
#
|
|
# May God have mercy on my soul for creating this abomination:
|
|
sed '1,'$LINENO'd; /^$/d; s/^## \(.*\): \(.*\)/\x00bind:\1:# \2/; $a\\x00' "$0" | bbcmd; exit
|
|
|
|
## 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 "$BB" ]; then bbcmd cd:"$BB"; fi
|
|
|
|
## Ctrl-f: Search for file
|
|
file="$(find . -mindepth 1 -printf '%P\0' | bbpick "Find: ")"
|
|
bbcmd goto:"$file"
|
|
|
|
## /: Pick a file
|
|
file="$(printf "%s\0" $BBGLOB | bbpick "Pick: ")"
|
|
bbcmd goto:"$file"
|
|
|
|
## *: Set the glob
|
|
glob="$(bbask "Show files matching: ")"
|
|
bbcmd glob:"$glob"
|
|
|
|
## Ctrl-g: Go to directory
|
|
dir="$(bbask "Go to directory: ")"
|
|
bbcmd cd:"$dir"
|
|
|
|
## m: Mark this directory
|
|
mkdir -p "$XDG_CONFIG_HOME/bb/marks"
|
|
ln -sT "$2" "$XDG_CONFIG_HOME/bb/marks/$1" 2>/dev/null
|
|
mark="$(bbask "Mark: ")"
|
|
ln -s "$PWD" "$XDG_CONFIG_HOME"/bb/marks/"$mark"
|
|
|
|
## ': Go to a marked directory
|
|
[ -d "$XDG_CONFIG_HOME"/bb/marks ]
|
|
mark="$(find "$XDG_CONFIG_HOME"/bb/marks/ -mindepth 1 -type l -printf '%P\0' | bbpick "Jump to: ")"
|
|
mark="$(readlink -f "$XDG_CONFIG_HOME"/bb/marks/"$mark")"
|
|
bbcmd cd:"$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:"$BB"
|
|
|
|
## Escape: Clear selection
|
|
bbcmd deselect
|
|
|
|
## S: Select pattern
|
|
patt="$(bbask "Select: ")"
|
|
bbcmd select: $patt
|
|
|
|
## U: Unselect pattern
|
|
patt="$(bbask "Unselect: ")"
|
|
bbcmd deselect: $patt
|
|
|
|
## Comma: Save the current settings
|
|
bbconfirm "Save the current settings? "
|
|
echo "bbcmd glob:'$BBGLOB' sort:'$BBSORT' columns:'$BBCOLUMNS' $BBINTERLEAVE" > "$XDG_DATA_HOME"/bb/settings.sh
|
|
|
|
## Ctrl-s: Save the selection
|
|
[ $# -gt 0 ]
|
|
savename="$(bbask "Save selection as: ")"
|
|
savename="${savename%.sel}.sel"
|
|
mkdir -p "$XDG_DATA_HOME"/bb
|
|
printf '%s\0' "$@" > "$XDG_DATA_HOME/bb/$savename"
|
|
|
|
## Ctrl-o: Open a saved selection
|
|
[ -d "$XDG_DATA_HOME"/bb ]
|
|
[ $# -gt 0 ] && bbconfirm "The current selection will be discarded. "
|
|
loadpath="$(find "$XDG_DATA_HOME"/bb/ -mindepth 1 -name '*.sel' -printf '%P\0' | bbpick "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 "$BB" ]; then bbcmd cd:"$BB"
|
|
elif [ "$(uname)" = "Darwin" ]; then
|
|
if expr "$(file -bI "$BB")" : '\(text/\|inode/empty\)' >/dev/null; then $EDITOR "$BB"
|
|
else open "$BB"; fi
|
|
else
|
|
if expr "$(file -bi "$BB")" : '\(text/\|inode/x-empty\)' >/dev/null; then $EDITOR "$BB"
|
|
else xdg-open "$BB"; fi
|
|
fi
|
|
|
|
## e: Edit file in $EDITOR
|
|
$EDITOR "$BB"
|
|
|
|
## d,Delete: Delete
|
|
case "$(bbtargets "$BB" "$@")" in
|
|
cursor) set -- "$BB" ;;
|
|
both) set -- "$BB" "$@" ;;
|
|
esac
|
|
printf "\033[1mDeleting the following:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | bbunscroll | more
|
|
bbconfirm
|
|
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" | bbunscroll | more
|
|
bbconfirm
|
|
printf "\033[1G\033[KMoving..."
|
|
mv -i "$@" .
|
|
printf "done."
|
|
bbcmd deselect refresh
|
|
bbcmd sel: "${@##*/}"
|
|
|
|
## c: Copy a file
|
|
[ $# -gt 0 ]
|
|
printf "\033[1mCopying the following to here:\n\033[33m$(printf ' %s\n' "$@")\033[0m" | bbunscroll | more
|
|
bbconfirm
|
|
printf "\033[1G\033[KCopying..."
|
|
for f; do
|
|
if [ "./${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 | bbpick "Create new: ")" in
|
|
File)
|
|
name="$(bbask "New File: ")" && printf '' >"$name"
|
|
;;
|
|
Directory)
|
|
name="$(bbask "New Directory: ")" && mkdir -- "$name"
|
|
;;
|
|
*) exit
|
|
;;
|
|
esac
|
|
bbcmd goto:"$name" refresh
|
|
|
|
## p: Page through a file with `less`
|
|
less -XK "$BB"
|
|
|
|
## r,F2: Rename files
|
|
case "$(bbtargets "$BB" "$@")" in
|
|
cursor) set -- "$BB";;
|
|
both) set -- "$BB" "$@";;
|
|
esac
|
|
for f; do
|
|
newname="$(bbask "Rename $(printf "\033[33m%s\033[39m" "${f##*/}"): " "${f##*/}")" || break
|
|
r="$(dirname "$f")/$newname"
|
|
[ "$r" = "$f" ] && continue
|
|
[ -e "$r" ] && printf "\033[31;1m$r already exists! It will be overwritten.\033[0m "
|
|
&& bbconfirm && { rm -rf "$r" || { bbpause; exit; }; }
|
|
mv "$f" "$r" || { bbpause; exit; }
|
|
bbcmd deselect:"$f" select:"$r"
|
|
[ "$f" = "$BB" ] && bbcmd goto:"$r"
|
|
done
|
|
bbcmd refresh
|
|
|
|
## ~: Regex rename files
|
|
if ! command -v rename >/dev/null; then
|
|
printf '\033[31;1mThe `rename` command is not installed. Please install it to use this key binding.\033[0m\n'
|
|
bbpause; exit 1
|
|
fi
|
|
if [ $# -eq 0 ]; then set -- $BBGLOB; fi
|
|
patt="$(bbask "Replace pattern: ")"
|
|
rep="$(bbask "Replacement: ")"
|
|
printf "\033[1mRenaming:\n\033[33m$(rename -nv "$patt" "$rep" "$@")\033[0m" | bbunscroll | more
|
|
bbconfirm
|
|
rename -i "$patt" "$rep" "$@"
|
|
bbcmd deselect refresh
|
|
|
|
|
|
## Section: Shell Commands
|
|
## Colon: Run a command
|
|
cmd="$(bbask ':')"
|
|
sh -c "$cmd" -- "$@" || true
|
|
bbpause
|
|
bbcmd refresh
|
|
|
|
## |: Pipe selected files to a command
|
|
cmd="$(bbask '|')"
|
|
if [ $# -eq 0 ]; then set -- "$BB"; fi
|
|
printf '%s\n' "$@" | sh -c "$cmd" || true
|
|
bbpause
|
|
bbcmd refresh
|
|
|
|
## @: Pass selected files as args to a command
|
|
cmd="$(bbask '@')"
|
|
if [ $# -eq 0 ]; then set -- "$BB"; fi
|
|
sh -c "$cmd \"\$@\"" -- "$@" || true
|
|
bbpause
|
|
bbcmd refresh
|
|
|
|
## $: Pass the cursor as an argument to a command
|
|
cmd="$(bbask '$')"
|
|
sh -c "$cmd \"\$1\"" -- "$BB" || true
|
|
bbpause
|
|
bbcmd refresh
|
|
|
|
## >: Open a shell
|
|
tput rmcup; tput cvvis
|
|
$SHELL || true
|
|
bbcmd refresh
|
|
|
|
## f: Resume suspended process
|
|
bbcmd fg
|
|
|
|
|
|
## Section: Viewing Options
|
|
## s: Sort by...
|
|
sort="$(bbask -1 "Sort (n)ame (s)ize (m)odification (c)reation (a)ccess (r)andom (p)ermissions: ")"
|
|
bbcmd sort:"~$sort"
|
|
|
|
## ---,#: Set columns
|
|
columns="$(bbask "Set columns (*)selected (a)ccessed (c)reated (m)odified (n)ame (p)ermissions (r)andom (s)ize: ")"
|
|
bbcmd col:"$columns"
|
|
|
|
## .: Toggle dotfile visibility
|
|
if [ "$BBGLOB" = ".* *" ]; then
|
|
bbcmd glob:"*"
|
|
else
|
|
bbcmd glob:".* *"
|
|
fi
|
|
|
|
## i: Toggle interleaving files and directories
|
|
bbcmd interleave
|
|
|
|
## F5,Ctrl-l: Refresh view
|
|
bbcmd refresh
|
|
|
|
## Ctrl-b: Bind a key to a script
|
|
key="$(bbask -1 "Press key to bind...")"
|
|
echo
|
|
script="$(bbask "Bind script: ")"
|
|
bbcmd bind:"$key":"{ $script; } || bbpause"
|
|
|
|
|
|
## Section: User Bindings
|