/* BB Configuration, Startup Commands, and Key Bindings User customization goes in config.h, which is created by running `make` (config.def.h is for keeping the defaults around, just in case) 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, or if no files are selected, the full path of the file under the cursor $BBCURSOR: the full path of the file under the cursor $BBSELECTED: "1" if any files are selected, otherwise "" $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: Navigate to columns: Change which columns are visible, and in what order deselect: Deselect dotfiles:[01] Whether dotfiles are visible goto: Move the cursor to (changing directory if needed) interleave:[01] Whether or not directories should be interleaved with files in the display move: Move the cursor a numeric amount quit Quit bb refresh Refresh the file listing scroll: Scroll the view a numeric amount select: Select sort:([+-]method)+ Set sorting method (+: normal, -: reverse), additional methods act as tiebreaker spread: Spread the selection state at the cursor toggle: Toggle the selection status of 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; } binding_t; typedef struct { int width; const char *name; } column_t; // Configurable options: #define SCROLLOFF MIN(5, (termheight-4)/2) #define CMDFILE_FORMAT "/tmp/bb.XXXXXX" #define SORT_INDICATOR "↓" #define RSORT_INDICATOR "↑" #define SELECTED_INDICATOR " \033[31;7m \033[0m" #define NOT_SELECTED_INDICATOR " " // Colors (using ANSI escape sequences): #define TITLE_COLOR "\033[37;1m" #define NORMAL_COLOR "\033[37m" #define CURSOR_COLOR "\033[43;30;1m" #define LINK_COLOR "\033[35m" #define DIR_COLOR "\033[34m" #define EXECUTABLE_COLOR "\033[31m" // Some handy macros for common shell script behaviors: #define PAUSE " read -n1 -p '\033[2mPress any key to continue...\033[0m\033[?25l' >/dev/tty /dev/tty" #endif // Macro for picking from a list of options: #ifndef PICK #define PICK(prompt, initial) " { "ASK("query", prompt, initial)" && 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) " { { echo \""B(action)"\"; printf '%s\\n' \""files"\"; } | more; " \ ASK("REPLY", "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[]; // Column widths and titles: const column_t columns[128] = { ['*'] = {2, "*"}, ['a'] = {21, " Accessed"}, ['c'] = {21, " Created"}, ['m'] = {21, " Modified"}, ['n'] = {40, "Name"}, ['p'] = {5, "Permissions"}, ['r'] = {2, "Random"}, ['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,...}, "