From d7becafbdd4c2e81a4192cebea482079fad00af5 Mon Sep 17 00:00:00 2001 From: Ivan Tishchenko Date: Tue, 7 Jul 2015 22:54:57 +0300 Subject: [PATCH] Fix bug with folds shortening on multibyte characters. If section title contains multibyte chars, the fold shortening function often fails, because it works with text as array of bytes, not characters (see strlen() doc for example). This commit fixes this issue. --- ftplugin/vimwiki.vim | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim index ea7616e..81cec3a 100644 --- a/ftplugin/vimwiki.vim +++ b/ftplugin/vimwiki.vim @@ -177,15 +177,20 @@ endfunction "}}} " for long enough "text", the string's length is within s:tolerance of "len" " (so that -s:tolerance <= spare <= s:tolerance, "string" ends with s:ellipsis) function! s:shorten_text(text, len) "{{{ returns [string, spare] - let spare_len = a:len - strlen(a:text) + " strlen() returns lenght in bytes, not in characters, so we'll have to do a + " trick here -- replace all non-spaces with dot, calculate lengths and + " indexes on it, then use original string to break at selected index. + let text_pattern = substitute(a:text, '\m\S', '.', 'g') + let spare_len = a:len - strlen(text_pattern) if (spare_len + s:tolerance >= 0) return [a:text, spare_len] endif " try to break on a space; assumes a:len-s:ell_len >= s:tolerance let newlen = a:len - s:ell_len - let idx = strridx(a:text, ' ', newlen + s:tolerance) + let idx = strridx(text_pattern, ' ', newlen + s:tolerance) let break_idx = (idx + s:tolerance >= newlen) ? idx : newlen - return [a:text[0:break_idx].s:ellipsis, newlen - break_idx] + return [matchstr(a:text, '\m^.\{'.break_idx.'\}').s:ellipsis, + \ newlen - break_idx] endfunction "}}} function! VimwikiFoldText() "{{{