Improve multibyte character handling in branch ext

This fixes a bug that causes a mangled statusline. The bug occurs, when
the `displayed_head_limit` variable is set and causes the substring
expression to take a substring, which ends in the middle of a multi-byte
character.

This patch replaces the byte-based methods for measuring the
length of the branch name and creating a substring with methods that are
character-based and multi-byte aware.

It also has the nice side effect of making the length measuring more
accurate, by taking the actual display width of multi-byte characters
and the ambiwidth setting into account.

Since we need to take into account older Vim 7.4 (which might not have
the strcharpart() function), do introduce a compatibility wrapper in
airline#util that checks for the existence of the function before using
it. Older Vims will keep on using the byte-based index. I suppose Vim
7.4 before the strcharpart() function was available (patch 7.4.1730)
shouldn't be in use anymore.

closes #1948
This commit is contained in:
Kai Moschcau 2019-07-30 12:32:39 +02:00 committed by Christian Brabandt
parent 0f375addd2
commit 3f82d3a975
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
2 changed files with 13 additions and 2 deletions

View File

@ -279,8 +279,10 @@ function! airline#extensions#branch#head()
if exists("g:airline#extensions#branch#displayed_head_limit")
let w:displayed_head_limit = g:airline#extensions#branch#displayed_head_limit
if len(b:airline_head) > w:displayed_head_limit - 1
let b:airline_head = b:airline_head[0:(w:displayed_head_limit - 1)].(&encoding ==? 'utf-8' ? '…' : '.')
if strwidth(b:airline_head) > w:displayed_head_limit - 1
let b:airline_head =
\ airline#util#strcharpart(b:airline_head, 0, w:displayed_head_limit - 1)
\ ..(&encoding ==? 'utf-8' ? '…' : '.')
endif
endif

View File

@ -107,6 +107,15 @@ function! airline#util#strchars(str)
endif
endfunction
function! airline#util#strcharpart(...)
if exists('*strcharpart')
return call('strcharpart', a:000)
else
" does not handle multibyte chars :(
return a:1[(a:2):(a:3)]
endif
endfunction
function! airline#util#ignore_buf(name)
let pat = '\c\v'. get(g:, 'airline#ignore_bufadd_pat', '').
\ get(g:, 'airline#extensions#tabline#ignore_bufadd_pat',