From 112f6c1580d2918ca2ece7cd20213b718232a8f6 Mon Sep 17 00:00:00 2001 From: thaafox <191024423+thaafox@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:21:47 -0400 Subject: [PATCH] Fix description truncation for multi-byte UTF-8 characters The "truncated" and "truncated_count" description styles use std::string::substr() with a byte offset derived from display width, which splits multi-byte UTF-8 sequences (emoji, CJK characters) mid-character, producing garbled output. Replace with utf8_truncate_to_width() which iterates by codepoint and respects character boundaries. Fixes #2333 --- src/columns/ColDescription.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/columns/ColDescription.cpp b/src/columns/ColDescription.cpp index 460465cff..c88768417 100644 --- a/src/columns/ColDescription.cpp +++ b/src/columns/ColDescription.cpp @@ -178,7 +178,7 @@ void ColumnDescription::render(std::vector& lines, Task& task, int else if (_style == "truncated") { int len = utf8_width(description); if (len > width) - renderStringLeft(lines, width, color, description.substr(0, width - 3) + "..."); + renderStringLeft(lines, width, color, utf8_truncate_to_width(description, width - 3) + "..."); else renderStringLeft(lines, width, color, description); } @@ -207,7 +207,7 @@ void ColumnDescription::render(std::vector& lines, Task& task, int if (len > width) renderStringLeft(lines, width, color, - description.substr(0, width - len_annos - 3) + "..." + annos_count); + utf8_truncate_to_width(description, width - len_annos - 3) + "..." + annos_count); else renderStringLeft(lines, width, color, description + annos_count); }