[PATCH 05/12] Add builtin command "column"
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-column.txt | 40 ++++++++++++++++
Makefile | 1 +
builtin.h | 1 +
builtin/column.c | 42 +++++++++++++++++
git.c | 1 +
t/t9002-column.sh | 101 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 186 insertions(+), 0 deletions(-)
create mode 100644 Documentation/git-column.txt
create mode 100644 builtin/column.c
create mode 100755 t/t9002-column.sh
diff --git a/Documentation/git-column.txt b/Documentation/git-column.txt
new file mode 100644
index 0000000..3ee887f
--- /dev/null
+++ b/Documentation/git-column.txt
@@ -0,0 +1,40 @@
+git-column(1)
+=============
+
+NAME
+----
+git-column - Columnate lists
+
+SYNOPSIS
+--------
+[verse]
+'git column' [--mode=<mode>] [--width=<width>] [--left-space=<N>] [--right-space=<N>]
+
+DESCRIPTION
+-----------
+This command formats its input into multiple columns. Rows are filled before
+columns.
+
+OPTIONS
+-------
+--width=<width>::
+ Specify the terminal width. By default 'git column' will detect the
+ terminal width, or fall back to 80 if it is unable to do so.
+
+--left-space=<N>::
+ Prepend a number of spaces on the first column.
+
+--right-space=<N>::
+ Append a number of spaces after the last column.
+
+--mode=<mode>::
+ Which layout mode to use. Supported modes are 'row' (default mode,
+ fill rows first) and 'column' (fill columns first)
+
+Author
+------
+Written by Nguyen Thai Ngoc Duy <pclouds@gmail.com>
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Makefile b/Makefile
index 337f5bf..53686a2 100644
--- a/Makefile
+++ b/Makefile
@@ -640,6 +640,7 @@ BUILTIN_OBJS += builtin/checkout-index.o
BUILTIN_OBJS += builtin/checkout.o
BUILTIN_OBJS += builtin/clean.o
BUILTIN_OBJS += builtin/clone.o
+BUILTIN_OBJS += builtin/column.o
BUILTIN_OBJS += builtin/commit-tree.o
BUILTIN_OBJS += builtin/commit.o
BUILTIN_OBJS += builtin/config.o
diff --git a/builtin.h b/builtin.h
index cdf9847..c68c758 100644
--- a/builtin.h
+++ b/builtin.h
@@ -39,6 +39,7 @@ extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
extern int cmd_clone(int argc, const char **argv, const char *prefix);
extern int cmd_clean(int argc, const char **argv, const char *prefix);
+extern int cmd_column(int argc, const char **argv, const char *prefix);
extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
diff --git a/builtin/column.c b/builtin/column.c
new file mode 100644
index 0000000..d5d7f80
--- /dev/null
+++ b/builtin/column.c
@@ -0,0 +1,42 @@
+#include "cache.h"
+#include "strbuf.h"
+#include "parse-options.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 cmd_column(int argc, const char **argv, const char *prefix)
+{
+ struct columnizer cp;
+ const char *mode = NULL;
+ struct strbuf sb = STRBUF_INIT;
+ struct option options[] = {
+ OPT_INTEGER(0, "width", &cp.terminal_width, "Maximum width"),
+ OPT_INTEGER(0, "left-space", &cp.left_space, "Padding space on left border"),
+ OPT_INTEGER(0, "right-space", &cp.right_space, "Padding space on right border"),
+ OPT_STRING(0, "mode", &mode, "mode", "Which layout mode to use"),
+ OPT_END()
+ };
+
+ memset(&cp, 0, sizeof(cp));
+ cp.space = 1;
+ cp.detach = free;
+
+ argc = parse_options(argc, argv, prefix, options, builtin_column_usage, 0);
+
+ if (!mode || !strcmp(mode, "column"))
+ cp.flags = COLUMNIZER_COLUMN_FIRST | COLUMNIZER_HAVE_ANSI | COLUMNIZER_HOMOGENEOUS;
+ else if (!strcmp(mode, "row"))
+ cp.flags = COLUMNIZER_ROW_FIRST | COLUMNIZER_HAVE_ANSI | COLUMNIZER_HOMOGENEOUS;
+ else
+ die("Invalid mode '%s'", mode);
+
+ while (!strbuf_getline(&sb, stdin, '\n'))
+ feed_columnizer(&cp, strbuf_detach(&sb, NULL));
+
+ feed_columnizer(&cp, NULL);
+ return 0;
+}
diff --git a/git.c b/git.c
index 6bae305..8dc6fdd 100644
--- a/git.c
+++ b/git.c
@@ -301,6 +301,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
{ "clone", cmd_clone },
{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
+ { "column", cmd_column },
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
new file mode 100755
index 0000000..b5b46fc
--- /dev/null
+++ b/t/t9002-column.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+test_description='git column'
+. ./test-lib.sh
+
+cat >lista <<\EOF
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+EOF
+
+cat >expected <<\EOF
+one two three four five six seven eight nine ten
+EOF
+test_expect_success '80 columns' '
+ COLUMNS=80 git column < lista > actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+EOF
+test_expect_success '1 column' '
+ COLUMNS=1 git column < lista > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '1 column (--width)' '
+ git column --width=1 < lista > actual &&
+ test_cmp expected actual
+'
+
+COLUMNS=20
+export COLUMNS
+
+cat >expected <<\EOF
+one five nine
+two six ten
+three seven
+four eight
+EOF
+test_expect_success '20 columns' '
+ git column < lista > actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+one two three
+four five six
+seven eight nine
+ten
+EOF
+test_expect_success '20 columns, row mode' '
+ git column --mode=row < lista > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'unsupported mode' '
+ test_must_fail git column --mode=foo
+'
+
+cat >expected <<\EOF
+ one five nine
+ two six ten
+ three seven
+ four eight
+EOF
+test_expect_success '20 columns, left indented' '
+ git column --left-space=2 < lista > actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+one six
+two seven
+three eight
+four nine
+five ten
+EOF
+test_expect_success '20 columns, right indented' '
+ git column --right-space=3 < lista > actual &&
+ test_cmp expected actual
+'
+
+test_done
--
1.7.0.1.370.gd3c5