summaryrefslogtreecommitdiff
path: root/lib/std/utf.myr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/utf.myr')
-rw-r--r--lib/std/utf.myr29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/std/utf.myr b/lib/std/utf.myr
index 6c655a3..439254c 100644
--- a/lib/std/utf.myr
+++ b/lib/std/utf.myr
@@ -1,3 +1,5 @@
+use "extremum"
+use "chartype"
use "die"
use "types"
@@ -12,6 +14,7 @@ pkg std =
const decode : (buf : byte[:] -> char)
const strstep : (str : byte[:] -> (char, byte[:]))
+ const strcellwidth : (str : byte[:] -> size)
;;
const charlen = {c
@@ -101,3 +104,29 @@ const strstep = {str
-> ((chr : char), str[len:])
}
+
+const strcellwidth = {str
+ var s : byte[:] = str
+ var c : char = Badchar
+ var n : size = 0
+
+ while s.len > 0
+ (c, s) = strstep(s)
+ if c == Badchar
+ /* Something will probably be printed as U+FFFD */
+ n++
+ elif c < 0x20
+ /* Control characters take 0 cells */
+ elif c < 0x7f
+ /* Bog standard ASCII takes 1 cell */
+ n++
+ elif c == 0x7f
+ /* DEL is like a control character */
+ else
+ /* It's not ASCII, so ask chartype what to do */
+ n += (abs(cellwidth(c)) : size)
+ ;;
+ ;;
+
+ -> n
+}