* [PATCH 0/9] column output v3
@ 2011-03-20 12:57 Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 1/9] Move term_columns() to pager.c and save terminal width before pager Nguyễn Thái Ngọc Duy
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Compared to v2 [1]. It's quite ready for consumption:
- dense mode works better (and consumes more cpu cycles, but not much)
- there should be no impact when it's not activated (i.e. no
output buffering)
- column.ui is used for default settings. Not sure if I should go for
column.branch and column.tag
- --[no-]column can be used to override column.ui
[1] http://mid.gmane.org/1297254284-3729-1-git-send-email-pclouds@gmail.com
Nguyễn Thái Ngọc Duy (9):
Move term_columns() to pager.c and save terminal width before pager
Add display_columns() to display in columnar layout
column: add functions to parse column settings
display_columns: add COL_MODE_{COLUMN,ROW} mode
display_columns: add COL_DENSE to do unequal column layout
column: add column.ui for default column output settings
help: reuse display_columns() for help -a
tag: add --column
branch: add --column
.gitignore | 1 +
Documentation/config.txt | 24 +++
Documentation/git-branch.txt | 9 +
Documentation/git-tag.txt | 11 +-
Makefile | 3 +
builtin/branch.c | 23 ++-
builtin/tag.c | 21 ++-
column.c | 378 ++++++++++++++++++++++++++++++++++++++++++
column.h | 22 +++
help.c | 53 +-----
pager.c | 33 ++++
parse-options.h | 2 +
t/t9002-column.sh | 135 +++++++++++++++
test-column.c | 39 +++++
14 files changed, 701 insertions(+), 53 deletions(-)
create mode 100644 column.c
create mode 100644 column.h
create mode 100755 t/t9002-column.sh
create mode 100644 test-column.c
--
1.7.4.74.g639db
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/9] Move term_columns() to pager.c and save terminal width before pager
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 2/9] Add display_columns() to display in columnar layout Nguyễn Thái Ngọc Duy
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
term_columns() checks for terminal width via ioctl(2). After
redirecting, stdin is no longer terminal to get terminal width.
Check terminal width and save it before redirect stdin in setup_pager()
and let term_columns() reuse the value.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Makefile | 1 +
column.h | 6 ++++++
help.c | 23 +----------------------
| 33 +++++++++++++++++++++++++++++++++
4 files changed, 41 insertions(+), 22 deletions(-)
create mode 100644 column.h
diff --git a/Makefile b/Makefile
index 775ee83..6007f68 100644
--- a/Makefile
+++ b/Makefile
@@ -1956,6 +1956,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
connect.o transport.o http-backend.o: url.h
+help.o pager.o: column.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
diff --git a/column.h b/column.h
new file mode 100644
index 0000000..55d8067
--- /dev/null
+++ b/column.h
@@ -0,0 +1,6 @@
+#ifndef COLUMN_H
+#define COLUMN_H
+
+extern int term_columns(void);
+
+#endif
diff --git a/help.c b/help.c
index 7654f1b..768f64c 100644
--- a/help.c
+++ b/help.c
@@ -4,28 +4,7 @@
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
-
-/* most GUI terminals set COLUMNS (although some don't export it) */
-static int term_columns(void)
-{
- char *col_string = getenv("COLUMNS");
- int n_cols;
-
- if (col_string && (n_cols = atoi(col_string)) > 0)
- return n_cols;
-
-#ifdef TIOCGWINSZ
- {
- struct winsize ws;
- if (!ioctl(1, TIOCGWINSZ, &ws)) {
- if (ws.ws_col)
- return ws.ws_col;
- }
- }
-#endif
-
- return 80;
-}
+#include "column.h"
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
{
--git a/pager.c b/pager.c
index dac358f..dad6329 100644
--- a/pager.c
+++ b/pager.c
@@ -12,6 +12,19 @@
*/
static int spawned_pager;
+static int max_columns;
+
+static int retrieve_terminal_width(void)
+{
+#ifdef TIOCGWINSZ
+ struct winsize ws;
+ if (ioctl(1, TIOCGWINSZ, &ws)) /* e.g., ENOSYS */
+ return 0;
+ return ws.ws_col;
+#else
+ return 0;
+#endif
+}
#ifndef WIN32
static void pager_preexec(void)
@@ -74,12 +87,17 @@ const char *git_pager(int stdout_is_tty)
void setup_pager(void)
{
const char *pager = git_pager(isatty(1));
+ int width;
if (!pager)
return;
spawned_pager = 1; /* means we are emitting to terminal */
+ width = retrieve_terminal_width();
+ if (width)
+ max_columns = width;
+
/* spawn the pager */
pager_argv[0] = pager;
pager_process.use_shell = 1;
@@ -116,3 +134,18 @@ int pager_in_use(void)
env = getenv("GIT_PAGER_IN_USE");
return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
}
+
+int term_columns()
+{
+ char *col_string = getenv("COLUMNS");
+ int n_cols;
+
+ if (col_string && (n_cols = atoi(col_string)) > 0)
+ return n_cols;
+
+ if (spawned_pager && max_columns)
+ return max_columns;
+
+ n_cols = retrieve_terminal_width();
+ return n_cols ? n_cols : 80;
+}
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/9] Add display_columns() to display in columnar layout
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 1/9] Move term_columns() to pager.c and save terminal width before pager Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 3/9] column: add functions to parse column settings Nguyễn Thái Ngọc Duy
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Currently it does not do that, just provide the API. In order to
output in columns, COL_ENABLED bit must be set. A nice consequence is
mode 0 is effectively no column mode.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Makefile | 3 ++-
column.c | 37 +++++++++++++++++++++++++++++++++++++
column.h | 5 +++++
3 files changed, 44 insertions(+), 1 deletions(-)
create mode 100644 column.c
diff --git a/Makefile b/Makefile
index 6007f68..94e1cf0 100644
--- a/Makefile
+++ b/Makefile
@@ -575,6 +575,7 @@ LIB_OBJS += branch.o
LIB_OBJS += bundle.o
LIB_OBJS += cache-tree.o
LIB_OBJS += color.o
+LIB_OBJS += column.o
LIB_OBJS += combine-diff.o
LIB_OBJS += commit.o
LIB_OBJS += config.o
@@ -1956,7 +1957,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
connect.o transport.o http-backend.o: url.h
-help.o pager.o: column.h
+column.o help.o pager.o: column.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
diff --git a/column.c b/column.c
new file mode 100644
index 0000000..8422c89
--- /dev/null
+++ b/column.c
@@ -0,0 +1,37 @@
+#include "cache.h"
+#include "column.h"
+#include "string-list.h"
+
+#define MODE(mode) ((mode) & COL_MODE)
+
+struct string_list_item *add_to_columns(struct string_list *list, int mode,
+ const char *string)
+{
+ if (mode & COL_ENABLED)
+ return string_list_append(list, string);
+ printf("%s\n", string);
+ return NULL;
+}
+
+/* Display without layout when COL_ENABLED is not set */
+static void display_plain(const struct string_list *list, const char *indent)
+{
+ int i;
+
+ for (i = 0; i < list->nr; i++)
+ printf("%s%s\n", indent, list->items[i].string);
+}
+
+void display_columns(const struct string_list *list, int mode,
+ int width, int padding, const char *indent)
+{
+ if (!list->nr)
+ return;
+ if (!indent)
+ indent = "";
+ if (width <= 1 || !(mode & COL_ENABLED)) {
+ display_plain(list, indent);
+ return;
+ }
+ die("BUG: invalid mode %d", MODE(mode));
+}
diff --git a/column.h b/column.h
index 55d8067..ffae87c 100644
--- a/column.h
+++ b/column.h
@@ -1,6 +1,11 @@
#ifndef COLUMN_H
#define COLUMN_H
+#define COL_MODE 0x000F
+#define COL_ENABLED (1 << 4)
+
extern int term_columns(void);
+extern struct string_list_item *add_to_columns(struct string_list *list, int mode, const char *string);
+extern void display_columns(const struct string_list *list, int mode, int width, int padding, const char *indent);
#endif
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/9] column: add functions to parse column settings
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 1/9] Move term_columns() to pager.c and save terminal width before pager Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 2/9] Add display_columns() to display in columnar layout Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 4/9] display_columns: add COL_MODE_{COLUMN,ROW} mode Nguyễn Thái Ngọc Duy
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
A column option string consists of many token separated by either
space of commas. A token belongs to one of three groups:
- enabling: always, never and auto
- layout mode: to be implemented
- other tuning, which could be negated be prefix 'no'
A command line option without argument (e.g. --column) will enable
column output and reuse existing settings (layout mode and options..).
--no-column disables columnar output.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
.gitignore | 1 +
Makefile | 1 +
column.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++
column.h | 4 ++
parse-options.h | 2 +
t/t9002-column.sh | 27 +++++++++++
test-column.c | 39 ++++++++++++++++
7 files changed, 199 insertions(+), 0 deletions(-)
create mode 100755 t/t9002-column.sh
create mode 100644 test-column.c
diff --git a/.gitignore b/.gitignore
index 3dd6ef7..a1a1202 100644
--- a/.gitignore
+++ b/.gitignore
@@ -162,6 +162,7 @@
/gitweb/gitweb.cgi
/gitweb/static/gitweb.min.*
/test-chmtime
+/test-column
/test-ctype
/test-date
/test-delta
diff --git a/Makefile b/Makefile
index 94e1cf0..ba9944b 100644
--- a/Makefile
+++ b/Makefile
@@ -417,6 +417,7 @@ PROGRAM_OBJS += http-backend.o
PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
TEST_PROGRAMS_NEED_X += test-chmtime
+TEST_PROGRAMS_NEED_X += test-column
TEST_PROGRAMS_NEED_X += test-ctype
TEST_PROGRAMS_NEED_X += test-date
TEST_PROGRAMS_NEED_X += test-delta
diff --git a/column.c b/column.c
index 8422c89..b32b9f9 100644
--- a/column.c
+++ b/column.c
@@ -1,6 +1,7 @@
#include "cache.h"
#include "column.h"
#include "string-list.h"
+#include "parse-options.h"
#define MODE(mode) ((mode) & COL_MODE)
@@ -35,3 +36,127 @@ void display_columns(const struct string_list *list, int mode,
}
die("BUG: invalid mode %d", MODE(mode));
}
+
+struct colopt {
+ enum {
+ ENABLE,
+ MODE,
+ OPTION
+ } type;
+ const char *name;
+ int value;
+};
+
+/*
+ * Set COL_ENABLED and COL_ENABLED_SET. If 'set' is -1, check if
+ * stdout is tty.
+ */
+static int set_enable_bit(int *mode, int set, int stdout_is_tty)
+{
+ if (set < 0) { /* auto */
+ if (stdout_is_tty < 0)
+ stdout_is_tty = isatty(1);
+ set = stdout_is_tty || (pager_in_use() && pager_use_color);
+ }
+ if (set)
+ *mode = *mode | COL_ENABLED | COL_ENABLED_SET;
+ else
+ *mode = (*mode & ~COL_ENABLED) | COL_ENABLED_SET;
+ return 0;
+}
+
+/*
+ * Set COL_MODE_*. mode is intially copied from column.ui. If
+ * COL_ENABLED_SET is not set, then neither 'always', 'never' nor
+ * 'auto' has been used. Default to 'always'.
+ */
+static int set_mode(int *mode, int value)
+{
+ *mode = (*mode & ~COL_MODE) | value;
+ if (!(*mode & COL_ENABLED_SET))
+ *mode |= COL_ENABLED | COL_ENABLED_SET;
+
+ return 0;
+}
+
+/* Set or unset other COL_* */
+static int set_option(int *mode, int opt, int set)
+{
+ if (set)
+ *mode |= opt;
+ else
+ *mode &= ~opt;
+ return 0;
+}
+
+static int parse_option(const char *arg, int len,
+ int *mode, int stdout_is_tty)
+{
+ struct colopt opts[] = {
+ { ENABLE, "always", 1 },
+ { ENABLE, "never", 0 },
+ { ENABLE, "auto", -1 },
+ };
+ int i, set, name_len;
+
+ for (i = 0; i < ARRAY_SIZE(opts); i++) {
+ if (opts[i].type == OPTION) {
+ if (len > 2 && !strncmp(arg, "no", 2)) {
+ arg += 2;
+ len -= 2;
+ set = 0;
+ }
+ else
+ set = 1;
+ }
+
+ name_len = strlen(opts[i].name);
+ if (len != name_len ||
+ strncmp(arg, opts[i].name, name_len))
+ continue;
+
+ switch (opts[i].type) {
+ case ENABLE: return set_enable_bit(mode, opts[i].value,
+ stdout_is_tty);
+ case MODE: return set_mode(mode, opts[i].value);
+ case OPTION: return set_option(mode, opts[i].value, set);
+ default: die("BUG: Unknown option type %d", opts[i].type);
+ }
+ }
+
+ return error("unsupported style '%s'", arg);
+}
+
+static int parse_string(int *mode, const char *value,
+ int stdout_is_tty)
+{
+ const char *sep = " ,";
+
+ while (*value) {
+ int len = strcspn(value, sep);
+ if (len) {
+ if (parse_option(value, len, mode, stdout_is_tty))
+ return -1;
+
+ value += len;
+ }
+ value += strspn(value, sep);
+ }
+ return 0;
+}
+
+int parseopt_column_callback(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *mode = opt->value;
+ if (unset) {
+ *mode = (*mode & ~COL_ENABLED) | COL_ENABLED_SET;
+ return 0;
+ }
+ if (arg)
+ return parse_string(mode, arg, -1);
+
+ /* no arg, turn it on */
+ *mode |= COL_ENABLED | COL_ENABLED_SET;
+ return 0;
+}
diff --git a/column.h b/column.h
index ffae87c..a8b24e8 100644
--- a/column.h
+++ b/column.h
@@ -3,9 +3,13 @@
#define COL_MODE 0x000F
#define COL_ENABLED (1 << 4)
+#define COL_ENABLED_SET (1 << 5) /* Has COL_ENABLED been set? */
extern int term_columns(void);
extern struct string_list_item *add_to_columns(struct string_list *list, int mode, const char *string);
extern void display_columns(const struct string_list *list, int mode, int width, int padding, const char *indent);
+struct option;
+extern int parseopt_column_callback(const struct option *opt, const char *arg, int unset);
+
#endif
diff --git a/parse-options.h b/parse-options.h
index 31ec5d2..14816b6 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -220,5 +220,7 @@ extern int parse_opt_tertiary(const struct option *, const char *, int);
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
#define OPT__COLOR(var, h) \
OPT_COLOR_FLAG(0, "color", (var), (h))
+#define OPT_COLUMN(s, l, v, h) \
+ { OPTION_CALLBACK, (s), (l), (v), "style", (h), PARSE_OPT_OPTARG, parseopt_column_callback }
#endif
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
new file mode 100755
index 0000000..099a29f
--- /dev/null
+++ b/t/t9002-column.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+test_description='git column'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ cat >lista <<\EOF
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+EOF
+'
+
+test_expect_success 'never' '
+ test-column --mode=never <lista >actual &&
+ test_cmp lista actual
+'
+
+test_done
diff --git a/test-column.c b/test-column.c
new file mode 100644
index 0000000..d6321a4
--- /dev/null
+++ b/test-column.c
@@ -0,0 +1,39 @@
+#include "cache.h"
+#include "strbuf.h"
+#include "parse-options.h"
+#include "string-list.h"
+#include "column.h"
+
+static const char * const builtin_column_usage[] = {
+ "git column [--mode=<mode>] [--width=<width>] [--left-space=<N>] [--right-space=<N>]",
+ NULL
+};
+
+int main(int argc, const char **argv)
+{
+ struct string_list list = STRING_LIST_INIT_DUP;
+ int mode = 0;
+ struct strbuf sb = STRBUF_INIT;
+ int left_space = 0, right_space = 0, padding = 1;
+ int term_width = term_columns();
+ struct option options[] = {
+ OPT_INTEGER(0, "width", &term_width, "Maximum width"),
+ OPT_INTEGER(0, "left", &left_space, "Padding space on left border"),
+ OPT_INTEGER(0, "right", &right_space, "Padding space on right border"),
+ OPT_INTEGER(0, "padding", &padding, "Padding space between columns"),
+ OPT_COLUMN(0, "mode", &mode, "layout to use"),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, "", options, builtin_column_usage, 0);
+
+ while (!strbuf_getline(&sb, stdin, '\n'))
+ string_list_append(&list, sb.buf);
+
+ strbuf_setlen(&sb, left_space);
+ memset(sb.buf, ' ', left_space);
+ display_columns(&list, mode,
+ term_width - right_space - left_space,
+ padding, sb.buf);
+ return 0;
+}
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/9] display_columns: add COL_MODE_{COLUMN,ROW} mode
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
` (2 preceding siblings ...)
2011-03-20 12:57 ` [PATCH 3/9] column: add functions to parse column settings Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 5/9] display_columns: add COL_DENSE to do unequal column layout Nguyễn Thái Ngọc Duy
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
COL_MODE_COLUMN and COL_MODE_ROW fill column by column (or row by row
respectively), given the terminal width and how many space between
columns.
Strings are supposed to be in UTF-8. If strings contain ANSI escape strings,
COL_ANSI must be specified for correct length calculation.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
column.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
column.h | 3 +
t/t9002-column.sh | 86 ++++++++++++++++++++++++++++++++++++
3 files changed, 215 insertions(+), 1 deletions(-)
diff --git a/column.c b/column.c
index b32b9f9..15f74a5 100644
--- a/column.c
+++ b/column.c
@@ -2,8 +2,65 @@
#include "column.h"
#include "string-list.h"
#include "parse-options.h"
+#include "utf8.h"
#define MODE(mode) ((mode) & COL_MODE)
+#define XY2LINEAR(d,x,y) (MODE((d)->mode) == COL_MODE_COLUMN ? \
+ (x) * (d)->rows + (y) : \
+ (y) * (d)->cols + (x))
+
+struct column_data {
+ const struct string_list *list; /* list of all cells */
+ int mode; /* COL_MODE */
+ int total_width; /* terminal width */
+ int padding; /* cell padding */
+ const char *indent; /* left most column indentation */
+
+ int rows, cols;
+ int *len; /* cell length */
+};
+
+/* return length of 's' in letters, ANSI escapes stripped */
+static int item_length(int mode, const char *s)
+{
+ int len, i = 0;
+ struct strbuf str = STRBUF_INIT;
+
+ if (!(mode & COL_ANSI))
+ return utf8_strwidth(s);
+
+ strbuf_addstr(&str, s);
+ while ((s = strstr(str.buf + i, "\033[")) != NULL) {
+ int len = strspn(s + 2, "0123456789;");
+ i = s - str.buf;
+ strbuf_remove(&str, i, len + 3); /* \033[<len><func char> */
+ }
+ len = utf8_strwidth(str.buf);
+ strbuf_release(&str);
+ return len;
+}
+
+/*
+ * Calculate cell width, rows and cols for a table of equal cells, given
+ * table width and how many spaces between cells.
+ */
+static void layout(struct column_data *data, int *width)
+{
+ int i;
+
+ *width = 0;
+ for (i = 0; i < data->list->nr; i++)
+ if (*width < data->len[i])
+ *width = data->len[i];
+
+ *width += data->padding;
+
+ data->cols = (data->total_width - strlen(data->indent)) / *width;
+ if (data->cols == 0)
+ data->cols = 1;
+
+ data->rows = DIV_ROUND_UP(data->list->nr, data->cols);
+}
struct string_list_item *add_to_columns(struct string_list *list, int mode,
const char *string)
@@ -23,6 +80,63 @@ static void display_plain(const struct string_list *list, const char *indent)
printf("%s%s\n", indent, list->items[i].string);
}
+/* Print a cell to stdout with all necessary leading/traling space */
+static int display_cell(struct column_data *data, int initial_width,
+ const char *empty_cell, int x, int y)
+{
+ int i, len, newline;
+
+ i = XY2LINEAR(data, x, y);
+ if (i >= data->list->nr)
+ return -1;
+ len = data->len[i];
+ if (MODE(data->mode) == COL_MODE_COLUMN)
+ newline = i + data->rows >= data->list->nr;
+ else
+ newline = x == data->cols - 1 || i == data->list->nr - 1;
+
+ printf("%s%s%s",
+ x == 0 ? data->indent : "",
+ data->list->items[i].string,
+ newline ? "\n" : empty_cell + len);
+ return 0;
+}
+
+/* Display COL_MODE_COLUMN or COL_MODE_ROW */
+static void display_table(const struct string_list *list,
+ int mode, int total_width,
+ int padding, const char *indent)
+{
+ struct column_data data;
+ int x, y, i, initial_width;
+ char *empty_cell;
+
+ memset(&data, 0, sizeof(data));
+ data.list = list;
+ data.mode = mode;
+ data.total_width = total_width;
+ data.padding = padding;
+ data.indent = indent;
+
+ data.len = xmalloc(sizeof(*data.len) * list->nr);
+ for (i = 0; i < list->nr; i++)
+ data.len[i] = item_length(mode, list->items[i].string);
+
+ layout(&data, &initial_width);
+
+ empty_cell = xmalloc(initial_width + 1);
+ memset(empty_cell, ' ', initial_width);
+ empty_cell[initial_width] = '\0';
+ for (y = 0; y < data.rows; y++) {
+ for (x = 0; x < data.cols; x++)
+ if (display_cell(&data, initial_width, empty_cell, x, y))
+ break;
+ }
+
+ free(data.len);
+ free(empty_cell);
+}
+
void display_columns(const struct string_list *list, int mode,
int width, int padding, const char *indent)
{
@@ -34,7 +148,16 @@ void display_columns(const struct string_list *list, int mode,
display_plain(list, indent);
return;
}
- die("BUG: invalid mode %d", MODE(mode));
+
+ switch (MODE(mode)) {
+ case COL_MODE_ROW:
+ case COL_MODE_COLUMN:
+ display_table(list, mode, width, padding, indent);
+ break;
+
+ default:
+ die("BUG: invalid mode %d", MODE(mode));
+ }
}
struct colopt {
@@ -96,6 +219,8 @@ static int parse_option(const char *arg, int len,
{ ENABLE, "always", 1 },
{ ENABLE, "never", 0 },
{ ENABLE, "auto", -1 },
+ { MODE, "column", COL_MODE_COLUMN },
+ { MODE, "row", COL_MODE_ROW },
};
int i, set, name_len;
diff --git a/column.h b/column.h
index a8b24e8..4fb1004 100644
--- a/column.h
+++ b/column.h
@@ -2,8 +2,11 @@
#define COLUMN_H
#define COL_MODE 0x000F
+#define COL_MODE_COLUMN 0 /* Fill columns before rows */
+#define COL_MODE_ROW 1 /* Fill rows before columns */
#define COL_ENABLED (1 << 4)
#define COL_ENABLED_SET (1 << 5) /* Has COL_ENABLED been set? */
+#define COL_ANSI (1 << 6) /* Remove ANSI escapes from string length */
extern int term_columns(void);
extern struct string_list_item *add_to_columns(struct string_list *list, int mode, const char *string);
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
index 099a29f..f801190 100755
--- a/t/t9002-column.sh
+++ b/t/t9002-column.sh
@@ -24,4 +24,90 @@ test_expect_success 'never' '
test_cmp lista actual
'
+test_expect_success '80 columns' '
+ cat >expected <<\EOF &&
+one two three four five six seven eight nine ten eleven
+EOF
+ COLUMNS=80 test-column --mode=column <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'COLUMNS = 1' '
+ cat >expected <<\EOF &&
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+EOF
+ COLUMNS=1 test-column --mode=column <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'width = 1' '
+ test-column --mode=column --width=1 <lista >actual &&
+ test_cmp expected actual
+'
+
+COLUMNS=20
+export COLUMNS
+
+test_expect_success '20 columns' '
+ cat >expected <<\EOF &&
+one seven
+two eight
+three nine
+four ten
+five eleven
+six
+EOF
+ test-column --mode=column <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, padding 2' '
+ cat >expected <<\EOF &&
+one seven
+two eight
+three nine
+four ten
+five eleven
+six
+EOF
+ test-column --mode=column --padding 2 <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, left indented' '
+ cat >expected <<\EOF &&
+ one seven
+ two eight
+ three nine
+ four ten
+ five eleven
+ six
+EOF
+ test-column --mode=column --left=2 <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, row first' '
+ cat >expected <<\EOF &&
+one two
+three four
+five six
+seven eight
+nine ten
+eleven
+EOF
+ test-column --mode=row <lista >actual &&
+ test_cmp expected actual
+'
+
test_done
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/9] display_columns: add COL_DENSE to do unequal column layout
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
` (3 preceding siblings ...)
2011-03-20 12:57 ` [PATCH 4/9] display_columns: add COL_MODE_{COLUMN,ROW} mode Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 6/9] column: add column.ui for default column output settings Nguyễn Thái Ngọc Duy
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
column.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++
column.h | 1 +
t/t9002-column.sh | 22 ++++++++++++++
3 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/column.c b/column.c
index 15f74a5..69d42f8 100644
--- a/column.c
+++ b/column.c
@@ -18,6 +18,7 @@ struct column_data {
int rows, cols;
int *len; /* cell length */
+ int *width; /* index to the longest row in column */
};
/* return length of 's' in letters, ANSI escapes stripped */
@@ -62,6 +63,69 @@ static void layout(struct column_data *data, int *width)
data->rows = DIV_ROUND_UP(data->list->nr, data->cols);
}
+static void compute_column_width(struct column_data *data)
+{
+ int i, x, y;
+ for (x = 0; x < data->cols; x++) {
+ data->width[x] = XY2LINEAR(data, x, 0);
+ for (y = 0; y < data->rows; y++) {
+ i = XY2LINEAR(data, x, y);
+ if (i >= data->list->nr)
+ continue;
+ if (data->len[data->width[x]] < data->len[i])
+ data->width[x] = i;
+ }
+ }
+}
+
+/*
+ * Shrink all columns by shortening them one row each time (and adding
+ * more columns along the way). Hopefully the longest cell will be
+ * moved to the next column, column is shrunk so we have more space
+ * for new columns. The process ends when the whole thing no longer
+ * fits in data->total_width.
+ */
+static void shrink_columns(struct column_data *data)
+{
+ int x, y, total_width, cols, rows;
+
+ data->width = xrealloc(data->width,
+ sizeof(*data->width) * data->cols);
+ for (x = 0; x < data->cols; x++) {
+ data->width[x] = 0;
+ for (y = 0; y < data->rows; y++) {
+ int len1 = data->len[data->width[x]];
+ int len2 = data->len[XY2LINEAR(data, x, y)];
+ if (len1 < len2)
+ data->width[x] = y;
+ }
+ }
+
+ while (data->rows > 1) {
+ rows = data->rows;
+ cols = data->cols;
+
+ data->rows--;
+ data->cols = DIV_ROUND_UP(data->list->nr, data->rows);
+ if (data->cols != cols)
+ data->width = xrealloc(data->width, sizeof(*data->width) * data->cols);
+
+ compute_column_width(data);
+
+ total_width = strlen(data->indent);
+ for (x = 0; x < data->cols; x++) {
+ total_width += data->len[data->width[x]];
+ total_width += data->padding;
+ }
+ if (total_width > data->total_width) {
+ data->rows = rows;
+ data->cols = cols;
+ compute_column_width(data);
+ break;
+ }
+ }
+}
+
struct string_list_item *add_to_columns(struct string_list *list, int mode,
const char *string)
{
@@ -89,7 +153,18 @@ static int display_cell(struct column_data *data, int initial_width,
i = XY2LINEAR(data, x, y);
if (i >= data->list->nr)
return -1;
+
len = data->len[i];
+ if (data->width && data->len[data->width[x]] < initial_width) {
+ /*
+ * empty_cell has initial_width chars, if real column
+ * is narrower, increase len a bit so we fill less
+ * space.
+ */
+ len += initial_width - data->len[data->width[x]];
+ len -= data->padding;
+ }
+
if (MODE(data->mode) == COL_MODE_COLUMN)
newline = i + data->rows >= data->list->nr;
else
@@ -124,6 +199,9 @@ static void display_table(const struct string_list *list,
layout(&data, &initial_width);
+ if (mode & COL_DENSE)
+ shrink_columns(&data);
+
empty_cell = xmalloc(initial_width + 1);
memset(empty_cell, ' ', initial_width);
empty_cell[initial_width] = '\0';
@@ -134,6 +212,7 @@ static void display_table(const struct string_list *list,
}
free(data.len);
+ free(data.width);
free(empty_cell);
}
@@ -221,6 +300,7 @@ static int parse_option(const char *arg, int len,
{ ENABLE, "auto", -1 },
{ MODE, "column", COL_MODE_COLUMN },
{ MODE, "row", COL_MODE_ROW },
+ { OPTION, "dense", COL_DENSE },
};
int i, set, name_len;
diff --git a/column.h b/column.h
index 4fb1004..48c6345 100644
--- a/column.h
+++ b/column.h
@@ -7,6 +7,7 @@
#define COL_ENABLED (1 << 4)
#define COL_ENABLED_SET (1 << 5) /* Has COL_ENABLED been set? */
#define COL_ANSI (1 << 6) /* Remove ANSI escapes from string length */
+#define COL_DENSE (1 << 7) /* Shrink columns when possible, making space for more columns */
extern int term_columns(void);
extern struct string_list_item *add_to_columns(struct string_list *list, int mode, const char *string);
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
index f801190..07161a9 100755
--- a/t/t9002-column.sh
+++ b/t/t9002-column.sh
@@ -71,6 +71,17 @@ EOF
test_cmp expected actual
'
+test_expect_success '20 columns, dense' '
+ cat >expected <<\EOF &&
+one five nine
+two six ten
+three seven eleven
+four eight
+EOF
+ test-column --mode=column,dense < lista > actual &&
+ test_cmp expected actual
+'
+
test_expect_success '20 columns, padding 2' '
cat >expected <<\EOF &&
one seven
@@ -110,4 +121,15 @@ EOF
test_cmp expected actual
'
+test_expect_success '20 columns, row first, dense' '
+ cat >expected <<\EOF &&
+one two three
+four five six
+seven eight nine
+ten eleven
+EOF
+ test-column --mode=row,dense <lista >actual &&
+ test_cmp expected actual
+'
+
test_done
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/9] column: add column.ui for default column output settings
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
` (4 preceding siblings ...)
2011-03-20 12:57 ` [PATCH 5/9] display_columns: add COL_DENSE to do unequal column layout Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 7/9] help: reuse display_columns() for help -a Nguyễn Thái Ngọc Duy
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/config.txt | 24 ++++++++++++++++++++++++
column.c | 11 +++++++++++
column.h | 3 +++
3 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index c5e1835..7183712 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -805,6 +805,30 @@ color.ui::
terminal. When more specific variables of color.* are set, they always
take precedence over this setting. Defaults to false.
+column.ui::
+ Specify whether supported commands should output in columns.
+ This variable consists of a list of tokens separated by spaces
+ or commas:
++
+--
+`always`;;
+ always show in columns
+`never`;;
+ never show in columns
+`auto`;;
+ show in columns if the output is to the terminal
+`column`;;
+ fill columns before rows (default)
+`row`;;
+ fill rows before columns
+`dense`;;
+ make unequal size columns to utilize more space
+`nodense`;;
+ make equal size columns
+--
++
+ This option defaults to 'never'.
+
commit.status::
A boolean to enable/disable inclusion of status information in the
commit message template when using an editor to prepare the commit
diff --git a/column.c b/column.c
index 69d42f8..7c1a6f1 100644
--- a/column.c
+++ b/column.c
@@ -2,6 +2,7 @@
#include "column.h"
#include "string-list.h"
#include "parse-options.h"
+#include "color.h"
#include "utf8.h"
#define MODE(mode) ((mode) & COL_MODE)
@@ -21,6 +22,8 @@ struct column_data {
int *width; /* index to the longest row in column */
};
+int git_core_column;
+
/* return length of 's' in letters, ANSI escapes stripped */
static int item_length(int mode, const char *s)
{
@@ -350,6 +353,14 @@ static int parse_string(int *mode, const char *value,
return 0;
}
+int git_column_default_config(const char *var, const char *value, void *cb)
+{
+ if (!strcmp(var, "column.ui"))
+ return parse_string(&git_core_column, value, -1);
+
+ return git_color_default_config(var, value, cb);
+}
+
int parseopt_column_callback(const struct option *opt,
const char *arg, int unset)
{
diff --git a/column.h b/column.h
index 48c6345..0f4190d 100644
--- a/column.h
+++ b/column.h
@@ -9,9 +9,12 @@
#define COL_ANSI (1 << 6) /* Remove ANSI escapes from string length */
#define COL_DENSE (1 << 7) /* Shrink columns when possible, making space for more columns */
+extern int git_core_column;
+
extern int term_columns(void);
extern struct string_list_item *add_to_columns(struct string_list *list, int mode, const char *string);
extern void display_columns(const struct string_list *list, int mode, int width, int padding, const char *indent);
+extern int git_column_default_config(const char *var, const char *value, void *cb);
struct option;
extern int parseopt_column_callback(const struct option *opt, const char *arg, int unset);
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/9] help: reuse display_columns() for help -a
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
` (5 preceding siblings ...)
2011-03-20 12:57 ` [PATCH 6/9] column: add column.ui for default column output settings Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 16:04 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 8/9] tag: add --column Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 9/9] branch: " Nguyễn Thái Ngọc Duy
8 siblings, 1 reply; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
help.c | 30 ++++++++----------------------
1 files changed, 8 insertions(+), 22 deletions(-)
diff --git a/help.c b/help.c
index 768f64c..dcc8b81 100644
--- a/help.c
+++ b/help.c
@@ -4,6 +4,7 @@
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
+#include "string-list.h"
#include "column.h"
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
@@ -73,29 +74,14 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
static void pretty_print_string_list(struct cmdnames *cmds, int longest)
{
- int cols = 1, rows;
- int space = longest + 1; /* min 1 SP between words */
- int max_cols = term_columns() - 1; /* don't print *on* the edge */
- int i, j;
-
- if (space < max_cols)
- cols = max_cols / space;
- rows = DIV_ROUND_UP(cmds->cnt, cols);
-
- for (i = 0; i < rows; i++) {
- printf(" ");
+ struct string_list list = STRING_LIST_INIT_NODUP;
+ int i;
- for (j = 0; j < cols; j++) {
- int n = j * rows + i;
- int size = space;
- if (n >= cmds->cnt)
- break;
- if (j == cols-1 || n + rows >= cmds->cnt)
- size = 1;
- printf("%-*s", size, cmds->names[n]->name);
- }
- putchar('\n');
- }
+ for (i = 0; i < cmds->cnt; i++)
+ string_list_append(&list, cmds->names[i]->name);
+ display_columns(&list, COL_MODE_COLUMN | COL_ENABLED,
+ term_columns(), 1, " ");
+ string_list_clear(&list, 0);
}
static int is_executable(const char *name)
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 8/9] tag: add --column
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
` (6 preceding siblings ...)
2011-03-20 12:57 ` [PATCH 7/9] help: reuse display_columns() for help -a Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 9/9] branch: " Nguyễn Thái Ngọc Duy
8 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-tag.txt | 11 ++++++++++-
Makefile | 2 +-
builtin/tag.c | 21 +++++++++++++++++----
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 8b169e3..0260eea 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -12,7 +12,8 @@ SYNOPSIS
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
<tagname> [<commit> | <object>]
'git tag' -d <tagname>...
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
+'git tag' [-n[<num>]] -l [--column[=<options>] | --no-column]
+ [--contains <commit>] [<pattern>]
'git tag' -v <tagname>...
DESCRIPTION
@@ -71,6 +72,14 @@ OPTIONS
List tags with names that match the given pattern (or all if no pattern is given).
Typing "git tag" without arguments, also lists all tags.
+--column[=<options>]::
+--no-column::
+ Override column.ui settings. See linkgit:git-config.txt[1] for
+ syntax. `--column` and `--no-column` without options are
+ equivalent to 'always' and 'never' respectively. This option
+ is only applicable if `git tag` is used to list tags without
+ annotation lines.
+
--contains <commit>::
Only list tags which contain the specified commit.
diff --git a/Makefile b/Makefile
index ba9944b..e1823dd 100644
--- a/Makefile
+++ b/Makefile
@@ -1958,7 +1958,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
connect.o transport.o http-backend.o: url.h
-column.o help.o pager.o: column.h
+builtin/tag.o column.o help.o pager.o: column.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
diff --git a/builtin/tag.c b/builtin/tag.c
index aa1f87d..cdf0f74 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -12,6 +12,8 @@
#include "tag.h"
#include "run-command.h"
#include "parse-options.h"
+#include "string-list.h"
+#include "column.h"
static const char * const git_tag_usage[] = {
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
@@ -22,6 +24,8 @@ static const char * const git_tag_usage[] = {
};
static char signingkey[1000];
+static struct string_list output = STRING_LIST_INIT_DUP;
+static int column_mode;
struct tag_filter {
const char *pattern;
@@ -52,7 +56,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
}
if (!filter->lines) {
- printf("%s\n", refname);
+ add_to_columns(&output, column_mode, refname);
return 0;
}
printf("%-15s ", refname);
@@ -233,7 +237,7 @@ static int git_tag_config(const char *var, const char *value, void *cb)
return 0;
}
- return git_default_config(var, value, cb);
+ return git_column_default_config(var, value, cb);
}
static void write_tag_body(int fd, const unsigned char *sha1)
@@ -383,6 +387,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_STRING('u', NULL, &keyid, "key-id",
"use another key to sign the tag"),
OPT__FORCE(&force, "replace the tag if exists"),
+ OPT_COLUMN(0, "column", &column_mode, "show tag list in columns" ),
OPT_GROUP("Tag listing options"),
{
@@ -395,6 +400,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
};
git_config(git_tag_config, NULL);
+ column_mode = git_core_column;
argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0);
@@ -413,9 +419,16 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (list + delete + verify > 1)
usage_with_options(git_tag_usage, options);
- if (list)
- return list_tags(argv[0], lines == -1 ? 0 : lines,
+ if (list) {
+ int ret;
+
+ if (lines != -1)
+ column_mode = 0;
+ ret = list_tags(argv[0], lines == -1 ? 0 : lines,
with_commit);
+ display_columns(&output, column_mode, term_columns(), 2, "");
+ return ret;
+ }
if (lines != -1)
die("-n option is only allowed with -l.");
if (with_commit)
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 9/9] branch: add --column
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
` (7 preceding siblings ...)
2011-03-20 12:57 ` [PATCH 8/9] tag: add --column Nguyễn Thái Ngọc Duy
@ 2011-03-20 12:57 ` Nguyễn Thái Ngọc Duy
2011-03-20 19:52 ` Teemu Likonen
8 siblings, 1 reply; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 12:57 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-branch.txt | 9 +++++++++
Makefile | 2 +-
builtin/branch.c | 23 +++++++++++++++++++----
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 9106d38..a7bf4a8 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,6 +9,7 @@ SYNOPSIS
--------
[verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
+ [--column[=<options>] | --no-column]
[-v [--abbrev=<length> | --no-abbrev]]
[(--merged | --no-merged | --contains) [<commit>]]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
@@ -99,6 +100,14 @@ OPTIONS
default to color output.
Same as `--color=never`.
+--column[=<options>]::
+--no-column::
+ Override column.ui settings. See linkgit:git-config.txt[1] for
+ syntax. `--column` and `--no-column` without options are
+ equivalent to 'always' and 'never' respectively. This option
+ is only applicable if `git tag` is used to list tags without
+ annotation lines.
+
-r::
List or delete (if used with -d) the remote-tracking branches.
diff --git a/Makefile b/Makefile
index e1823dd..92c49ac 100644
--- a/Makefile
+++ b/Makefile
@@ -1958,7 +1958,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
connect.o transport.o http-backend.o: url.h
-builtin/tag.o column.o help.o pager.o: column.h
+builtin/branch.o builtin/tag.o column.o help.o pager.o: column.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
diff --git a/builtin/branch.c b/builtin/branch.c
index 9e546e4..ff94192 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -15,6 +15,8 @@
#include "branch.h"
#include "diff.h"
#include "revision.h"
+#include "string-list.h"
+#include "column.h"
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -53,6 +55,9 @@ static enum merge_filter {
} merge_filter;
static unsigned char merge_filter_ref[20];
+static struct string_list output = STRING_LIST_INIT_DUP;
+static int column_mode;
+
static int parse_branch_color_slot(const char *var, int ofs)
{
if (!strcasecmp(var+ofs, "plain"))
@@ -83,7 +88,7 @@ static int git_branch_config(const char *var, const char *value, void *cb)
color_parse(value, var, branch_colors[slot]);
return 0;
}
- return git_color_default_config(var, value, cb);
+ return git_column_default_config(var, value, cb);
}
static const char *branch_get_color(enum color_branch ix)
@@ -451,7 +456,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
strbuf_release(&stat);
strbuf_release(&subject);
}
- printf("%s\n", out.buf);
+ add_to_columns(&output, column_mode, out.buf);
strbuf_release(&name);
strbuf_release(&out);
}
@@ -660,6 +665,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
opt_parse_merge_filter, (intptr_t) "HEAD",
},
+ OPT_COLUMN(0, "column", &column_mode, "list branches in columns" ),
OPT_END(),
};
@@ -686,6 +692,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
}
hashcpy(merge_filter_ref, head_sha1);
+ column_mode = git_core_column | COL_ANSI;
+
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
0);
if (!!delete + !!rename + !!force_create > 1)
@@ -693,8 +701,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (delete)
return delete_branches(argc, argv, delete > 1, kinds);
- else if (argc == 0)
- return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
+ else if (argc == 0) {
+ int ret;
+ if (verbose)
+ column_mode = 0;
+
+ ret = print_ref_list(kinds, detached, verbose, abbrev, with_commit);
+ display_columns(&output, column_mode, term_columns(), 1, "");
+ return ret;
+ }
else if (rename && (argc == 1))
rename_branch(head, argv[0], rename > 1);
else if (rename && (argc == 2))
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/9] help: reuse display_columns() for help -a
2011-03-20 12:57 ` [PATCH 7/9] help: reuse display_columns() for help -a Nguyễn Thái Ngọc Duy
@ 2011-03-20 16:04 ` Nguyễn Thái Ngọc Duy
0 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 16:04 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
This one is better. Because 'longest' is no longer used, all support
code may be removed as well.
help.c | 45 +++++++++++----------------------------------
1 files changed, 11 insertions(+), 34 deletions(-)
diff --git a/help.c b/help.c
index 768f64c..92150ea 100644
--- a/help.c
+++ b/help.c
@@ -4,6 +4,7 @@
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
+#include "string-list.h"
#include "column.h"
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
@@ -71,31 +72,16 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
cmds->cnt = cj;
}
-static void pretty_print_string_list(struct cmdnames *cmds, int longest)
+static void pretty_print_string_list(struct cmdnames *cmds)
{
- int cols = 1, rows;
- int space = longest + 1; /* min 1 SP between words */
- int max_cols = term_columns() - 1; /* don't print *on* the edge */
- int i, j;
-
- if (space < max_cols)
- cols = max_cols / space;
- rows = DIV_ROUND_UP(cmds->cnt, cols);
-
- for (i = 0; i < rows; i++) {
- printf(" ");
+ struct string_list list = STRING_LIST_INIT_NODUP;
+ int i;
- for (j = 0; j < cols; j++) {
- int n = j * rows + i;
- int size = space;
- if (n >= cmds->cnt)
- break;
- if (j == cols-1 || n + rows >= cmds->cnt)
- size = 1;
- printf("%-*s", size, cmds->names[n]->name);
- }
- putchar('\n');
- }
+ for (i = 0; i < cmds->cnt; i++)
+ string_list_append(&list, cmds->names[i]->name);
+ display_columns(&list, COL_MODE_COLUMN | COL_ENABLED,
+ term_columns(), 1, " ");
+ string_list_clear(&list, 0);
}
static int is_executable(const char *name)
@@ -204,22 +190,13 @@ void load_command_list(const char *prefix,
void list_commands(const char *title, struct cmdnames *main_cmds,
struct cmdnames *other_cmds)
{
- int i, longest = 0;
-
- for (i = 0; i < main_cmds->cnt; i++)
- if (longest < main_cmds->names[i]->len)
- longest = main_cmds->names[i]->len;
- for (i = 0; i < other_cmds->cnt; i++)
- if (longest < other_cmds->names[i]->len)
- longest = other_cmds->names[i]->len;
-
if (main_cmds->cnt) {
const char *exec_path = git_exec_path();
printf("available %s in '%s'\n", title, exec_path);
printf("----------------");
mput_char('-', strlen(title) + strlen(exec_path));
putchar('\n');
- pretty_print_string_list(main_cmds, longest);
+ pretty_print_string_list(main_cmds);
putchar('\n');
}
@@ -228,7 +205,7 @@ void list_commands(const char *title, struct cmdnames *main_cmds,
printf("---------------------------------------");
mput_char('-', strlen(title));
putchar('\n');
- pretty_print_string_list(other_cmds, longest);
+ pretty_print_string_list(other_cmds);
putchar('\n');
}
}
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 9/9] branch: add --column
2011-03-20 12:57 ` [PATCH 9/9] branch: " Nguyễn Thái Ngọc Duy
@ 2011-03-20 19:52 ` Teemu Likonen
2011-03-20 23:26 ` Nguyễn Thái Ngọc Duy
0 siblings, 1 reply; 13+ messages in thread
From: Teemu Likonen @ 2011-03-20 19:52 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
* 2011-03-20 19:57 (+0700), Nguyễn Thái Ngọc Duy wrote:
> diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
> index 9106d38..a7bf4a8 100644
> --- a/Documentation/git-branch.txt
> +++ b/Documentation/git-branch.txt
> +--column[=<options>]::
> +--no-column::
> + Override column.ui settings. See linkgit:git-config.txt[1] for
> + syntax. `--column` and `--no-column` without options are
> + equivalent to 'always' and 'never' respectively. This option
> + is only applicable if `git tag` is used to list tags without
> + annotation lines.
> +
I admit that I have not been following the development of this feature
but I'll confirm this anyway: Do you really mean to speak of "git tag"
in the man page of "git branch"?
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 9/9] branch: add --column
2011-03-20 19:52 ` Teemu Likonen
@ 2011-03-20 23:26 ` Nguyễn Thái Ngọc Duy
0 siblings, 0 replies; 13+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2011-03-20 23:26 UTC (permalink / raw)
To: git, Teemu Likonen; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
2011/3/21 Teemu Likonen <tlikonen@iki.fi>:
> I admit that I have not been following the development of this feature
> but I'll confirm this anyway: Do you really mean to speak of "git tag"
> in the man page of "git branch"?
>
Copy/paste error. Fixed
Documentation/git-branch.txt | 8 ++++++++
Makefile | 2 +-
builtin/branch.c | 23 +++++++++++++++++++----
3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 9106d38..f129339 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,6 +9,7 @@ SYNOPSIS
--------
[verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
+ [--column[=<options>] | --no-column]
[-v [--abbrev=<length> | --no-abbrev]]
[(--merged | --no-merged | --contains) [<commit>]]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
@@ -99,6 +100,13 @@ OPTIONS
default to color output.
Same as `--color=never`.
+--column[=<options>]::
+--no-column::
+ Override column.ui settings. See linkgit:git-config.txt[1] for
+ syntax. `--column` and `--no-column` without options are
+ equivalent to 'always' and 'never' respectively. This option
+ is only applicable in non-verbose mode.
+
-r::
List or delete (if used with -d) the remote-tracking branches.
diff --git a/Makefile b/Makefile
index e1823dd..92c49ac 100644
--- a/Makefile
+++ b/Makefile
@@ -1958,7 +1958,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
connect.o transport.o http-backend.o: url.h
-builtin/tag.o column.o help.o pager.o: column.h
+builtin/branch.o builtin/tag.o column.o help.o pager.o: column.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
diff --git a/builtin/branch.c b/builtin/branch.c
index 9e546e4..ff94192 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -15,6 +15,8 @@
#include "branch.h"
#include "diff.h"
#include "revision.h"
+#include "string-list.h"
+#include "column.h"
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -53,6 +55,9 @@ static enum merge_filter {
} merge_filter;
static unsigned char merge_filter_ref[20];
+static struct string_list output = STRING_LIST_INIT_DUP;
+static int column_mode;
+
static int parse_branch_color_slot(const char *var, int ofs)
{
if (!strcasecmp(var+ofs, "plain"))
@@ -83,7 +88,7 @@ static int git_branch_config(const char *var, const char *value, void *cb)
color_parse(value, var, branch_colors[slot]);
return 0;
}
- return git_color_default_config(var, value, cb);
+ return git_column_default_config(var, value, cb);
}
static const char *branch_get_color(enum color_branch ix)
@@ -451,7 +456,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
strbuf_release(&stat);
strbuf_release(&subject);
}
- printf("%s\n", out.buf);
+ add_to_columns(&output, column_mode, out.buf);
strbuf_release(&name);
strbuf_release(&out);
}
@@ -660,6 +665,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
opt_parse_merge_filter, (intptr_t) "HEAD",
},
+ OPT_COLUMN(0, "column", &column_mode, "list branches in columns" ),
OPT_END(),
};
@@ -686,6 +692,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
}
hashcpy(merge_filter_ref, head_sha1);
+ column_mode = git_core_column | COL_ANSI;
+
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
0);
if (!!delete + !!rename + !!force_create > 1)
@@ -693,8 +701,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (delete)
return delete_branches(argc, argv, delete > 1, kinds);
- else if (argc == 0)
- return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
+ else if (argc == 0) {
+ int ret;
+ if (verbose)
+ column_mode = 0;
+
+ ret = print_ref_list(kinds, detached, verbose, abbrev, with_commit);
+ display_columns(&output, column_mode, term_columns(), 1, "");
+ return ret;
+ }
else if (rename && (argc == 1))
rename_branch(head, argv[0], rename > 1);
else if (rename && (argc == 2))
--
1.7.4.74.g639db
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-03-20 23:26 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-20 12:57 [PATCH 0/9] column output v3 Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 1/9] Move term_columns() to pager.c and save terminal width before pager Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 2/9] Add display_columns() to display in columnar layout Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 3/9] column: add functions to parse column settings Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 4/9] display_columns: add COL_MODE_{COLUMN,ROW} mode Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 5/9] display_columns: add COL_DENSE to do unequal column layout Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 6/9] column: add column.ui for default column output settings Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 7/9] help: reuse display_columns() for help -a Nguyễn Thái Ngọc Duy
2011-03-20 16:04 ` Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 8/9] tag: add --column Nguyễn Thái Ngọc Duy
2011-03-20 12:57 ` [PATCH 9/9] branch: " Nguyễn Thái Ngọc Duy
2011-03-20 19:52 ` Teemu Likonen
2011-03-20 23:26 ` Nguyễn Thái Ngọc Duy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.