bb/scripts/bbbindkeys

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