From 3f82d3a9753f29bb2007a24fc5ef434774c22824 Mon Sep 17 00:00:00 2001 From: Kai Moschcau Date: Tue, 30 Jul 2019 12:32:39 +0200 Subject: [PATCH] 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 --- autoload/airline/extensions/branch.vim | 6 ++++-- autoload/airline/util.vim | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/autoload/airline/extensions/branch.vim b/autoload/airline/extensions/branch.vim index fc7de3d5..4b8e51ec 100644 --- a/autoload/airline/extensions/branch.vim +++ b/autoload/airline/extensions/branch.vim @@ -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 diff --git a/autoload/airline/util.vim b/autoload/airline/util.vim index 973cdfbc..8d67021a 100644 --- a/autoload/airline/util.vim +++ b/autoload/airline/util.vim @@ -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',