diff options
Diffstat (limited to 'config.def.h')
| -rw-r--r-- | config.def.h | 247 |
1 files changed, 5 insertions, 242 deletions
diff --git a/config.def.h b/config.def.h index f4ae750..f8f431e 100644 --- a/config.def.h +++ b/config.def.h @@ -7,66 +7,15 @@ This file contains: - Global options, like which colors are used - Column formatting (width and title) - - Startup commands - - User key bindings - - For startup commands and key bindings, the following values are provided as - environment variables: - - $@ (the list of arguments): the full paths of the selected files - $BBCURSOR: the full path of the file under the cursor - $BBDOTFILES: "1" if files beginning with "." are visible in bb, otherwise "" - $BB_DEPTH: the number of `bb` instances deep (in case you want to run a - shell and have that shell print something special in the prompt) - $BBCMD: a file to which `bb` commands can be written (used internally) - - In order to modify bb's internal state, you can call `bb +cmd`, where "cmd" - is one of the following commands (or a unique prefix of one): - - .:[01] Whether to show "." in each directory - ..:[01] Whether to show ".." in each directory - cd:<path> Navigate to <path> - columns:<columns> Change which columns are visible, and in what order - deselect:<filename> Deselect <filename> - dotfiles:[01] Whether dotfiles are visible - goto:<filename> Move the cursor to <filename> (changing directory if needed) - interleave:[01] Whether or not directories should be interleaved with files in the display - move:<num*> Move the cursor a numeric amount - quit Quit bb - refresh Refresh the file listing - scroll:<num*> Scroll the view a numeric amount - select:<filename> Select <filename> - sort:([+-]method)+ Set sorting method (+: normal, -: reverse), additional methods act as tiebreaker - spread:<num*> Spread the selection state at the cursor - toggle:<filename> Toggle the selection status of <filename> - - Note: for numeric-based commands (like scroll), the number can be either - an absolute value or a relative value (starting with '+' or '-'), and/or - a percent (ending with '%'). Scrolling and moving, '%' means percent of - screen height, and '%n' means percent of number of files (e.g. +50% means - half a screen height down, and 100%n means the last file) - - Internally, bb will write the commands (NUL terminated) to $BBCMD, if - $BBCMD is set, and read the file when file browsing resumes. These commands - can also be passed to bb at startup, and will run immediately. - E.g. `bb '+col:n' '+sort:+r' .` will launch `bb` only showing the name column, randomly sorted. - - As a shorthand and performance optimization, commands that don't rely on any - shell variables or scripting can be written as "+move:+1" instead of "bb '+move:+1'", - which is a bit faster because internally it avoids writing to and reading from - the $BBCMD file. */ #include "bterm.h" -// Constants: -#define MAX_REBINDINGS 8 - // Types: typedef struct { - int keys[MAX_REBINDINGS+1]; - const char *script; - const char *description; + int key; + char *script; + char *description; } binding_t; typedef struct { @@ -93,58 +42,9 @@ typedef struct { #define SH "sh" #endif -// Used for STRINGIFY(__COUNTER__) to embed the line number as a string -// (as in "ask --history=bb."STRINGIFY(__COUNTER__)") -#define STRINGIFY2(x) #x -#define STRINGIFY(x) STRINGIFY2(x) - -// Some handy macros for common shell script behaviors: -// Bold text: -#define B(s) "\033[1m" s "\033[22m" - -// Macro for getting user input: -#ifndef ASK -#define ASK(var, prompt, initial) " read -p \"" B(prompt) "\" " var " </dev/tty >/dev/tty " -#endif - -#ifndef ASK1 -#define ASK1(var, prompt) " { printf \""prompt"\"; stty -icanon -echo; "var"=$(dd bs=1 count=1 2> /dev/null); stty icanon echo; } " -#endif - -#define PAUSE ASK1("REPLY", "\033[2mPress any key to continue...\033[0m\033[?25l") - -// Macro for picking from a list of options: -#ifndef PICK -#define PICK(prompt) " { "ASK("query", prompt)" && awk '{print length, $1}' | sort -n | cut -d' ' -f2- | "\ - "grep -i -m1 \"$(echo \"$query\" | sed 's;.;[^/&]*[&];g')\"; } " -#endif - -// Display a spinning indicator if command takes longer than 10ms: -#ifndef SPIN -#define SPIN(cmd) "{ { " cmd "; } & " \ - "pid=$!; "\ - "spinner='-\\|/'; "\ - "sleep 0.01; "\ - "while kill -0 $pid 2>/dev/null; do "\ - " printf '%c\\033[D' \"$spinner\" >/dev/tty; "\ - " spinner=\"$(echo $spinner | sed 's/\\(.\\)\\(.*\\)/\\2\\1/')\"; "\ - " sleep 0.1; "\ - "done; "\ - "wait $pid; }" -#endif - -#ifndef CONFIRM -#define CONFIRM(action, files) " { printf '%s\\n' \""B(action)"\" \""files"\" | more; " \ - ASK1("REPLY", B("Is that okay? [y/N] "))"; [ \"$REPLY\" = 'y' ]; } " -#endif - -#define SECTION(name) {{0}, NULL, name} - - // These commands will run at startup (before command-line arguments) -extern const char *startupcmds[]; extern const column_t columns[128]; -extern binding_t bindings[]; +extern binding_t bindings[1024]; // Column widths and titles: const column_t columns[128] = { @@ -158,20 +58,6 @@ const column_t columns[128] = { ['s'] = {9, " Size"}, }; -// This is a list of commands that runs when `bb` launches: -const char *startupcmds[] = { - // Set some default marks: - "mkdir -p ~/.config/bb/marks", - "ln -sT ~/.config/bb/marks ~/.config/bb/marks/marks 2>/dev/null", - "ln -sT ~ ~/.config/bb/marks/home 2>/dev/null", - "ln -sT / ~/.config/bb/marks/root 2>/dev/null", - "ln -sT ~/.config ~/.config/bb/marks/config 2>/dev/null", - "ln -sT ~/.local ~/.config/bb/marks/local 2>/dev/null", - // Default column and sorting options: - "+sort:+n", "+col:*smpn", - NULL, // NULL-terminated array -}; - /****************************************************************************** * These are all the key bindings for bb. * The format is: {{keys,...}, "<script>", "<description>"} @@ -183,129 +69,6 @@ const char *startupcmds[] = { * `vim -c 'set t_ti= t_te=' "$@"` to prevent momentarily seeing the shell * after editing. *****************************************************************************/ -binding_t bindings[] = { - SECTION("Key Bindings"), - {{'?', KEY_F1}, "+help", B("Help")" menu"}, - {{'q', 'Q'}, "+quit", B("Quit")}, - - SECTION("Navigation"), - {{'j', KEY_ARROW_DOWN}, "+move:+1", B("Next")" file"}, - {{'k', KEY_ARROW_UP}, "+move:-1", B("Previous")" file"}, - {{'h', KEY_ARROW_LEFT}, "+cd:..", B("Parent")" directory"}, - {{'l', KEY_ARROW_RIGHT}, "[ -d \"$BBCURSOR\" ] && bb \"+cd:$BBCURSOR\"", B("Enter")" a directory"}, - {{KEY_CTRL_F}, "bb \"+goto:$(if [ $BBDOTFILES ]; then find -mindepth 1; else find -mindepth 1 ! -path '*/.*'; fi " - "| "PICK("Find: ")")\"", B("Search")" for file"}, - {{'/'}, "bb \"+goto:$(if [ $BBDOTFILES ]; then find -mindepth 1 -maxdepth 1; else find -mindepth 1 -maxdepth 1 ! -path '*/.*'; fi " - "| "PICK("Pick: ")")\"", B("Pick")" file"}, - {{KEY_CTRL_G}, ASK("goto", "Go to directory: ", "")" && bb +cd:\"$goto\"", B("Go to")" directory"}, - {{'m'}, ASK("mark", "Mark: ", "")" && ln -s \"$PWD\" ~/.config/bb/marks/\"$mark\"", B("Mark")" this directory"}, - {{'\''}, "mark=\"$(ls ~/.config/bb/marks | " PICK("Jump to: ") ")\" " - "&& bb +cd:\"$(readlink -f ~/.config/bb/marks/\"$mark\")\"", - "Go to a "B("marked")" directory"}, - {{'-', KEY_BACKSPACE, KEY_BACKSPACE2}, - "[ $BBPREVPATH ] && bb +cd:\"$BBPREVPATH\"", "Go to "B("previous")" directory"}, - {{';'}, "bb +cd:'<selection>'", "Show "B("selected files")}, - {{'0'}, "bb +cd:\"$BBINITIALPATH\"", "Go to "B("initial directory")}, - {{'g', KEY_HOME}, "+move:0", "Go to "B("first")" file"}, - {{'G', KEY_END}, "+move:100%n", "Go to "B("last")" file"}, - {{KEY_PGDN}, "+scroll:+100%", B("Page down")}, - {{KEY_PGUP}, "+scroll:-100%", B("Page up")}, - {{KEY_CTRL_D}, "+scroll:+50%", B("Half page down")}, - {{KEY_CTRL_U}, "+scroll:-50%", B("Half page up")}, - {{KEY_MOUSE_WHEEL_DOWN}, "+scroll:+3", B("Scroll down")}, - {{KEY_MOUSE_WHEEL_UP}, "+scroll:-3", B("Scroll up")}, - - SECTION("File Selection"), - {{' ','v','V'}, "+toggle", B("Toggle")" selection at cursor"}, - {{KEY_ESC}, "bb +deselect: \"$@\"", B("Clear")" selection"}, - {{KEY_CTRL_S}, "[ $# -gt 0 ] && "ASK("savename", "Save selection as: ", "") " && printf '%s\\0' \"$@\" > ~/.config/bb/\"$savename\"", - B("Save")" the selection"}, - {{KEY_CTRL_O}, "loadpath=\"$(find ~/.config/bb -maxdepth 1 -type f | " PICK("Load selection: ") ")\" " - "&& [ -e \"$loadpath\" ] && bb +deselect:'*' " - "&& while IFS= read -r -d $'\\0'; do bb +select:\"$REPLY\"; done < \"$loadpath\"", - B("Open")" a saved selection"}, - {{'J'}, "+spread:+1", B("Spread")" selection down"}, - {{'K'}, "+spread:-1", B("Spread")" selection up"}, - {{KEY_CTRL_A}, - "if [ $BBDOTFILES ]; then find -mindepth 1 -maxdepth 1 -print0; " - "else find -mindepth 1 -maxdepth 1 ! -path '*/.*' -print0; fi | bb +sel:", - B("Select all")" files here"}, - - SECTION("Actions"), - {{'\r', KEY_MOUSE_DOUBLE_LEFT}, - "if [ -d \"$BBCURSOR\" ]; then bb \"+cd:$BBCURSOR\"; " -#ifdef __APPLE__ - "elif file -bI \"$BBCURSOR\" | grep -q '^\\(text/\\|inode/empty\\)'; then $EDITOR \"$BBCURSOR\"; " - "else open \"$BBCURSOR\"; fi", -#else - "elif file -bi \"$BBCURSOR\" | grep -q '^\\(text/\\|inode/empty\\)'; then $EDITOR \"$BBCURSOR\"; " - "else xdg-open \"$BBCURSOR\"; fi", -#endif - B("Open")" file/directory"}, - {{'e'}, "$EDITOR \"$BBCURSOR\" || "PAUSE, B("Edit")" file in $EDITOR"}, - {{'E'}, "[ $# -gt 0 ] && $EDITOR \"$@\" || "PAUSE, B("Edit")" selected files in $EDITOR"}, - {{'d'}, CONFIRM("The following will be deleted:", "$BBCURSOR") " && rm -rf \"$BBCURSOR\" && bb +refresh && bb +deselect: \"$BBCURSOR\"", - B("Delete")" a file"}, - {{'D', KEY_DELETE}, - "[ $# -gt 0 ] && "CONFIRM("The following will be deleted:", "$@") " && rm -rf \"$@\" && bb +refresh && bb +deselect: \"$@\"", - B("Delete")" selected files"}, - {{KEY_CTRL_V}, "[ $# -gt 0 ] && " - CONFIRM("The following will be moved here:", "$@") " && { " - SPIN("mv -i \"$@\" . && bb +refresh && bb +deselect: \"$@\" && for f; do bb \"+sel:$(basename \"$f\")\"; done")" || "PAUSE"; }", - B("Move")" files here"}, - {{'c'}, CONFIRM("Copy file:", "$BBCURSOR")" && cp -ri \"$BBCURSOR\" \"$BBCURSOR.copy\" && bb +refresh", - B("Copy")" a file"}, - {{'C'}, "[ $# -gt 0 ] && "CONFIRM("The following will be copied here:", "$@") - " && for f; do if [ \"./$(basename \"$f\")\" -ef \"$f\" ]; then " - SPIN("cp -ri \"$f\" \"$(basename \"$f\").copy\"")"; " - "else "SPIN("cp -ri \"$f\" .")"; fi; done; bb +refresh", - B("Copy")" the selected files here"}, - {{KEY_CTRL_N}, "type=\"$(printf '%s\\n' File Directory | "PICK("Create new: ")")\" " - "&& "ASK("name", "New $type: ", "")" && " - "{ if [ $type = File ]; then touch \"$name\"; else mkdir \"$name\"; fi " - "&& bb \"+goto:$name\" +r || "PAUSE"; }", B("New")" file/directory"}, - {{'p'}, "$PAGER \"$BBCURSOR\"", B("Page")" through a file in $PAGER"}, - {{'P'}, "[ $# -gt 0 ] && $PAGER \"$@\"", B("Page")" through selected files in $PAGER"}, - {{'|'}, ASK("cmd", "|", "") " && printf '%s\\n' \"$@\" | "SH" -c \"$BBSHELLFUNC$cmd\"; " PAUSE "; bb +r", - B("Pipe")" selected files to a command"}, - {{':'}, ASK("cmd", ":", "")" && "SH" -c \"$BBSHELLFUNC$cmd\" -- \"$@\"; " PAUSE "; bb +refresh", - B("Run")" a command"}, - {{'>'}, "tput rmcup >/dev/tty; $SHELL; bb +r", "Open a "B("shell")}, - {{'r', KEY_F2}, - ASK("newname", "Rename \033[33m$(basename \"$BBCURSOR\")\033[39m: ", "$(basename \"$BBCURSOR\")")" && " - "r=\"$(dirname \"$BBCURSOR\")/$newname\" && " - "[ \"$r\" != \"$BBCURSOR\" ] && mv -i \"$BBCURSOR\" \"$r\" && bb +refresh && " - "while [ $# -gt 0 ]; do [ \"$1\" = \"$BBCURSOR\" ] && bb \"+deselect:$BBCURSOR\" \"+select:$r\"; shift; done && " - "bb +goto:\"$r\"", - B("Rename")" a file"}, - {{'R'}, - "bb +refresh; " - "for f; do " - " "ASK("newname", "Rename \033[33m$(basename \"$f\")\033[39m: ", "$(basename \"$f\")")" || break; " - " r=\"$(dirname \"$f\")/$newname\"; " - " [ \"$r\" != \"$f\" ] && mv -i \"$f\" \"$r\" && bb \"+deselect:$f\" \"+select:$r\"; " - " [ \"$f\" = \"$BBCURSOR\" ] && bb +goto:\"$r\"; " - "done", B("Rename")" selected files"}, - {{KEY_CTRL_R}, - "command -v rename >/dev/null || { echo 'The `rename` command is not installed. Please install it to use this key binding.'; "PAUSE"; exit; }; " - ASK("patt", "Replace pattern: ", "")" && "ASK("rep", "Replacement: ", "")" && " - CONFIRM("Renaming:", "$(if [ $# -gt 0 ]; then rename -nv \"$patt\" \"$rep\" \"$@\"; else rename -nv \"$patt\" \"$rep\" *; fi)")" && " - "if [ $# -gt 0 ]; then rename -i \"$patt\" \"$rep\" \"$@\"; else rename -i \"$patt\" \"$rep\" *; fi; bb +refresh", - B("Regex rename")" files"}, - - SECTION("File Display"), - {{'s'}, - ASK1("sort", B("Sort (n)ame (s)ize (m)odification (c)reation (a)ccess (r)andom (p)ermissions: ")) - " && bb +sort:\"~$sort\" +refresh", - B("Sort")" by..."}, - {{'#'}, ASK("columns", "Set columns (*)selected (a)ccessed (c)reated (m)odified (n)ame (p)ermissions (r)andom (s)ize: ", "") - " && bb +col:\"$columns\"", - "Set "B("columns")}, - {{'.'}, "+dotfiles", "Toggle "B("dotfile")" visibility"}, - {{'i'}, "+interleave", "Toggle "B("interleaving")" files and directories"}, - {{KEY_F5}, "+refresh", B("Refresh")}, - - {{-1}} // Array must be -1-terminated -}; +binding_t bindings[1024]; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 |
