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

[PATCH v4 3/3] Add colors to interactive git-clean

From
Jiang Xin <worldhello.net@gmail.com>
Date
May 2, 2013, 13:15 UTC
Message-ID
<bb5463fa4ef09df08ad3bf5abf4660a5df414e64.1367500374.git.worldhello.net@gmail.com>
In-Reply-To
<3b80db3d2e8f31b1d9373406cce3cbdee2094a29.1367500374.git.worldhello.net@gmail.com>

Show help, error messages, and prompt in colors for interactive git-clean. Re-use config variables from git-add--interactive:

 * color.interactive: When set to always, always use colors for
   interactive prompts and displays. When false (or never),
   never. When set to true or auto, use colors only when the
   output is to the terminal.
 * color.interactive.<slot>: Use customized color for interactive
   git-clean output (like git add --interactive). <slot> may be
   prompt, header, help or error.
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
---
 builtin/clean.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)
diff --git a/builtin/clean.c b/builtin/clean.c
index ac48e..c85b 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -14,6 +14,7 @@
 #include "string-list.h"
 #include "quote.h"
 #include "column.h"
+#include "color.h"
 
 static int force = -1; /* unset */
 static int interactive;
@@ -30,15 +31,71 @@ static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
 static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
 static const char *msg_warn_remove_failed = N_("failed to remove %s");
 
+static int clean_use_color = -1;
+static char clean_colors[][COLOR_MAXLEN] = {
+	GIT_COLOR_RESET,
+	GIT_COLOR_NORMAL,	/* PLAIN */
+	GIT_COLOR_BOLD_BLUE,	/* PROMPT */
+	GIT_COLOR_BOLD_RED,	/* HELP */
+	GIT_COLOR_BOLD_RED,	/* ERROR */
+};
+enum color_clean {
+	CLEAN_COLOR_RESET = 0,
+	CLEAN_COLOR_PLAIN = 1,
+	CLEAN_COLOR_PROMPT = 2,
+	CLEAN_COLOR_HELP = 3,
+	CLEAN_COLOR_ERROR = 4
+};
+
+static int parse_clean_color_slot(const char *var, int ofs)
+{
+	if (!strcasecmp(var+ofs, "reset"))
+		return CLEAN_COLOR_RESET;
+	if (!strcasecmp(var+ofs, "plain"))
+		return CLEAN_COLOR_PLAIN;
+	if (!strcasecmp(var+ofs, "prompt"))
+		return CLEAN_COLOR_PROMPT;
+	if (!strcasecmp(var+ofs, "help"))
+		return CLEAN_COLOR_HELP;
+	if (!strcasecmp(var+ofs, "error"))
+		return CLEAN_COLOR_ERROR;
+	return -1;
+}
+
 static int git_clean_config(const char *var, const char *value, void *cb)
 {
 	if (!prefixcmp(var, "column."))
 		return git_column_config(var, value, "clean", &colopts);
+	if (!strcmp(var, "color.interactive")) {
+		clean_use_color = git_config_colorbool(var, value);
+		return 0;
+	}
+	if (!prefixcmp(var, "color.interactive.")) {
+		int slot = parse_clean_color_slot(var, 18);
+		if (slot < 0)
+			return 0;
+		if (!value)
+			return config_error_nonbool(var);
+		color_parse(value, var, clean_colors[slot]);
+		return 0;
+	}
 	if (!strcmp(var, "clean.requireforce")) {
 		force = !git_config_bool(var, value);
 		return 0;
 	}
-	return git_default_config(var, value, cb);
+	return git_color_default_config(var, value, cb);
+}
+
+static const char *clean_get_color(enum color_clean ix)
+{
+	if (want_color(clean_use_color))
+		return clean_colors[ix];
+	return "";
+}
+
+static void clean_print_color(enum color_clean ix)
+{
+	printf("%s", clean_get_color(ix));
 }
 
 static int exclude_cb(const struct option *opt, const char *arg, int unset)
@@ -190,16 +247,20 @@ void interactive_clean_edit(struct string_list *dels, const char *prefix)
 	while (1) {
 		/* dels list may become empty when we run string_list_remove_empty_items later */
 		if (!dels->nr) {
+			clean_print_color(CLEAN_COLOR_ERROR);
 			printf_ln(_("No more files to clean, exiting."));
+			clean_print_color(CLEAN_COLOR_RESET);
 			break;
 		}
 
 		if (changed) {
+			clean_print_color(CLEAN_COLOR_HELP);
 			printf(_(
 				 "NOTE: Will remove the following items. You can input space-seperated\n"
 				 "NOTE: patterns (just like .gitignore) to exclude items from deletion,\n"
 				 "NOTE: or press ENTER to continue."
 				));
+			clean_print_color(CLEAN_COLOR_RESET);
 			putchar('\n');
 			putchar('\n');
 
@@ -207,7 +268,9 @@ void interactive_clean_edit(struct string_list *dels, const char *prefix)
 			pretty_print_dels(dels, prefix);
 		}
 
+		clean_print_color(CLEAN_COLOR_PROMPT);
 		printf(_("Input ignore patterns> "));
+		clean_print_color(CLEAN_COLOR_RESET);
 		strbuf_getline(&confirm, stdin, '\n');
 		strbuf_trim(&confirm);
 		putchar('\n');
@@ -244,7 +307,9 @@ void interactive_clean_edit(struct string_list *dels, const char *prefix)
 		if (changed) {
 			string_list_remove_empty_items(dels, 0);
 		} else {
+			clean_print_color(CLEAN_COLOR_ERROR);
 			printf(_("WARNING: Cannot find items matched by: %s"), confirm.buf);
+			clean_print_color(CLEAN_COLOR_RESET);
 			putchar('\n');
 		}
 
@@ -263,6 +328,7 @@ void interactive_clean(struct string_list *dels, const char *prefix)
 
 	/* dels list may become empty after return back from edit mode */
 	while (dels->nr) {
+		clean_print_color(CLEAN_COLOR_HELP);
 		printf_ln(_(
 			    "WARNING: The following items will be removed permanently. Press \"y\"\n"
 			    "WARNING: to start cleaning, and press \"n\" to abort the cleaning.\n"
@@ -270,12 +336,15 @@ void interactive_clean(struct string_list *dels, const char *prefix)
 			    "WARNING: to be excluded from the cleaning."
 			   ));
 		putchar('\n');
+		clean_print_color(CLEAN_COLOR_RESET);
 
 		/* Display dels in columns */
 		pretty_print_dels(dels, prefix);
 
 		/* Confirmation dialog */
+		clean_print_color(CLEAN_COLOR_PROMPT);
 		printf(count > 0 ? _("Remove (Yes/no/edit) ? ") : _("Remove (yes/no/Edit) ? "));
+		clean_print_color(CLEAN_COLOR_RESET);
 		strbuf_getline(&confirm, stdin, '\n');
 		strbuf_trim(&confirm);
 		putchar('\n');
-- 
1.8.3.rc0.364.gbb5463f
Previous: Jiang XinNext: Matthieu Moy
Message 24 of 30 in “clean: confirm before cleaning files and directories”
  1. clean: confirm before cleaning files and directoriesJiang Xin, Apr 26, 2013
  2. Matthieu MoyApr 26, 2013
  3. Jiang XinApr 26, 2013
  4. Matthieu MoyApr 26, 2013
  5. Jiang XinApr 26, 2013
  6. Thomas RastApr 26, 2013
  7. Junio C HamanoApr 26, 2013
  8. Matthieu MoyApr 26, 2013
  9. Junio C HamanoApr 26, 2013
  10. Junio C HamanoApr 26, 2013
  11. Jiang XinApr 27, 2013
  12. Add support for -i/--interactive to git-cleanJiang Xin, Apr 27, 2013
  13. Matthieu MoyApr 27, 2013
  14. Junio C HamanoApr 27, 2013
  15. Eric SunshineApr 28, 2013
  16. Matthieu MoyApr 29, 2013
  17. clean: Introduce -z for machine readable outputMichael J Gruber, Apr 29, 2013
  18. Matthieu MoyApr 29, 2013
  19. Jiang XinApr 29, 2013
  20. Add support for -i/--interactive to git-cleanJiang Xin, Apr 30, 2013
  21. Matthieu MoyMay 1, 2013
  22. 1/3 Add support for -i/--interactive to git-cleanJiang Xin, May 2, 2013
  23. 2/3 Show items of interactive git-clean in columnsJiang Xin, May 2, 2013
  24. 3/3 Add colors to interactive git-cleanJiang Xin, May 2, 2013
  25. Matthieu MoyMay 2, 2013
  26. Jiang XinMay 3, 2013
  27. Matthieu MoyMay 2, 2013
  28. Jiang XinMay 3, 2013
  29. Matthieu MoyMay 3, 2013
  30. Jiang XinMay 2, 2013

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.