vimwiki

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

commit b79977d6b8bc28414081746ec76890a291b55a67
parent 411d8da0a456bd6ff7b754000dd2a242d30d7fd2
Author: Alexey Radkov <alexey.radkov@gmail.com>
Date:   Sun,  4 May 2014 15:46:19 +0400

further large table optimizations

1. s:get_aligned_rows(): getting 2 last rows is enough for having been
   formatted tables
2. vimwiki#tbl#get_cells(): using faster strpart() instead concatenating
   every new character into variables cell and quote
3. checking by getline() whether the line was changed before setline()
   does matter on slower computers

Diffstat:
Mautoload/vimwiki/tbl.vim | 74++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 48 insertions(+), 26 deletions(-)

diff --git a/autoload/vimwiki/tbl.vim b/autoload/vimwiki/tbl.vim @@ -124,11 +124,10 @@ function! s:create_row_sep(cols) "{{{ return row endfunction "}}} -function! vimwiki#tbl#get_cells(line) "{{{ +function! vimwiki#tbl#get_cells(line, ...) "{{{ let result = [] - let cell = '' - let quote = '' let state = 'NONE' + let cell_start = -1 " 'Simple' FSM for idx in range(strlen(a:line)) @@ -136,44 +135,39 @@ function! vimwiki#tbl#get_cells(line) "{{{ 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 = ch elseif ch == '|' - call add(result, vimwiki#u#trim(cell)) - let cell = "" - else - let cell .= 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 .= ch else let state = 'CELL' - let cell .= quote.ch - let quote = '' endif elseif state == 'QUOTE' if ch == ']' || ch == '}' let state = 'BEFORE_QUOTE_END' endif - let quote .= ch elseif state == 'BEFORE_QUOTE_END' if ch == ']' || ch == '}' let state = 'CELL' endif - let cell .= quote.ch - let quote = '' endif endfor - if cell.quote != '' - call add(result, vimwiki#u#trim(cell.quote, '|')) - endif return result endfunction "}}} @@ -201,7 +195,7 @@ function! s:get_indent(lnum) "{{{ return indent endfunction " }}} -function! s:get_rows(lnum) "{{{ +function! s:get_rows(lnum, ...) "{{{ if !s:is_table(getline(a:lnum)) return endif @@ -210,7 +204,9 @@ function! s:get_rows(lnum) "{{{ let lower_rows = [] let lnum = a:lnum - 1 - while lnum >= 1 + let depth = a:0 > 0 ? a:1 : 0 + let ldepth = 0 + while lnum >= 1 && (depth == 0 || ldepth < depth) let line = getline(lnum) if s:is_table(line) call add(upper_rows, [lnum, line]) @@ -218,6 +214,7 @@ function! s:get_rows(lnum) "{{{ break endif let lnum -= 1 + let ldepth += 1 endwhile call reverse(upper_rows) @@ -229,6 +226,9 @@ function! s:get_rows(lnum) "{{{ else break endif + if depth > 0 + break + endif let lnum += 1 endwhile @@ -237,7 +237,8 @@ endfunction "}}} function! s:get_cell_max_lens(lnum, ...) "{{{ let max_lens = {} - for [lnum, row] in s:get_rows(a:lnum) + let rows = a:0 > 2 ? a:3 : s:get_rows(a:lnum) + for [lnum, row] in rows if s:is_separator(row) continue endif @@ -255,13 +256,32 @@ function! s:get_cell_max_lens(lnum, ...) "{{{ endfunction "}}} function! s:get_aligned_rows(lnum, col1, col2) "{{{ - let rows = s:get_rows(a:lnum) + " 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] let cells = [] - for [lnum, row] in rows - call add(cells, vimwiki#tbl#get_cells(row)) - endfor - let max_lens = s:get_cell_max_lens(a:lnum, cells, startlnum) + let max_lens = {} + let lrows = len(rows) + if lrows == depth + 1 + let i = 1 + for [lnum, row] in rows + call add(cells, vimwiki#tbl#get_cells(row, i == lrows - 1 ? 0 : 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]) + if max_lens != fst_lens + " all the table must be re-formatted + let rows = s:get_rows(a:lnum) + let startlnum = rows[0][0] + let cells = [] + for [lnum, row] in rows + call add(cells, vimwiki#tbl#get_cells(row)) + endfor + let max_lens = s:get_cell_max_lens(a:lnum, cells, startlnum, rows) + endif + endif let result = [] for [lnum, row] in rows if s:is_separator(row) @@ -520,7 +540,9 @@ function! vimwiki#tbl#format(lnum, ...) "{{{ for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2) let row = indentstring.row - call setline(lnum, row) + if getline(lnum) != row + call setline(lnum, row) + endif endfor let &tw = s:textwidth