commit 6aff1b6cd3f5306a6828e20375cc0fc11cabe590
parent 727770147a7589ab3a06722f4852c0237c8b3549
Author: bravestarr <freasy@gmail.com>
Date: Sun, 22 Apr 2018 21:18:46 +0800
Display a path with multi-byte characters correctly when it is truncated
When a path is rendered in the Bookmarks area or as the header line of the
tree, it is truncated if there is no enough space for it. But if a path
contains multi-byte characters, it should be truncated by characters, not
bytes, otherwise the path may be truncated between the bytes of a
multi-byte character. To deal with multi-byte characters, use
strdisplaywidth() instead of len() to get the number of display cells, and
use strcharpart() instead of strpart() to truncate a path.
Diffstat:
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/lib/nerdtree/bookmark.vim b/lib/nerdtree/bookmark.vim
@@ -280,14 +280,17 @@ endfunction
" FUNCTION: Bookmark.str() {{{1
" Get the string that should be rendered in the view for this bookmark
function! s:Bookmark.str()
- let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - len(self.name)
+ let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - strdisplaywidth(self.name)
if &nu
let pathStrMaxLen = pathStrMaxLen - &numberwidth
endif
let pathStr = self.path.str({'format': 'UI'})
- if len(pathStr) > pathStrMaxLen
- let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
+ if strdisplaywidth(pathStr) > pathStrMaxLen
+ while strdisplaywidth(pathStr) > pathStrMaxLen && strchars(pathStr) > 0
+ let pathStr = strcharpart(pathStr, 1)
+ endwhile
+ let pathStr = '<' . pathStr
endif
return '>' . self.name . ' ' . pathStr
endfunction
diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim
@@ -719,8 +719,10 @@ function! s:Path.str(...)
if has_key(options, 'truncateTo')
let limit = options['truncateTo']
- if len(toReturn) > limit-1
- let toReturn = toReturn[(len(toReturn)-limit+1):]
+ if strdisplaywidth(toReturn) > limit-1
+ while strdisplaywidth(toReturn) > limit-1 && strchars(toReturn) > 0
+ let toReturn = strcharpart(toReturn, 1)
+ endwhile
if len(split(toReturn, '/')) > 1
let toReturn = '</' . join(split(toReturn, '/')[1:], '/') . '/'
else