git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/3] grep: fix coloring of hunk marks between files

From
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Date
Jun 5, 2011, 15:24 UTC
Message-ID
<4DEB9F9F.7040704@lsrfire.ath.cx>
In-Reply-To
<4DEB9F07.1070006@lsrfire.ath.cx>

Commit 431d6e7b (grep: enable threading for context line printing) split the printing of the "--\n" mark between results from different files out into two places: show_line() in grep.c for the non-threaded case and work_done() in builtin/grep.c for the threaded case. Commit 55f638bd (grep: Colorize filename, line number, and separator) updated the former, but not the latter, so the separators between files are not colored if threads are used.

This patch merges the two. In the threaded case, hunk marks are now printed by show_line() for every file, including the first one, and the very first mark is simply skipped in work_done(). This ensures that the output is properly colored and works just as well.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 builtin/grep.c  |   23 ++++++++++++++++-------
 grep.c          |   15 ++++++++++++---
 t/t7810-grep.sh |   30 ++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/builtin/grep.c b/builtin/grep.c
index 871afaa..0d5a90b 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -93,8 +93,7 @@ static pthread_cond_t cond_write;
 /* Signalled when we are finished with everything. */
 static pthread_cond_t cond_result;
 
-static int print_hunk_marks_between_files;
-static int printed_something;
+static int skip_first_line;
 
 static void add_work(enum work_type type, char *name, void *id)
 {
@@ -160,10 +159,20 @@ static void work_done(struct work_item *w)
 	    todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
 		w = &todo[todo_done];
 		if (w->out.len) {
-			if (print_hunk_marks_between_files && printed_something)
-				write_or_die(1, "--\n", 3);
-			write_or_die(1, w->out.buf, w->out.len);
-			printed_something = 1;
+			const char *p = w->out.buf;
+			size_t len = w->out.len;
+
+			/* Skip the leading hunk mark of the first file. */
+			if (skip_first_line) {
+				while (len) {
+					len--;
+					if (*p++ == '\n')
+						break;
+				}
+				skip_first_line = 0;
+			}
+
+			write_or_die(1, p, len);
 		}
 		free(w->name);
 		free(w->identifier);
@@ -968,7 +977,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 
 	if (use_threads) {
 		if (opt.pre_context || opt.post_context)
-			print_hunk_marks_between_files = 1;
+			skip_first_line = 1;
 		start_threads(&opt);
 	}
 #else
diff --git a/grep.c b/grep.c
index d03d9e2..3f15085 100644
--- a/grep.c
+++ b/grep.c
@@ -941,9 +941,18 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 	if (!opt->output)
 		opt->output = std_output;
 
-	if (opt->last_shown && (opt->pre_context || opt->post_context) &&
-	    opt->output == std_output)
-		opt->show_hunk_mark = 1;
+	if (opt->pre_context || opt->post_context) {
+		/* Show hunk marks, except for the first file. */
+		if (opt->last_shown)
+			opt->show_hunk_mark = 1;
+		/*
+		 * If we're using threads then we can't easily identify
+		 * the first file.  Always put hunk marks in that case
+		 * and skip the very first one later in work_done().
+		 */
+		if (opt->output != std_output)
+			opt->show_hunk_mark = 1;
+	}
 	opt->last_shown = 0;
 
 	switch (opt->binary) {
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 69bd576..539a8fe 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -716,4 +716,34 @@ test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '
 	test_cmp expected actual
 '
 
+test_config() {
+	git config "$1" "$2" &&
+	test_when_finished "git config --unset $1"
+}
+
+cat >expected <<EOF
+hello.c<RED>:<RESET>int main(int argc, const char **argv)
+hello.c<RED>-<RESET>{
+<RED>--<RESET>
+hello.c<RED>:<RESET>	/* char ?? */
+hello.c<RED>-<RESET>}
+<RED>--<RESET>
+hello_world<RED>:<RESET>Hello_world
+hello_world<RED>-<RESET>HeLLo_world
+EOF
+
+test_expect_success 'grep --color, separator' '
+	test_config color.grep.context		normal &&
+	test_config color.grep.filename		normal &&
+	test_config color.grep.function		normal &&
+	test_config color.grep.linenumber	normal &&
+	test_config color.grep.match		normal &&
+	test_config color.grep.selected		normal &&
+	test_config color.grep.separator	red &&
+
+	git grep --color=always -A1 -e char -e lo_w hello.c hello_world |
+	test_decode_color >actual &&
+	test_cmp expected actual
+'
+
 test_done
-- 
1.7.6.rc0.3.ga805ac
Previous: René ScharfeNext: René Scharfe
Message 2 of 5 in “grep: add result grouping, ack style”
  1. 0/3 grep: add result grouping, ack styleRené Scharfe, Jun 5, 2011
  2. 1/3 grep: fix coloring of hunk marks between filesRené Scharfe, Jun 5, 2011
  3. 2/3 grep: add --breakRené Scharfe, Jun 5, 2011
  4. 3/3 grep: add --headingRené Scharfe, Jun 5, 2011
  5. Michał KiedrowiczJun 6, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.