Thread (11 messages) 11 messages, 4 authors, 2025-11-15

Re: [PATCH 2/2] builtin/repo: fix table alignment for UTF-8 characters

From: Justin Tobler <hidden>
Date: 2025-11-14 17:50:37

On 25/11/14 12:52AM, Jiang Xin wrote:
The output table from "git repo structure" is misaligned when displaying
UTF-8 characters (e.g., non-ASCII glyphs). E.g.:

    | 仓库结构   | 值  |
    | -------------- | ---- |
    | * 引用       |      |
    |   * 计数     |   67 |
    |     * 分支   |    6 |
    |     * 标签   |   30 |
    |     * 远程   |   19 |
    |     * 其它   |   12 |
    |                |      |
    | * 可达对象 |      |
    |   * 计数     | 2217 |
    |     * 提交   |  279 |
    |     * 树      |  740 |
    |     * 数据对象 | 1168 |
    |     * 标签   |   30 |

The previous implementation used simple width formatting with printf()
which didn't properly handle multi-byte UTF-8 characters, causing
misaligned table columns when displaying repository structure
information.
Thanks for finding this issue and submitting a fix! I failed to consider
the fact that the printf() format specifier width would be counting
bytes. This causes the overall line width to fall short in some
scenarios with multi-byte UTF-8 characters.
This change modifies the stats_table_print_structure function to use
strbuf_utf8_align() instead of basic printf width specifiers. This
ensures proper column alignment regardless of the character encoding of
the content being displayed.
Makes sense.
quoted hunk ↗ jump to hunk
Co-developed-by: Gemini <redacted>
Signed-off-by: Jiang Xin <redacted>
---
 builtin/repo.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/builtin/repo.c b/builtin/repo.c
index 9d4749f79b..d0b4a060b1 100644
--- a/builtin/repo.c
+++ b/builtin/repo.c
@@ -292,14 +292,21 @@ static void stats_table_print_structure(const struct stats_table *table)
 	int name_col_width = utf8_strwidth(name_col_title);
 	int value_col_width = utf8_strwidth(value_col_title);
 	struct string_list_item *item;
+	struct strbuf buf = STRBUF_INIT;
 
 	if (table->name_col_width > name_col_width)
 		name_col_width = table->name_col_width;
 	if (table->value_col_width > value_col_width)
 		value_col_width = table->value_col_width;
 
-	printf("| %-*s | %-*s |\n", name_col_width, name_col_title,
-	       value_col_width, value_col_title);
+	strbuf_addstr(&buf, "| ");
+	strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, name_col_title);
+	strbuf_addstr(&buf, " | ");
+	strbuf_utf8_align(&buf, ALIGN_LEFT, value_col_width, value_col_title);
+	strbuf_addstr(&buf, " |");
+	printf("%s\n", buf.buf);
Ok, using strbuf_utf8_align() compensates the line width when using
multi-byte UTF-8 characters to ensure the correct length. Looks good.
+	strbuf_reset(&buf);
Do we need to reset the buffer here? In the following loop we reset it
at the start of each iteration.
quoted hunk ↗ jump to hunk
+
 	printf("| ");
 	for (int i = 0; i < name_col_width; i++)
 		putchar('-');
@@ -317,9 +324,16 @@ static void stats_table_print_structure(const struct stats_table *table)
 			value = entry->value;
 		}
 
-		printf("| %-*s | %*s |\n", name_col_width, item->string,
-		       value_col_width, value);
+		strbuf_reset(&buf);
+		strbuf_addstr(&buf, "| ");
+		strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, item->string);
+		strbuf_addstr(&buf, " | ");
+		strbuf_utf8_align(&buf, ALIGN_RIGHT, value_col_width, value);
+		strbuf_addstr(&buf, " |");
+		printf("%s\n", buf.buf);
Here we do the same thing for the values column. Looks good to me.

Thanks,
-Justin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help