Compare commits

..

32 Commits

Author SHA1 Message Date
Dhruva Sagar
766066394c Updated docs 2014-04-28 13:48:17 +05:30
Dhruva Sagar
f2f62d78e5 Added support for negative indices
When defining formulas you can now use negative indices for target /
cells to refer to them relative to the last. -1 being the last and so
on.
2014-04-28 13:41:21 +05:30
Dhruva Sagar
7810ce0ca0 Fixed #26
Not assuming a length for alignments, looping through all and adding 'l'
as default first then updating as per the column alignments.
2014-04-26 23:52:18 +05:30
Dhruva Sagar
b22d793135 Improved fix for #20
Instead of relying on a /g or /gg flag based on gdefault, I temporarily
disable gdefault and set it back to the old value aftwards.
2014-04-25 18:18:19 +05:30
Dhruva Sagar
de2ad0b71d Fixed header creation as first line of table 2014-04-25 18:10:12 +05:30
Dhruva Sagar
29c7ec1a23 Cosmetic change
changed variable name from i to jdx since for consistency, i is short
for insert which is a vim ex command so to make things unambiguous.
2014-04-25 15:59:08 +05:30
Dhruva Sagar
9ce981cc77 Updated README.md 2014-04-25 15:05:19 +05:30
Dhruva Sagar
0c9cd8fb50 Releasing v4.3.0 2014-04-25 15:02:27 +05:30
Dhruva Sagar
da39088fd8 Merge branch 'feature/gfm_column_alignment' 2014-04-25 14:55:22 +05:30
Dhruva Sagar
a0fcb89f43 Fixed #19
Updated tablemode#table#IsRow() to allow hiphens within the row.
2014-04-25 14:54:43 +05:30
Dhruva Sagar
5007e5f728 Added support for column alignment #23
Now we can define gfm-style aligment by adding them to the header column
2014-04-25 14:42:02 +05:30
Dhruva Sagar
71051e2c22 Merge branch 'master' into feature/gfm_column_alignment
Conflicts:
	autoload/tablemode/table.vim
2014-04-25 14:31:33 +05:30
Dhruva Sagar
43d0c0ff6f Cosmetic refactoring
* Changed the API calls to be more sensible & simple and free of
  redundancy.
2014-04-25 11:09:14 +05:30
Dhruva Sagar
00c54e8e02 Refactoring alignment 2014-04-24 15:48:57 +05:30
Dhruva Sagar
cfbac6979d Fixed #25
Minor refactoring & corrected variable names
2014-04-23 11:27:25 +05:30
Dhruva Sagar
7e00cea7f5 Improved table.vim tests. Fixed #24. 2014-04-22 00:11:40 +05:30
Dhruva Sagar
79166b3d4e Fixing #24
Exposed a public api for IsTableModeActive and using it instead.
2014-04-21 14:58:02 +05:30
Dhruva Sagar
6862a8b7e4 Update CHANGELOG.md 2014-04-09 14:40:31 +05:30
Dhruva Sagar
d889c342d3 Fixed the tests with new changes 2014-04-09 11:45:02 +05:30
Dhruva Sagar
8a54ef28ab Removed CellTextObject() from spreadsheet.vim 2014-04-09 11:34:54 +05:30
Dhruva Sagar
a2492fbf08 Removed old TableMotion from autoload/tablemode/table.vim 2014-04-09 11:32:03 +05:30
Dhruva Sagar
652de4d29c Releasing v4.2.0
* Refactored cell & formula logic out into separate files
* Added more tests to test things independently.
2014-04-09 11:20:10 +05:30
Dhruva Sagar
f91782fca2 Added tests for formula evaluation
* Minor fixes as detected by the tests
2014-04-09 08:09:28 +05:30
Dhruva Sagar
1ef8c812d6 Fixed table motions over corners with borders 2014-04-07 22:21:16 +05:30
Dhruva Sagar
63cb175d57 Releasing v4.1.0
* Fixed bad references within plugin.
* Added fixtures for cleaner tests.
* Updated readme, changelog & doc
2014-04-07 19:15:52 +05:30
Dhruva Sagar
4eae4a659d Merge branch 'master' of github.com:dhruvasagar/vim-table-mode 2014-04-07 19:11:05 +05:30
Dhruva Sagar
5012486cbe Fixed function references in plugin 2014-04-07 19:10:26 +05:30
Dhruva Sagar
12f4c39982 Added silent! to ignore errors on disabling errors 2014-04-07 19:09:20 +05:30
Dhruva Sagar
943496c535 Added fixtures 2014-04-07 19:09:02 +05:30
Dhruva Sagar
151d489a53 Update README.md 2014-04-07 17:31:40 +05:30
Dhruva Sagar
aa5b5ef526 Update README.md 2014-04-07 16:17:27 +05:30
Dhruva Sagar
a0207b7895 Updated README & CHANGELOG 2014-04-07 15:37:38 +05:30
28 changed files with 934 additions and 687 deletions

View File

@@ -1,4 +1,29 @@
# Change Log
## Version 4.4.0
* Minor bug fixes
* Added feature to allow using negative indices within formulas to access rows,
columns relative to the last, -1 being the last.
## Version 4.3.0
* Refactored some more
* Fixed issue #19, hiphens in the table broke alignment
* Added feature #26, you can now define column alignments in the table header
## Version 4.2.0
* Refactored cells logic out to autoload/tablemode/spreadsheet/cell.vim
* Refactored formula logic out to autoload/tablemode/spreadsheet/formula.vim
## Version 4.1.0
* Fixed bad references within plugin
* Added fixtures
## Version 4.0.0
* Major refactoring of the codebase.
* Improved modular tests.
* Fixed long standing unicode character alignment issue.
* Moved to providing \<Plug\> mappings rather than configuration based mappings
which can be more easily overriden by end user.
## Version 3.3.2
* Added new mapping \t? to echo a cells representation for use while defining
formulas.

View File

@@ -1,4 +1,4 @@
# VIM Table Mode [![Build Status](https://travis-ci.org/dhruvasagar/vim-table-mode.png?branch=master)](https://travis-ci.org/dhruvasagar/vim-table-mode)
# VIM Table Mode v4.4.0 [![Build Status](https://travis-ci.org/dhruvasagar/vim-table-mode.png?branch=master)](https://travis-ci.org/dhruvasagar/vim-table-mode)
An awesome automatic table creator & formatter allowing one to create neat
tables as you type.
@@ -48,6 +48,10 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
per buffer basis and so it does not cause any unusual behavior unless it is
enabled explicitly. Please read `:h table-mode` for further information.
You can also define in a table header border how it's content should be
aligned, whether right or left by using a `:` character defined by
`g:table_mode_align_char` option.
- **Format existing content into a table** :
Table Mode wouldn't justify it's name if it didn't allow formatting
@@ -72,29 +76,20 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
- **Move between cells** :
Now you can move between cells using table mode motions <kbd>\<Leader\>t[hjkl]</kbd>
to move left | down | up | right cells respectively. You can use
`g:table_mode_map_prefix` option to define the prefix mapping to be used
before 'hjkl'. The left | right motions wrap around the table and move to
the next | previous row after the last | first cell in the current row if
one exists.
Now you can move between cells using table mode motions <kbd>[|</kbd>,
<kbd>]|</kbd>, <kbd>{|</kbd> & <kbd>}|</kbd> to move left | right | up |
down cells respectively. The left | right motions wrap around the table
and move to the next | previous row after the last | first cell in the
current row if one exists.
- **Manipulating Table** :
- **Cell Text Object** :
Tableize provides a text object for manipulating table cells. By default
it's <kbd>tc</kbd>, but that can be changed if you wish to by setting the
`g:table_mode_cell_text_object` option.
This is intelligent in the sense that if you use it to delete the
contents it will delete everything till the `g:table_mode_separator` so
that the cell is removed and you can enter new stuff if you wish to (had
you used 'c' operator), having to input the `g:table_mode_separator`
again to form the cell & realign it (since it can't be done from the
text object itself). However if you were to 'y' or yank the text, it
would copy the right text, i.e. the contents of the cell and nothing
else.
Tableize provides a text object for manipulating table cells. Following
the vim philosophy the you have <kbd>i|</kbd> & <kbd>a|</kbd> for the
inner and around (including the immidiate right table separator) the
table cell.
- **Delete Row** :
@@ -142,11 +137,13 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
- `$n`: This matches the table column number `n`. So the `formula` would
be evaluated for each cell in that column and the result would be placed
in it.
in it. You can use negative indice to represent column relative to the
last, -1 being the last.
- `$n,m`: This matches the table cell n,m (row, column). So in this case
the formula would be evaluated and the result will be placed in this
cell.
cell. You can also use negative values to refer to cells relative to
the size, -1 being the last (row or column).
- The `formula` can be a simple mathematical expression involving cells
which are also defined by the same format as that of the target cell. You

View File

@@ -4,7 +4,6 @@
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Version: 4.0.0
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
@@ -33,13 +32,6 @@ function! s:SetBufferOptDefault(opt, val) "{{{2
endif
endfunction
function! s:IsTableModeActive() "{{{2
if g:table_mode_always_active | return 1 | endif
call s:SetBufferOptDefault('table_mode_active', 0)
return b:table_mode_active
endfunction
function! s:ToggleMapping() "{{{2
if exists('b:table_mode_active') && b:table_mode_active
call s:SetBufferOptDefault('table_mode_separator_map', g:table_mode_separator)
@@ -49,7 +41,7 @@ function! s:ToggleMapping() "{{{2
execute "inoremap <silent> <buffer> " . b:table_mode_separator_map . ' ' .
\ b:table_mode_separator_map . "<Esc>:call tablemode#TableizeInsertMode()<CR>a"
else
execute "iunmap <silent> <buffer> " . b:table_mode_separator_map
silent! execute "iunmap <silent> <buffer> " . b:table_mode_separator_map
endif
endfunction
@@ -59,13 +51,13 @@ function! s:SetActive(bool) "{{{2
endfunction
function! s:ConvertDelimiterToSeparator(line, ...) "{{{2
let gflag = 'g'
if &gdefault | let gflag = 'gg' | endif
let old_gdefault = &gdefault
set nogdefault
let delim = g:table_mode_delimiter
if a:0 | let delim = a:1 | endif
if delim ==# ','
silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs,\\ze[^\'\"]*[\'\"]/__COMMA__/" . gflag
silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs,\\ze[^\'\"]*[\'\"]/__COMMA__/g"
endif
let [cstart, cend] = [tablemode#table#GetCommentStart(), tablemode#table#GetCommentEnd()]
@@ -75,11 +67,13 @@ function! s:ConvertDelimiterToSeparator(line, ...) "{{{2
silent! execute a:line . 's/' . tablemode#table#StartExpr() . '\zs\ze' . match_char_start .
\ '\|' . delim . '\|' . match_char_end . '\zs\ze' . tablemode#table#EndExpr() . '/' .
\ g:table_mode_separator . '/' . gflag
\ g:table_mode_separator . '/g'
if delim ==# ','
silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs__COMMA__\\ze[^\'\"]*[\'\"]/,/" . gflag
silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs__COMMA__\\ze[^\'\"]*[\'\"]/,/g"
endif
let &gdefault=old_gdefault
endfunction
function! s:Tableizeline(line, ...) "{{{2
@@ -98,28 +92,35 @@ function! tablemode#scope() "{{{2
return s:
endfunction
function! tablemode#IsActive() "{{{2
if g:table_mode_always_active | return 1 | endif
call s:SetBufferOptDefault('table_mode_active', 0)
return b:table_mode_active
endfunction
function! tablemode#TableizeInsertMode() "{{{2
if s:IsTableModeActive() && getline('.') =~# (tablemode#table#StartExpr() . g:table_mode_separator . g:table_mode_separator)
if tablemode#IsActive() && getline('.') =~# (tablemode#table#StartExpr() . g:table_mode_separator . g:table_mode_separator)
call tablemode#table#AddHeaderBorder('.')
normal! A
elseif s:IsTableModeActive() && getline('.') =~# (tablemode#table#StartExpr() . g:table_mode_separator)
elseif tablemode#IsActive() && getline('.') =~# (tablemode#table#StartExpr() . g:table_mode_separator)
let column = tablemode#utils#strlen(substitute(getline('.')[0:col('.')], '[^' . g:table_mode_separator . ']', '', 'g'))
let position = tablemode#utils#strlen(matchstr(getline('.')[0:col('.')], '.*' . g:table_mode_separator . '\s*\zs.*'))
call tablemode#table#TableRealign('.')
call tablemode#table#Realign('.')
normal! 0
call search(repeat('[^' . g:table_mode_separator . ']*' . g:table_mode_separator, column) . '\s\{-\}' . repeat('.', position), 'ce', line('.'))
endif
endfunction
function! tablemode#TableModeEnable() "{{{2
function! tablemode#Enable() "{{{2
call s:SetActive(1)
endfunction
function! tablemode#TableModeDisable() "{{{2
function! tablemode#Disable() "{{{2
call s:SetActive(0)
endfunction
function! tablemode#TableModeToggle() "{{{2
function! tablemode#Toggle() "{{{2
if g:table_mode_always_active
return 1
endif
@@ -136,7 +137,7 @@ function! tablemode#TableizeRange(...) range "{{{2
let lnum += 1
endwhile
call tablemode#table#TableRealign(lnum - 1)
call tablemode#table#Realign(lnum - 1)
endfunction
function! tablemode#TableizeByDelimiter() "{{{2

View File

@@ -4,7 +4,6 @@
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Version: 4.0.0
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
@@ -65,11 +64,21 @@ function! s:Padding(string, length, where) "{{{3
endif
endfunction
" function! s:Split() - Split a string into fields and delimiters {{{2
" Public Functions {{{1
function! tablemode#align#sid() "{{{2
return maparg('<sid>', 'n')
endfunction
nnoremap <sid> <sid>
function! tablemode#align#scope() "{{{2
return s:
endfunction
" function! tablemode#align#Split() - Split a string into fields and delimiters {{{2
" Like split(), but include the delimiters as elements
" All odd numbered elements are delimiters
" All even numbered elements are non-delimiters (including zero)
function! s:Split(string, delim)
function! tablemode#align#Split(string, delim)
let rv = []
let beg = 0
@@ -108,59 +117,65 @@ function! s:Split(string, delim)
return rv
endfunction
" Public Functions {{{1
function! tablemode#align#sid() "{{{2
return maparg('<sid>', 'n')
endfunction
nnoremap <sid> <sid>
function! tablemode#align#scope() "{{{2
return s:
function! tablemode#align#alignments(lnum, ncols) "{{{2
let alignments = []
if tablemode#table#IsHeader(a:lnum+1)
let hcols = tablemode#align#Split(getline(a:lnum+1), '[' . g:table_mode_corner . g:table_mode_corner_corner . ']')
for idx in range(len(hcols))
" Right align if header
call add(alignments, 'l')
if hcols[idx] =~# g:table_mode_align_char . '$' | let alignments[idx] = 'r' | endif
if hcols[idx] !~# '[^0-9\.]' | let alignments[idx] = 'r' | endif
endfor
end
return alignments
endfunction
function! tablemode#align#Align(lines) "{{{2
let lines = map(a:lines, 's:Split(v:val, g:table_mode_separator)')
let lines = map(a:lines, 'map(v:val, "v:key =~# \"text\" ? tablemode#align#Split(v:val, g:table_mode_separator) : v:val")')
for line in lines
if len(line) <= 1 | continue | endif
let stext = line.text
if len(stext) <= 1 | continue | endif
if line[0] !~ tablemode#table#StartExpr()
let line[0] = s:StripTrailingSpaces(line[0])
if stext[0] !~ tablemode#table#StartExpr()
let stext[0] = s:StripTrailingSpaces(stext[0])
endif
if len(line) >= 2
for i in range(1, len(line)-1)
let line[i] = tablemode#utils#strip(line[i])
if len(stext) >= 2
for i in range(1, len(stext)-1)
let stext[i] = tablemode#utils#strip(stext[i])
endfor
endif
endfor
let maxes = []
for line in lines
if len(line) <= 1 | continue | endif
for i in range(len(line))
let stext = line.text
if len(stext) <= 1 | continue | endif
for i in range(len(stext))
if i == len(maxes)
let maxes += [ s:Strlen(line[i]) ]
let maxes += [ s:Strlen(stext[i]) ]
else
let maxes[i] = max([ maxes[i], s:Strlen(line[i]) ])
let maxes[i] = max([ maxes[i], s:Strlen(stext[i]) ])
endif
endfor
endfor
let alignments = tablemode#align#alignments(lines[0].lnum, len(lines[0].text))
for idx in range(len(lines))
let line = lines[idx]
let tlnum = lines[idx].lnum
let tline = lines[idx].text
if len(line) <= 1 | continue | endif
for i in range(len(line))
if line[i] !~# '[^0-9\.]'
let field = s:Padding(line[i], maxes[i], 'r')
else
let field = s:Padding(line[i], maxes[i], 'l')
endif
let line[i] = field . (i == 0 || i == len(line) ? '' : ' ')
if len(tline) <= 1 | continue | endif
for jdx in range(len(tline))
" Dealing with the header being the first line
if jdx >= len(alignments) | call add(alignments, 'l') | endif
let field = s:Padding(tline[jdx], maxes[jdx], alignments[jdx])
let tline[jdx] = field . (jdx == 0 || jdx == len(tline) ? '' : ' ')
endfor
let lines[idx] = s:StripTrailingSpaces(join(line, ''))
let lines[idx].text = s:StripTrailingSpaces(join(tline, ''))
endfor
return lines

View File

@@ -4,7 +4,6 @@
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Version: 4.0.0
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
@@ -37,42 +36,6 @@ function! s:Average(list) "{{{2
return s:Sum(a:list)/len(a:list)
endfunction
" function! s:ParseRange(range, ...) {{{2
" range: A string representing range of cells.
" - Can be row1:row2 for values in the current columns in those rows.
" - Can be row1,col1:row2,col2 for range between row1,col1 till
" row2,col2.
function! s:ParseRange(range, ...)
if a:0 < 1
let default_col = tablemode#spreadsheet#ColumnNr('.')
elseif a:0 < 2
let default_col = a:1
endif
if type(a:range) != type('')
let range = string(a:range)
else
let range = a:range
endif
let [rowcol1, rowcol2] = split(range, ':')
let [rcs1, rcs2] = [map(split(rowcol1, ','), 'str2nr(v:val)'), map(split(rowcol2, ','), 'str2nr(v:val)')]
if len(rcs1) == 2
let [row1, col1] = rcs1
else
let [row1, col1] = [rcs1[0], default_col]
endif
if len(rcs2) == 2
let [row2, col2] = rcs2
else
let [row2, col2] = [rcs2[0], default_col]
endif
return [row1, col1, row2, col2]
endfunction
" Public Functions {{{1
function! tablemode#spreadsheet#sid() "{{{2
return maparg('<sid>', 'n')
@@ -84,50 +47,50 @@ function! tablemode#spreadsheet#scope() "{{{2
endfunction
function! tablemode#spreadsheet#GetFirstRow(line) "{{{2
if tablemode#table#IsATableRow(a:line)
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line - 1) || tablemode#table#IsATableHeader(line - 1)
while tablemode#table#IsRow(line - 1) || tablemode#table#IsHeader(line - 1)
let line -= 1
endwhile
if tablemode#table#IsATableHeader(line) | let line += 1 | endif
if tablemode#table#IsHeader(line) | let line += 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#MoveToFirstRow() "{{{2
if tablemode#table#IsATableRow('.')
if tablemode#table#IsRow('.')
call cursor(tablemode#spreadsheet#GetFirstRow('.'), col('.'))
endif
endfunction
function! tablemode#spreadsheet#GetLastRow(line) "{{{2
if tablemode#table#IsATableRow(a:line)
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line + 1) || tablemode#table#IsATableHeader(line + 1)
while tablemode#table#IsRow(line + 1) || tablemode#table#IsHeader(line + 1)
let line += 1
endwhile
if tablemode#table#IsATableHeader(line) | let line -= 1 | endif
if tablemode#table#IsHeader(line) | let line -= 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#MoveToLastRow() "{{{2
if tablemode#table#IsATableRow('.')
if tablemode#table#IsRow('.')
call cursor(tablemode#spreadsheet#GetLastRow('.'), col('.'))
endif
endfunction
function! tablemode#spreadsheet#LineNr(row) "{{{2
if tablemode#table#IsATableRow('.')
if tablemode#table#IsRow('.')
let line = tablemode#spreadsheet#GetFirstRow('.')
let row_nr = 0
while tablemode#table#IsATableRow(line + 1) || tablemode#table#IsATableHeader(line + 1)
if tablemode#table#IsATableRow(line)
while tablemode#table#IsRow(line + 1) || tablemode#table#IsHeader(line + 1)
if tablemode#table#IsRow(line)
let row_nr += 1
if row ==# row_nr | break | endif
endif
@@ -142,8 +105,8 @@ function! tablemode#spreadsheet#RowNr(line) "{{{2
let line = tablemode#utils#line(a:line)
let rowNr = 0
while tablemode#table#IsATableRow(line) || tablemode#table#IsATableHeader(line)
if tablemode#table#IsATableRow(line) | let rowNr += 1 | endif
while tablemode#table#IsRow(line) || tablemode#table#IsHeader(line)
if tablemode#table#IsRow(line) | let rowNr += 1 | endif
let line -= 1
endwhile
@@ -154,14 +117,14 @@ function! tablemode#spreadsheet#RowCount(line) "{{{2
let line = tablemode#utils#line(a:line)
let [tline, totalRowCount] = [line, 0]
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline)
if tablemode#table#IsATableRow(tline) | let totalRowCount += 1 | endif
while tablemode#table#IsRow(tline) || tablemode#table#IsHeader(tline)
if tablemode#table#IsRow(tline) | let totalRowCount += 1 | endif
let tline -= 1
endwhile
let tline = line + 1
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline)
if tablemode#table#IsATableRow(tline) | let totalRowCount += 1 | endif
while tablemode#table#IsRow(tline) || tablemode#table#IsHeader(tline)
if tablemode#table#IsRow(tline) | let totalRowCount += 1 | endif
let tline += 1
endwhile
@@ -204,142 +167,33 @@ function! tablemode#spreadsheet#MoveToStartOfCell() "{{{2
endfunction
function! tablemode#spreadsheet#GetLastRow(line) "{{{2
if tablemode#table#IsATableRow(a:line)
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line + 1) || tablemode#table#IsATableHeader(line + 1)
while tablemode#table#IsRow(line + 1) || tablemode#table#IsHeader(line + 1)
let line += 1
endwhile
if tablemode#table#IsATableHeader(line) | let line -= 1 | endif
if tablemode#table#IsHeader(line) | let line -= 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#GetFirstRow(line) "{{{2
if tablemode#table#IsATableRow(a:line)
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line - 1) || tablemode#table#IsATableHeader(line - 1)
while tablemode#table#IsRow(line - 1) || tablemode#table#IsHeader(line - 1)
let line -= 1
endwhile
if tablemode#table#IsATableHeader(line) | let line += 1 | endif
if tablemode#table#IsHeader(line) | let line += 1 | endif
return line
endif
endfunction
" function! tablemode#spreadsheet#GetCells() - Function to get values of cells in a table {{{2
" tablemode#spreadsheet#GetCells(row) - Get values of all cells in a row as a List.
" tablemode#spreadsheet#GetCells(0, col) - Get values of all cells in a column as a List.
" tablemode#spreadsheet#GetCells(row, col) - Get the value of table cell by given row, col.
function! tablemode#spreadsheet#GetCells(line, ...) abort "{{{2
let line = tablemode#utils#line(a:line)
if tablemode#table#IsATableRow(line)
if a:0 < 1
let [row, colm] = [line, 0]
elseif a:0 < 2
let [row, colm] = [a:1, 0]
elseif a:0 < 3
let [row, colm] = a:000
endif
let first_row = tablemode#spreadsheet#GetFirstRow(line)
if row == 0
let values = []
let line = first_row
while tablemode#table#IsATableRow(line) || tablemode#table#IsATableHeader(line)
if tablemode#table#IsATableRow(line)
let row_line = getline(line)[stridx(getline(line), g:table_mode_separator):strridx(getline(line), g:table_mode_separator)]
call add(values, tablemode#utils#strip(get(split(row_line, g:table_mode_separator), colm>0?colm-1:colm, '')))
endif
let line += 1
endwhile
return values
else
let row_nr = 0
let line = first_row
while tablemode#table#IsATableRow(line) || tablemode#table#IsATableHeader(line)
if tablemode#table#IsATableRow(line)
let row_nr += 1
if row ==# row_nr | break | endif
endif
let line += 1
endwhile
let row_line = getline(line)[stridx(getline(line), g:table_mode_separator):strridx(getline(line), g:table_mode_separator)]
if colm == 0
return map(split(row_line, g:table_mode_separator), 'tablemode#utils#strip(v:val)')
else
let split_line = split(row_line, g:table_mode_separator)
return tablemode#utils#strip(get(split(row_line, g:table_mode_separator), colm>0?colm-1:colm, ''))
endif
endif
endif
endfunction
function! tablemode#spreadsheet#GetCell(...) "{{{2
if a:0 == 0
let [row, colm] = [tablemode#RowNr('.'), tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 == 2
let [row, colm] = [a:1, a:2]
endif
return tablemode#spreadsheet#GetCells('.', row, col)
endfunction
function! tablemode#spreadsheet#GetRow(row, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
return tablemode#spreadsheet#GetCells(line, a:row)
endfunction
function! tablemode#spreadsheet#GetRowColumn(col, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
let row = tablemode#RowNr('.')
return tablemode#spreadsheet#GetCells(line, row, a:col)
endfunction
function! tablemode#spreadsheet#GetColumn(col, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
return tablemode#spreadsheet#GetCells(line, 0, a:col)
endfunction
function! tablemode#spreadsheet#GetColumnRow(row, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
let col = tablemode#spreadsheet#ColumnNr('.')
return tablemode#spreadsheet#GetCells(line, a:row, col)
endfunction
function! tablemode#spreadsheet#SetCell(val, ...) "{{{2
if a:0 == 0
let [line, row, colm] = ['.', tablemode#spreadsheet#RowNr('.'), tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 == 2
let [line, row, colm] = ['.', a:1, a:2]
elseif a:0 == 3
let [line, row, colm] = a:000
endif
if tablemode#table#IsATableRow(line)
let line = tablemode#utils#line(line) + (row - tablemode#spreadsheet#RowNr(line)) * 1
let line_val = getline(line)
let cstartexpr = tablemode#table#StartCommentExpr()
let values = split(getline(line)[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)], g:table_mode_separator)
if len(values) < colm | return | endif
let values[colm-1] = a:val
let line_value = g:table_mode_separator . join(values, g:table_mode_separator) . g:table_mode_separator
if tablemode#utils#strlen(cstartexpr) > 0 && line_val =~# cstartexpr
let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
let ece = matchstr(line_val, tablemode#table#EndCommentExpr())
let line_value = sce . line_value . ece
endif
call setline(line, line_value)
call tablemode#table#TableRealign(line)
endif
endfunction
function! tablemode#spreadsheet#DeleteColumn() "{{{2
if tablemode#table#IsATableRow('.')
if tablemode#table#IsRow('.')
for i in range(v:count1)
call tablemode#spreadsheet#MoveToStartOfCell()
call tablemode#spreadsheet#MoveToFirstRow()
@@ -348,201 +202,35 @@ function! tablemode#spreadsheet#DeleteColumn() "{{{2
normal! d
endfor
call tablemode#table#TableRealign('.')
call tablemode#table#Realign('.')
endif
endfunction
function! tablemode#spreadsheet#DeleteRow() "{{{2
if tablemode#table#IsATableRow('.')
if tablemode#table#IsRow('.')
for i in range(v:count1)
if tablemode#table#IsATableRow('.')
if tablemode#table#IsRow('.')
normal! dd
endif
if !tablemode#table#IsATableRow('.')
if !tablemode#table#IsRow('.')
normal! k
endif
endfor
call tablemode#table#TableRealign('.')
call tablemode#table#Realign('.')
endif
endfunction
function! tablemode#spreadsheet#GetCellRange(range, ...) abort "{{{2
if a:0 < 1
let [line, colm] = ['.', tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 < 2
let [line, colm] = [a:1, tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 < 3
let [line, colm] = [a:1, a:2]
else
call tablemode#utils#throw('Invalid Range')
endif
let values = []
if tablemode#table#IsATableRow(line)
let [row1, col1, row2, col2] = s:ParseRange(a:range, colm)
if row1 == row2
if col1 == col2
call add(values, tablemode#spreadsheet#GetCells(line, row1, col1))
else
let values = tablemode#spreadsheet#GetRow(row1, line)[(col1-1):(col2-1)]
endif
else
if col1 == col2
let values = tablemode#spreadsheet#GetColumn(col1, line)[(row1-1):(row2-1)]
else
let tcol = col1
while tcol <= col2
call add(values, tablemode#spreadsheet#GetColumn(tcol, line)[(row1-1):(row2-1)])
let tcol += 1
endwhile
endif
endif
endif
return values
endfunction
function! tablemode#spreadsheet#Sum(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:Sum(call('tablemode#spreadsheet#GetCellRange', args))
return s:Sum(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#Average(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:Average(call('tablemode#spreadsheet#GetCellRange', args))
return s:Average(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#AddFormula() "{{{2
let fr = input('f=')
let row = tablemode#spreadsheet#RowNr('.')
let colm = tablemode#spreadsheet#ColumnNr('.')
let indent = indent('.')
let indent_str = repeat(' ', indent)
if fr !=# ''
let fr = '$' . row . ',' . colm . '=' . fr
let fline = tablemode#spreadsheet#GetLastRow('.') + 1
if tablemode#table#IsATableHeader(fline) | let fline += 1 | endif
let cursor_pos = [line('.'), col('.')]
if getline(fline) =~# 'tmf: '
" Comment line correctly
let line_val = getline(fline)
let line_expr = line_val[match(line_val, tablemode#table#StartCommentExpr()):match(line_val, tablemode#table#EndCommentExpr())]
let sce = matchstr(line_val, tablemode#table#StartCommentExpr() . '\zs')
let ece = matchstr(line_val, tablemode#table#EndCommentExpr())
call setline(fline, sce . line_expr . '; ' . fr . ece)
else
let cstring = &commentstring
let [cmss, cmse] = ['', '']
if len(cstring) > 0
let cms = split(cstring, '%s')
if len(cms) == 2
let [cmss, cmse] = cms
else
let [cmss, cmse] = [cms[0], '']
endif
endif
let fr = indent_str . cmss . ' tmf: ' . fr . ' ' . cmse
call append(fline-1, fr)
call cursor(cursor_pos)
endif
call tablemode#spreadsheet#EvaluateFormulaLine()
endif
endfunction
function! tablemode#spreadsheet#EvaluateExpr(expr, line) abort "{{{2
let line = tablemode#utils#line(a:line)
let [target, expr] = map(split(a:expr, '='), 'tablemode#utils#strip(v:val)')
let cell = substitute(target, '\$', '', '')
if cell =~# ','
let [row, colm] = map(split(cell, ','), 'str2nr(v:val)')
else
let [row, colm] = [0, str2nr(cell)]
endif
if expr =~# 'Sum(.*)'
let expr = substitute(expr, 'Sum(\([^)]*\))', 'tablemode#spreadsheet#Sum("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'Average(.*)'
let expr = substitute(expr, 'Average(\([^)]*\))', 'tablemode#spreadsheet#Average("\1",'.line.','.colm.')', 'g')
endif
if expr =~# '\$\d\+,\d\+'
let expr = substitute(expr, '\$\(\d\+\),\(\d\+\)',
\ '\=str2float(tablemode#spreadsheet#GetCells(line, submatch(1), submatch(2)))', 'g')
endif
if cell =~# ','
if expr =~# '\$'
let expr = substitute(expr, '\$\(\d\+\)',
\ '\=str2float(tablemode#spreadsheet#GetCells(line, row, submatch(1)))', 'g')
endif
call tablemode#spreadsheet#SetCell(eval(expr), line, row, colm)
else
let [row, line] = [1, tablemode#spreadsheet#GetFirstRow(line)]
while tablemode#table#IsATableRow(line)
let texpr = expr
if expr =~# '\$'
let texpr = substitute(texpr, '\$\(\d\+\)',
\ '\=str2float(tablemode#spreadsheet#GetCells(line, row, submatch(1)))', 'g')
endif
call tablemode#spreadsheet#SetCell(eval(texpr), line, row, colm)
let row += 1
let line += 1
endwhile
endif
endfunction
function! tablemode#spreadsheet#EvaluateFormulaLine() abort "{{{2
let exprs = []
let cstring = &commentstring
let matchexpr = ''
if len(cstring) > 0
let cms = split(cstring, '%s')
if len(cms) == 2
let matchexpr = '^\s*' . escape(cms[0], '/*') . '\s*tmf: \zs.*\ze' . escape(cms[1], '/*') . '\s*$'
else
let matchexpr = '^\s*' . escape(cms[0], '/*') . '\s*tmf: \zs.*$'
endif
else
let matchexpr = '^\s* tmf: \zs.*$'
endif
if tablemode#table#IsATableRow('.') " We're inside the table
let line = tablemode#spreadsheet#GetLastRow('.')
let fline = line + 1
if tablemode#table#IsATableHeader(fline) | let fline += 1 | endif
if getline(fline) =~# 'tmf: '
let exprs = split(matchstr(getline(fline), matchexpr), ';')
endif
elseif getline('.') =~# 'tmf: ' " We're on the formula line
let line = line('.') - 1
if tablemode#table#IsATableHeader(line) | let line -= 1 | endif
if tablemode#table#IsATableRow(line)
let exprs = split(matchstr(getline('.'), matchexpr), ';')
endif
endif
for expr in exprs
call tablemode#spreadsheet#EvaluateExpr(expr, line)
endfor
endfunction
function! tablemode#spreadsheet#CellTextObject(inner) "{{{2
if tablemode#table#IsATableRow('.')
call tablemode#spreadsheet#MoveToStartOfCell()
if a:inner
normal! v
call search('[^' . g:table_mode_separator . ']\ze\s*' . g:table_mode_separator)
else
execute 'normal! vf' . g:table_mode_separator . 'l'
endif
endif
endfunction

View File

@@ -0,0 +1,285 @@
" ============================== Header ======================================
" File: autoload/tablemode/spreadsheet/cell.vim
" Description: Table mode for vim for creating neat tables.
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
" Copyright Notice:
" Permission is hereby granted to use and distribute this code,
" with or without modifications, provided that this copyright
" notice is copied with it. Like anything else that's free,
" table-mode.vim is provided *as is* and comes with no warranty
" of any kind, either expressed or implied. In no event will
" the copyright holder be liable for any damamges resulting
" from the use of this software.
" =============================================================================
" Private Functions {{{1
" function! s:ParseRange(range, ...) {{{2
" range: A string representing range of cells.
" - Can be row1:row2 for values in the current columns in those rows.
" - Can be row1,col1:row2,col2 for range between row1,col1 till
" row2,col2.
function! s:ParseRange(range, ...)
if a:0 < 1
let default_col = tablemode#spreadsheet#ColumnNr('.')
elseif a:0 < 2
let default_col = a:1
endif
if type(a:range) != type('')
let range = string(a:range)
else
let range = a:range
endif
let [rowcol1, rowcol2] = split(range, ':')
let [rcs1, rcs2] = [map(split(rowcol1, ','), 'str2nr(v:val)'), map(split(rowcol2, ','), 'str2nr(v:val)')]
if len(rcs1) == 2
let [row1, col1] = rcs1
else
let [row1, col1] = [rcs1[0], default_col]
endif
if len(rcs2) == 2
let [row2, col2] = rcs2
else
let [row2, col2] = [rcs2[0], default_col]
endif
return [row1, col1, row2, col2]
endfunction
" Public Functions {{{1
function! tablemode#spreadsheet#cell#sid() "{{{2
return maparg('<sid>', 'n')
endfunction
nnoremap <sid> <sid>
function! tablemode#spreadsheet#cell#scope() "{{{2
return s:
endfunction
" function! tablemode#spreadsheet#cell#GetCells() - Function to get values of cells in a table {{{2
" tablemode#spreadsheet#GetCells(row) - Get values of all cells in a row as a List.
" tablemode#spreadsheet#GetCells(0, col) - Get values of all cells in a column as a List.
" tablemode#spreadsheet#GetCells(row, col) - Get the value of table cell by given row, col.
function! tablemode#spreadsheet#cell#GetCells(line, ...) abort
let line = tablemode#utils#line(a:line)
if tablemode#table#IsRow(line)
if a:0 < 1
let [row, colm] = [line, 0]
elseif a:0 < 2
let [row, colm] = [a:1, 0]
elseif a:0 < 3
let [row, colm] = a:000
endif
let first_row = tablemode#spreadsheet#GetFirstRow(line)
let last_row = tablemode#spreadsheet#GetLastRow(line)
if row == 0
let values = []
let line = first_row
while tablemode#table#IsRow(line) || tablemode#table#IsHeader(line)
if tablemode#table#IsRow(line)
let row_line = getline(line)[stridx(getline(line), g:table_mode_separator):strridx(getline(line), g:table_mode_separator)]
call add(values, tablemode#utils#strip(get(split(row_line, g:table_mode_separator), colm>0?colm-1:colm, '')))
endif
let line += 1
endwhile
return values
else
let row_nr = 0
let row_diff = row > 0 ? 1 : -1
let line = row > 0 ? first_row : last_row
while tablemode#table#IsRow(line) || tablemode#table#IsHeader(line)
if tablemode#table#IsRow(line)
let row_nr += row_diff
if row ==# row_nr | break | endif
endif
let line += row_diff
endwhile
let row_line = getline(line)[stridx(getline(line), g:table_mode_separator):strridx(getline(line), g:table_mode_separator)]
if colm == 0
return map(split(row_line, g:table_mode_separator), 'tablemode#utils#strip(v:val)')
else
let split_line = split(row_line, g:table_mode_separator)
return tablemode#utils#strip(get(split(row_line, g:table_mode_separator), colm>0?colm-1:colm, ''))
endif
endif
endif
endfunction
function! tablemode#spreadsheet#cell#GetCell(...) "{{{2
if a:0 == 0
let [row, colm] = [tablemode#spreadsheet#RowNr('.'), tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 == 2
let [row, colm] = [a:1, a:2]
endif
return tablemode#spreadsheet#cell#GetCells('.', row, colm)
endfunction
function! tablemode#spreadsheet#cell#GetRow(row, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
return tablemode#spreadsheet#cell#GetCells(line, a:row)
endfunction
function! tablemode#spreadsheet#cell#GetCellRange(range, ...) abort "{{{2
if a:0 < 1
let [line, colm] = ['.', tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 < 2
let [line, colm] = [a:1, tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 < 3
let [line, colm] = [a:1, a:2]
else
call tablemode#utils#throw('Invalid Range')
endif
let values = []
if tablemode#table#IsRow(line)
let [row1, col1, row2, col2] = s:ParseRange(a:range, colm)
if row1 == row2
if col1 == col2
call add(values, tablemode#spreadsheet#cell#GetCells(line, row1, col1))
else
let values = tablemode#spreadsheet#cell#GetRow(row1, line)[(col1-1):(col2-1)]
endif
else
if col1 == col2
let values = tablemode#spreadsheet#cell#GetColumn(col1, line)[(row1-1):(row2-1)]
else
let tcol = col1
while tcol <= col2
call add(values, tablemode#spreadsheet#cell#GetColumn(tcol, line)[(row1-1):(row2-1)])
let tcol += 1
endwhile
endif
endif
endif
return values
endfunction
function! tablemode#spreadsheet#cell#GetRowColumn(col, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
let row = tablemode#spreadsheet#RowNr('.')
return tablemode#spreadsheet#cell#GetCells(line, row, a:col)
endfunction
function! tablemode#spreadsheet#cell#GetColumn(col, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
return tablemode#spreadsheet#cell#GetCells(line, 0, a:col)
endfunction
function! tablemode#spreadsheet#cell#GetColumnRow(row, ...) abort "{{{2
let line = a:0 < 1 ? '.' : a:1
let col = tablemode#spreadsheet#ColumnNr('.')
return tablemode#spreadsheet#cell#GetCells(line, a:row, col)
endfunction
function! tablemode#spreadsheet#cell#SetCell(val, ...) "{{{2
if a:0 == 0
let [line, row, colm] = ['.', tablemode#spreadsheet#RowNr('.'), tablemode#spreadsheet#ColumnNr('.')]
elseif a:0 == 2
let [line, row, colm] = ['.', a:1, a:2]
elseif a:0 == 3
let [line, row, colm] = a:000
endif
" Account for negative values to reference from relatively from the last
if row < 0 | let row = tablemode#spreadsheet#RowCount(line) + row + 1 | endif
if colm < 0 | let colm = tablemode#spreadsheet#ColumnCount(line) + colm + 1 | endif
if tablemode#table#IsRow(line)
let line = tablemode#utils#line(line) + (row - tablemode#spreadsheet#RowNr(line)) * 1
let line_val = getline(line)
let cstartexpr = tablemode#table#StartCommentExpr()
let values = split(getline(line)[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)], g:table_mode_separator)
if len(values) < colm | return | endif
let values[colm-1] = a:val
let line_value = g:table_mode_separator . join(values, g:table_mode_separator) . g:table_mode_separator
if tablemode#utils#strlen(cstartexpr) > 0 && line_val =~# cstartexpr
let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
let ece = matchstr(line_val, tablemode#table#EndCommentExpr())
let line_value = sce . line_value . ece
endif
call setline(line, line_value)
call tablemode#table#Realign(line)
endif
endfunction
function! tablemode#spreadsheet#cell#TextObject(inner) "{{{2
if tablemode#table#IsRow('.')
call tablemode#spreadsheet#MoveToStartOfCell()
if a:inner
normal! v
call search('[^' . g:table_mode_separator . ']\ze\s*' . g:table_mode_separator)
else
execute 'normal! vf' . g:table_mode_separator . 'l'
endif
endif
endfunction
function! tablemode#spreadsheet#cell#Motion(direction, ...) "{{{2
let l:count = a:0 ? a:1 : v:count1
if tablemode#table#IsRow('.')
for ii in range(l:count)
if a:direction ==# 'l'
if tablemode#spreadsheet#IsLastCell()
if !tablemode#table#IsRow(line('.') + 1) && (tablemode#table#IsHeader(line('.') + 1) && !tablemode#table#IsRow(line('.') + 2))
return
endif
call tablemode#spreadsheet#cell#Motion('j', 1)
normal! 0
endif
" If line starts with g:table_mode_separator
if getline('.')[col('.')-1] ==# g:table_mode_separator
normal! 2l
else
execute 'normal! f' . g:table_mode_separator . '2l'
endif
elseif a:direction ==# 'h'
if tablemode#spreadsheet#IsFirstCell()
if !tablemode#table#IsRow(line('.') - 1) && (tablemode#table#IsHeader(line('.') - 1) && !tablemode#table#IsRow(line('.') - 2))
return
endif
call tablemode#spreadsheet#cell#Motion('k', 1)
normal! $
endif
" If line ends with g:table_mode_separator
if getline('.')[col('.')-1] ==# g:table_mode_separator
execute 'normal! F' . g:table_mode_separator . '2l'
else
execute 'normal! 2F' . g:table_mode_separator . '2l'
endif
elseif a:direction ==# 'j'
if tablemode#table#IsRow(line('.') + 1)
" execute 'normal! ' . 1 . 'j'
normal! j
elseif tablemode#table#IsHeader(line('.') + 1) && tablemode#table#IsRow(line('.') + 2)
" execute 'normal! ' . 2 . 'j'
normal! 2j
endif
elseif a:direction ==# 'k'
if tablemode#table#IsRow(line('.') - 1)
" execute 'normal! ' . 1 . 'k'
normal! k
elseif tablemode#table#IsHeader(line('.') - 1) && tablemode#table#IsRow(line('.') - 2)
" execute 'normal! ' . (1 + 1) . 'k'
normal! 2k
endif
endif
endfor
endif
endfunction
" vim: sw=2 sts=2 fdl=0 fdm=marker

View File

@@ -0,0 +1,147 @@
" ============================== Header ======================================
" File: autoload/tablemode/spreadsheet/formula.vim
" Description: Table mode for vim for creating neat tables.
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
" Copyright Notice:
" Permission is hereby granted to use and distribute this code,
" with or without modifications, provided that this copyright
" notice is copied with it. Like anything else that's free,
" table-mode.vim is provided *as is* and comes with no warranty
" of any kind, either expressed or implied. In no event will
" the copyright holder be liable for any damamges resulting
" from the use of this software.
" =============================================================================
" Private Functions {{{1
" Public Functions {{{1
function! tablemode#spreadsheet#formula#sid() "{{{2
return maparg('<sid>', 'n')
endfunction
nnoremap <sid> <sid>
function! tablemode#spreadsheet#formula#scope() "{{{2
return s:
endfunction
function! tablemode#spreadsheet#formula#Add(...) "{{{2
let fr = a:0 ? a:1 : input('f=')
let row = tablemode#spreadsheet#RowNr('.')
let colm = tablemode#spreadsheet#ColumnNr('.')
let indent = indent('.')
let indent_str = repeat(' ', indent)
if fr !=# ''
let fr = '$' . row . ',' . colm . '=' . fr
let fline = tablemode#spreadsheet#GetLastRow('.') + 1
if tablemode#table#IsHeader(fline) | let fline += 1 | endif
let cursor_pos = [line('.'), col('.')]
if getline(fline) =~# 'tmf: '
" Comment line correctly
let line_val = getline(fline)
let line_expr = line_val[match(line_val, tablemode#table#StartCommentExpr()):match(line_val, tablemode#table#EndCommentExpr())]
let sce = matchstr(line_val, tablemode#table#StartCommentExpr() . '\zs')
let ece = matchstr(line_val, tablemode#table#EndCommentExpr())
call setline(fline, sce . line_expr . '; ' . fr . ece)
else
let cstring = &commentstring
let [cmss, cmse] = ['', '']
if len(cstring) > 0
let cms = split(cstring, '%s')
if len(cms) == 2
let [cmss, cmse] = cms
else
let [cmss, cmse] = [cms[0], '']
endif
endif
let fr = indent_str . cmss . ' tmf: ' . fr . ' ' . cmse
call append(fline-1, fr)
call cursor(cursor_pos)
endif
call tablemode#spreadsheet#formula#EvaluateFormulaLine()
endif
endfunction
function! tablemode#spreadsheet#formula#EvaluateExpr(expr, line) abort "{{{2
let line = tablemode#utils#line(a:line)
let [target, expr] = map(split(a:expr, '='), 'tablemode#utils#strip(v:val)')
let cell = substitute(target, '\$', '', '')
if cell =~# ','
let [row, colm] = map(split(cell, ','), 'str2nr(v:val)')
else
let [row, colm] = [0, str2nr(cell)]
endif
if expr =~# 'Sum(.*)'
let expr = substitute(expr, 'Sum(\([^)]*\))', 'tablemode#spreadsheet#Sum("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'Average(.*)'
let expr = substitute(expr, 'Average(\([^)]*\))', 'tablemode#spreadsheet#Average("\1",'.line.','.colm.')', 'g')
endif
if expr =~# '\$\d\+,\d\+'
let expr = substitute(expr, '\$\(\d\+\),\(\d\+\)',
\ '\=str2float(tablemode#spreadsheet#cell#GetCells(line, submatch(1), submatch(2)))', 'g')
endif
if cell =~# ','
if expr =~# '\$'
let expr = substitute(expr, '\$\(\d\+\)',
\ '\=str2float(tablemode#spreadsheet#cell#GetCells(line, row, submatch(1)))', 'g')
endif
call tablemode#spreadsheet#cell#SetCell(eval(expr), line, row, colm)
else
let [row, line] = [1, tablemode#spreadsheet#GetFirstRow(line)]
while tablemode#table#IsRow(line)
let texpr = expr
if expr =~# '\$'
let texpr = substitute(texpr, '\$\(\d\+\)',
\ '\=str2float(tablemode#spreadsheet#cell#GetCells(line, row, submatch(1)))', 'g')
endif
call tablemode#spreadsheet#cell#SetCell(eval(texpr), line, row, colm)
let row += 1
let line += 1
endwhile
endif
endfunction
function! tablemode#spreadsheet#formula#EvaluateFormulaLine() abort "{{{2
let exprs = []
let cstring = &commentstring
let matchexpr = ''
if len(cstring) > 0
let cms = split(cstring, '%s')
if len(cms) == 2
let matchexpr = '^\s*' . escape(cms[0], '/*') . '\s*tmf: \zs.*\ze' . escape(cms[1], '/*') . '\s*$'
else
let matchexpr = '^\s*' . escape(cms[0], '/*') . '\s*tmf: \zs.*$'
endif
else
let matchexpr = '^\s* tmf: \zs.*$'
endif
if tablemode#table#IsRow('.') " We're inside the table
let line = tablemode#spreadsheet#GetLastRow('.')
let fline = line + 1
if tablemode#table#IsHeader(fline) | let fline += 1 | endif
if getline(fline) =~# 'tmf: '
let exprs = split(matchstr(getline(fline), matchexpr), ';')
endif
elseif getline('.') =~# 'tmf: ' " We're on the formula line
let line = line('.') - 1
if tablemode#table#IsHeader(line) | let line -= 1 | endif
if tablemode#table#IsRow(line)
let exprs = split(matchstr(getline('.'), matchexpr), ';')
endif
endif
for expr in exprs
call tablemode#spreadsheet#formula#EvaluateExpr(expr, line)
endfor
endfunction

View File

@@ -4,7 +4,6 @@
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Version: 4.0.0
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
@@ -22,13 +21,13 @@
function! s:HeaderBorderExpr() "{{{2
return tablemode#table#StartExpr() .
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
\ '[' . g:table_mode_fillchar . g:table_mode_corner . ']*' .
\ '[' . g:table_mode_fillchar . g:table_mode_corner . g:table_mode_align_char . ']*' .
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
\ tablemode#table#EndExpr()
endfunction
function! s:DefaultHeaderBorder() "{{{2
if s:IsTableModeActive()
if tablemode#IsActive()
return g:table_mode_corner_corner . g:table_mode_fillchar . g:table_mode_corner . g:table_mode_fillchar . g:table_mode_corner_corner
else
return ''
@@ -37,19 +36,38 @@ endfunction
function! s:GenerateHeaderBorder(line) "{{{2
let line = tablemode#utils#line(a:line)
if tablemode#table#IsATableRow(line - 1) || tablemode#table#IsATableRow(line + 1)
if tablemode#table#IsRow(line - 1) || tablemode#table#IsRow(line + 1)
let line_val = ''
if tablemode#table#IsATableRow(line + 1)
if tablemode#table#IsRow(line + 1)
let line_val = getline(line + 1)
endif
if tablemode#table#IsATableRow(line - 1) && tablemode#utils#strlen(line_val) < tablemode#utils#strlen(getline(line - 1))
if tablemode#table#IsRow(line - 1) && tablemode#utils#strlen(line_val) < tablemode#utils#strlen(getline(line - 1))
let line_val = getline(line - 1)
endif
if tablemode#utils#strlen(line_val) <= 1 | return s:DefaultHeaderBorder() | endif
let border = substitute(line_val[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)], g:table_mode_separator, g:table_mode_corner, 'g')
let border = substitute(border, '[^' . g:table_mode_corner . ']', g:table_mode_fillchar, 'g')
let border = substitute(border, '^' . g:table_mode_corner . '\(.*\)' . g:table_mode_corner . '$', g:table_mode_corner_corner . '\1' . g:table_mode_corner_corner, '')
" Incorporate header alignment chars
if getline(line) =~# g:table_mode_align_char
let pat = '[' . g:table_mode_corner_corner . g:table_mode_corner . ']'
let hcols = tablemode#align#Split(getline(line), pat)
let gcols = tablemode#align#Split(border, pat)
for idx in range(len(hcols))
if hcols[idx] =~# g:table_mode_align_char
if hcols[idx] =~# g:table_mode_align_char . '$'
let gcols[idx] = gcols[idx][:-2] . g:table_mode_align_char
else
let gcols[idx] = g:table_mode_align_char . gcols[idx][1:]
endif
endif
endfor
let border = join(gcols, '')
endif
let cstartexpr = tablemode#table#StartCommentExpr()
if tablemode#utils#strlen(cstartexpr) > 0 && getline(line) =~# cstartexpr
let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
@@ -135,109 +153,51 @@ function! tablemode#table#EndExpr() "{{{2
endif
endfunction
function! tablemode#table#IsATableRow(line) "{{{2
return getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator . '[^' .
\ g:table_mode_fillchar . ']*[^' . g:table_mode_corner . ']*$')
function! tablemode#table#IsHeader(line) "{{{2
return getline(a:line) =~# s:HeaderBorderExpr()
endfunction
function! tablemode#table#IsATableHeader(line) "{{{2
return getline(a:line) =~# s:HeaderBorderExpr()
function! tablemode#table#IsRow(line) "{{{2
return !tablemode#table#IsHeader(a:line) && getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator)
endfunction
function! tablemode#table#AddHeaderBorder(line) "{{{2
call setline(a:line, s:GenerateHeaderBorder(a:line))
endfunction
function! tablemode#table#TableRealign(line) "{{{2
function! tablemode#table#Realign(line) "{{{2
let line = tablemode#utils#line(a:line)
let [lnums, lines] = [[], []]
let [tline, blines] = [line, []]
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline)
if tablemode#table#IsATableHeader(tline)
call insert(blines, tline)
let tline -= 1
let lines = []
let [lnum, blines] = [line, []]
while tablemode#table#IsRow(lnum) || tablemode#table#IsHeader(lnum)
if tablemode#table#IsHeader(lnum)
call insert(blines, lnum)
let lnum -= 1
continue
endif
call insert(lnums, tline)
call insert(lines, getline(tline))
let tline -= 1
call insert(lines, {'lnum': lnum, 'text': getline(lnum)})
let lnum -= 1
endwhile
let tline = line + 1
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline)
if tablemode#table#IsATableHeader(tline)
call insert(blines, tline)
let tline += 1
let lnum = line + 1
while tablemode#table#IsRow(lnum) || tablemode#table#IsHeader(lnum)
if tablemode#table#IsHeader(lnum)
call add(blines, lnum)
let lnum += 1
continue
endif
call add(lnums, tline)
call add(lines, getline(tline))
let tline += 1
call add(lines, {'lnum': lnum, 'text': getline(lnum)})
let lnum += 1
endwhile
let lines = tablemode#align#Align(lines)
for lnum in lnums
let index = index(lnums, lnum)
call setline(lnum, lines[index])
for aline in lines
call setline(aline.lnum, aline.text)
endfor
for bline in blines
call tablemode#table#AddHeaderBorder(bline)
endfor
endfunction
function! tablemode#table#TableMotion(direction, ...) "{{{2
let l:count = a:0 ? a:1 : v:count1
if tablemode#table#IsATableRow('.')
for ii in range(l:count)
if a:direction ==# 'l'
if tablemode#spreadsheet#IsLastCell()
if !tablemode#table#IsATableRow(line('.') + 1) || (tablemode#table#IsATableHeader(line('.') + 1) && !tablemode#table#IsATableRow(line('.') + 2 * 1))
return
endif
call tablemode#table#TableMotion('j', 1)
normal! 0
endif
" If line starts with g:table_mode_separator
if getline('.')[col('.')-1] ==# g:table_mode_separator
normal! 2l
else
execute 'normal! f' . g:table_mode_separator . '2l'
endif
elseif a:direction ==# 'h'
if tablemode#spreadsheet#IsFirstCell()
if !tablemode#table#IsATableRow(line('.') - 1) || (tablemode#table#IsATableHeader(line('.') - 1) && !tablemode#table#IsATableRow(line('.') - 2 * 1))
return
endif
call tablemode#table#TableMotion('k', 1)
normal! $
endif
" If line ends with g:table_mode_separator
if getline('.')[col('.')-1] ==# g:table_mode_separator
execute 'normal! F' . g:table_mode_separator . '2l'
else
execute 'normal! 2F' . g:table_mode_separator . '2l'
endif
elseif a:direction ==# 'j'
if tablemode#table#IsATableRow(line('.') + 1)
execute 'normal! ' . 1 . 'j'
elseif tablemode#table#IsATableHeader(line('.') + 1) && tablemode#table#IsATableRow(line('.') + 2)
execute 'normal! ' . (1 + 1) . 'j'
endif
elseif a:direction ==# 'k'
if tablemode#table#IsATableRow(line('.') - 1)
execute 'normal! ' . 1 . 'k'
elseif tablemode#table#IsATableHeader(line('.') - 1) && tablemode#table#IsATableRow(line('.') - 2)
execute 'normal! ' . (1 + 1) . 'k'
endif
endif
endfor
endif
endfunction
" vim: sw=2 sts=2 fdl=0 fdm=marker

View File

@@ -4,7 +4,6 @@
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: https://github.com/dhruvasagar/vim-table-mode
" Version: 4.0.0
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"

View File

@@ -1,7 +1,7 @@
*table-mode.txt* Table Mode for easy table formatting. v4.0.0
*table-mode.txt* Table Mode for easy table formatting. v4.4.0
===============================================================================
Table Mode, THE AWESOME AUTOMATIC TABLE CREATOR & FORMATTER
VERSION 4.0.0
VERSION 4.4.0
Author: Dhruva Sagar <http://dhruvasagar.com/>
License: MIT <http://opensource.org/licenses/MIT/>
@@ -34,6 +34,11 @@ Create Table on the fly:
each additional separator you add, it aligns the table properly,
without having to do anything else.
Table Mode now supports gfm style tables and allows to define column
alignments with the aid of placing ':' (configured using
|g:table_mode_align_char|) on the table header border appropriately to
align content left or right.
The table mode is disabled by default and you can enter table mode
using |table-mode-toggle-map| or you can also enable it permanently
using |table-mode-always-active| if you wish though not recommended.
@@ -99,11 +104,14 @@ Formula Expressions :
'$n': This matches the table column number 'n'. So the formula
would be evaluated for each cell in that column and the result
would be placed in it.
would be placed in it. You can use negative indice to
represent column relative to the last, -1 being the last.
'$n,m': This matches the table cell n,m (row, column). So in
this case the formula would be evaluated and the result will
be placed in this cell.
be placed in this cell. You can also use negative values to
refer to cells relative to the size, -1 being the last (row or
column).
The formula can be a simple mathematical expression involving cells
which are also defined by the same format as that of the target cell.
@@ -139,6 +147,10 @@ Overview:
|table-mode-delimiter| .......... Set the delimiter for Tableize.
|table-mode-corner-corner| ...... Set the character to be used for
extreme corners of the table border.
|table-mode-align-char|.......... Set the alignment character which
can be added to the table header
border to control alignment of that
column.
g:loaded_table_mode *table-mode-loaded*
Use this option to disable the plugin: >
@@ -196,6 +208,11 @@ g:table_mode_corner_corner *table-mode-corner-corner*
corners of the table border. >
let g:table_mode_corner_corner = '|'
<
g:table_mode_align_char *table-mode-align-char*
Use this option to define the character to be used for defining
alignments for columns in the table header border. >
let g:table_mode_align_char = ':'
<
===============================================================================
MAPPINGS *table-mode-mappings*

View File

@@ -4,7 +4,6 @@
" Author: Dhruva Sagar <http://dhruvasagar.com/>
" License: MIT (http://www.opensource.org/licenses/MIT)
" Website: http://github.com/dhruvasagar/vim-table-mode
" Version: 3.3.3
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope.
"
@@ -43,20 +42,21 @@ call s:SetGlobalOptDefault('table_mode_toggle_map', 'm')
call s:SetGlobalOptDefault('table_mode_always_active', 0)
call s:SetGlobalOptDefault('table_mode_delimiter', ',')
call s:SetGlobalOptDefault('table_mode_corner_corner', '|')
call s:SetGlobalOptDefault('table_mode_align_char', ':')
function! s:TableEchoCell() "{{{1
if tablemode#table#IsATableRow('.')
echomsg '$' . tablemode#table#RowNr('.') . ',' . tablemode#table#ColumnNr('.')
if tablemode#table#IsRow('.')
echomsg '$' . tablemode#spreadsheet#RowNr('.') . ',' . tablemode#spreadsheet#ColumnNr('.')
endif
endfunction
" Define Commands & Mappings {{{1
if !g:table_mode_always_active "{{{2
exec "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_toggle_map .
\ " <Esc>:call tablemode#TableModeToggle()<CR>"
command! -nargs=0 TableModeToggle call tablemode#TableModeToggle()
command! -nargs=0 TableModeEnable call tablemode#TableModeEnable()
command! -nargs=0 TableModeDisable call tablemode#TableModeDisable()
\ " <Esc>:call tablemode#Toggle()<CR>"
command! -nargs=0 TableModeToggle call tablemode#Toggle()
command! -nargs=0 TableModeEnable call tablemode#Enable()
command! -nargs=0 TableModeDisable call tablemode#Disable()
else
let table_mode_separator_map = g:table_mode_separator
" '|' is a special character, we need to map <Bar> instead
@@ -69,29 +69,29 @@ endif
" }}}2
command! -nargs=? -range Tableize <line1>,<line2>call tablemode#TableizeRange(<q-args>)
command! TableAddFormula call tablemode#table#AddFormula()
command! TableModeRealign call tablemode#table#TableRealign('.')
command! TableEvalFormulaLine call tablemode#table#EvaluateFormulaLine()
command! TableAddFormula call tablemode#spreadsheet#formula#Add()
command! TableModeRealign call tablemode#table#Realign('.')
command! TableEvalFormulaLine call tablemode#spreadsheet#formula#EvaluateFormulaLine()
nnoremap <silent> <Plug>(table-mode-tableize) :Tableize<CR>
xnoremap <silent> <Plug>(table-mode-tableize) :Tableize<CR>
xnoremap <silent> <Plug>(table-mode-tableize-delimiter) :<C-U>call tablemode#TableizeByDelimiter()<CR>
nnoremap <silent> <Plug>(table-mode-realign) :call tablemode#table#TableRealign('.')<CR>
nnoremap <silent> <Plug>(table-mode-realign) :call tablemode#table#Realign('.')<CR>
nnoremap <silent> <Plug>(table-mode-motion-up) :<C-U>call tablemode#table#TableMotion('k')<CR>
nnoremap <silent> <Plug>(table-mode-motion-down) :<C-U>call tablemode#table#TableMotion('j')<CR>
nnoremap <silent> <Plug>(table-mode-motion-left) :<C-U>call tablemode#table#TableMotion('h')<CR>
nnoremap <silent> <Plug>(table-mode-motion-right) :<C-U>call tablemode#table#TableMotion('l')<CR>
nnoremap <silent> <Plug>(table-mode-motion-up) :<C-U>call tablemode#spreadsheet#cell#Motion('k')<CR>
nnoremap <silent> <Plug>(table-mode-motion-down) :<C-U>call tablemode#spreadsheet#cell#Motion('j')<CR>
nnoremap <silent> <Plug>(table-mode-motion-left) :<C-U>call tablemode#spreadsheet#cell#Motion('h')<CR>
nnoremap <silent> <Plug>(table-mode-motion-right) :<C-U>call tablemode#spreadsheet#cell#Motion('l')<CR>
onoremap <silent> <Plug>(table-mode-cell-text-object-a) :<C-U>call tablemode#table#CellTextObject(0)<CR>
onoremap <silent> <Plug>(table-mode-cell-text-object-i) :<C-U>call tablemode#table#CellTextObject(1)<CR>
onoremap <silent> <Plug>(table-mode-cell-text-object-a) :<C-U>call tablemode#spreadsheet#cell#TextObject(0)<CR>
onoremap <silent> <Plug>(table-mode-cell-text-object-i) :<C-U>call tablemode#spreadsheet#cell#TextObject(1)<CR>
nnoremap <silent> <Plug>(table-mode-delete-row) :call tablemode#table#DeleteRow()<CR>
nnoremap <silent> <Plug>(table-mode-delete-column) :call tablemode#table#DeleteColumn()<CR>
nnoremap <silent> <Plug>(table-mode-delete-row) :call tablemode#spreadsheet#DeleteRow()<CR>
nnoremap <silent> <Plug>(table-mode-delete-column) :call tablemode#spreadsheet#DeleteColumn()<CR>
nnoremap <silent> <Plug>(table-mode-add-formula) :call tablemode#table#AddFormula()<CR>
nnoremap <silent> <Plug>(table-mode-eval-formula) :call tablemode#table#EvaluateFormulaLine()<CR>
nnoremap <silent> <Plug>(table-mode-add-formula) :call tablemode#spreadsheet#formula#Add()<CR>
nnoremap <silent> <Plug>(table-mode-eval-formula) :call tablemode#spreadsheet#formula#EvaluateFormulaLine()<CR>
nnoremap <silent> <Plug>(table-mode-echo-cell) :call <SID>TableEchoCell()<CR>

View File

@@ -1,18 +1,22 @@
" vim: fdm=indent
source t/config.vim
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#align#scope()', 'sid': 'tablemode#align#sid()'})
function! ConvertLines2Dict(lines)
let lines = []
for idx in range(len(a:lines))
call insert(lines, {"lnum": idx+1, "text": a:lines[idx]})
endfor
return lines
endfunction
describe 'Align'
it 'should align table content correctly'
let lines = ['| This | is a | table |', '| This | is also | a table |']
let result = ['| This | is a | table |', '| This | is also | a table |']
Expect tablemode#align#Align(lines) == result
Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/simple_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/simple_after.txt'))
end
it 'should align table content with unicode characters correctly'
let lines = ['| This | is 測試 | table |', '| This | is also | a table |']
let result = ['| This | is 測試 | table |', '| This | is also | a table |']
Expect tablemode#align#Align(lines) == result
Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/unicode_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/unicode_after.txt'))
end
end

129
t/cell.vim Normal file
View File

@@ -0,0 +1,129 @@
" vim: fdm=indent
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#spreadsheet#cell#scope()', 'sid': 'tablemode#spreadsheet#cell#sid()'})
describe 'cell'
describe 'API'
before
new
read t/fixtures/sample.txt
end
it 'should return the cells'
Expect tablemode#spreadsheet#cell#GetCells(2, 1, 1) ==# 'test11'
" Get Rows
Expect tablemode#spreadsheet#cell#GetCells(2, 1) == ['test11', 'test12']
Expect tablemode#spreadsheet#cell#GetCells(2, 2) == ['test21', 'test22']
" Get Columns
Expect tablemode#spreadsheet#cell#GetCells(2, 0, 1) == ['test11', 'test21']
Expect tablemode#spreadsheet#cell#GetCells(2, 0, 2) == ['test12', 'test22']
end
it 'should return the cells in a range'
" Entire table as range
Expect tablemode#spreadsheet#cell#GetCellRange('1,1:2,2', 2, 1) == [['test11', 'test21'], ['test12', 'test22']]
" Get Rows given different seed lines and columns
Expect tablemode#spreadsheet#cell#GetCellRange('1,1:1,2', 2, 1) == ['test11', 'test12']
Expect tablemode#spreadsheet#cell#GetCellRange('1,1:1,2', 2, 2) == ['test11', 'test12']
Expect tablemode#spreadsheet#cell#GetCellRange('1,1:1,2', 3, 1) == ['test11', 'test12']
Expect tablemode#spreadsheet#cell#GetCellRange('1,1:1,2', 3, 2) == ['test11', 'test12']
Expect tablemode#spreadsheet#cell#GetCellRange('2,1:2,2', 2, 1) == ['test21', 'test22']
Expect tablemode#spreadsheet#cell#GetCellRange('2,1:2,2', 2, 2) == ['test21', 'test22']
Expect tablemode#spreadsheet#cell#GetCellRange('2,1:2,2', 3, 1) == ['test21', 'test22']
Expect tablemode#spreadsheet#cell#GetCellRange('2,1:2,2', 3, 2) == ['test21', 'test22']
" Get Columns given different seed lines and column
Expect tablemode#spreadsheet#cell#GetCellRange('1:2', 2, 1) == ['test11', 'test21']
Expect tablemode#spreadsheet#cell#GetCellRange('1:2', 2, 2) == ['test12', 'test22']
Expect tablemode#spreadsheet#cell#GetCellRange('1:2', 3, 1) == ['test11', 'test21']
Expect tablemode#spreadsheet#cell#GetCellRange('1:2', 3, 2) == ['test12', 'test22']
" Get Column given negative values in range for representing rows from
" the end, -1 being the second last row.
Expect tablemode#spreadsheet#cell#GetCellRange('1:-1', 2, 1) == ['test11']
Expect tablemode#spreadsheet#cell#GetCellRange('1:-1', 3, 1) == ['test11']
Expect tablemode#spreadsheet#cell#GetCellRange('1:-1', 2, 2) == ['test12']
Expect tablemode#spreadsheet#cell#GetCellRange('1:-1', 3, 2) == ['test12']
end
end
describe 'Motions'
describe 'left or right'
before
new
normal! ggdG
call tablemode#Enable()
normal i|test11|test12|
|test21|test22|
call cursor(1, 3)
end
it 'should move left when not on first column'
call cursor(1, 12)
Expect tablemode#spreadsheet#ColumnNr('.') == 2
call tablemode#spreadsheet#cell#Motion('h')
Expect tablemode#spreadsheet#ColumnNr('.') == 1
end
it 'should move to the previous row last column if it exists when on first column'
call cursor(2, 3)
Expect tablemode#spreadsheet#RowNr('.') == 2
Expect tablemode#spreadsheet#ColumnNr('.') == 1
call tablemode#spreadsheet#cell#Motion('h')
Expect tablemode#spreadsheet#RowNr('.') == 1
Expect tablemode#spreadsheet#ColumnNr('.') == 2
end
it 'should move right when not on last column'
Expect tablemode#spreadsheet#ColumnNr('.') == 1
call tablemode#spreadsheet#cell#Motion('l')
Expect tablemode#spreadsheet#ColumnNr('.') == 2
end
it 'should move to the next row first column if it exists when on last column'
call cursor(1, 12)
Expect tablemode#spreadsheet#RowNr('.') == 1
Expect tablemode#spreadsheet#ColumnNr('.') == 2
call tablemode#spreadsheet#cell#Motion('l')
Expect tablemode#spreadsheet#RowNr('.') == 2
Expect tablemode#spreadsheet#ColumnNr('.') == 1
end
end
describe 'up or down'
before
new
normal! ggdG
call tablemode#Enable()
normal i|test11|test12|
|test21|test22|
call cursor(1, 3)
end
it 'should move a row up unless on first row'
call cursor(2, 3)
Expect tablemode#spreadsheet#RowNr('.') == 2
call tablemode#spreadsheet#cell#Motion('k')
Expect tablemode#spreadsheet#RowNr('.') == 1
end
it 'should remain on first row when trying to move up'
Expect tablemode#spreadsheet#RowNr('.') == 1
call tablemode#spreadsheet#cell#Motion('k')
Expect tablemode#spreadsheet#RowNr('.') == 1
end
it 'should move a row down unless on last row'
Expect tablemode#spreadsheet#RowNr('.') == 1
call tablemode#spreadsheet#cell#Motion('j')
Expect tablemode#spreadsheet#RowNr('.') == 2
end
it 'should remain on last row when trying to move down'
Expect tablemode#spreadsheet#RowNr('.') == 1
call tablemode#spreadsheet#cell#Motion('k')
Expect tablemode#spreadsheet#RowNr('.') == 1
end
end

View File

@@ -6,3 +6,4 @@ let g:table_mode_toggle_map = 'm'
let g:table_mode_always_active = 0
let g:table_mode_delimiter = ','
let g:table_mode_corner_corner = '|'
let g:table_mode_align_char = ':'

View File

@@ -0,0 +1,2 @@
| This | is a | table |
| This | is also | a table |

View File

@@ -0,0 +1,2 @@
|This|is a|table|
|This|is also|a table|

View File

@@ -0,0 +1,2 @@
| This | is 測試 | table |
| This | is also | a table |

View File

@@ -0,0 +1,2 @@
| This | is 測試 | table |
| This | is also | a table |

View File

@@ -0,0 +1,7 @@
| Item | Cost |
|----------+-------|
| Bread | 20 |
| Tomatoes | 5 |
| Pasta | 100 |
| Total | 0 |
/* tmf: $5,2=Sum(1:-1) */

View File

@@ -0,0 +1,7 @@
| Item | Cost |
|----------+------|
| Bread | 20 |
| Tomatoes | 5 |
| Pasta | 100 |
| Total | |
| Test | |

4
t/fixtures/sample.txt Normal file
View File

@@ -0,0 +1,4 @@
| test11 | test12 |
| test21 | test22 |

View File

@@ -0,0 +1,7 @@
| Title | Message |
|--------+---------|
| test11 | test12 |
| test21 | test22 |
|--------+---------|

4
t/fixtures/tableize.txt Normal file
View File

@@ -0,0 +1,4 @@
asd,asd;asd,asd
asd,asd;asd,asd

41
t/formula.vim Normal file
View File

@@ -0,0 +1,41 @@
" vim: fdm=indent
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#spreadsheet#formula#scope()', 'sid': 'tablemode#spreadsheet#formula#sid()'})
describe 'Formulas'
describe 'Add Formula'
before
new
read t/fixtures/formula/sample.txt
end
it 'should add a formula successfully'
call cursor(6, 15)
call tablemode#spreadsheet#formula#Add("Sum(1:4)")
Expect tablemode#spreadsheet#cell#GetCell() == '125.0'
call cursor(8, 15)
Expect getline('.') == '/* tmf: $5,2=Sum(1:4) */'
call cursor(7, 15)
call tablemode#spreadsheet#formula#Add("Sum(1:-1)")
Expect tablemode#spreadsheet#cell#GetCell() == '250.0'
call cursor(8, 15)
Expect getline('.') == '/* tmf: $5,2=Sum(1:4) ; $6,2=Sum(1:-1) */'
end
end
describe 'Evaluate Formula'
before
new
read t/fixtures/formula/formula.txt
end
it 'should evaluate the formula successfull'
call cursor(6, 15)
call tablemode#spreadsheet#formula#EvaluateFormulaLine()
Expect &modified == 1
Expect tablemode#spreadsheet#cell#GetCell() == '125.0'
end
end
end

View File

@@ -1,5 +1,5 @@
" vim: fdm=indent
source t/config.vim
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#spreadsheet#scope()', 'sid': 'tablemode#spreadsheet#sid()'})
@@ -7,9 +7,7 @@ describe 'spreadsheet'
describe 'API'
before
new
normal! ggdG
call tablemode#TableModeEnable()
normal i
read t/fixtures/sample.txt
end
it 'should return the row count'
@@ -36,50 +34,11 @@ describe 'spreadsheet'
Expect tablemode#spreadsheet#GetLastRow(2) == 3
Expect tablemode#spreadsheet#GetLastRow(3) == 3
end
Expect tablemode#spreadsheet#GetLastRow(3) == 3
end
it 'should return the cells'
Expect tablemode#spreadsheet#GetCells(2, 1, 1) ==# 'test11'
" Get Rows
Expect tablemode#spreadsheet#GetCells(2, 1) == ['test11', 'test12']
Expect tablemode#spreadsheet#GetCells(2, 2) == ['test21', 'test22']
" Get Columns
Expect tablemode#spreadsheet#GetCells(2, 0, 1) == ['test11', 'test21']
Expect tablemode#spreadsheet#GetCells(2, 0, 2) == ['test12', 'test22']
end
it 'should return the cells in a range'
" Entire table as range
Expect tablemode#spreadsheet#GetCellRange('1,1:2,2', 2, 1) == [['test11', 'test21'], ['test12', 'test22']]
" Get Rows given different seed lines and columns
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 2, 1) == ['test11', 'test12']
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 2, 2) == ['test11', 'test12']
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 3, 1) == ['test11', 'test12']
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 3, 2) == ['test11', 'test12']
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 2, 1) == ['test21', 'test22']
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 2, 2) == ['test21', 'test22']
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 3, 1) == ['test21', 'test22']
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 3, 2) == ['test21', 'test22']
" Get Columns given different seed lines and column
Expect tablemode#spreadsheet#GetCellRange('1:2', 2, 1) == ['test11', 'test21']
Expect tablemode#spreadsheet#GetCellRange('1:2', 2, 2) == ['test12', 'test22']
Expect tablemode#spreadsheet#GetCellRange('1:2', 3, 1) == ['test11', 'test21']
Expect tablemode#spreadsheet#GetCellRange('1:2', 3, 2) == ['test12', 'test22']
" Get Column given negative values in range for representing rows from
" the end, -1 being the second last row.
Expect tablemode#spreadsheet#GetCellRange('1:-1', 2, 1) == ['test11']
Expect tablemode#spreadsheet#GetCellRange('1:-1', 3, 1) == ['test11']
Expect tablemode#spreadsheet#GetCellRange('1:-1', 2, 2) == ['test12']
end
describe 'Manipulations'
before
new
before
normal i|test11|test12|
|test21|test22|
call cursor(1, 3)

View File

@@ -1,122 +1,43 @@
" vim: fdm=indent
source t/config.vim
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#table#scope()', 'sid': 'tablemode#table#sid()'})
describe 'table'
describe 'API'
before
new
normal! ggdG
call tablemode#TableModeEnable()
normal i
|test11|test12|
|test21|test22|
end
it 'should return true when inside a table'
Expect tablemode#table#IsATableRow(2) to_be_true
end
it 'should return false when outside a table'
Expect tablemode#table#IsATableRow(4) to_be_false
end
end
describe 'Tableize'
before
new
normal! ggdG
normal i
asd,asd;asd,asd
asd,asd;asd,asd
end
it 'should tableize with default delimiter'
:2,3call tablemode#TableizeRange('')
Expect tablemode#table#IsATableRow(2) to_be_true
Expect tablemode#spreadsheet#RowCount(2) == 2
Expect tablemode#spreadsheet#ColumnCount(2) == 3
end
it 'should tableize with given delimiter'
:2,3call tablemode#TableizeRange('/;')
Expect tablemode#table#IsATableRow(2) to_be_true
Expect tablemode#spreadsheet#RowCount(2) == 2
Expect tablemode#spreadsheet#ColumnCount(2) == 2
end
describe 'IsRow'
before
new
describe 'Motions'
describe 'left or right'
before
new
read t/fixtures/sample.txt
end
normal i|test11|test12|
|test21|test22|
call cursor(1, 3)
end
it 'should return true when inside a table'
Expect tablemode#table#IsRow(2) to_be_true
Expect tablemode#table#IsRow(3) to_be_true
end
Expect tablemode#spreadsheet#ColumnNr('.') == 2
call tablemode#table#TableMotion('h')
Expect tablemode#spreadsheet#ColumnNr('.') == 1
end
it 'should move to the previous row last column if it exists when on first column'
call cursor(2, 3)
Expect tablemode#spreadsheet#RowNr('.') == 2
Expect tablemode#spreadsheet#ColumnNr('.') == 1
call tablemode#table#TableMotion('h')
Expect tablemode#spreadsheet#RowNr('.') == 1
Expect tablemode#spreadsheet#ColumnNr('.') == 2
end
it 'should move right when not on last column'
Expect tablemode#spreadsheet#ColumnNr('.') == 1
call tablemode#table#TableMotion('l')
Expect tablemode#spreadsheet#ColumnNr('.') == 2
end
it 'should move to the next row first column if it exists when on last column'
call cursor(1, 12)
it 'should return false when outside a table'
Expect tablemode#table#IsRow(1) to_be_false
Expect tablemode#table#IsRow(4) to_be_false
end
end
Expect tablemode#spreadsheet#RowNr('.') == 2
describe 'IsHeader'
before
new
end
describe 'up or down'
before
read t/fixtures/sample_with_header.txt
end
call tablemode#TableModeEnable()
normal i|test11|test12|
|test21|test22|
call cursor(1, 3)
end
it 'should return true when on a table header'
Expect tablemode#table#IsHeader(3) to_be_true
Expect tablemode#table#IsHeader(6) to_be_true
end
call cursor(2, 3)
Expect tablemode#spreadsheet#RowNr('.') == 2
call tablemode#table#TableMotion('k')
Expect tablemode#spreadsheet#RowNr('.') == 1
end
it 'should remain on first row when trying to move up'
Expect tablemode#spreadsheet#RowNr('.') == 1
call tablemode#table#TableMotion('k')
Expect tablemode#spreadsheet#RowNr('.') == 1
end
it 'should move a row down unless on last row'
Expect tablemode#spreadsheet#RowNr('.') == 1
call tablemode#table#TableMotion('j')
Expect tablemode#spreadsheet#RowNr('.') == 2
it 'should return false when not on a table header'
Expect tablemode#table#IsHeader(1) to_be_false
Expect tablemode#table#IsHeader(2) to_be_false
Expect tablemode#table#IsHeader(4) to_be_false
Expect tablemode#table#IsHeader(5) to_be_false
end
end
end

View File

@@ -1,13 +1,13 @@
" vim: fdm=indent
source t/config.vim
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#scope()', 'sid': 'tablemode#sid()'})
describe 'tablemode'
describe 'Activation'
describe 'tablemode#TableModeEnable()'
describe 'tablemode#Enable()'
before
call tablemode#TableModeEnable()
call tablemode#Enable()
end
it 'should enable table mode'
@@ -15,9 +15,9 @@ describe 'tablemode'
end
end
describe 'tablemode#TableModeDisable()'
describe 'tablemode#Disable()'
before
call tablemode#TableModeDisable()
call tablemode#Disable()
end
it 'should disable table mode'
@@ -25,13 +25,34 @@ describe 'tablemode'
end
end
describe 'tablemode#TableModeToggle()'
describe 'tablemode#Toggle()'
it 'should toggle table mode'
call tablemode#TableModeToggle()
call tablemode#Toggle()
Expect b:table_mode_active to_be_true
call tablemode#TableModeToggle()
call tablemode#Toggle()
Expect b:table_mode_active to_be_false
end
end
end
describe 'Tableize'
before
new
read t/fixtures/tableize.txt
end
it 'should tableize with default delimiter'
:2,3call tablemode#TableizeRange('')
Expect tablemode#table#IsRow(2) to_be_true
Expect tablemode#spreadsheet#RowCount(2) == 2
Expect tablemode#spreadsheet#ColumnCount(2) == 3
end
it 'should tableize with given delimiter'
:2,3call tablemode#TableizeRange('/;')
Expect tablemode#table#IsRow(2) to_be_true
Expect tablemode#spreadsheet#RowCount(2) == 2
Expect tablemode#spreadsheet#ColumnCount(2) == 2
end
end
end

View File

@@ -1,5 +1,5 @@
" vim: fdm=indent
source t/config.vim
source t/config/options.vim
call vspec#hint({'scope': 'tablemode#utils#scope()', 'sid': 'tablemode#utils#sid()'})