diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2005-10-19 08:39:02 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2005-10-19 08:39:02 +0000 |
commit | 4ca967e200843d0ff64b01a1404b4989e81d6696 (patch) | |
tree | 4e20a896abf01ed8c6a90d2024b5f9bbc1503f95 /Src/utils.c | |
parent | 4c213d57ac42b51e41fcbbb4a50968c12ea05d8a (diff) | |
download | zsh-4ca967e200843d0ff64b01a1404b4989e81d6696.tar.gz zsh-4ca967e200843d0ff64b01a1404b4989e81d6696.tar.xz zsh-4ca967e200843d0ff64b01a1404b4989e81d6696.zip |
21882: extend prompt truncation to handle multibyte characters
Diffstat (limited to 'Src/utils.c')
-rw-r--r-- | Src/utils.c | 43 |
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, ¨en); + /* + * 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 */ |