Re: [PATCH 2/2] builtin/repo: fix table alignment for UTF-8 characters
- From
Justin Tobler <jltobler@gmail.com>
- Date
- Nov 14, 2025, 17:50 UTC
- Message-ID
- <wgxzx47nsro3h6ju3t2aatrygkr5g7i2dbl26fj53qh4f7jdxw@d233r7jflrke>
- In-Reply-To
- <a50bcde6446fbd87b4fb04b28c579a915457813a.1763098804.git.worldhello.net@gmail.com>
On 25/11/14 12:52AM, Jiang Xin wrote:
Show 23 quoted lines
> 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.
Show 29 quoted lines
> Co-developed-by: Gemini <noreply@developers.google.com>
> Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
> ---
> 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.
Show 17 quoted lines
> +
> 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