From: Jasper Lievisse Adriaanse Subject: tog: handle Home/End for log and diff views To: gameoftrees@openbsd.org Date: Sun, 29 Aug 2021 22:14:38 +0200 Hi, Here's a diff that allows one to quickly navigate to the first or last item of a particular view. Currently I've implemented it for the diff and log views as these are the ones I use most often. The 'End' handling for the log view was the trickiest because of the way new commits are progressively discovered. I think the approach below might be the quickest way we currently can do. Is this an acceptable approach or did I miss anything? diff --git a/tog/tog.1 b/tog/tog.1 index 4296b08..e058891 100644 --- a/tog/tog.1 +++ b/tog/tog.1 @@ -108,6 +108,12 @@ Move the selection cursor up. Move the selection cursor down one page. .It Cm Page-up, Ctrl+b Move the selection cursor up one page. +.It Cm Home +Move the cursor to the newest commit. +.It Cm End, G +Move the cursor to the oldest commit. +This will iterate over all commit objects in the repository and may take +a long time depending on the size of the repository. .It Cm Enter, Space Open a .Cm diff @@ -210,6 +216,10 @@ Scroll up. Scroll down one page. .It Cm Page-up, Ctrl+b Scroll up one page. +.It Cm Home +Scroll to the top of the view. +.It Cm End, G +Scroll to the bottom of the view. .It Cm \&[ Reduce the amount of diff context lines. .It Cm \&] diff --git a/tog/tog.c b/tog/tog.c index 2f62fb3..145f0f4 100644 --- a/tog/tog.c +++ b/tog/tog.c @@ -2406,6 +2406,14 @@ input_log_view(struct tog_view **new_view, struct tog_view *view, int ch) log_scroll_up(s, 1); select_commit(s); break; + case KEY_HOME: + if (s->first_displayed_entry == NULL) + break; + + s->selected = 0; + log_scroll_up(s, s->commits.ncommits); + select_commit(s); + break; case KEY_PPAGE: case CTRL('b'): if (s->first_displayed_entry == NULL) @@ -2432,6 +2440,23 @@ input_log_view(struct tog_view **new_view, struct tog_view *view, int ch) } select_commit(s); break; + case 'G': + case KEY_END: { + /* We don't know yet how many commits, so we're forced to + * traverse them all. */ + while (1) { + if (s->thread_args.log_complete) + break; + + s->thread_args.commits_needed++; + trigger_log_thread(view, 1); + } + + log_scroll_down(view, s->commits.ncommits); + s->selected = MIN(view->nlines - 2, s->commits.ncommits - 1); + select_commit(s); + break; + } case KEY_NPAGE: case CTRL('f'): { struct commit_queue_entry *first; @@ -3633,6 +3658,17 @@ input_diff_view(struct tog_view **new_view, struct tog_view *view, int ch) diff_view_indicate_progress(view); err = create_diff(s); break; + case KEY_HOME: + s->first_displayed_line = 1; + break; + case 'G': + case KEY_END: + if (s->eof) + break; + + s->first_displayed_line = (s->nlines - view->nlines) + 2; + s->eof = 1; + break; case 'k': case KEY_UP: if (s->first_displayed_line > 1) -- jasper