diff --git a/add-interactive.c b/add-interactive.c index a14c0feaa2..9b8cdb4a31 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -12,10 +12,10 @@ #include "prompt.h" static void init_color(struct repository *r, struct add_i_state *s, - const char *slot_name, char *dst, + const char *section_and_slot, char *dst, const char *default_color) { - char *key = xstrfmt("color.interactive.%s", slot_name); + char *key = xstrfmt("color.%s", section_and_slot); const char *value; if (!s->use_color) @@ -40,20 +40,27 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) git_config_colorbool("color.interactive", value); s->use_color = want_color(s->use_color); - init_color(r, s, "header", s->header_color, GIT_COLOR_BOLD); - init_color(r, s, "help", s->help_color, GIT_COLOR_BOLD_RED); - init_color(r, s, "prompt", s->prompt_color, GIT_COLOR_BOLD_BLUE); - init_color(r, s, "error", s->error_color, GIT_COLOR_BOLD_RED); - init_color(r, s, "reset", s->reset_color, GIT_COLOR_RESET); - init_color(r, s, "fraginfo", s->fraginfo_color, + init_color(r, s, "interactive.header", s->header_color, GIT_COLOR_BOLD); + init_color(r, s, "interactive.help", s->help_color, GIT_COLOR_BOLD_RED); + init_color(r, s, "interactive.prompt", s->prompt_color, + GIT_COLOR_BOLD_BLUE); + init_color(r, s, "interactive.error", s->error_color, + GIT_COLOR_BOLD_RED); + + init_color(r, s, "diff.frag", s->fraginfo_color, diff_get_color(s->use_color, DIFF_FRAGINFO)); - init_color(r, s, "context", s->context_color, - diff_get_color(s->use_color, DIFF_CONTEXT)); - init_color(r, s, "old", s->file_old_color, + init_color(r, s, "diff.context", s->context_color, "fall back"); + if (!strcmp(s->context_color, "fall back")) + init_color(r, s, "diff.plain", s->context_color, + diff_get_color(s->use_color, DIFF_CONTEXT)); + init_color(r, s, "diff.old", s->file_old_color, diff_get_color(s->use_color, DIFF_FILE_OLD)); - init_color(r, s, "new", s->file_new_color, + init_color(r, s, "diff.new", s->file_new_color, diff_get_color(s->use_color, DIFF_FILE_NEW)); + strlcpy(s->reset_color, + s->use_color ? GIT_COLOR_RESET : "", COLOR_MAXLEN); + FREE_AND_NULL(s->interactive_diff_filter); git_config_get_string("interactive.difffilter", &s->interactive_diff_filter); @@ -194,7 +201,8 @@ static ssize_t find_unique(const char *string, struct prefix_item_list *list) else if (index + 1 < list->sorted.nr && starts_with(list->sorted.items[index + 1].string, string)) return -1; - else if (index < list->sorted.nr) + else if (index < list->sorted.nr && + starts_with(list->sorted.items[index].string, string)) item = list->sorted.items[index].util; else return -1; @@ -364,7 +372,7 @@ static ssize_t list_and_choose(struct add_i_state *s, if (from < 0 || from >= items->items.nr || (singleton && from + 1 != to)) { - color_fprintf_ln(stdout, s->error_color, + color_fprintf_ln(stderr, s->error_color, _("Huh (%s)?"), p); break; } else if (singleton) { @@ -1131,7 +1139,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps) print_file_item_data.color = data.color; print_file_item_data.reset = data.reset; - strbuf_addstr(&header, " "); + strbuf_addstr(&header, " "); strbuf_addf(&header, print_file_item_data.modified_fmt, _("staged"), _("unstaged"), _("path")); opts.list_opts.header = header.buf; diff --git a/add-patch.c b/add-patch.c index be4cf6e9e5..2fad92ca37 100644 --- a/add-patch.c +++ b/add-patch.c @@ -661,13 +661,18 @@ static void render_hunk(struct add_p_state *s, struct hunk *hunk, else new_offset += delta; - strbuf_addf(out, "@@ -%lu,%lu +%lu,%lu @@", - old_offset, header->old_count, - new_offset, header->new_count); + strbuf_addf(out, "@@ -%lu", old_offset); + if (header->old_count != 1) + strbuf_addf(out, ",%lu", header->old_count); + strbuf_addf(out, " +%lu", new_offset); + if (header->new_count != 1) + strbuf_addf(out, ",%lu", header->new_count); + strbuf_addstr(out, " @@"); + if (len) strbuf_add(out, p, len); else if (colored) - strbuf_addf(out, "%s\n", GIT_COLOR_RESET); + strbuf_addf(out, "%s\n", s->s.reset_color); else strbuf_addch(out, '\n'); } @@ -1060,7 +1065,7 @@ static void recolor_hunk(struct add_p_state *s, struct hunk *hunk) s->s.file_new_color : s->s.context_color); strbuf_add(&s->colored, plain + current, eol - current); - strbuf_addstr(&s->colored, GIT_COLOR_RESET); + strbuf_addstr(&s->colored, s->s.reset_color); if (next > eol) strbuf_add(&s->colored, plain + eol, next - eol); current = next; @@ -1456,15 +1461,15 @@ static int patch_update_file(struct add_p_state *s, else prompt_mode_type = PROMPT_HUNK; - color_fprintf(stdout, s->s.prompt_color, - "(%"PRIuMAX"/%"PRIuMAX") ", + printf("%s(%"PRIuMAX"/%"PRIuMAX") ", s->s.prompt_color, (uintmax_t)hunk_index + 1, (uintmax_t)(file_diff->hunk_nr ? file_diff->hunk_nr : 1)); - color_fprintf(stdout, s->s.prompt_color, - _(s->mode->prompt_mode[prompt_mode_type]), - s->buf.buf); + printf(_(s->mode->prompt_mode[prompt_mode_type]), + s->buf.buf); + if (*s->s.reset_color) + fputs(s->s.reset_color, stdout); fflush(stdout); if (read_single_character(s) == EOF) break; diff --git a/git-add--interactive.perl b/git-add--interactive.perl index e713fe3d02..bc3a1e8eff 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -30,9 +30,9 @@ my ($fraginfo_color) = $diff_use_color ? ( $repo->get_color('color.diff.frag', 'cyan'), ) : (); -my ($diff_plain_color) = +my ($diff_context_color) = $diff_use_color ? ( - $repo->get_color('color.diff.plain', ''), + $repo->get_color($repo->config('color.diff.context') ? 'color.diff.context' : 'color.diff.plain', ''), ) : (); my ($diff_old_color) = $diff_use_color ? ( @@ -483,10 +483,8 @@ sub list_and_choose { my $last_lf = 0; if ($opts->{HEADER}) { - if (!$opts->{LIST_FLAT}) { - print " "; - } - print colored $header_color, "$opts->{HEADER}\n"; + my $indent = $opts->{LIST_FLAT} ? "" : " "; + print colored $header_color, "$indent$opts->{HEADER}\n"; } for ($i = 0; $i < @stuff; $i++) { my $chosen = $chosen[$i] ? '*' : ' '; @@ -1048,7 +1046,7 @@ sub color_diff { colored((/^@/ ? $fraginfo_color : /^\+/ ? $diff_new_color : /^-/ ? $diff_old_color : - $diff_plain_color), + $diff_context_color), $_); } @_; } diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index ca04fac417..cc3f434a97 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -589,6 +589,90 @@ test_expect_success 'diffs can be colorized' ' grep "$(printf "\\033")" output ' +test_expect_success 'colors can be overridden' ' + git reset --hard && + test_when_finished "git rm -f color-test" && + test_write_lines context old more-context >color-test && + git add color-test && + test_write_lines context new more-context another-one >color-test && + + echo trigger an error message >input && + force_color git \ + -c color.interactive.error=blue \ + add -i 2>err.raw err && + grep "Huh (trigger)?" err && + + test_write_lines help quit >input && + force_color git \ + -c color.interactive.header=red \ + -c color.interactive.help=green \ + -c color.interactive.prompt=yellow \ + add -i >actual.raw actual && + cat >expect <<-\EOF && + staged unstaged path + 1: +3/-0 +2/-1 color-test + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> status - show paths with changes + update - add working tree state to the staged set of changes + revert - revert staged set of changes back to the HEAD version + patch - pick hunks and update selectively + diff - view diff between HEAD and index + add untracked - add contents of untracked files to the staged set of changes + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> Bye. + EOF + test_cmp expect actual && + + : exercise recolor_hunk by editing and then look at the hunk again && + test_write_lines s e K q >input && + force_color git \ + -c color.interactive.prompt=yellow \ + -c color.diff.meta=italic \ + -c color.diff.frag=magenta \ + -c color.diff.context=cyan \ + -c color.diff.old=bold \ + -c color.diff.new=blue \ + -c core.editor=touch \ + add -p >actual.raw actual.decoded && + sed "s/index [0-9a-f]*\\.\\.[0-9a-f]* 100644//" actual && + cat >expect <<-\EOF && + diff --git a/color-test b/color-test + + --- a/color-test + +++ b/color-test + @@ -1,3 +1,4 @@ + context + -old + +new + more-context + +another-one + (1/1) Stage this hunk [y,n,q,a,d,s,e,?]? Split into 2 hunks. + @@ -1,3 +1,3 @@ + context + -old + +new + more-context + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? @@ -3 +3,2 @@ + more-context + +another-one + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? @@ -1,3 +1,3 @@ + context + -old + +new + more-context + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? + EOF + test_cmp expect actual +' + test_expect_success 'colorized diffs respect diff.wsErrorHighlight' ' git reset --hard &&