From c5b7f7e76f7d9b07036948a2f9c1d6cd0167e884 Mon Sep 17 00:00:00 2001 From: Julian Prein Date: Fri, 23 Jun 2023 01:10:54 +0200 Subject: [PATCH] Fix: Handle multibyte chars properly in get_cells (#1298) (fixes #1297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously vimwiki#tbl#get_cells() would act on `line` as a normal string (i.e. using `[idx]` and strpart()). This breaks when the column separator (s:s_rep() or rxTableSep) is a multibyte character like the vertical box drawing character │. In that case the separator is never found and only one empty cell is returned. This also affects vimwiki#tbl#format() which in turn clears the whole table each time the insert mode is left. Fix this issue by initially splitting the line into a list of the characters. Getting the elements with `[idx]` now returns each character instead of a byte. In addition len() is used in place of strlen() as well as slicing together with join() instead of strpart(). Fixes: #1297 ("Table formatting breaks on multibyte separator") --- autoload/vimwiki/tbl.vim | 13 +++++++------ doc/vimwiki.txt | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/autoload/vimwiki/tbl.vim b/autoload/vimwiki/tbl.vim index 03b07ec..6e9fa7e 100644 --- a/autoload/vimwiki/tbl.vim +++ b/autoload/vimwiki/tbl.vim @@ -149,7 +149,9 @@ function! vimwiki#tbl#get_cells(line, ...) abort let state = 'NONE' let cell_start = 0 let quote_start = 0 - let len = strlen(a:line) - 1 + " Split byte string into list of character to properly handle multibyte chars + let chars = split(a:line, '\zs') + let len = len(chars) - 1 " 'Simple' FSM while state !=# 'CELL' @@ -157,10 +159,9 @@ function! vimwiki#tbl#get_cells(line, ...) abort let state = 'CELL' endif for idx in range(quote_start, len) - " The only way I know Vim can do Unicode... - let ch = a:line[idx] + let ch = chars[idx] if state ==# 'NONE' - if ch ==# s:s_sep() && (idx < 1 || a:line[idx-1] !=# '\') + if ch ==# s:s_sep() && (idx < 1 || chars[idx-1] !=# '\') let cell_start = idx + 1 let state = 'CELL' endif @@ -168,8 +169,8 @@ function! vimwiki#tbl#get_cells(line, ...) abort if ch ==# '[' || ch ==# '{' let state = 'BEFORE_QUOTE_START' let quote_start = idx - elseif ch ==# s:s_sep() && (idx < 1 || a:line[idx-1] !=# '\') - let cell = strpart(a:line, cell_start, idx - cell_start) + elseif ch ==# s:s_sep() && (idx < 1 || chars[idx-1] !=# '\') + let cell = join(chars[cell_start : idx-1], '') if a:0 && a:1 let cell = substitute(cell, '^ \(.*\) $', '\1', '') else diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt index 58d2372..96920fb 100644 --- a/doc/vimwiki.txt +++ b/doc/vimwiki.txt @@ -4002,9 +4002,11 @@ Contributors and their Github usernames in roughly chronological order: - Thomas Leyh (@leyhline) - nebulaeandstars (@nebulaeandstars) - dmitry kim (@jsn) + - Julian Prein (@druckdev) - Luke Atkinson (@LukeDAtkinson) - Joe Planisky (@jplanisky) + ============================================================================== 16. Changelog *vimwiki-changelog*