From: Mark Jamsek Subject: Re: u/ctrl-u/d/ctrl-d bindings for scrolling in tog To: Christian Weisgerber , gameoftrees@openbsd.org, Mikhail Date: Mon, 13 Jun 2022 10:16:35 +1000 On 22-06-12 06:36pm, Stefan Sperling wrote: > On Mon, Jun 13, 2022 at 12:31:33AM +1000, Mark Jamsek wrote: > > On 22-06-12 03:40pm, Christian Weisgerber wrote: > > > Stefan Sperling: > > > > > > > In my opinion it would make sense to match less(1) behaviour and implement > > > > half-page scroll for ^D and ^U. Or only offer the full-page scroll bindings > > > > used by less(1), i.e. delete our ^D and ^U keybindings again. > > > > > > Personally, I have no use for ^D/^U. I'm not opposed to adding it > > > with "scroll half-screen" semantics, though. > > > > > > > Something like this? > > Don't only Ctrl+u/Ctrl+u scroll half a page? > It seems this patch is deleting the u/d keys again, which as far as I > understood should remain as a full-page scroll? > (If I misunderstood something, please forgive me; I never knew about > these shortcuts in less(1) before this discussion.) C-u and C-d are the same (half-page scroll) as u and d in more(1) or less(1). And as Christian suggested, I thought d and u might be best left for other keymaps (e.g., we use last modified 'd'ate in branch and tree views). > Style-wise, I would prefer /= 2 over >>= 1. This makes the code more > accessible to people who are still in the process of learning C. Modern > compilers are smart enough to implement division by 2 via bit shift. Done! diff --git a/tog/tog.1 b/tog/tog.1 index 5221b4ad..e8c907d8 100644 --- a/tog/tog.1 +++ b/tog/tog.1 @@ -104,10 +104,14 @@ are as follows: Move the selection cursor down. .It Cm Up-arrow, k, <, Comma, Ctrl-p Move the selection cursor up. -.It Cm Page-down, Ctrl+f, d, Ctrl+d +.It Cm Page-down, Ctrl+f Move the selection cursor down one page. -.It Cm Page-up, Ctrl+b, u, Ctrl+u +.It Cm Page-up, Ctrl+b Move the selection cursor up one page. +.It Cm Ctrl+d +Move the selection cursor down one half page. +.It Cm Ctrl+u +Move the selection cursor up one half page. .It Cm Home, g Move the cursor to the newest commit. .It Cm End, G @@ -215,10 +219,14 @@ detected. Scroll down. .It Cm Up-arrow, k, Ctrl-p Scroll up. -.It Cm Page-down, Space, Ctrl+f, d, Ctrl+d +.It Cm Page-down, Space, Ctrl+f Scroll down one page. -.It Cm Page-up, Ctrl+b, u, Ctrl+u +.It Cm Page-up, Ctrl+b Scroll up one page. +.It Cm Ctrl+d +Scroll down one half page. +.It Cm Ctrl+u +Scroll up one half page. .It Cm Home, g Scroll to the top of the view. .It Cm End, G @@ -282,10 +290,14 @@ are as follows: Move the selection cursor down. .It Cm Up-arrow, k, Ctrl-p Move the selection cursor up. -.It Cm Page-down, Space, Ctrl+f, d, Ctrl+d +.It Cm Page-down, Space, Ctrl+f Move the selection cursor down one page. -.It Cm Page-up, Ctrl+b, u, Ctrl+u +.It Cm Page-up, Ctrl+b Move the selection cursor up one page. +.It Cm Ctrl+d +Move the selection cursor down one half page. +.It Cm Ctrl+u +Move the selection cursor up one half page. .It Cm Home, g Move the selection cursor to the first line of the file. .It Cm End, G @@ -361,10 +373,14 @@ are as follows: Move the selection cursor down. .It Cm Up-arrow, k, Ctrl-p Move the selection cursor up. -.It Cm Page-down, Ctrl+f, d, Ctrl+d +.It Cm Page-down, Ctrl+f Move the selection cursor down one page. -.It Cm Page-up, Ctrl+b, u, Ctrl+u +.It Cm Page-up, Ctrl+b Move the selection cursor up one page. +.It Cm Ctrl+d +Move the selection cursor down one half page. +.It Cm Ctrl+u +Move the selection cursor up one half page. .It Cm Home, g Move the selection cursor to the first entry. .It Cm End, G @@ -431,10 +447,14 @@ are as follows: Move the selection cursor down. .It Cm Up-arrow, k, Ctrl-p Move the selection cursor up. -.It Cm Page-down, Ctrl+f, d, Ctrl+d +.It Cm Page-down, Ctrl+f Move the selection cursor down one page. -.It Cm Page-up, Ctrl+b, u, Ctrl+u +.It Cm Page-up, Ctrl+b Move the selection cursor up one page. +.It Cm Ctrl+d +Move the selection cursor down one half page. +.It Cm Ctrl+u +Move the selection cursor up one half page. .It Cm Home, g Move the selection cursor to the first reference. .It Cm End, G diff --git a/tog/tog.c b/tog/tog.c index b3235c1f..4f498030 100644 --- a/tog/tog.c +++ b/tog/tog.c @@ -2441,7 +2441,7 @@ input_log_view(struct tog_view **new_view, struct tog_view *view, int ch) struct tog_view *diff_view = NULL, *tree_view = NULL; struct tog_view *ref_view = NULL; struct commit_queue_entry *entry; - int begin_x = 0, n; + int begin_x = 0, n, nscroll = view->nlines - 1; if (s->thread_args.load_all) { if (ch == KEY_BACKSPACE) @@ -2479,16 +2479,17 @@ input_log_view(struct tog_view **new_view, struct tog_view *view, int ch) s->first_displayed_entry = TAILQ_FIRST(&s->commits.head); select_commit(s); break; + case CTRL('u'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_PPAGE: case CTRL('b'): - case CTRL('u'): - case 'u': if (s->first_displayed_entry == NULL) break; if (TAILQ_FIRST(&s->commits.head) == s->first_displayed_entry) - s->selected = 0; + s->selected = MAX(0, s->selected - nscroll - 1); else - log_scroll_up(s, view->nlines - 1); + log_scroll_up(s, nscroll); select_commit(s); break; case 'j': @@ -2530,23 +2531,24 @@ input_log_view(struct tog_view **new_view, struct tog_view *view, int ch) select_commit(s); break; } - case KEY_NPAGE: - case CTRL('f'): case CTRL('d'): - case 'd': { + nscroll /= 2; + /* FALL THROUGH */ + case KEY_NPAGE: + case CTRL('f'): { struct commit_queue_entry *first; first = s->first_displayed_entry; if (first == NULL) break; - err = log_scroll_down(view, view->nlines - 1); + err = log_scroll_down(view, nscroll); if (err) break; if (first == s->first_displayed_entry && s->selected < MIN(view->nlines - 2, s->commits.ncommits - 1)) { /* can't scroll further down */ - s->selected = MIN(view->nlines - 2, - s->commits.ncommits - 1); + s->selected += MIN(s->last_displayed_entry->idx - + s->selected_entry->idx, nscroll + 1); } select_commit(s); break; @@ -3755,7 +3757,7 @@ input_diff_view(struct tog_view **new_view, struct tog_view *view, int ch) char *line = NULL; size_t linesize = 0; ssize_t linelen; - int i; + int i, nscroll = view->nlines - 1; switch (ch) { case 'a': @@ -3789,15 +3791,15 @@ input_diff_view(struct tog_view **new_view, struct tog_view *view, int ch) if (s->first_displayed_line > 1) s->first_displayed_line--; break; + case CTRL('u'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_PPAGE: case CTRL('b'): - case CTRL('u'): - case 'u': if (s->first_displayed_line == 1) break; i = 0; - while (i++ < view->nlines - 1 && - s->first_displayed_line > 1) + while (i++ < nscroll && s->first_displayed_line > 1) s->first_displayed_line--; break; case 'j': @@ -3806,15 +3808,16 @@ input_diff_view(struct tog_view **new_view, struct tog_view *view, int ch) if (!s->eof) s->first_displayed_line++; break; + case CTRL('d'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_NPAGE: case CTRL('f'): case ' ': - case CTRL('d'): - case 'd': if (s->eof) break; i = 0; - while (!s->eof && i++ < view->nlines - 1) { + while (!s->eof && i++ < nscroll) { linelen = getline(&line, &linesize, s->f); s->first_displayed_line++; if (linelen == -1) { @@ -4637,7 +4640,7 @@ input_blame_view(struct tog_view **new_view, struct tog_view *view, int ch) const struct got_error *err = NULL, *thread_err = NULL; struct tog_view *diff_view; struct tog_blame_view_state *s = &view->state.blame; - int begin_x = 0; + int begin_x = 0, nscroll = view->nlines - 2; switch (ch) { case 'q': @@ -4668,17 +4671,17 @@ input_blame_view(struct tog_view **new_view, struct tog_view *view, int ch) s->first_displayed_line > 1) s->first_displayed_line--; break; + case CTRL('u'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_PPAGE: case CTRL('b'): - case CTRL('u'): - case 'u': if (s->first_displayed_line == 1) { - s->selected_line = 1; + s->selected_line = MAX(1, s->selected_line - nscroll); break; } - if (s->first_displayed_line > view->nlines - 2) - s->first_displayed_line -= - (view->nlines - 2); + if (s->first_displayed_line > nscroll) + s->first_displayed_line -= nscroll; else s->first_displayed_line = 1; break; @@ -4823,11 +4826,12 @@ input_blame_view(struct tog_view **new_view, struct tog_view *view, int ch) break; break; } + case CTRL('d'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_NPAGE: case CTRL('f'): case ' ': - case CTRL('d'): - case 'd': if (s->last_displayed_line >= s->blame.nlines && s->selected_line >= MIN(s->blame.nlines, view->nlines - 2)) { @@ -4835,18 +4839,15 @@ input_blame_view(struct tog_view **new_view, struct tog_view *view, int ch) } if (s->last_displayed_line >= s->blame.nlines && s->selected_line < view->nlines - 2) { - s->selected_line = MIN(s->blame.nlines, - view->nlines - 2); - break; + s->selected_line += + MIN(nscroll, s->last_displayed_line - + s->first_displayed_line - s->selected_line + 1); } - if (s->last_displayed_line + view->nlines - 2 - <= s->blame.nlines) - s->first_displayed_line += - view->nlines - 2; + if (s->last_displayed_line + nscroll <= s->blame.nlines) + s->first_displayed_line += nscroll; else s->first_displayed_line = - s->blame.nlines - - (view->nlines - 3); + s->blame.nlines - (view->nlines - 3); break; case KEY_RESIZE: if (s->selected_line > view->nlines - 2) { @@ -5528,7 +5529,7 @@ input_tree_view(struct tog_view **new_view, struct tog_view *view, int ch) struct tog_tree_view_state *s = &view->state.tree; struct tog_view *log_view, *ref_view; struct got_tree_entry *te; - int begin_x = 0, n; + int begin_x = 0, n, nscroll = view->nlines - 3; switch (ch) { case 'i': @@ -5610,19 +5611,20 @@ input_tree_view(struct tog_view **new_view, struct tog_view *view, int ch) } tree_scroll_up(s, 1); break; + case CTRL('u'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_PPAGE: case CTRL('b'): - case CTRL('u'): - case 'u': if (s->tree == s->root) { if (got_object_tree_get_first_entry(s->tree) == s->first_displayed_entry) - s->selected = 0; + s->selected -= MIN(s->selected, nscroll); } else { if (s->first_displayed_entry == NULL) - s->selected = 0; + s->selected -= MIN(s->selected, nscroll); } - tree_scroll_up(s, MAX(0, view->nlines - 3)); + tree_scroll_up(s, MAX(0, nscroll)); break; case 'j': case KEY_DOWN: @@ -5637,18 +5639,20 @@ input_tree_view(struct tog_view **new_view, struct tog_view *view, int ch) break; tree_scroll_down(s, 1); break; + case CTRL('d'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_NPAGE: case CTRL('f'): - case CTRL('d'): - case 'd': if (got_tree_entry_get_next(s->tree, s->last_displayed_entry) == NULL) { /* can't scroll any further; move cursor down */ if (s->selected < s->ndisplayed - 1) - s->selected = s->ndisplayed - 1; + s->selected += MIN(nscroll, + s->ndisplayed - s->selected - 1); break; } - tree_scroll_down(s, view->nlines - 3); + tree_scroll_down(s, nscroll); break; case KEY_ENTER: case '\r': @@ -6340,7 +6344,7 @@ input_ref_view(struct tog_view **new_view, struct tog_view *view, int ch) struct tog_ref_view_state *s = &view->state.ref; struct tog_view *log_view, *tree_view; struct tog_reflist_entry *re; - int begin_x = 0, n; + int begin_x = 0, n, nscroll = view->nlines - 1; switch (ch) { case 'i': @@ -6427,13 +6431,14 @@ input_ref_view(struct tog_view **new_view, struct tog_view *view, int ch) } ref_scroll_up(s, 1); break; + case CTRL('u'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_PPAGE: case CTRL('b'): - case CTRL('u'): - case 'u': if (s->first_displayed_entry == TAILQ_FIRST(&s->refs)) - s->selected = 0; - ref_scroll_up(s, MAX(0, view->nlines - 1)); + s->selected -= MIN(nscroll, s->selected); + ref_scroll_up(s, MAX(0, nscroll)); break; case 'j': case KEY_DOWN: @@ -6447,17 +6452,19 @@ input_ref_view(struct tog_view **new_view, struct tog_view *view, int ch) break; ref_scroll_down(s, 1); break; + case CTRL('d'): + nscroll /= 2; + /* FALL THROUGH */ case KEY_NPAGE: case CTRL('f'): - case CTRL('d'): - case 'd': if (TAILQ_NEXT(s->last_displayed_entry, entry) == NULL) { /* can't scroll any further; move cursor down */ if (s->selected < s->ndisplayed - 1) - s->selected = s->ndisplayed - 1; + s->selected += MIN(nscroll, + s->ndisplayed - s->selected - 1); break; } - ref_scroll_down(s, view->nlines - 1); + ref_scroll_down(s, nscroll); break; case CTRL('l'): tog_free_refs(); -- Mark Jamsek GPG: F2FF 13DE 6A06 C471 CA80 E6E2 2930 DC66 86EE CF68