"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Jasper Lievisse Adriaanse <j@jasper.la>
Subject:
tog: handle Home/End for log and diff views
To:
gameoftrees@openbsd.org
Date:
Sun, 29 Aug 2021 22:14:38 +0200

Download raw body.

Thread
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