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")
This commit is contained in:
@@ -149,7 +149,9 @@ function! vimwiki#tbl#get_cells(line, ...) abort
|
|||||||
let state = 'NONE'
|
let state = 'NONE'
|
||||||
let cell_start = 0
|
let cell_start = 0
|
||||||
let quote_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
|
" 'Simple' FSM
|
||||||
while state !=# 'CELL'
|
while state !=# 'CELL'
|
||||||
@@ -157,10 +159,9 @@ function! vimwiki#tbl#get_cells(line, ...) abort
|
|||||||
let state = 'CELL'
|
let state = 'CELL'
|
||||||
endif
|
endif
|
||||||
for idx in range(quote_start, len)
|
for idx in range(quote_start, len)
|
||||||
" The only way I know Vim can do Unicode...
|
let ch = chars[idx]
|
||||||
let ch = a:line[idx]
|
|
||||||
if state ==# 'NONE'
|
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 cell_start = idx + 1
|
||||||
let state = 'CELL'
|
let state = 'CELL'
|
||||||
endif
|
endif
|
||||||
@@ -168,8 +169,8 @@ function! vimwiki#tbl#get_cells(line, ...) abort
|
|||||||
if ch ==# '[' || ch ==# '{'
|
if ch ==# '[' || ch ==# '{'
|
||||||
let state = 'BEFORE_QUOTE_START'
|
let state = 'BEFORE_QUOTE_START'
|
||||||
let quote_start = idx
|
let quote_start = idx
|
||||||
elseif ch ==# s:s_sep() && (idx < 1 || a:line[idx-1] !=# '\')
|
elseif ch ==# s:s_sep() && (idx < 1 || chars[idx-1] !=# '\')
|
||||||
let cell = strpart(a:line, cell_start, idx - cell_start)
|
let cell = join(chars[cell_start : idx-1], '')
|
||||||
if a:0 && a:1
|
if a:0 && a:1
|
||||||
let cell = substitute(cell, '^ \(.*\) $', '\1', '')
|
let cell = substitute(cell, '^ \(.*\) $', '\1', '')
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4002,9 +4002,11 @@ Contributors and their Github usernames in roughly chronological order:
|
|||||||
- Thomas Leyh (@leyhline)
|
- Thomas Leyh (@leyhline)
|
||||||
- nebulaeandstars (@nebulaeandstars)
|
- nebulaeandstars (@nebulaeandstars)
|
||||||
- dmitry kim (@jsn)
|
- dmitry kim (@jsn)
|
||||||
|
- Julian Prein (@druckdev)
|
||||||
- Luke Atkinson (@LukeDAtkinson)
|
- Luke Atkinson (@LukeDAtkinson)
|
||||||
- Joe Planisky (@jplanisky)
|
- Joe Planisky (@jplanisky)
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
16. Changelog *vimwiki-changelog*
|
16. Changelog *vimwiki-changelog*
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user