summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-10-19 08:39:02 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-10-19 08:39:02 +0000
commit4ca967e200843d0ff64b01a1404b4989e81d6696 (patch)
tree4e20a896abf01ed8c6a90d2024b5f9bbc1503f95 /Src/utils.c
parent4c213d57ac42b51e41fcbbb4a50968c12ea05d8a (diff)
downloadzsh-4ca967e200843d0ff64b01a1404b4989e81d6696.tar.gz
zsh-4ca967e200843d0ff64b01a1404b4989e81d6696.zip
21882: extend prompt truncation to handle multibyte characters
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/Src/utils.c b/Src/utils.c
index 3394b0526..aef26165d 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -3520,6 +3520,49 @@ mb_niceztrdup(const char *s)
return retstr;
}
+/*
+ * Return the screen width of a multibyte string. The input
+ * string is metafied.
+ */
+/**/
+mod_export int
+mb_width(const char *s)
+{
+ char *ums = ztrdup(s), *umptr;
+ int umlen;
+ int width = 0;
+ mbstate_t mbs;
+
+ memset(&mbs, 0, sizeof(mbs));
+ umptr = unmetafy(ums, &umlen);
+ /*
+ * Convert one wide character at a time. We could convet
+ * the entire string using mbsrtowcs(), but that terminates on
+ * a NUL and we might have embedded NULs.
+ */
+ while (umlen > 0) {
+ wchar_t cc;
+ int ret = mbrtowc(&cc, umptr, umlen, &mbs);
+
+ if (ret <= 0) {
+ /* Assume a single-width character. */
+ width++;
+ ret = 1;
+ } else {
+ int wret = wcwidth(cc);
+ if (wret > 0)
+ width += wret;
+ }
+
+ umlen -= ret;
+ umptr += ret;
+ }
+
+ free(ums);
+
+ return width;
+}
+
/**/
#endif /* ZLE_UNICODE_SUPPORT */