commit 920f41b318831cca3e18684f8521e4527608e14f
parent 72ad6d1b16de450b916e45f63ae9a72f23d8d22d
Author: Alexey Radkov <alexey.radkov@gmail.com>
Date: Fri, 9 May 2014 12:47:21 +0400
fixed get_cells() FSM and gqq command
- get_cells() FSM correctly treats unclosed quotes now,
- fixed gqq command: now it aligns all the table
- proposed 'fast' variant of gqq: gq1 that aligns current + 2 above rows
Diffstat:
2 files changed, 74 insertions(+), 55 deletions(-)
diff --git a/autoload/vimwiki/tbl.vim b/autoload/vimwiki/tbl.vim
@@ -127,46 +127,58 @@ endfunction "}}}
function! vimwiki#tbl#get_cells(line, ...) "{{{
let result = []
let state = 'NONE'
- let cell_start = -1
+ let cell_start = 0
+ let quote_start = 0
+ let len = strlen(a:line) - 1
" 'Simple' FSM
- for idx in range(strlen(a:line))
- " The only way I know Vim can do Unicode...
- let ch = a:line[idx]
- if state == 'NONE'
- if ch == '|'
- let cell_start = idx + 1
- let state = 'CELL'
- endif
- elseif state == 'CELL'
- if ch == '[' || ch == '{'
- let state = 'BEFORE_QUOTE_START'
- elseif ch == '|'
- let cell = strpart(a:line, cell_start, idx - cell_start)
- if a:0 && a:1
- let cell = substitute(cell, '^ \(.*\) $', '\1', '')
+ while state != 'CELL'
+ if quote_start != 0 && state != 'CELL'
+ 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]
+ if state == 'NONE'
+ if ch == '|'
+ let cell_start = idx + 1
+ let state = 'CELL'
+ endif
+ elseif state == 'CELL'
+ if ch == '[' || ch == '{'
+ let state = 'BEFORE_QUOTE_START'
+ let quote_start = idx
+ elseif ch == '|'
+ let cell = strpart(a:line, cell_start, idx - cell_start)
+ if a:0 && a:1
+ let cell = substitute(cell, '^ \(.*\) $', '\1', '')
+ else
+ let cell = vimwiki#u#trim(cell)
+ endif
+ call add(result, cell)
+ let cell_start = idx + 1
+ endif
+ elseif state == 'BEFORE_QUOTE_START'
+ if ch == '[' || ch == '{'
+ let state = 'QUOTE'
+ let quote_start = idx
else
- let cell = vimwiki#u#trim(cell)
+ let state = 'CELL'
+ endif
+ elseif state == 'QUOTE'
+ if ch == ']' || ch == '}'
+ let state = 'BEFORE_QUOTE_END'
+ endif
+ elseif state == 'BEFORE_QUOTE_END'
+ if ch == ']' || ch == '}'
+ let state = 'CELL'
endif
- call add(result, cell)
- let cell_start = idx + 1
- endif
- elseif state == 'BEFORE_QUOTE_START'
- if ch == '[' || ch == '{'
- let state = 'QUOTE'
- else
- let state = 'CELL'
- endif
- elseif state == 'QUOTE'
- if ch == ']' || ch == '}'
- let state = 'BEFORE_QUOTE_END'
- endif
- elseif state == 'BEFORE_QUOTE_END'
- if ch == ']' || ch == '}'
- let state = 'CELL'
endif
+ endfor
+ if state == 'NONE'
+ break
endif
- endfor
+ endwhile
return result
endfunction "}}}
@@ -255,24 +267,26 @@ function! s:get_cell_max_lens(lnum, ...) "{{{
return max_lens
endfunction "}}}
-function! s:get_aligned_rows(lnum, col1, col2) "{{{
- " getting 2 last rows is enough for having been formatted tables
- let depth = 2
- let rows = s:get_rows(a:lnum, depth)
- let startlnum = rows[0][0]
+function! s:get_aligned_rows(lnum, col1, col2, depth) "{{{
+ let rows = []
+ let startlnum = 0
let cells = []
let max_lens = {}
- let lrows = len(rows)
let check_all = 1
- if lrows == depth + 1
- let i = 1
- for [lnum, row] in rows
- call add(cells, vimwiki#tbl#get_cells(row, i != lrows - 1))
- let i += 1
- endfor
- let max_lens = s:get_cell_max_lens(a:lnum, cells, startlnum, rows)
- let fst_lens = s:get_cell_max_lens(a:lnum, cells, startlnum, rows[0:0])
- let check_all = max_lens != fst_lens
+ if a:depth > 0
+ let rows = s:get_rows(a:lnum, a:depth)
+ let startlnum = rows[0][0]
+ let lrows = len(rows)
+ if lrows == a:depth + 1
+ let i = 1
+ for [lnum, row] in rows
+ call add(cells, vimwiki#tbl#get_cells(row, i != lrows - 1))
+ let i += 1
+ endfor
+ let max_lens = s:get_cell_max_lens(a:lnum, cells, startlnum, rows)
+ let fst_lens = s:get_cell_max_lens(a:lnum, cells, startlnum, rows[0:0])
+ let check_all = max_lens != fst_lens
+ endif
endif
if check_all
" all the table must be re-formatted
@@ -376,7 +390,7 @@ endfunction "}}}
" Keyboard functions "{{{
function! s:kbd_create_new_row(cols, goto_first) "{{{
let cmd = "\<ESC>o".s:create_empty_row(a:cols)
- let cmd .= "\<ESC>:call vimwiki#tbl#format(line('.'))\<CR>"
+ let cmd .= "\<ESC>:call vimwiki#tbl#format(line('.'), 2)\<CR>"
let cmd .= "\<ESC>0"
if a:goto_first
let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'c', line('.'))\<CR>"
@@ -537,6 +551,8 @@ function! vimwiki#tbl#format(lnum, ...) "{{{
return
endif
+ let depth = a:0 == 1 ? a:1 : 0
+
if a:0 == 2
let col1 = a:1
let col2 = a:2
@@ -552,7 +568,8 @@ function! vimwiki#tbl#format(lnum, ...) "{{{
let indentstring = repeat(' ', indent / &tabstop) . repeat(' ', indent % &tabstop)
endif
- for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2)
+ " getting N = depth last rows is enough for having been formatted tables
+ for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2, depth)
let row = indentstring.row
if getline(lnum) != row
call setline(lnum, row)
@@ -597,9 +614,9 @@ function! vimwiki#tbl#create(...) "{{{
call append(line('.'), lines)
endfunction "}}}
-function! vimwiki#tbl#align_or_cmd(cmd) "{{{
+function! vimwiki#tbl#align_or_cmd(cmd, ...) "{{{
if s:is_table(getline('.'))
- call vimwiki#tbl#format(line('.'))
+ call call('vimwiki#tbl#format', [line('.')] + a:000)
else
exe 'normal! '.a:cmd
endif
diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim
@@ -342,8 +342,8 @@ command! -buffer VimwikiListToggle call vimwiki#lst#toggle_list_item()
" table commands
command! -buffer -nargs=* VimwikiTable call vimwiki#tbl#create(<f-args>)
-command! -buffer VimwikiTableAlignQ call vimwiki#tbl#align_or_cmd('gqq')
-command! -buffer VimwikiTableAlignW call vimwiki#tbl#align_or_cmd('gww')
+command! -buffer -nargs=? VimwikiTableAlignQ call vimwiki#tbl#align_or_cmd('gqq', <f-args>)
+command! -buffer -nargs=? VimwikiTableAlignW call vimwiki#tbl#align_or_cmd('gww', <f-args>)
command! -buffer VimwikiTableMoveColumnLeft call vimwiki#tbl#move_column_left()
command! -buffer VimwikiTableMoveColumnRight call vimwiki#tbl#move_column_right()
@@ -614,6 +614,8 @@ endif
nnoremap <buffer> gqq :VimwikiTableAlignQ<CR>
nnoremap <buffer> gww :VimwikiTableAlignW<CR>
+nnoremap <buffer> gq1 :VimwikiTableAlignQ 2<CR>
+nnoremap <buffer> gw1 :VimwikiTableAlignW 2<CR>
if !hasmapto('<Plug>VimwikiTableMoveColumnLeft')
nmap <silent><buffer> <A-Left> <Plug>VimwikiTableMoveColumnLeft
endif