Skip to content

Commit 6aff1b6

Browse files
author
bravestarr
committed
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.
1 parent 7277701 commit 6aff1b6

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

lib/nerdtree/bookmark.vim

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,17 @@ endfunction
280280
" FUNCTION: Bookmark.str() {{{1
281281
" Get the string that should be rendered in the view for this bookmark
282282
function! s:Bookmark.str()
283-
let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - len(self.name)
283+
let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - strdisplaywidth(self.name)
284284
if &nu
285285
let pathStrMaxLen = pathStrMaxLen - &numberwidth
286286
endif
287287

288288
let pathStr = self.path.str({'format': 'UI'})
289-
if len(pathStr) > pathStrMaxLen
290-
let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
289+
if strdisplaywidth(pathStr) > pathStrMaxLen
290+
while strdisplaywidth(pathStr) > pathStrMaxLen && strchars(pathStr) > 0
291+
let pathStr = strcharpart(pathStr, 1)
292+
endwhile
293+
let pathStr = '<' . pathStr
291294
endif
292295
return '>' . self.name . ' ' . pathStr
293296
endfunction

lib/nerdtree/path.vim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,8 +719,10 @@ function! s:Path.str(...)
719719

720720
if has_key(options, 'truncateTo')
721721
let limit = options['truncateTo']
722-
if len(toReturn) > limit-1
723-
let toReturn = toReturn[(len(toReturn)-limit+1):]
722+
if strdisplaywidth(toReturn) > limit-1
723+
while strdisplaywidth(toReturn) > limit-1 && strchars(toReturn) > 0
724+
let toReturn = strcharpart(toReturn, 1)
725+
endwhile
724726
if len(split(toReturn, '/')) > 1
725727
let toReturn = '</' . join(split(toReturn, '/')[1:], '/') . '/'
726728
else

0 commit comments

Comments
 (0)