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

From:
Mikhail <mp39590@gmail.com>
Subject:
tog: cycle a searches and movements
To:
gameoftrees@openbsd.org
Date:
Fri, 10 Feb 2023 20:32:32 +0300

Download raw body.

Thread
When I made a patch to make tog respect current cursor position in log
view searches Mark said that he would like to see cycle searches in
log view, like it's done in an editors (won't vouch for exact wording,
though).

When Mark had done his work on next/prev hunk/file keybindings I noticed
that it was done with cycling (jump to the first file/hunk after hitting
"next" on last one and vice verse).

Personally I would want to have all searches and movements the way we
have a search done in log view - stop after last hunk/file, primarily
because I found myself cycling around while reviewing >moderate diffs.

This patch introduces cycle searches/movement customization through
TOG_CYCLE_MOVEMENT environment variable, when set - all searches and
movements inside diff view will cycle, when it's NULL - we will stop
after last match.

What do you think about the idea and implementation?

diff /home/misha/work/got
commit - faf054c3d5fbad3a55534ebe525d58156c7aad27
path + /home/misha/work/got
blob - 667bfe283076f37b6cb5690da6b2a98d9aae516a
file + tog/tog.1
--- tog/tog.1
+++ tog/tog.1
@@ -773,6 +773,10 @@ is used.
 If not set, the default value
 .Dq magenta
 is used.
+.It Ev TOG_CYCLE_MOVEMENT
+If set tog will start searches and hunk/file movement
+(in diff view) from the beginning of the view when hit
+the last match or last section.
 .It Ev TOG_DIFF_ALGORITHM
 Determines the default diff algorithm used by
 .Nm .
blob - 59f6749677b14d49ad79028572ac387a766ff9db
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -3332,6 +3332,24 @@ search_next_log_view(struct tog_view *view)
 				view->search_next_done =
 				    (s->matched_entry == NULL ?
 				    TOG_SEARCH_HAVE_NONE : TOG_SEARCH_NO_MORE);
+
+				if (view->search_next_done ==
+				    TOG_SEARCH_NO_MORE &&
+				    getenv("TOG_CYCLE_MOVEMENT")) {
+					if (view->searching ==
+					    TOG_SEARCH_FORWARD) {
+						entry =
+						    TAILQ_FIRST(
+							&s->commits->head);
+					} else {
+						entry =
+						    TAILQ_LAST(
+							&s->commits->head,
+							commit_queue_head);
+					}
+					goto matchit;
+				}
+
 				s->search_entry = NULL;
 				return NULL;
 			}
@@ -3344,6 +3362,7 @@ search_next_log_view(struct tog_view *view)
 			return trigger_log_thread(view, 0);
 		}
 
+matchit:
 		err = match_commit(&have_match, entry->id, entry->commit,
 		    &view->regex);
 		if (err)
@@ -4982,6 +5001,11 @@ search_next_view_match(struct tog_view *view)
 				break;
 			}
 
+			if (getenv("TOG_CYCLE_MOVEMENT") == NULL) {
+				view->search_next_done = TOG_SEARCH_NO_MORE;
+				break;
+			}
+
 			if (view->searching == TOG_SEARCH_FORWARD)
 				lineno = 1;
 			else
@@ -5270,8 +5294,12 @@ diff_prev_index(struct tog_diff_view_state *s, enum go
 	i = start = s->first_displayed_line - 1;
 
 	while (s->lines[i].type != type) {
-		if (i == 0)
-			i = s->nlines - 1;
+		if (i == 0) {
+			if (getenv("TOG_CYCLE_MOVEMENT") == NULL)
+				return;
+			else
+				i = s->nlines - 1;
+		}
 		if (--i == start)
 			return; /* do nothing, requested type not in file */
 	}
@@ -5288,8 +5316,12 @@ diff_next_index(struct tog_diff_view_state *s, enum go
 	i = start = s->first_displayed_line + 1;
 
 	while (s->lines[i].type != type) {
-		if (i == s->nlines - 1)
-			i = 0;
+		if (i == s->nlines - 1) {
+			if (getenv("TOG_CYCLE_MOVEMENT") == NULL)
+				return;
+			else
+				i = 0;
+		}
 		if (++i == start)
 			return; /* do nothing, requested type not in file */
 	}
@@ -7278,7 +7310,8 @@ search_next_tree_view(struct tog_view *view)
 
 	while (1) {
 		if (te == NULL) {
-			if (s->matched_entry == NULL) {
+			if (s->matched_entry == NULL ||
+			    getenv("TOG_CYCLE_MOVEMENT") == NULL) {
 				view->search_next_done = TOG_SEARCH_HAVE_MORE;
 				return NULL;
 			}
@@ -8036,7 +8069,8 @@ search_next_ref_view(struct tog_view *view)
 
 	while (1) {
 		if (re == NULL) {
-			if (s->matched_entry == NULL) {
+			if (s->matched_entry == NULL ||
+			    getenv("TOG_CYCLE_MOVEMENT") == NULL) {
 				view->search_next_done = TOG_SEARCH_HAVE_MORE;
 				return NULL;
 			}