diff options
| -rw-r--r-- | bb.c | 66 | ||||
| -rw-r--r-- | config.h | 11 | ||||
| -rw-r--r-- | keys.h | 65 |
3 files changed, 94 insertions, 48 deletions
@@ -427,7 +427,11 @@ static void clear_selection(bb_state_t *state) static void explore(char *path, int print_dir, int print_selection) { char *tmp = path; - path = malloc(strlen(tmp) + 1); + char *original_path = calloc(strlen(tmp) + 1, 1); + if (!original_path) err("allocation failure"); + strcpy(original_path, path); + path = calloc(strlen(tmp) + 1, 1); + if (!path) err("allocation failure"); strcpy(path, tmp); tmp = NULL; char to_select[MAX_PATH+1] = {0}; @@ -586,7 +590,14 @@ static void explore(char *path, int print_dir, int print_selection) break; } - case 'q': case 'Q': case KEY_CTRL_C: + case KEY_CTRL_C: + close_term(); + if (print_dir) + printf("%s\n", original_path); + _exit(1); + return; + + case 'q': case 'Q': goto done; case KEY_MOUSE_WHEEL_DOWN: @@ -609,18 +620,18 @@ static void explore(char *path, int print_dir, int print_selection) state.scroll = 0; goto redraw; - case KEY_CTRL_D: + case KEY_CTRL_D: case KEY_PGDN: if (state.cursor == state.nfiles - 1) goto skip_redraw; state.cursor = MIN(state.nfiles - 1, state.cursor + (height - 4) / 2); if (state.nfiles <= height - 4) goto redraw; state.scroll += (height - 4)/2; - if (state.scroll > state.nfiles - (height - 4)) - state.scroll = state.nfiles - (height - 4); + if (state.scroll > state.nfiles - (height - 4) - 1) + state.scroll = state.nfiles - (height - 4) - 1; goto redraw; - case KEY_CTRL_U: + case KEY_CTRL_U: case KEY_PGUP: state.cursor = MAX(0, state.cursor - (height - 4) / 2); if (state.nfiles <= height - 4) goto redraw; @@ -629,15 +640,15 @@ static void explore(char *path, int print_dir, int print_selection) state.scroll = 0; goto redraw; - case 'g': + case 'g': case KEY_HOME: state.cursor = 0; state.scroll = 0; goto redraw; - case 'G': + case 'G': case KEY_END: state.cursor = state.nfiles - 1; if (state.nfiles > height - 4) - state.scroll = state.nfiles - (height - 4); + state.scroll = state.nfiles - (height - 4) - 1; goto redraw; case ' ': @@ -683,6 +694,10 @@ static void explore(char *path, int print_dir, int print_selection) clear_selection(&state); goto redraw; + case KEY_F5: case KEY_CTRL_R: + strcpy(to_select, state.files[state.cursor]->d_name); + goto tail_call; + case 'j': case KEY_ARROW_DOWN: if (state.cursor >= state.nfiles - 1) goto skip_redraw; @@ -765,7 +780,7 @@ static void explore(char *path, int print_dir, int print_selection) } goto sort_files; - case 'd': + case 't': sort_date: if (state.sortmethod == SORT_DATE) state.sort_reverse ^= 1; @@ -851,29 +866,6 @@ static void explore(char *path, int print_dir, int print_selection) goto tail_call; } - /* - case '|': { - char *cmd = input("> ", NULL); - if (!cmd) - goto redraw; - // TODO: avoid having this spam the terminal history - close_term(); - int fd; - pid_t child = run_cmd(NULL, &fd, cmd); - free(cmd); - if (state.nselected > 0) { - write_selection(fd, state.firstselected); - } else { - write(fd, state.files[state.cursor]->d_name, state.files[state.cursor]->d_namlen); - write(fd, "\n", 1); - } - close(fd); - waitpid(child, NULL, 0); - init_term(); - goto tail_call; - } - */ - default: for (int i = 0; bindings[i].key; i++) { if (key == bindings[i].key) { @@ -908,8 +900,10 @@ static void explore(char *path, int print_dir, int print_selection) if (bindings[i].flags & CLEAR_SELECTION) clear_selection(&state); - if (bindings[i].flags & REFRESH) + if (bindings[i].flags & REFRESH) { + strcpy(to_select, state.files[state.cursor]->d_name); goto tail_call; + } goto redraw; } @@ -936,7 +930,6 @@ done: int main(int argc, char *argv[]) { - init_term(); char _realpath[MAX_PATH+1]; char *path = "."; int print_dir = 0, print_selection = 0; @@ -945,11 +938,12 @@ int main(int argc, char *argv[]) print_dir = 1; } else if (strcmp(argv[i], "-s") == 0) { print_selection = 1; - } else { + } else if (path[0]) { path = argv[i]; break; } } + init_term(); if (!realpath(path, _realpath)) err("realpath failed"); explore(_realpath, print_dir, print_selection); @@ -12,7 +12,7 @@ #define CLEAR_SELECTION (1<<4) #define SILENT (1<<5) -#define DEVNULL " >/dev/null 2>/dev/null" +#define DEVNULL " >/dev/null" struct { int key; @@ -24,12 +24,13 @@ struct { {'D', "xargs rm -rf" DEVNULL, CLEAR_SELECTION | REFRESH | SILENT}, {'d', "xargs -I @ sh -c 'rm -rfi @ </dev/tty'", CLEAR_SELECTION | REFRESH}, {'+', "xargs -n1 -I @ cp @ @.copy" DEVNULL, REFRESH | SILENT}, - {'m', "xargs -I @ mv @ ." DEVNULL, CLEAR_SELECTION | REFRESH | SILENT}, - {'p', "xargs -I @ cp @ ." DEVNULL, CLEAR_SELECTION | REFRESH | SILENT}, + {'m', "xargs -I @ mv -i @ . </dev/tty" DEVNULL, CLEAR_SELECTION | REFRESH | SILENT}, + {'p', "xargs -I @ cp -i @ . </dev/tty" DEVNULL, CLEAR_SELECTION | REFRESH | SILENT}, {'n', "touch %s", SILENT | PROMPT | REFRESH | NO_FILES, "New file: "}, - {'|', "sh -c \"`read -p '> ' </dev/tty`\"", 0},//, PROMPT, "> "}, + {'|', "sh -c \"`printf '> ' >/dev/tty && head -n1 /dev/tty`\"", REFRESH},//, PROMPT, "> "}, //{'|', "%s", PROMPT, "> "}, - {'>', "%s", PROMPT | NO_FILES, "> "}, + //{'>', "%s", PROMPT | NO_FILES, "> "}, + {'>', "sh -c \"`printf '> ' >/dev/tty && head -n1 /dev/tty`\"", NO_FILES | REFRESH},//, PROMPT, "> "}, {'r', "xargs -I @ -n1 sh -c 'mv \"@\" \"`printf \"\\033[1mRename \\033[0;33m%%s\\033[0m: \" \"@\" >&2 && head -n1 </dev/tty`\"'", REFRESH | CLEAR_SELECTION}, {0}, @@ -75,38 +75,77 @@ #define KEY_CTRL_8 0x7F /* clash with 'BACKSPACE2' */ -int term_getkey(int fd, int *mouse_x, int *mouse_y) +static inline int nextchar(int fd) { char c; - if (read(fd, &c, 1) != 1) - return -1; + return read(fd, &c, 1) == 1 ? c : -1; +} +int term_getkey(int fd, int *mouse_x, int *mouse_y) +{ + int c = nextchar(fd); if (c == '\x1b') goto escape; return c; escape: + c = nextchar(fd); // Actual escape key: - if (read(fd, &c, 1) != 1) + if (c == -1) return KEY_ESC; switch (c) { case '[': goto CSI; + case 'P': goto DCS; + case 'O': goto SS3; default: return -1; } CSI: - if (read(fd, &c, 1) != 1) + c = nextchar(fd); + if (c == -1) return -1; switch (c) { - case 'H': return KEY_HOME; - case 'F': return KEY_END; case 'A': return KEY_ARROW_UP; case 'B': return KEY_ARROW_DOWN; case 'C': return KEY_ARROW_RIGHT; case 'D': return KEY_ARROW_LEFT; + case 'F': return KEY_END; + case 'H': return KEY_HOME; + case '1': + switch (nextchar(fd)) { + case '5': + return nextchar(fd) == '~' ? KEY_F5 : -1; + case '7': + return nextchar(fd) == '~' ? KEY_F6 : -1; + case '8': + return nextchar(fd) == '~' ? KEY_F7 : -1; + case '9': + return nextchar(fd) == '~' ? KEY_F8 : -1; + default: return -1; + } + break; + case '2': + switch (nextchar(fd)) { + case '0': + return nextchar(fd) == '~' ? KEY_F9 : -1; + case '1': + return nextchar(fd) == '~' ? KEY_F10 : -1; + case '3': + return nextchar(fd) == '~' ? KEY_F11 : -1; + case '4': + return nextchar(fd) == '~' ? KEY_F12 : -1; + default: return -1; + } + break; + case '3': + return nextchar(fd) == '~' ? KEY_DELETE : -1; + case '5': + return nextchar(fd) == '~' ? KEY_PGUP : -1; + case '6': + return nextchar(fd) == '~' ? KEY_PGDN : -1; case '<': { // Mouse clicks int buttons = 0, x = 0, y = 0; char buf; @@ -135,6 +174,18 @@ int term_getkey(int fd, int *mouse_x, int *mouse_y) break; } } + return -1; + + DCS: + return -1; + SS3: + switch (nextchar(fd)) { + case 'P': return KEY_F1; + case 'Q': return KEY_F2; + case 'R': return KEY_F3; + case 'S': return KEY_F4; + default: break; + } return -1; } |
