diff --git a/bb.c b/bb.c index 34bfc09..641e327 100644 --- a/bb.c +++ b/bb.c @@ -27,7 +27,7 @@ #define MAX_PATH 4096 #define startswith(str, start) (strncmp(str, start, strlen(start)) == 0) #define writez(fd, str) write(fd, str, strlen(str)) -#define IS_SELECTED(p) ((p)->atme) +#define IS_SELECTED(p) (((p)->atme) != NULL) #define KEY_DELAY 50 @@ -113,10 +113,6 @@ static void init_term() writez(termfd, "\e[?1000h\e[?1002h\e[?1015h\e[?1006h"); // hide cursor writez(termfd, "\e[?25l"); - // Set the scrolling region - char buf[16]; - sprintf(buf, "\e[3;%dr", height-1); - writez(termfd, buf); } static void close_term() @@ -125,10 +121,8 @@ static void close_term() writez(termfd, "\e[?1049l"); // Show cursor: writez(termfd, "\e[?25h"); - // Restore scrollable region - char buf[16]; - sprintf(buf, "\e[1;%dr", height); - writez(termfd, buf); + // Disable mouse tracking: + writez(termfd, "\e[?1000l\e[?1002l\e[?1015l\e[?1006l"); tcsetattr(termfd, TCSAFLUSH, &orig_termios); close(termfd); @@ -234,6 +228,19 @@ static int write_escaped(int fd, const char *str, size_t n, const char *reset_co static void render(bb_state_t *state, int lazy) { static int lastcursor = -1, lastscroll = -1; + if (lastcursor == -1 || lastscroll == -1) + lazy = 0; + + if (lazy) { + char buf[32]; + if (lastscroll > state->scroll) { + int n = sprintf(buf, "\e[3;%dr\e[%dT\e[1;%dr", height-1, lastscroll - state->scroll, height); + write(termfd, buf, n); + } else if (lastscroll < state->scroll) { + int n = sprintf(buf, "\e[3;%dr\e[%dS\e[1;%dr", height-1, state->scroll - lastscroll, height); + write(termfd, buf, n); + } + } if (!lazy) { term_move(0,0); @@ -243,27 +250,16 @@ static void render(bb_state_t *state, int lazy) term_move(0,1); { // Column labels - char buf[] = "\e[32m Size Date Perm Name\e[0m"; - buf[8] = state->sortmethod == SORT_SIZE ? (state->sort_reverse ? '-' : '+') : ' '; - buf[21] = state->sortmethod == SORT_TIME ? (state->sort_reverse ? '-' : '+') : ' '; - buf[36] = state->sortmethod == SORT_BITS ? (state->sort_reverse ? '-' : '+') : ' '; - buf[42] = state->sortmethod == SORT_ALPHA ? (state->sort_reverse ? '-' : '+') : ' '; + char buf[] = " \e[42;30m Size | Date | Perm| Name \e[0m"; + buf[11] = state->sortmethod == SORT_SIZE ? (state->sort_reverse ? '-' : '+') : ' '; + buf[24] = state->sortmethod == SORT_TIME ? (state->sort_reverse ? '-' : '+') : ' '; + buf[39] = state->sortmethod == SORT_BITS ? (state->sort_reverse ? '-' : '+') : ' '; + buf[45] = state->sortmethod == SORT_ALPHA ? (state->sort_reverse ? '-' : '+') : ' '; writez(termfd, buf); writez(termfd, "\e[K"); } } - if (lazy) { - char buf[16]; - if (lastscroll > state->scroll) { - int n = sprintf(buf, "\e[%dT", lastscroll - state->scroll); - write(termfd, buf, n); - } else if (lastscroll < state->scroll) { - int n = sprintf(buf, "\e[%dS", state->scroll - lastscroll); - write(termfd, buf, n); - } - } - entry_t **files = state->files; static const char *NORMAL_COLOR = "\e[0m"; static const char *CURSOR_COLOR = "\e[0;30;47m"; @@ -697,46 +693,6 @@ static void explore(char *path, int print_dir, int print_selection, char sep) init_term(); goto redraw; - case KEY_MOUSE_WHEEL_DOWN: - if (state.cursor >= state.nfiles - 1) - goto skip_redraw; - ++state.cursor; - lazy = 1; - if (state.nfiles > height - 4) - ++state.scroll; - goto redraw; - - case KEY_MOUSE_WHEEL_UP: - if (state.cursor <= 0) - goto skip_redraw; - --state.cursor; - lazy = 1; - if (state.nfiles > height - 4 && state.scroll > 0) - --state.scroll; - goto redraw; - - case 'J': - if (state.cursor < state.nfiles - 1) { - lazy = 1; - if (IS_SELECTED(state.files[state.cursor])) - select_file(&state, state.files[++state.cursor]); - else - deselect_file(&state, state.files[++state.cursor]); - goto redraw; - } - goto skip_redraw; - - case 'K': - if (state.cursor > 0) { - lazy = 1; - if (IS_SELECTED(state.files[state.cursor])) - select_file(&state, state.files[--state.cursor]); - else - deselect_file(&state, state.files[--state.cursor]); - goto redraw; - } - goto skip_redraw; - case 's': // Change sorting method: term_move(0, height-1); @@ -857,11 +813,6 @@ static void explore(char *path, int print_dir, int print_selection, char sep) if (bindings[i].flags & NORMAL_TERM) { close_term(); } else { - { // Restore scrolling region - char buf[16]; - sprintf(buf, "\e[1;%dr", height); - writez(termfd, buf); - } /* tcgetattr(termfd, &cur_tios); tcsetattr(termfd, TCSAFLUSH, &orig_termios); @@ -880,11 +831,6 @@ static void explore(char *path, int print_dir, int print_selection, char sep) tcsetattr(termfd, TCSAFLUSH, &cur_tios); writez(termfd, "\e[?25l"); // Hide cursor */ - { // Restore scrolling region - char buf[16]; - sprintf(buf, "\e[3;%dr", height-1); - writez(termfd, buf); - } } // Scan for IPC requests @@ -956,6 +902,11 @@ static void explore(char *path, int print_dir, int print_selection, char sep) found_it:; } else if (startswith(line, "move:")) { char *value = line + strlen("move:"); + int expand_sel = 0; + if (*value == 'x') { + expand_sel = 1; + ++value; + } int oldcur = state.cursor; int isabs = value[0] != '-' && value[0] != '+'; long delta = strtol(value, &value, 10); @@ -980,6 +931,16 @@ static void explore(char *path, int print_dir, int print_selection, char sep) state.scroll = clamped(state.scroll, state.cursor - (height-4) + 1, state.cursor); state.scroll = clamped(state.scroll, 0, state.nfiles-1 - (height-4)); } + if (expand_sel) { + int sel = IS_SELECTED(state.files[oldcur]); + for (int i = state.cursor; i != oldcur; i += (oldcur > i ? 1 : -1)) { + if (sel && !IS_SELECTED(state.files[i])) + select_file(&state, state.files[i]); + else if (!sel && IS_SELECTED(state.files[i])) + deselect_file(&state, state.files[i]); + } + lazy &= abs(oldcur - state.cursor) <= 1; + } } else if (startswith(line, "scroll:")) { char *value = line + strlen("scroll:"); int oldscroll = state.scroll; diff --git a/config.def.h b/config.def.h index 0061490..6c4e17a 100644 --- a/config.def.h +++ b/config.def.h @@ -20,6 +20,13 @@ struct { // Please note that these are sh scripts, not bash scripts, so bash-isms // won't work unless you make your script use `bash -c ""` //////////////////////////////////////////////////////////////////////// + + + {'1', "bb -c 'move:x+1'"}, + {'2', "bb -c 'move:x-1'"}, + {'3', "bb -c 'move:x+10'"}, + {'4', "bb -c 'move:x-10'"}, + {'e', "$EDITOR \"$@\"", NORMAL_TERM}, {'L', PIPE_SELECTION_TO "less", NORMAL_TERM}, {'D', "rm -rf \"$@\"; bb -c 'deselect:*' refresh"}, @@ -34,15 +41,14 @@ struct { {'>', "$SHELL", NORMAL_TERM}, {'r', "for f; do read -p \"Rename $f: \e[K\" renamed && mv \"$f\" \"$renamed\"; done;" " bb -c 'deselect:*' refresh"}, - - {'h', "bb -c \"cd:..\""}, {KEY_ARROW_LEFT, "bb -c 'cd:..'"}, {'j', "bb -c 'move:+1'"}, + {'J', "bb -c 'move:x+1'"}, {KEY_ARROW_DOWN, "bb -c 'move:+1'"}, {'k', "bb -c 'move:-1'"}, + {'K', "bb -c 'move:x-1'"}, {KEY_ARROW_UP, "bb -c 'move:-1'"}, - {'l', "bb -c \"cd:$BBFULLCURSOR\""}, {KEY_ARROW_RIGHT, "bb -c \"cd:$BBFULLCURSOR\""}, #ifdef __APPLE__ @@ -57,8 +63,6 @@ struct { "else xdg-open \"$BBCURSOR\"; fi"}, #endif {' ', "bb -c \"toggle:$BBCURSOR\""}, - //{-1, "J\t\e[0;34mMove selection state down\e[0m"}, - //{-1, "K\t\e[0;34mMove selection state up\e[0m"}, {'q', "bb -c quit"}, {'Q', "bb -c quit"}, {'g', "bb -c move:0"}, @@ -71,13 +75,12 @@ struct { {KEY_F5, "bb -c refresh"}, {KEY_CTRL_R, "bb -c refresh"}, {KEY_CTRL_A, "bb -c 'select:*'"}, - //{-1, "Ctrl-C\t\e[0;34mAbort and exit\e[0m"}, {KEY_PGDN, "bb -c 'scroll:+100%'"}, {KEY_CTRL_D, "bb -c 'scroll:+50%'"}, {KEY_PGUP, "bb -c 'scroll:-100%'"}, {KEY_CTRL_U, "bb -c 'scroll:-50%'"}, - //{-1, "Ctrl-Z\t\e[0;34mSuspend\e[0m"}, - + {KEY_MOUSE_WHEEL_DOWN, "bb -c 'scroll:+3'"}, + {KEY_MOUSE_WHEEL_UP, "bb -c 'scroll:-3'"}, // Hard-coded behaviors (these are just placeholders for the help):