git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Leon Michalak via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Leon Michalak <leonmichalak6@gmail.com>,
	Leon Michalak <leonmichalak6@gmail.com>
Subject: [PATCH 3/3] add-interactive: add new "context" subcommand
Date: Mon, 05 May 2025 09:18:39 +0000	[thread overview]
Message-ID: <b4b7854f330af7588b12e3361bed40723febddad.1746436719.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1915.git.1746436719.gitgitgadget@gmail.com>

From: Leon Michalak <leonmichalak6@gmail.com>

This teaches `add/commit --interactive` a new "context" subcommand, which
changes the amount of context lines subsequent subcommands like "patch"
or "diff" generate in their diffs.

Signed-off-by: Leon Michalak <leonmichalak6@gmail.com>
---
 Documentation/git-add.adoc | 10 ++++--
 add-interactive.c          | 72 +++++++++++++++++++++++++++++++++++++-
 t/t3701-add-interactive.sh | 36 ++++++++++++++++---
 3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc
index e3a50706acd5..1ab98c9b876e 100644
--- a/Documentation/git-add.adoc
+++ b/Documentation/git-add.adoc
@@ -265,14 +265,15 @@ and type return, like this:
 ------------
     *** Commands ***
       1: status       2: update       3: revert       4: add untracked
-      5: patch        6: diff         7: quit         8: help
+      5: patch        6: diff         7: context      8: quit
+      9: help
     What now> 1
 ------------
 
 You also could say `s` or `sta` or `status` above as long as the
 choice is unique.
 
-The main command loop has 6 subcommands (plus help and quit).
+The main command loop has 7 subcommands (plus help and quit).
 
 status::
 
@@ -373,6 +374,11 @@ diff::
   This lets you review what will be committed (i.e. between
   `HEAD` and index).
 
+context::
+
+  This lets you change the amount of context lines shown in diffs that
+  the 'patch' and 'diff' subcommands generate.
+
 
 EDITING PATCHES
 ---------------
diff --git a/add-interactive.c b/add-interactive.c
index 1ea8eb711a60..42b1bb8c5b64 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -20,6 +20,8 @@
 #include "prompt.h"
 #include "tree.h"
 
+static void choose_prompt_help_context(struct add_i_state *s);
+
 static void init_color(struct repository *r, struct add_i_state *s,
 		       const char *section_and_slot, char *dst,
 		       const char *default_color)
@@ -259,7 +261,8 @@ static void list(struct add_i_state *s, struct string_list *list, int *selected,
 		opts->print_item(i, selected ? selected[i] : 0, list->items + i,
 				 opts->print_item_data);
 
-		if ((opts->columns) && ((i + 1) % (opts->columns))) {
+		if (i < list->nr - 1 &&
+		    (opts->columns) && ((i + 1) % (opts->columns))) {
 			putchar('\t');
 			last_lf = 0;
 		}
@@ -1047,6 +1050,60 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps,
 	return res;
 }
 
+static int run_context(struct add_i_state *s, const struct pathspec *ps UNUSED,
+		       struct prefix_item_list *files UNUSED,
+		       struct list_and_choose_options *opts UNUSED)
+{
+	struct diff_options diffopts;
+	struct strbuf input = STRBUF_INIT;
+	int res = 0;
+
+	repo_diff_setup(s->r, &diffopts);
+
+	for (;;) {
+		int new_context;
+		char *endp;
+
+		strbuf_reset(&input);
+
+		color_fprintf(stdout, s->header_color, "  %s:", N_("Current"));
+		fprintf(stdout, " %i\n", s->context == -1 ?
+			diffopts.context : s->context);
+
+		color_fprintf(stdout, s->prompt_color, "%s", N_("Change context"));
+		fputs("> ", stdout);
+		fflush(stdout);
+
+		if (git_read_line_interactively(&input) == EOF) {
+			putchar('\n');
+			break;
+		}
+
+		if (!input.len)
+			break;
+
+		if (!strcmp(input.buf, "?")) {
+			choose_prompt_help_context(s);
+			continue;
+		}
+
+		new_context = strtol(input.buf, &endp, 10);
+		if (*endp) {
+			color_fprintf_ln(stderr, s->error_color,
+				_("Context must be a numerical value"));
+			continue;
+		}
+
+		s->context = new_context;
+
+		break;
+	}
+
+	strbuf_release(&input);
+	putchar('\n');
+	return res;
+}
+
 static int run_help(struct add_i_state *s, const struct pathspec *ps UNUSED,
 		    struct prefix_item_list *files UNUSED,
 		    struct list_and_choose_options *opts UNUSED)
@@ -1061,6 +1118,8 @@ static int run_help(struct add_i_state *s, const struct pathspec *ps UNUSED,
 			 _("pick hunks and update selectively"));
 	color_fprintf_ln(stdout, s->help_color, "diff          - %s",
 			 _("view diff between HEAD and index"));
+	color_fprintf_ln(stdout, s->help_color, "context       - %s",
+			 _("change how many context lines diffs are generated with"));
 	color_fprintf_ln(stdout, s->help_color, "add untracked - %s",
 			 _("add contents of untracked files to the staged set of changes"));
 
@@ -1087,6 +1146,16 @@ static void choose_prompt_help(struct add_i_state *s)
 			 _("(empty) finish selecting"));
 }
 
+static void choose_prompt_help_context(struct add_i_state *s)
+{
+	color_fprintf_ln(stdout, s->help_color, "%s",
+			 _("Prompt help:"));
+	color_fprintf_ln(stdout, s->help_color, "<n>        - %s",
+			 _("specify new context lines amount"));
+	color_fprintf_ln(stdout, s->help_color, "           - %s",
+			 _("(empty) finish selecting"));
+}
+
 typedef int (*command_t)(struct add_i_state *s, const struct pathspec *ps,
 			 struct prefix_item_list *files,
 			 struct list_and_choose_options *opts);
@@ -1147,6 +1216,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps,
 		{ "add untracked", run_add_untracked },
 		{ "patch", run_patch },
 		{ "diff", run_diff },
+		{ "context", run_context },
 		{ "quit", NULL },
 		{ "help", run_help },
 	};
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index b8a05d95f3f1..9dcbc07d5876 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -758,16 +758,19 @@ test_expect_success 'colors can be overridden' '
 
 	<RED>*** Commands ***<RESET>
 	  1: <YELLOW>s<RESET>tatus	  2: <YELLOW>u<RESET>pdate	  3: <YELLOW>r<RESET>evert	  4: <YELLOW>a<RESET>dd untracked
-	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>q<RESET>uit	  8: <YELLOW>h<RESET>elp
+	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>c<RESET>ontext	  8: <YELLOW>q<RESET>uit
+	  9: <YELLOW>h<RESET>elp
 	<YELLOW>What now<RESET>> <GREEN>status        - show paths with changes<RESET>
 	<GREEN>update        - add working tree state to the staged set of changes<RESET>
 	<GREEN>revert        - revert staged set of changes back to the HEAD version<RESET>
 	<GREEN>patch         - pick hunks and update selectively<RESET>
 	<GREEN>diff          - view diff between HEAD and index<RESET>
+	<GREEN>context       - change how many context lines diffs are generated with<RESET>
 	<GREEN>add untracked - add contents of untracked files to the staged set of changes<RESET>
 	<RED>*** Commands ***<RESET>
 	  1: <YELLOW>s<RESET>tatus	  2: <YELLOW>u<RESET>pdate	  3: <YELLOW>r<RESET>evert	  4: <YELLOW>a<RESET>dd untracked
-	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>q<RESET>uit	  8: <YELLOW>h<RESET>elp
+	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>c<RESET>ontext	  8: <YELLOW>q<RESET>uit
+	  9: <YELLOW>h<RESET>elp
 	<YELLOW>What now<RESET>> Bye.
 	EOF
 	test_cmp expect actual &&
@@ -831,7 +834,8 @@ test_expect_success 'brackets appear without color' '
 	|
 	|*** Commands ***
 	|  1: [s]tatus	  2: [u]pdate	  3: [r]evert	  4: [a]dd untracked
-	|  5: [p]atch	  6: [d]iff	  7: [q]uit	  8: [h]elp
+	|  5: [p]atch	  6: [d]iff	  7: [c]ontext	  8: [q]uit
+	|  9: [h]elp
 	|What now> Bye.
 	EOF
 
@@ -1172,16 +1176,19 @@ test_expect_success 'show help from add--helper' '
 
 	<BOLD>*** Commands ***<RESET>
 	  1: <BOLD;BLUE>s<RESET>tatus	  2: <BOLD;BLUE>u<RESET>pdate	  3: <BOLD;BLUE>r<RESET>evert	  4: <BOLD;BLUE>a<RESET>dd untracked
-	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>q<RESET>uit	  8: <BOLD;BLUE>h<RESET>elp
+	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>c<RESET>ontext	  8: <BOLD;BLUE>q<RESET>uit
+	  9: <BOLD;BLUE>h<RESET>elp
 	<BOLD;BLUE>What now<RESET>> <BOLD;RED>status        - show paths with changes<RESET>
 	<BOLD;RED>update        - add working tree state to the staged set of changes<RESET>
 	<BOLD;RED>revert        - revert staged set of changes back to the HEAD version<RESET>
 	<BOLD;RED>patch         - pick hunks and update selectively<RESET>
 	<BOLD;RED>diff          - view diff between HEAD and index<RESET>
+	<BOLD;RED>context       - change how many context lines diffs are generated with<RESET>
 	<BOLD;RED>add untracked - add contents of untracked files to the staged set of changes<RESET>
 	<BOLD>*** Commands ***<RESET>
 	  1: <BOLD;BLUE>s<RESET>tatus	  2: <BOLD;BLUE>u<RESET>pdate	  3: <BOLD;BLUE>r<RESET>evert	  4: <BOLD;BLUE>a<RESET>dd untracked
-	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>q<RESET>uit	  8: <BOLD;BLUE>h<RESET>elp
+	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>c<RESET>ontext	  8: <BOLD;BLUE>q<RESET>uit
+	  9: <BOLD;BLUE>h<RESET>elp
 	<BOLD;BLUE>What now<RESET>>$SP
 	Bye.
 	EOF
@@ -1230,4 +1237,23 @@ test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' '
 	test_cmp expect actual
 '
 
+test_expect_success 'change context works' '
+	git reset --hard &&
+	cat >template <<-\EOF &&
+	firstline
+	preline
+	TARGET
+	postline
+	lastline
+	EOF
+	sed "/TARGET/d" >x <template &&
+	git update-index --add x &&
+	git commit -m initial &&
+	sed "s/TARGET/ADDED/" >x <template &&
+	test_write_lines p 1 | git add -i >output &&
+	grep firstline output &&
+	test_write_lines c 0 p 1 | git add -i >output &&
+	! grep firstline output
+'
+
 test_done
-- 
gitgitgadget

  parent reply	other threads:[~2025-05-05  9:18 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-05  9:18 [PATCH 0/3] Better support for customising context lines in --patch commands Leon Michalak via GitGitGadget
2025-05-05  9:18 ` [PATCH 1/3] add-patch: respect diff.context configuration Leon Michalak via GitGitGadget
2025-05-05 20:29   ` Eric Sunshine
2025-05-06  8:55   ` Phillip Wood
2025-05-06 17:29   ` Junio C Hamano
2025-05-05  9:18 ` [PATCH 2/3] add-patch: add diff.context command line overrides Leon Michalak via GitGitGadget
2025-05-05  9:49   ` Kristoffer Haugsbakk
     [not found]     ` <CAP9jKjHj7WP91aKA9SE94zYj+naBGLUs99mF3G4BhTGcGjFDUQ@mail.gmail.com>
2025-05-05 10:11       ` Leon Michalak
2025-05-07  9:51   ` Phillip Wood
2025-05-07 18:07     ` Junio C Hamano
2025-05-07 18:28       ` Leon Michalak
2025-05-07 20:25         ` Junio C Hamano
2025-05-05  9:18 ` Leon Michalak via GitGitGadget [this message]
2025-05-06  0:02   ` [PATCH 3/3] add-interactive: add new "context" subcommand Eric Sunshine
2025-05-06  7:20     ` Leon Michalak
2025-05-06  8:28       ` Christian Couder
2025-05-06 17:07         ` Leon Michalak
2025-05-06 16:37     ` Junio C Hamano
2025-05-06 17:25       ` Leon Michalak
2025-05-07 13:30       ` Phillip Wood
2025-05-07 19:10         ` Junio C Hamano
2025-05-10 13:46 ` [PATCH v2 0/4] Better support for customising context lines in --patch commands Leon Michalak via GitGitGadget
2025-05-10 13:46   ` [PATCH v2 1/4] test: refactor to use "test_grep" Leon Michalak via GitGitGadget
2025-05-12 13:42     ` Junio C Hamano
2025-05-12 16:58       ` Leon Michalak
2025-05-10 13:46   ` [PATCH v2 2/4] test: refactor to use "test_config" Leon Michalak via GitGitGadget
2025-05-10 13:46   ` [PATCH v2 3/4] add-patch: respect diff.context configuration Leon Michalak via GitGitGadget
2025-05-13 13:52     ` Phillip Wood
2025-05-13 15:47       ` Junio C Hamano
2025-05-14 15:13         ` Phillip Wood
2025-05-15 12:58           ` Junio C Hamano
2025-05-10 13:46   ` [PATCH v2 4/4] add-patch: add diff.context command line overrides Leon Michalak via GitGitGadget
2025-05-12 16:45     ` Junio C Hamano
2025-05-12 17:03       ` Leon Michalak
2025-05-13 13:52     ` Phillip Wood
2025-05-13 14:39       ` Phillip Wood
2025-05-13 15:05         ` Leon Michalak
2025-05-14 15:13           ` phillip.wood123
2025-06-28 16:34   ` [PATCH v3 0/4] Better support for customising context lines in --patch commands Leon Michalak via GitGitGadget
2025-06-28 16:34     ` [PATCH v3 1/4] test: use "test_grep" Leon Michalak via GitGitGadget
2025-06-30 16:23       ` Junio C Hamano
2025-06-28 16:34     ` [PATCH v3 2/4] test: use "test_config" Leon Michalak via GitGitGadget
2025-06-30 16:35       ` Junio C Hamano
2025-06-28 16:34     ` [PATCH v3 3/4] add-patch: respect diff.context configuration Leon Michalak via GitGitGadget
2025-06-30 16:55       ` Junio C Hamano
2025-07-01 10:00       ` Phillip Wood
2025-06-28 16:34     ` [PATCH v3 4/4] add-patch: add diff.context command line overrides Leon Michalak via GitGitGadget
2025-06-30 17:03       ` Junio C Hamano
2025-07-01  9:59         ` Phillip Wood
2025-07-01 15:54           ` Junio C Hamano
2025-07-02 14:07             ` Phillip Wood
2025-07-02 18:28               ` Junio C Hamano
2025-07-01  9:59       ` Phillip Wood
2025-06-30 16:16     ` [PATCH v3 0/4] Better support for customising context lines in --patch commands Junio C Hamano
2025-07-09  0:09     ` Junio C Hamano
2025-07-09  7:57       ` Leon Michalak
2025-07-09 15:32         ` Junio C Hamano
2025-07-19 12:28     ` [PATCH v4 " Leon Michalak via GitGitGadget
2025-07-19 12:28       ` [PATCH v4 1/4] t: use test_grep in t3701 and t4055 Leon Michalak via GitGitGadget
2025-07-19 12:28       ` [PATCH v4 2/4] t: use test_config in t4055 Leon Michalak via GitGitGadget
2025-07-19 12:28       ` [PATCH v4 3/4] add-patch: respect diff.context configuration Leon Michalak via GitGitGadget
2025-07-19 12:28       ` [PATCH v4 4/4] add-patch: add diff.context command line overrides Leon Michalak via GitGitGadget
2025-07-22 16:01         ` Phillip Wood
2025-07-22 18:02           ` Leon Michalak
2025-07-22 18:05             ` Leon Michalak
2025-07-23  9:41             ` Phillip Wood
2025-07-21 16:50       ` [PATCH v4 0/4] Better support for customising context lines in --patch commands Junio C Hamano
2025-07-22 16:05         ` Phillip Wood
2025-07-22 17:20           ` Junio C Hamano
2025-07-29  7:01       ` [PATCH v5 " Leon Michalak via GitGitGadget
2025-07-29  7:01         ` [PATCH v5 1/4] t: use test_grep in t3701 and t4055 Leon Michalak via GitGitGadget
2025-07-29  7:01         ` [PATCH v5 2/4] t: use test_config in t4055 Leon Michalak via GitGitGadget
2025-07-29  7:01         ` [PATCH v5 3/4] add-patch: respect diff.context configuration Leon Michalak via GitGitGadget
2025-07-29  7:01         ` [PATCH v5 4/4] add-patch: add diff.context command line overrides Leon Michalak via GitGitGadget
2025-07-29 15:21         ` [PATCH v5 0/4] Better support for customising context lines in --patch commands Phillip Wood
2025-07-29 15:55           ` Junio C Hamano
2025-07-29 16:18             ` Leon Michalak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b4b7854f330af7588b12e3361bed40723febddad.1746436719.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=leonmichalak6@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).