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:
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