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