[PATCH v5 04/10] add-interactive.c: implement list_and_choose

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Slavica Djukic <slawica92@xxxxxxxxxxx>

This is one of the two functions translated from Perl script, besides
list_modified that will be used by *_cmd functions (including status)
to collect index/worktree changes, list those changes and let user
make a choice.

At this point, it only prints worktree and index changes, but later on
in this patch series there will be upgraded to highlighting unique
prefixes of list items and let user pick those items.

Mentored-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx>
Signed-off-by: Slavica Djukic <slawica92@xxxxxxxxxxx>
---
 add-interactive.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/add-interactive.c b/add-interactive.c
index 7d096207d4..9a475a5d48 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -5,6 +5,8 @@
 #include "diffcore.h"
 #include "revision.h"
 
+#define HEADER_INDENT "      "
+
 enum collection_phase {
 	WORKTREE,
 	INDEX
@@ -27,6 +29,61 @@ struct collection_status {
 	struct hashmap file_map;
 };
 
+struct list_and_choose_options {
+	int column_n;
+	unsigned singleton:1;
+	unsigned list_flat:1;
+	unsigned list_only:1;
+	unsigned list_only_file_names:1;
+	unsigned immediate:1;
+	char *header;
+	const char *prompt;
+	void (*on_eof_fn)(void);
+};
+
+struct choice {
+	struct hashmap_entry e;
+	char type;
+	union {
+		void (*command_fn)(void);
+		struct {
+			struct {
+				uintmax_t added, deleted;
+			} index, worktree;
+		} file;
+	} u;
+	size_t prefix_length;
+	const char *name;
+};
+
+struct choices {
+	struct choice **choices;
+	size_t alloc, nr;
+};
+#define CHOICES_INIT { NULL, 0, 0 }
+
+static int use_color = -1;
+enum color_add_i {
+	COLOR_PROMPT,
+	COLOR_HEADER,
+	COLOR_HELP,
+	COLOR_ERROR
+};
+
+static char colors[][COLOR_MAXLEN] = {
+	GIT_COLOR_BOLD_BLUE, /* Prompt */
+	GIT_COLOR_BOLD,      /* Header */
+	GIT_COLOR_BOLD_RED,  /* Help */
+	GIT_COLOR_RESET      /* Reset */
+};
+
+static const char *get_color(enum color_add_i ix)
+{
+	if (want_color(use_color))
+		return colors[ix];
+	return "";
+}
+
 static int hash_cmp(const void *unused_cmp_data, const void *entry,
 		    const void *entry_or_key, const void *keydata)
 {
@@ -186,3 +243,73 @@ static struct collection_status *list_modified(struct repository *r, const char
 	free(files);
 	return s;
 }
+
+static struct choices *list_and_choose(struct choices *data,
+				       struct list_and_choose_options *opts)
+{
+	if (!data)
+		return NULL;
+
+	while (1) {
+		int last_lf = 0;
+
+		if (opts->header) {
+			const char *header_color = get_color(COLOR_HEADER);
+			if (!opts->list_flat)
+				printf(HEADER_INDENT);
+			color_fprintf_ln(stdout, header_color, "%s", opts->header);
+		}
+
+		for (int i = 0; i < data->nr; i++) {
+			struct choice *c = data->choices[i];
+			char *print;
+			const char *modified_fmt = _("%12s %12s %s");
+			char worktree_changes[50];
+			char index_changes[50];
+			char print_buf[100];
+
+			print = (char *)c->name;
+			
+			if ((data->choices[i]->type == 'f') && (!opts->list_only_file_names)) {
+				uintmax_t worktree_added = c->u.file.worktree.added;
+				uintmax_t worktree_deleted = c->u.file.worktree.deleted;
+				uintmax_t index_added = c->u.file.index.added;
+				uintmax_t index_deleted = c->u.file.index.deleted;
+
+				if (worktree_added || worktree_deleted)
+					snprintf(worktree_changes, 50, "+%"PRIuMAX"/-%"PRIuMAX,
+						 worktree_added, worktree_deleted);
+				else
+					snprintf(worktree_changes, 50, "%s", _("nothing"));
+
+				if (index_added || index_deleted)
+					snprintf(index_changes, 50, "+%"PRIuMAX"/-%"PRIuMAX,
+						 index_added, index_deleted);
+				else
+					snprintf(index_changes, 50, "%s", _("unchanged"));
+
+				snprintf(print_buf, 100, modified_fmt, index_changes,
+					 worktree_changes, print);
+				print = xmalloc(strlen(print_buf) + 1);
+				snprintf(print, 100, "%s", print_buf);
+			}
+
+			printf(" %2d: %s", i + 1, print);
+
+			if ((opts->list_flat) && ((i + 1) % (opts->column_n))) {
+				printf("\t");
+				last_lf = 0;
+			}
+			else {
+				printf("\n");
+				last_lf = 1;
+			}
+
+		}
+
+		if (!last_lf)
+			printf("\n");
+
+		return NULL;
+	}
+}
-- 
gitgitgadget




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux