Some tweaks to how the help menu displays bindings and added BBSHELLFUNC
for allowing the `bb` function to be used in the ':' and '|' bindings
This commit is contained in:
parent
23bed00467
commit
a50e439b42
14
bb.c
14
bb.c
@ -325,6 +325,7 @@ int run_script(bb_t *bb, const char *cmd)
|
|||||||
setenv("BBSELECTED", bb->firstselected ? "1" : "", 1);
|
setenv("BBSELECTED", bb->firstselected ? "1" : "", 1);
|
||||||
setenv("BBDOTFILES", bb->show_dotfiles ? "1" : "", 1);
|
setenv("BBDOTFILES", bb->show_dotfiles ? "1" : "", 1);
|
||||||
setenv("BBCURSOR", bb->nfiles ? bb->files[bb->cursor]->fullname : "", 1);
|
setenv("BBCURSOR", bb->nfiles ? bb->files[bb->cursor]->fullname : "", 1);
|
||||||
|
setenv("BBSHELLFUNC", bbcmdfn, 1);
|
||||||
|
|
||||||
int ttyout, ttyin;
|
int ttyout, ttyin;
|
||||||
ttyout = open("/dev/tty", O_RDWR);
|
ttyout = open("/dev/tty", O_RDWR);
|
||||||
@ -1286,7 +1287,7 @@ void bb_browse(bb_t *bb, const char *path)
|
|||||||
// Search user-defined key bindings from config.h:
|
// Search user-defined key bindings from config.h:
|
||||||
binding_t *binding;
|
binding_t *binding;
|
||||||
user_bindings:
|
user_bindings:
|
||||||
for (int i = 0; bindings[i].keys[0] > 0; i++) {
|
for (int i = 0; bindings[i].keys[0] >= 0; i++) {
|
||||||
for (int j = 0; bindings[i].keys[j]; j++) {
|
for (int j = 0; bindings[i].keys[j]; j++) {
|
||||||
if (key == bindings[i].keys[j]) {
|
if (key == bindings[i].keys[j]) {
|
||||||
// Move to front optimization:
|
// Move to front optimization:
|
||||||
@ -1337,13 +1338,16 @@ void bb_browse(bb_t *bb, const char *path)
|
|||||||
void print_bindings(int fd)
|
void print_bindings(int fd)
|
||||||
{
|
{
|
||||||
char buf[1000], buf2[1024];
|
char buf[1000], buf2[1024];
|
||||||
char *kb = "Key Bindings";
|
for (int i = 0; bindings[i].keys[0] >= 0; i++) {
|
||||||
sprintf(buf, "\n\033[33;1;4m\033[%dG%s\033[0m\n\n", (termwidth-(int)strlen(kb))/2, kb);
|
if (bindings[i].keys[0] == 0) {
|
||||||
|
const char *label = bindings[i].description;
|
||||||
|
sprintf(buf, "\n\033[33;1;4m\033[%dG%s\033[0m\n", (termwidth-(int)strlen(label))/2, label);
|
||||||
write(fd, buf, strlen(buf));
|
write(fd, buf, strlen(buf));
|
||||||
for (int i = 0; bindings[i].keys[0] > 0; i++) {
|
continue;
|
||||||
|
}
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
for (int j = 0; bindings[i].keys[j]; j++) {
|
for (int j = 0; bindings[i].keys[j]; j++) {
|
||||||
if (j > 0) *(p++) = ',';
|
if (j > 0) p = stpcpy(p, ", ");
|
||||||
int key = bindings[i].keys[j];
|
int key = bindings[i].keys[j];
|
||||||
const char *name = bkeyname(key);
|
const char *name = bkeyname(key);
|
||||||
if (name)
|
if (name)
|
||||||
|
105
config.def.h
105
config.def.h
@ -131,6 +131,8 @@ typedef struct {
|
|||||||
ASK("REPLY", "Is that okay? [y/N] ", "")"; test \"$REPLY\" = 'y'; } "
|
ASK("REPLY", "Is that okay? [y/N] ", "")"; test \"$REPLY\" = 'y'; } "
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SECTION(name) {{0}, NULL, name}
|
||||||
|
|
||||||
|
|
||||||
// These commands will run at startup (before command-line arguments)
|
// These commands will run at startup (before command-line arguments)
|
||||||
extern const char *startupcmds[];
|
extern const char *startupcmds[];
|
||||||
@ -175,12 +177,57 @@ const char *startupcmds[] = {
|
|||||||
* after editing.
|
* after editing.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
binding_t bindings[] = {
|
binding_t bindings[] = {
|
||||||
|
SECTION("Key Bindings"),
|
||||||
{{'?', KEY_F1}, "+help", B("Help")" menu"},
|
{{'?', KEY_F1}, "+help", B("Help")" menu"},
|
||||||
{{'q', 'Q'}, "+quit", B("Quit")},
|
{{'q', 'Q'}, "+quit", B("Quit")},
|
||||||
|
|
||||||
|
SECTION("Navigation"),
|
||||||
{{'j', KEY_ARROW_DOWN}, "+move:+1", B("Next")" file"},
|
{{'j', KEY_ARROW_DOWN}, "+move:+1", B("Next")" file"},
|
||||||
{{'k', KEY_ARROW_UP}, "+move:-1", B("Previous")" file"},
|
{{'k', KEY_ARROW_UP}, "+move:-1", B("Previous")" file"},
|
||||||
{{'h', KEY_ARROW_LEFT}, "+cd:..", B("Parent")" directory"},
|
{{'h', KEY_ARROW_LEFT}, "+cd:..", B("Parent")" directory"},
|
||||||
{{'l', KEY_ARROW_RIGHT}, "test -d \"$BBCURSOR\" && bb \"+cd:$BBCURSOR\"", B("Enter")" a directory"},
|
{{'l', KEY_ARROW_RIGHT}, "test -d \"$BBCURSOR\" && bb \"+cd:$BBCURSOR\"", B("Enter")" a directory"},
|
||||||
|
{{KEY_CTRL_F}, "bb \"+goto:$(if test $BBDOTFILES; then find -mindepth 1; else find -mindepth 1 ! -path '*/.*'; fi "
|
||||||
|
"| "PICK("Find: ", "")")\"", B("Search")" for file"},
|
||||||
|
{{'/'}, "bb \"+goto:$(if test $BBDOTFILES; then find -mindepth 1 -maxdepth 1; else find -mindepth 1 -maxdepth 1 ! -path '*/.*'; fi "
|
||||||
|
"| "PICK("Pick: ", "")")\"", B("Pick")" file"},
|
||||||
|
{{KEY_CTRL_G}, "bb \"+cd:$(" ASKECHO("Go to directory: ", "") ")\"", B("Go to")" directory"},
|
||||||
|
{{'m'}, "ln -s \"$PWD\" ~/.config/bb/marks/\"$("ASKECHO("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},
|
||||||
|
"test $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}, 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: ", "") ")\" "
|
||||||
|
"&& test -e \"$loadpath\" && bb +deselect:'*' "
|
||||||
|
"&& while IFS= read -r -d $'\\0'; do bb +select:\"$REPLY\"; done < \"$loadpath\"",
|
||||||
|
B("Open")" a saved selection"},
|
||||||
|
{{'S'},
|
||||||
|
ASK("patt", "Select pattern: ", "")" && bb +sel: \"$patt\"",
|
||||||
|
B("Select")" file(s) by pattern"},
|
||||||
|
{{'J'}, "+spread:+1", B("Spread")" selection down"},
|
||||||
|
{{'K'}, "+spread:-1", B("Spread")" selection up"},
|
||||||
|
{{KEY_CTRL_A},
|
||||||
|
"if test $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},
|
{{'\r', KEY_MOUSE_DOUBLE_LEFT},
|
||||||
"if test -d \"$BBCURSOR\"; then bb \"+cd:$BBCURSOR\"; "
|
"if test -d \"$BBCURSOR\"; then bb \"+cd:$BBCURSOR\"; "
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -191,21 +238,14 @@ binding_t bindings[] = {
|
|||||||
"else xdg-open \"$BBCURSOR\"; fi",
|
"else xdg-open \"$BBCURSOR\"; fi",
|
||||||
#endif
|
#endif
|
||||||
B("Open")" file/directory"},
|
B("Open")" file/directory"},
|
||||||
{{' ','v','V'}, "+toggle", B("Toggle")" selection"},
|
|
||||||
{{KEY_ESC}, "bb +deselect: \"$@\"", B("Clear")" selection"},
|
|
||||||
{{'e'}, "$EDITOR \"$@\" || "PAUSE, B("Edit")" file in $EDITOR"},
|
{{'e'}, "$EDITOR \"$@\" || "PAUSE, B("Edit")" file in $EDITOR"},
|
||||||
{{'p'}, "$PAGER \"$@\"", B("Page")" through a file in $PAGER"},
|
|
||||||
{{KEY_CTRL_F}, "bb \"+goto:$(if test $BBDOTFILES; then find -mindepth 1; else find -mindepth 1 ! -path '*/.*'; fi "
|
|
||||||
"| "PICK("Find: ", "")")\"", B("Search")" for file"},
|
|
||||||
{{'/'}, "bb \"+goto:$(if test $BBDOTFILES; then find -mindepth 1 -maxdepth 1; else find -mindepth 1 -maxdepth 1 ! -path '*/.*'; fi "
|
|
||||||
"| "PICK("Pick: ", "")")\"", B("Pick")" file"},
|
|
||||||
{{'d', KEY_DELETE}, CONFIRM("The following will be deleted:", "$@") " && rm -rf \"$@\" && bb +refresh && bb +deselect: \"$@\"",
|
{{'d', KEY_DELETE}, CONFIRM("The following will be deleted:", "$@") " && rm -rf \"$@\" && bb +refresh && bb +deselect: \"$@\"",
|
||||||
B("Delete")" files"},
|
B("Delete")" files"},
|
||||||
{{'M'}, "test $BBSELECTED || exit; "
|
{{'m'}, "test $BBSELECTED || exit; "
|
||||||
"if " CONFIRM("The following will be moved here:", "$@") "; then "
|
"if " CONFIRM("The following will be moved here:", "$@") "; then "
|
||||||
SPIN("mv -i \"$@\" . && bb +refresh && bb +deselect: \"$@\" && for f; do bb \"+sel:$(basename \"$f\")\"; done")" || "PAUSE
|
SPIN("mv -i \"$@\" . && bb +refresh && bb +deselect: \"$@\" && for f; do bb \"+sel:$(basename \"$f\")\"; done")" || "PAUSE
|
||||||
"; fi",
|
"; fi",
|
||||||
B("Move")" files to current directory"},
|
B("Move")" files here"},
|
||||||
{{'c'}, CONFIRM("The following will be copied here:", "$@")
|
{{'c'}, CONFIRM("The following will be copied here:", "$@")
|
||||||
" && for f; do if test \"./$(basename \"$f\")\" -ef \"$f\"; then "
|
" && for f; do if test \"./$(basename \"$f\")\" -ef \"$f\"; then "
|
||||||
SPIN("cp -ri \"$f\" \"$(basename \"$f\").copy\"")"; "
|
SPIN("cp -ri \"$f\" \"$(basename \"$f\").copy\"")"; "
|
||||||
@ -213,26 +253,12 @@ binding_t bindings[] = {
|
|||||||
B("Copy")" the selected files here"},
|
B("Copy")" the selected files here"},
|
||||||
{{'n'}, ASK("name", "New file: ", "")" && touch \"$name\" && bb \"+goto:$name\" +r || "PAUSE, B("New file")},
|
{{'n'}, ASK("name", "New file: ", "")" && touch \"$name\" && bb \"+goto:$name\" +r || "PAUSE, B("New file")},
|
||||||
{{'N'}, ASK("name", "New dir: ", "")" && mkdir \"$name\" && bb \"+goto:$name\" +r || "PAUSE, B("New directory")},
|
{{'N'}, ASK("name", "New dir: ", "")" && mkdir \"$name\" && bb \"+goto:$name\" +r || "PAUSE, B("New directory")},
|
||||||
{{KEY_CTRL_G}, "bb \"+cd:$(" ASKECHO("Go to directory: ", "") ")\"", B("Go to")" directory"},
|
{{'p'}, "$PAGER \"$@\"", B("Page")" through a file in $PAGER"},
|
||||||
{{KEY_CTRL_S}, ASK("savename", "Save selection as: ", "") " && printf '%s\\0' \"$@\" > ~/.config/bb/\"$savename\"",
|
{{'|'}, ASK("cmd", "|", "") " && printf '%s\\n' \"$@\" | sh -c \"$BBSHELLFUNC$cmd\"; " PAUSE "; bb +r",
|
||||||
B("Save")" the selection"},
|
|
||||||
{{KEY_CTRL_O}, "loadpath=\"$(find ~/.config/bb -maxdepth 1 -type f | " PICK("Load selection: ", "") ")\" "
|
|
||||||
"&& test -e \"$loadpath\" && bb +deselect:'*' "
|
|
||||||
"&& while IFS= read -r -d $'\\0'; do bb +select:\"$REPLY\"; done < \"$loadpath\"",
|
|
||||||
B("Open")" a selection"},
|
|
||||||
{{'|'}, ASK("cmd", "|", "") " && printf '%s\\n' \"$@\" | sh -c \"$cmd\"; " PAUSE "; bb +r",
|
|
||||||
B("Pipe")" selected files to a command"},
|
B("Pipe")" selected files to a command"},
|
||||||
{{':'}, "sh -c \"$(" ASKECHO(":", "") ")\" -- \"$@\"; " PAUSE "; bb +refresh",
|
{{':'}, "sh -c \"$BBSHELLFUNC$(" ASKECHO(":", "") ")\" -- \"$@\"; " PAUSE "; bb +refresh",
|
||||||
B("Run")" a command"},
|
B("Run")" a command"},
|
||||||
{{'>'}, "tput rmcup >/dev/tty; $SHELL; bb +r", "Open a "B("shell")},
|
{{'>'}, "tput rmcup >/dev/tty; $SHELL; bb +r", "Open a "B("shell")},
|
||||||
{{'\''}, "mark=\"$(ls ~/.config/bb/marks | " PICK("Jump to: ", "") ")\" "
|
|
||||||
"&& bb +cd:\"$(readlink -f ~/.config/bb/marks/\"$mark\")\"",
|
|
||||||
B("Jump")" to a directory"},
|
|
||||||
{{'-', KEY_BACKSPACE, KEY_BACKSPACE2},
|
|
||||||
"test $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")},
|
|
||||||
{{'m'}, "ln -s \"$PWD\" ~/.config/bb/marks/\"$("ASKECHO("Mark: ", "")")\"", B("Mark")" this directory"},
|
|
||||||
{{'r'},
|
{{'r'},
|
||||||
"bb +refresh; "
|
"bb +refresh; "
|
||||||
"for f; do "
|
"for f; do "
|
||||||
@ -253,31 +279,18 @@ binding_t bindings[] = {
|
|||||||
" bb \"+deselect:$f\" \"+select:$renamed\"; "
|
" bb \"+deselect:$f\" \"+select:$renamed\"; "
|
||||||
" fi;"
|
" fi;"
|
||||||
"done", B("Regex rename")" files"},
|
"done", B("Regex rename")" files"},
|
||||||
{{'S'},
|
|
||||||
ASK("patt", "Select pattern: ", "")" && bb +sel: \"$patt\"",
|
SECTION("File Display"),
|
||||||
B("Select")" file(s) by pattern"},
|
|
||||||
{{'J'}, "+spread:+1", B("Spread")" selection down"},
|
|
||||||
{{'K'}, "+spread:-1", B("Spread")" selection up"},
|
|
||||||
{{'b'}, "bb \"+$("ASKECHO("bb +", "")")\"", "Run a "B("bb command")},
|
|
||||||
{{'s'},
|
{{'s'},
|
||||||
"read -n1 -p \"" B("Sort (n)ame (s)ize (m)odification (c)reation (a)ccess (r)andom (p)ermissions: ") "\" sort"
|
"read -n1 -p \"" B("Sort (n)ame (s)ize (m)odification (c)reation (a)ccess (r)andom (p)ermissions: ") "\" sort"
|
||||||
" && bb \"+sort:+$sort\" +refresh",
|
" && bb \"+sort:+$sort\" +refresh",
|
||||||
B("Sort")" by..."},
|
B("Sort")" by..."},
|
||||||
{{'#'}, "bb \"+col:$("ASKECHO("Set columns: ", "")")\"", "Set "B("columns")},
|
{{'#'}, "bb \"+col:$("ASKECHO("Set columns (*)selected (a)ccessed (c)reated (m)odified (n)ame (p)ermissions (r)andom (s)ize: ", "")")\"",
|
||||||
{{'.'}, "+dotfiles", "Toggle "B("dotfiles")},
|
"Set "B("columns")},
|
||||||
{{'g', KEY_HOME}, "+move:0", "Go to "B("first")" file"},
|
{{'.'}, "+dotfiles", "Toggle "B("dotfile")" visibility"},
|
||||||
{{'G', KEY_END}, "+move:100%n", "Go to "B("last")" file"},
|
|
||||||
{{KEY_F5, KEY_CTRL_R}, "+refresh", B("Refresh")},
|
{{KEY_F5, KEY_CTRL_R}, "+refresh", B("Refresh")},
|
||||||
{{KEY_CTRL_A}, "if test $BBDOTFILES; then find -mindepth 1 -maxdepth 1 -print0; else find -mindepth 1 -maxdepth 1 ! -path '*/.*' -print0; fi | bb +sel:",
|
|
||||||
B("Select all")" files in current directory"},
|
{{-1}} // Array must be -1-terminated
|
||||||
{{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")},
|
|
||||||
{{-1}}
|
|
||||||
// Array must be -1-terminated
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1
|
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1
|
||||||
|
Loading…
Reference in New Issue
Block a user