Index | Thread | Search

From:
Dante Catalfamo <dante@lambda.cx>
Subject:
mg: grep buffer improvements
To:
tech@openbsd.org
Date:
Sun, 02 Jun 2024 23:31:17 -0400

Download raw body.

Thread
Hi,

This copies behaviour from Emacs, and makes navigating the `grep`
buffer easier and faster.

The grep output buffer is marked read-only. Pressing `n` will jump to
the next file:line and open it in a split, but will keep focus on the
grep buffer. This lets you quickly press `n` so scan through the
results. It does the same with `p`, but it goes to the previous result
instead of the next.

Dante

diff --git def.h def.h
index 403635036..9682c0927 100644
--- def.h
+++ def.h
@@ -724,6 +724,7 @@ int		 cc_lfindent(int, int);
 
 /* grep.c X */
 int		 next_error(int, int);
+int		 previous_error(int, int);
 int		 globalwdtoggle(int, int);
 int		 compile(int, int);
 
diff --git grep.c grep.c
index aa7f9dfd8..2b5ff239a 100644
--- grep.c
+++ grep.c
@@ -22,6 +22,9 @@
 int	 globalwd = FALSE;
 static int	 compile_goto_error(int, int);
 int		 next_error(int, int);
+int		 previous_error(int, int);
+int		 grep_next_error(int, int);
+int		 grep_previous_error(int, int);
 static int	 grep(int, int);
 static int	 gid(int, int);
 static struct buffer	*compile_mode(const char *, const char *);
@@ -37,16 +40,23 @@ static char compile_last_command[NFILEN] = "make ";
 struct mgwin	*compile_win;
 struct buffer	*compile_buffer;
 
-static PF compile_pf[] = {
+static PF compile_cm[] = {
 	compile_goto_error
 };
 
-static struct KEYMAPE (1) compilemap = {
-	1,
-	1,
+static PF compile_n[] = {
+	grep_next_error, /* n */
+	rescan, /* o */
+	grep_previous_error, /* p */
+};
+
+static struct KEYMAPE (2) compilemap = {
+	2,
+	2,
 	rescan,
 	{
-		{ CCHR('M'), CCHR('M'), compile_pf, NULL }
+		{ CCHR('M'), CCHR('M'), compile_cm, NULL },
+		{ 'n', 'p', compile_n, NULL }
 	}
 };
 
@@ -55,6 +65,9 @@ grep_init(void)
 {
 	funmap_add(compile_goto_error, "compile-goto-error", 0);
 	funmap_add(next_error, "next-error", 0);
+	funmap_add(previous_error, "previous-error", 0);
+	funmap_add(grep_next_error, "grep-next-error", 0);
+	funmap_add(grep_previous_error, "grep-previous-error", 0);
 	funmap_add(grep, "grep", 1);
 	funmap_add(compile, "compile", 0);
 	funmap_add(gid, "gid", 1);
@@ -83,6 +96,7 @@ grep(int f, int n)
 		return (FALSE);
 	curbp = bp;
 	compile_win = curwp = wp;
+	curbp->b_flag |= BFREADONLY;
 	return (TRUE);
 }
 
@@ -317,6 +331,60 @@ fail:
 	return (FALSE);
 }
 
+int
+grep_next_error(int f, int n)
+{
+	int ret;
+
+	if ((ret = next_error(f, n)) != (TRUE)) {
+		return ret;
+	}
+
+	curwp = compile_win;
+	curbp = compile_buffer;
+
+	return (TRUE);
+}
+
+int
+grep_previous_error(int f, int n)
+{
+	int ret;
+
+	if ((ret = previous_error(f, n)) != (TRUE)) {
+		return ret;
+	}
+
+	curwp = compile_win;
+	curbp = compile_buffer;
+
+	return (TRUE);
+}
+
+int
+previous_error(int f, int n)
+{
+	if (compile_win == NULL || compile_buffer == NULL) {
+		dobeep();
+		ewprintf("No compilation active");
+		return (FALSE);
+	}
+
+	curwp = compile_win;
+	curbp = compile_buffer;
+
+	if (curwp->w_dotp == bfirstlp(curbp)) {
+		dobeep();
+		ewprintf("Beginning of buffer");
+		return (FALSE);
+	}
+
+	curwp->w_dotp = lback(curwp->w_dotp);
+	curwp->w_rflag |= WFMOVE;
+
+	return (compile_goto_error(f, n));
+}
+
 int
 next_error(int f, int n)
 {