summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hurst <julian.hurst@digdash.com>2025-03-20 14:46:33 +0100
committerJulian Hurst <julian.hurst@digdash.com>2025-03-20 14:46:33 +0100
commit5efb8c021fe2166648591e46591144a49bf575bf (patch)
treea557f6cc09cf30bf55e30d7592d57ff0399f19b3
parenta1b536135d35c7937d7f6dbf76e16ce4c48abfa6 (diff)
downloadhare-tui-5efb8c021fe2166648591e46591144a49bf575bf.tar.gz
Substring widthwise instead of runewise
-rw-r--r--tui/widget/widget.ha4
-rw-r--r--tui/width.ha14
2 files changed, 16 insertions, 2 deletions
diff --git a/tui/widget/widget.ha b/tui/widget/widget.ha
index 7c82dfa..4212eae 100644
--- a/tui/widget/widget.ha
+++ b/tui/widget/widget.ha
@@ -234,11 +234,11 @@ fn truncate_to_size(w: *widget) []str = {
const line = w.buf.lines[i];
let item = match (w.sz) {
case let sz: tty::ttysize =>
- const s = if (tui::strwidth(line) > sz.columns) strings::sub(line, 0z, sz.columns) else line;
+ const s = if (tui::strwidth(line) > sz.columns) tui::subwidth(line, sz.columns) else line;
yield strings::rpad(s, ' ', sz.columns);
case void =>
const wsz = tty::winsize(w.state.out)!;
- const s = if (tui::strwidth(line) > wsz.columns) strings::sub(line, 0z, wsz.columns) else line;
+ const s = if (tui::strwidth(line) > wsz.columns) tui::subwidth(line, wsz.columns) else line;
yield strings::dup(s);
};
append(lines, item);
diff --git a/tui/width.ha b/tui/width.ha
index 6f9631c..ed498e6 100644
--- a/tui/width.ha
+++ b/tui/width.ha
@@ -30,3 +30,17 @@ export fn strwidth(s: str) uint = {
};
return sum;
};
+
+export fn subwidth(s: str, end: (size | strings::end)) str = {
+ const runes = strings::torunes(s);
+ defer free(runes);
+ let sum = 0u;
+ for (let i = 0z; i < len(runes); i += 1) {
+ const r = runes[i];
+ sum += runewidth(r);
+ if (sum > end: uint) {
+ return strings::sub(s, 0, i - 1);
+ };
+ };
+ return s;
+};