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

[PATCH v7 11/9] column: support "denser" mode

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Mar 13, 2012, 12:11 UTC
Message-ID
<25ba0cdc7d4898e65af12b584c0e9ebf4e412557.1331638664.git.pclouds@gmail.com>
In-Reply-To
<79a9a0dd76d72d9cda14378acb16a2fc6456dd0e.1331638664.git.pclouds@gmail.com>

Sometimes a few long entries in the listing would stretch out columns, wasting space. If these entries are cut out, the columns could become smaller, hence more columns.

This new mode does that by looking for the longest entry, if cutting the list before that entry results in much denser layout, then the entry will be cut out and printed in a separate line. The remaining will put in a new layout.

Multiple tables with different column width might be unpleasant to look at, especially if the tables are really short. But on the other hand it could be quite handy. For example, "COLUMNS=80 ./git ls-files --column=dense -- '*.[ch]'" takes 415 lines, while "denser" only takes 223 because it break the layout at contrib/credential/osxkeychain/git-credential-osxkeychain.c and relayout again:

abspath.c builtin/rm.c advice.c builtin/send-pack.c <snip> builtin/rev-parse.c connected.h builtin/revert.c contrib/convert-objects/convert-objects.c

contrib/credential/osxkeychain/git-credential-osxkeychain.c

contrib/examples/builtin-fetch--tool.c refs.c xdiff/xutils.c contrib/svn-fe/svn-fe.c refs.h xdiff/xutils.h convert.c remote-curl.c zlib.c convert.h remote.c <snip> reflog-walk.c xdiff/xprepare.h reflog-walk.h xdiff/xtypes.h

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 column.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 column.h |    1 +
 2 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/column.c b/column.c
index 1e545a0..80eefa0 100644
--- a/column.c
+++ b/column.c
@@ -152,10 +152,55 @@ static int display_cell(struct column_data *data, int initial_width,
 	return 0;
 }
 
+/*
+ * Attempt to put the longest cell into a separate line, see if it
+ * improves the layout
+ */
+static int break_long_line(const struct column_data *old_data)
+{
+	struct column_data data;
+	struct string_list faked_list;
+	int initial_width, x, y, i, item = 0, row1, row2;
+	char *empty_cell;
+
+	memcpy(&data, old_data, sizeof(data));
+	for (i = 0; i < data.list->nr; i++)
+		if (data.len[i] > data.len[item])
+			item = i;
+	data.list = &faked_list;
+	data.width = NULL;
+	faked_list = *old_data->list;
+
+	faked_list.nr = item + 1;
+	layout(&data, &initial_width);
+	shrink_columns(&data);
+	row1 = data.rows;
+
+	faked_list.nr = item;
+	layout(&data, &initial_width);
+	shrink_columns(&data);
+	row2 = data.rows;
+
+	if (row1 - row2 < 3)
+		return -1;
+
+	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.width);
+	free(empty_cell);
+	return item;
+}
+
 /* Display COL_COLUMN or COL_ROW */
-static void display_table(const struct string_list *list,
-			  unsigned int colopts,
-			  const struct column_options *opts)
+static int display_table(const struct string_list *list,
+			 unsigned int colopts,
+			 const struct column_options *opts)
 {
 	struct column_data data;
 	int x, y, i, initial_width;
@@ -174,6 +219,19 @@ static void display_table(const struct string_list *list,
 
 	if (colopts & COL_DENSE)
 		shrink_columns(&data);
+	if (colopts & COL_DENSER) {
+		i = break_long_line(&data);
+		if (i != -1) {
+			printf("%s%s" "%s%s%s" "%s%s",
+			       indent, nl,
+			       indent, list->items[i].string, nl,
+			       indent, nl);
+			free(data.len);
+			free(data.width);
+			return i + 1;
+		}
+		shrink_columns(&data);
+	}
 
 	empty_cell = xmalloc(initial_width + 1);
 	memset(empty_cell, ' ', initial_width);
@@ -187,12 +245,15 @@ static void display_table(const struct string_list *list,
 	free(data.len);
 	free(data.width);
 	free(empty_cell);
+	return list->nr;
 }
 
 void print_columns(const struct string_list *list, unsigned int colopts,
 		   const struct column_options *opts)
 {
 	struct column_options nopts;
+	int processed;
+	struct string_list l = *list;
 
 	if (!list->nr)
 		return;
@@ -213,7 +274,11 @@ void print_columns(const struct string_list *list, unsigned int colopts,
 		break;
 	case COL_ROW:
 	case COL_COLUMN:
-		display_table(list, colopts, &nopts);
+		while (l.nr &&
+		       (processed = display_table(&l, colopts, &nopts)) < l.nr) {
+			l.items += processed;
+			l.nr -= processed;
+		}
 		break;
 	default:
 		die("BUG: invalid layout mode %d", COL_LAYOUT(colopts));
@@ -252,6 +317,7 @@ static int parse_option(const char *arg, int len, unsigned int *colopts,
 		{ "column", COL_COLUMN,   COL_LAYOUT_MASK },
 		{ "row",    COL_ROW,      COL_LAYOUT_MASK },
 		{ "dense",  COL_DENSE,    0 },
+		{ "denser", COL_DENSER,   0 },
 	};
 	int i;
 
diff --git a/column.h b/column.h
index b6872fe..dbc5da2 100644
--- a/column.h
+++ b/column.h
@@ -6,6 +6,7 @@
 #define COL_PARSEOPT      0x0040   /* --column is given from cmdline */
 #define COL_DENSE         0x0080   /* Shrink columns when possible,
 				      making space for more columns */
+#define COL_DENSER        0x0100
 
 #define COL_ENABLE(c) ((c) & COL_ENABLE_MASK)
 #define COL_DISABLED      0x0000   /* must be zero */
-- 
1.7.8.36.g69ee2
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 62 of 66 in “Column display”
  1. 00/11 Column displayNguyễn Thái Ngọc Duy, Feb 25, 2012
  2. 01/11 column: add API to print items in columnsNguyễn Thái Ngọc Duy, Feb 25, 2012
  3. 02/11 Add git-column and column mode parsingNguyễn Thái Ngọc Duy, Feb 25, 2012
  4. Ramsay JonesFeb 27, 2012
  5. Nguyen Thai Ngoc DuyFeb 28, 2012
  6. 03/11 Stop starting pager recursivelyNguyễn Thái Ngọc Duy, Feb 25, 2012
  7. 04/11 column: add columnar layoutNguyễn Thái Ngọc Duy, Feb 25, 2012
  8. 05/11 column: support columns with different widthsNguyễn Thái Ngọc Duy, Feb 25, 2012
  9. Junio C HamanoFeb 26, 2012
  10. 06/11 column: add column.ui for default column output settingsNguyễn Thái Ngọc Duy, Feb 25, 2012
  11. Junio C HamanoFeb 27, 2012
  12. Nguyen Thai Ngoc DuyFeb 27, 2012
  13. 07/11 help: reuse print_columns() for help -aNguyễn Thái Ngọc Duy, Feb 25, 2012
  14. 08/11 branch: add --columnNguyễn Thái Ngọc Duy, Feb 25, 2012
  15. 09/11 status: add --columnNguyễn Thái Ngọc Duy, Feb 25, 2012
  16. 10/11 column: support piping stdout to external git-column processNguyễn Thái Ngọc Duy, Feb 25, 2012
  17. 11/11 tag: add --columnNguyễn Thái Ngọc Duy, Feb 25, 2012
  18. Junio C HamanoFeb 26, 2012
  19. Nguyen Thai Ngoc DuyFeb 27, 2012
  20. Junio C HamanoFeb 27, 2012
  21. Junio C HamanoFeb 27, 2012
  22. Nguyen Thai Ngoc DuyFeb 27, 2012
  23. 00/10 Column displayNguyễn Thái Ngọc Duy, Feb 28, 2012
  24. 01/10 Add git-column for columnar displayNguyễn Thái Ngọc Duy, Feb 28, 2012
  25. Junio C HamanoFeb 28, 2012
  26. Nguyen Thai Ngoc DuyMar 2, 2012
  27. 02/10 Stop starting pager recursivelyNguyễn Thái Ngọc Duy, Feb 28, 2012
  28. Junio C HamanoFeb 28, 2012
  29. Junio C HamanoFeb 28, 2012
  30. Nguyen Thai Ngoc DuyFeb 29, 2012
  31. Junio C HamanoFeb 29, 2012
  32. Nguyen Thai Ngoc DuyFeb 29, 2012
  33. Junio C HamanoFeb 29, 2012
  34. 03/10 column: add columnar layoutNguyễn Thái Ngọc Duy, Feb 28, 2012
  35. Junio C HamanoFeb 28, 2012
  36. 04/10 column: add dense layout supportNguyễn Thái Ngọc Duy, Feb 28, 2012
  37. Junio C HamanoFeb 28, 2012
  38. Nguyen Thai Ngoc DuyMar 2, 2012
  39. Junio C HamanoMar 2, 2012
  40. 05/10 column: add column.ui for default column output settingsNguyễn Thái Ngọc Duy, Feb 28, 2012
  41. Junio C HamanoFeb 28, 2012
  42. 06/10 help: reuse print_columns() for help -aNguyễn Thái Ngọc Duy, Feb 28, 2012
  43. 07/10 branch: add --columnNguyễn Thái Ngọc Duy, Feb 28, 2012
  44. 08/10 status: add --columnNguyễn Thái Ngọc Duy, Feb 28, 2012
  45. 09/10 column: support piping stdout to external git-column processNguyễn Thái Ngọc Duy, Feb 28, 2012
  46. 10/10 tag: add --columnNguyễn Thái Ngọc Duy, Feb 28, 2012
  47. Thomas RastMar 2, 2012
  48. Nguyen Thai Ngoc DuyMar 11, 2012
  49. Junio C HamanoMar 12, 2012
  50. 00/9 Column displayNguyễn Thái Ngọc Duy, Mar 13, 2012
  51. Nguyen Thai Ngoc DuyMar 13, 2012
  52. 01/9 Add column layout skeleton and git-columnNguyễn Thái Ngọc Duy, Mar 13, 2012
  53. 02/9 Stop starting pager recursivelyNguyễn Thái Ngọc Duy, Mar 13, 2012
  54. 03/9 column: add columnar layoutNguyễn Thái Ngọc Duy, Mar 13, 2012
  55. 04/9 column: add dense layout supportNguyễn Thái Ngọc Duy, Mar 13, 2012
  56. 05/9 help: reuse print_columns() for help -aNguyễn Thái Ngọc Duy, Mar 13, 2012
  57. 06/9 branch: add --columnNguyễn Thái Ngọc Duy, Mar 13, 2012
  58. 07/9 status: add --columnNguyễn Thái Ngọc Duy, Mar 13, 2012
  59. 08/9 column: support piping stdout to external git-column processNguyễn Thái Ngọc Duy, Mar 13, 2012
  60. 09/9 tag: add --columnNguyễn Thái Ngọc Duy, Mar 13, 2012
  61. 10/9 ls-files: support --columnNguyễn Thái Ngọc Duy, Mar 13, 2012
  62. 11/9 column: support "denser" modeNguyễn Thái Ngọc Duy, Mar 13, 2012
  63. 12/9 column: support grouping entriesNguyễn Thái Ngọc Duy, Mar 13, 2012
  64. Junio C HamanoMar 13, 2012
  65. Nguyen Thai Ngoc DuyMar 14, 2012
  66. Junio C HamanoMar 14, 2012

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.