vimwiki

Personal wiki for vim
git clone https://github.com/vimwiki/vimwiki.git
Log | Files | Refs | README | LICENSE

commit c5b7f7e76f7d9b07036948a2f9c1d6cd0167e884
parent bc3bc208d727444da57cff634f3c6a9f12870e48
Author: Julian Prein <druckdev@protonmail.com>
Date:   Fri, 23 Jun 2023 01:10:54 +0200

Fix: Handle multibyte chars properly in get_cells (#1298) (fixes #1297)

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")
Diffstat:
Mautoload/vimwiki/tbl.vim | 13+++++++------
Mdoc/vimwiki.txt | 2++
2 files changed, 9 insertions(+), 6 deletions(-)

diff --git 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 @@ -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*