├── .gitignore ├── t ├── fixtures │ ├── cell │ │ ├── sample.txt │ │ └── counts.txt │ ├── tableize.txt │ ├── align │ │ ├── simple_before.txt │ │ ├── unicode_before.txt │ │ ├── unicode_after.txt │ │ └── simple_after.txt │ ├── sample.txt │ ├── table │ │ ├── sample_realign_before.txt │ │ ├── sample.txt │ │ ├── sample_for_header.txt │ │ ├── sample_realign_after.txt │ │ ├── sample_header_realign_before.txt │ │ ├── sample_realign_unicode_before.txt │ │ ├── sample_header_realign_after.txt │ │ ├── sample_with_header.txt │ │ ├── sample_realign_unicode_after.txt │ │ ├── sample_for_header_unicode.txt │ │ ├── sample_header_realign_unicode_before.txt │ │ └── sample_header_realign_unicode_after.txt │ ├── big_sample.txt │ ├── formula │ │ ├── sample.txt │ │ └── formula.txt │ ├── complex_header.txt │ └── escaped_seperator.txt ├── utils.vim ├── autoload │ ├── tablemode │ │ ├── table │ │ │ ├── realign_test.vim │ │ │ ├── is_row_test.vim │ │ │ ├── realign_with_unicode_test.vim │ │ │ ├── realign_with_header_alignments_test.vim │ │ │ ├── add_border_test.vim │ │ │ ├── realign_with_header_realignments_and_unicode_test.vim │ │ │ ├── is_border_test.vim │ │ │ ├── is_header_test.vim │ │ │ ├── is_table_test.vim │ │ │ └── add_border_with_unicode_test.vim │ │ ├── spreadsheet │ │ │ ├── formula │ │ │ │ ├── eval_test.vim │ │ │ │ └── add_test.vim │ │ │ ├── api │ │ │ │ ├── manipulation_with_unicode_test.vim │ │ │ │ ├── manipulation_test.vim │ │ │ │ ├── repeated_manipulations_test.vim │ │ │ │ ├── manipulation_with_escaped_table_separator_test.vim │ │ │ │ ├── manipulation_with_headers_test.vim │ │ │ │ ├── test.vim │ │ │ │ ├── math_test.vim │ │ │ │ └── count_test.vim │ │ │ └── cell_test.vim │ │ └── align_test.vim │ ├── tablemode_test.vim │ └── tablemode_tableize_test.vim └── config │ └── options.vim ├── ftplugin ├── markdown_tablemode.vim └── rst_tablemode.vim ├── .travis.yml ├── youtube.png ├── autoload ├── tablemode │ ├── logger.vim │ ├── utils.vim │ ├── align.vim │ ├── spreadsheet │ │ ├── formula.vim │ │ └── cell.vim │ ├── table.vim │ └── spreadsheet.vim └── tablemode.vim ├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── CHANGELOG.md ├── plugin └── table-mode.vim ├── README.md └── doc └── table-mode.txt /.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | .vim-flavor/ 3 | -------------------------------------------------------------------------------- /t/fixtures/cell/sample.txt: -------------------------------------------------------------------------------- 1 | | 1 | 2 | 2 | | 3 | 4 | 3 | -------------------------------------------------------------------------------- /ftplugin/markdown_tablemode.vim: -------------------------------------------------------------------------------- 1 | let b:table_mode_corner = '|' 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 3.0.0 4 | script: rake ci 5 | -------------------------------------------------------------------------------- /t/fixtures/tableize.txt: -------------------------------------------------------------------------------- 1 | 2 | asd,asd;asd,asd 3 | asd,asd;asd,asd 4 | 5 | -------------------------------------------------------------------------------- /t/fixtures/align/simple_before.txt: -------------------------------------------------------------------------------- 1 | |This|is a|table| 2 | |This|is also|a table| 3 | -------------------------------------------------------------------------------- /t/fixtures/cell/counts.txt: -------------------------------------------------------------------------------- 1 | | 1 | 2 | 3 | 2 | | | 0 | | 3 | | 4 | 5 | 6 | 4 | -------------------------------------------------------------------------------- /t/fixtures/sample.txt: -------------------------------------------------------------------------------- 1 | 2 | | test11 | test12 | 3 | | test21 | test22 | 4 | 5 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_realign_before.txt: -------------------------------------------------------------------------------- 1 | |test11|test12| 2 | |test21|test22| 3 | -------------------------------------------------------------------------------- /t/fixtures/align/unicode_before.txt: -------------------------------------------------------------------------------- 1 | |This|is 測試|table| 2 | |This|is also|a table| 3 | -------------------------------------------------------------------------------- /t/fixtures/table/sample.txt: -------------------------------------------------------------------------------- 1 | 2 | | test11 | test12 | 3 | | test21 | test22 | 4 | 5 | -------------------------------------------------------------------------------- /youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhruvasagar/vim-table-mode/HEAD/youtube.png -------------------------------------------------------------------------------- /t/fixtures/table/sample_for_header.txt: -------------------------------------------------------------------------------- 1 | | test11 | test12 | 2 | 3 | | test21 | test22 | 4 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_realign_after.txt: -------------------------------------------------------------------------------- 1 | | test11 | test12 | 2 | | test21 | test22 | 3 | -------------------------------------------------------------------------------- /t/fixtures/align/unicode_after.txt: -------------------------------------------------------------------------------- 1 | | This | is 測試 | table | 2 | | This | is also | a table | 3 | -------------------------------------------------------------------------------- /t/fixtures/align/simple_after.txt: -------------------------------------------------------------------------------- 1 | | This | is a | table | 2 | | This | is also | a table | 3 | -------------------------------------------------------------------------------- /ftplugin/rst_tablemode.vim: -------------------------------------------------------------------------------- 1 | let b:table_mode_corner_corner = '+' 2 | let b:table_mode_header_fillchar = '=' 3 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_header_realign_before.txt: -------------------------------------------------------------------------------- 1 | |S. No|Title|Message| 2 | |-----+:----+:-----:| 3 | |1|t1|msg1| 4 | |2|t2|msg2| 5 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_realign_unicode_before.txt: -------------------------------------------------------------------------------- 1 | |abc|测试长度|长测试| 2 | |长|测试测试测试测试|测试测试| 3 | |测试测试|测试|测试测测试| 4 | |测试测试测试|测试测试|测试| 5 | -------------------------------------------------------------------------------- /autoload/tablemode/logger.vim: -------------------------------------------------------------------------------- 1 | function! tablemode#logger#log(message) 2 | if g:table_mode_verbose 3 | echom a:message 4 | endif 5 | endfunction 6 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_header_realign_after.txt: -------------------------------------------------------------------------------- 1 | | S. No | Title | Message | 2 | |-------+:------+:-------:| 3 | | 1 | t1 | msg1 | 4 | | 2 | t2 | msg2 | 5 | -------------------------------------------------------------------------------- /t/fixtures/big_sample.txt: -------------------------------------------------------------------------------- 1 | |---+---+---+---| 2 | | 1 | 9 | a | z | 3 | | 2 | 8 | b | y | 4 | | 3 | 7 | c | x | 5 | | 4 | 6 | d | w | 6 | | 5 | 5 | e | v | 7 | |---+---+---+---| 8 | -------------------------------------------------------------------------------- /t/fixtures/formula/sample.txt: -------------------------------------------------------------------------------- 1 | | Item | Cost | 2 | |----------+------| 3 | | Bread | 20 | 4 | | Tomatoes | 5 | 5 | | Pasta | 100 | 6 | | Total | | 7 | | Test | | 8 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_with_header.txt: -------------------------------------------------------------------------------- 1 | |--------+---------| 2 | | Title | Message | 3 | |--------+---------| 4 | | test11 | test12 | 5 | | test21 | test22 | 6 | |--------+---------| 7 | 8 | -------------------------------------------------------------------------------- /t/fixtures/formula/formula.txt: -------------------------------------------------------------------------------- 1 | | Item | Cost | 2 | |----------+------| 3 | | Bread | 20 | 4 | | Tomatoes | 5 | 5 | | Pasta | 100 | 6 | | Total | 0 | 7 | tmf: $4,2=Sum(1:-1) 8 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_realign_unicode_after.txt: -------------------------------------------------------------------------------- 1 | | abc | 测试长度 | 长测试 | 2 | | 长 | 测试测试测试测试 | 测试测试 | 3 | | 测试测试 | 测试 | 测试测测试 | 4 | | 测试测试测试 | 测试测试 | 测试 | 5 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_for_header_unicode.txt: -------------------------------------------------------------------------------- 1 | 2 | | abc | 测试长度 | 长测试 | 3 | 4 | | 长 | 测试测试测试测试 | 测试测试 | 5 | 6 | | 测试测试 | 测试 | 测试测测试 | 7 | 8 | | 测试测试测试 | 测试测试 | 测试 | 9 | 10 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_header_realign_unicode_before.txt: -------------------------------------------------------------------------------- 1 | |--------+--------+------| 2 | |测试测试|测试长度|长测试| 3 | |--------+:------:+-----:| 4 | |abc|测试长度|长测试| 5 | |长|测试测试测试测试|测试测试| 6 | |测试测试|测试|测试测测试| 7 | |测试测试测试|测试测试|测试| 8 | |------------+--------+----| 9 | -------------------------------------------------------------------------------- /t/fixtures/table/sample_header_realign_unicode_after.txt: -------------------------------------------------------------------------------- 1 | |--------------+------------------+------------| 2 | | 测试测试 | 测试长度 | 长测试 | 3 | |--------------+:----------------:+-----------:| 4 | | abc | 测试长度 | 长测试 | 5 | | 长 | 测试测试测试测试 | 测试测试 | 6 | | 测试测试 | 测试 | 测试测测试 | 7 | | 测试测试测试 | 测试测试 | 测试 | 8 | |--------------+------------------+------------| 9 | -------------------------------------------------------------------------------- /t/utils.vim: -------------------------------------------------------------------------------- 1 | function! utils#TestSetup(file) abort 2 | new 3 | silent! exec 'read' a:file 4 | endfunction 5 | 6 | function! utils#TestTeardown() abort 7 | bw! 8 | endfunction 9 | 10 | function! utils#TestUndo(file) abort 11 | :%delete 12 | silent! exec 'read' a:file 13 | endfunction 14 | 15 | function! utils#TableTest(tests) abort 16 | for test in a:tests 17 | call testify#assert#equals(test.actual, test.expected) 18 | endfor 19 | endfunction 20 | -------------------------------------------------------------------------------- /t/fixtures/complex_header.txt: -------------------------------------------------------------------------------- 1 | |----------+----------+----------+----------| 2 | | counting | backward | alphabet | backward | 3 | |:========:+:=========+=========:+==========| 4 | | 1 | 9 | a | z | 5 | | 2 | 8 | b | y | 6 | | 3 | 7 | c | x | 7 | | 4 | 6 | d | w | 8 | | 5 | 5 | e | v | 9 | |----------+----------+----------+----------| 10 | -------------------------------------------------------------------------------- /t/fixtures/escaped_seperator.txt: -------------------------------------------------------------------------------- 1 | |-------------------+---------------------------| 2 | | The \| works as | It can be escaped by a \. | 3 | | a separator. | | 4 | | | | 5 | | Escaping \ with | This feature would | 6 | | a \ doesn't work. | be unnecessary, because | 7 | | | a separator must be | 8 | | | preceded by a space. | 9 | |-------------------+---------------------------| 10 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/realign_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_realign_before.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestRealign() 12 | call tablemode#table#Realign(2) 13 | call testify#assert#equals(getline(2, '$'), readfile('t/fixtures/table/sample_realign_after.txt')) 14 | call utils#TestUndo(s:test_file) 15 | endfunction 16 | call testify#it('Realign should align table properly', function('s:TestRealign')) 17 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: dhruvasagar 4 | patreon: # Replace with a single Patreon username 5 | open_collective: vim-table-mode 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/is_row_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestIsRow() 12 | call testify#assert#assert(tablemode#table#IsRow(3)) 13 | call testify#assert#assert(tablemode#table#IsRow(4)) 14 | 15 | call testify#assert#assert(!tablemode#table#IsRow(1)) 16 | call testify#assert#assert(!tablemode#table#IsRow(5)) 17 | endfunction 18 | call testify#it('IsRow should be correct', function('s:TestIsRow')) 19 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/realign_with_unicode_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_realign_unicode_before.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestRealign() 12 | call tablemode#table#Realign(2) 13 | call testify#assert#equals(getline(2, '$'), readfile('t/fixtures/table/sample_realign_unicode_after.txt')) 14 | call utils#TestUndo(s:test_file) 15 | endfunction 16 | call testify#it('Realign should align table properly with unicode characters', function('s:TestRealign')) 17 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/realign_with_header_alignments_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_header_realign_before.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestRealign() 12 | call tablemode#table#Realign(2) 13 | call testify#assert#equals(getline(2, '$'), readfile('t/fixtures/table/sample_header_realign_after.txt')) 14 | call utils#TestUndo(s:test_file) 15 | endfunction 16 | call testify#it('Realign should align table properly with header realignments', function('s:TestRealign')) 17 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/formula/eval_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/formula/formula.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestEvalFormula() 12 | call cursor(7, 15) 13 | call tablemode#spreadsheet#formula#EvaluateFormulaLine() 14 | call testify#assert#equals(&modified, 1) 15 | let cell_value = tablemode#spreadsheet#cell#GetCell() 16 | call testify#assert#equals(cell_value, '125.0') 17 | endfunction 18 | call testify#it('Should evaluate the formula correctly', function('s:TestEvalFormula')) 19 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/add_border_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_for_header.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestAddBorder() 12 | call testify#assert#assert(!tablemode#table#IsHeader(2)) 13 | call tablemode#table#AddBorder(3) 14 | call testify#assert#assert(tablemode#table#IsHeader(2)) 15 | call testify#assert#assert(tablemode#table#IsBorder(3)) 16 | call utils#TestUndo(s:test_file) 17 | endfunction 18 | call testify#it('AddBorder should be able to add borders correctly', function('s:TestAddBorder')) 19 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/realign_with_header_realignments_and_unicode_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_header_realign_unicode_before.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestRealign() 12 | call tablemode#table#Realign(2) 13 | call testify#assert#equals(getline(2, '$'), readfile('t/fixtures/table/sample_header_realign_unicode_after.txt')) 14 | call utils#TestUndo(s:test_file) 15 | endfunction 16 | call testify#it('Realign should align table properly with header realignments and unicode characters', function('s:TestRealign')) 17 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/is_border_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_with_header.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestIsBorder() 12 | call testify#assert#assert(tablemode#table#IsBorder(2)) 13 | call testify#assert#assert(tablemode#table#IsBorder(4)) 14 | call testify#assert#assert(tablemode#table#IsBorder(7)) 15 | 16 | call testify#assert#assert(!tablemode#table#IsBorder(1)) 17 | call testify#assert#assert(!tablemode#table#IsBorder(3)) 18 | call testify#assert#assert(!tablemode#table#IsBorder(5)) 19 | call testify#assert#assert(!tablemode#table#IsBorder(6)) 20 | endfunction 21 | call testify#it('IsBorder should be correct', function('s:TestIsBorder')) 22 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/is_header_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_with_header.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestIsHeader() 12 | call testify#assert#assert(tablemode#table#IsHeader(3)) 13 | 14 | call testify#assert#assert(!tablemode#table#IsHeader(1)) 15 | call testify#assert#assert(!tablemode#table#IsHeader(2)) 16 | call testify#assert#assert(!tablemode#table#IsHeader(4)) 17 | call testify#assert#assert(!tablemode#table#IsHeader(5)) 18 | call testify#assert#assert(!tablemode#table#IsHeader(6)) 19 | call testify#assert#assert(!tablemode#table#IsHeader(7)) 20 | endfunction 21 | call testify#it('IsHeader should be correct', function('s:TestIsHeader')) 22 | -------------------------------------------------------------------------------- /t/autoload/tablemode_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | 3 | function! s:TestTablemodeEnable() 4 | silent call tablemode#Enable() 5 | call testify#assert#assert(b:table_mode_active) 6 | endfunction 7 | call testify#it('tablemode#Enable should work', function('s:TestTablemodeEnable')) 8 | 9 | function! s:TestTablemodeDisable() 10 | silent call tablemode#Disable() 11 | call testify#assert#assert(!b:table_mode_active) 12 | endfunction 13 | call testify#it('tablemode#Disable should work', function('s:TestTablemodeDisable')) 14 | 15 | function! s:TestTablemodeToggle() 16 | if exists('b:table_mode_active') 17 | call testify#assert#assert(!b:table_mode_active) 18 | endif 19 | silent call tablemode#Toggle() 20 | call testify#assert#assert(b:table_mode_active) 21 | silent call tablemode#Toggle() 22 | call testify#assert#assert(!b:table_mode_active) 23 | endfunction 24 | call testify#it('tablemode#Toggle should work', function('s:TestTablemodeToggle')) 25 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/is_table_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_with_header.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestIsTable() 12 | " when on row 13 | call testify#assert#assert(tablemode#table#IsTable(2)) 14 | call testify#assert#assert(tablemode#table#IsTable(4)) 15 | call testify#assert#assert(tablemode#table#IsTable(7)) 16 | 17 | " when on border 18 | call testify#assert#assert(tablemode#table#IsTable(3)) 19 | call testify#assert#assert(tablemode#table#IsTable(5)) 20 | call testify#assert#assert(tablemode#table#IsTable(6)) 21 | 22 | " when not in a table 23 | call testify#assert#assert(!tablemode#table#IsTable(1)) 24 | endfunction 25 | call testify#it('IsTable should be correct', function('s:TestIsTable')) 26 | -------------------------------------------------------------------------------- /t/autoload/tablemode/align_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | 3 | function! ConvertLines2Dict(lines) 4 | let lines = [] 5 | for idx in range(len(a:lines)) 6 | call insert(lines, {"lnum": idx+1, "text": a:lines[idx]}) 7 | endfor 8 | return lines 9 | endfunction 10 | 11 | function! s:TestAlignTable() 12 | let actual = tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/simple_before.txt'))) 13 | let expected = ConvertLines2Dict(readfile('t/fixtures/align/simple_after.txt')) 14 | call testify#assert#equals(actual, expected) 15 | endfunction 16 | call testify#it('Align should align table content', function('s:TestAlignTable')) 17 | 18 | function! s:TestAlignTableUnicode() 19 | let actual = tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/unicode_before.txt'))) 20 | let expected = ConvertLines2Dict(readfile('t/fixtures/align/unicode_after.txt')) 21 | call testify#assert#equals(actual, expected) 22 | endfunction 23 | call testify#it('Align should align table content with unicode characters', function('s:TestAlignTableUnicode')) 24 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/formula/add_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/formula/sample.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestAddFormula() 12 | call cursor(7, 15) 13 | call tablemode#spreadsheet#formula#Add('Sum(1:3)') 14 | let cell_value = tablemode#spreadsheet#cell#GetCell() 15 | call testify#assert#equals(cell_value, '125.0') 16 | 17 | call cursor(9, 15) 18 | call testify#assert#equals(getline('.'), ' tmf: $4,2=Sum(1:3) ') 19 | 20 | call cursor(8, 15) 21 | call tablemode#spreadsheet#formula#Add('Sum(1:-1)') 22 | let cell_value = tablemode#spreadsheet#cell#GetCell() 23 | call testify#assert#equals(cell_value, '250.0') 24 | 25 | call cursor(9, 15) 26 | call testify#assert#equals(getline('.'), ' tmf: $4,2=Sum(1:3) ; $5,2=Sum(1:-1)') 27 | endfunction 28 | call testify#it('Should Add a formula to the table correctly', function('s:TestAddFormula')) 29 | -------------------------------------------------------------------------------- /t/autoload/tablemode_tableize_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/tableize.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestTabelize() 12 | :3,4call tablemode#TableizeRange('') 13 | call testify#assert#assert(tablemode#table#IsRow(3)) 14 | call testify#assert#equals(tablemode#spreadsheet#RowCount(3), 2) 15 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount(3), 3) 16 | call utils#TestUndo(s:test_file) 17 | endfunction 18 | call testify#it('Tableize should tableize with default delimiter correctly', function('s:TestTabelize')) 19 | 20 | function! s:TestTabelizeCustomDelimiter() 21 | :3,4call tablemode#TableizeRange('/;') 22 | call testify#assert#assert(tablemode#table#IsRow(3)) 23 | call testify#assert#equals(tablemode#spreadsheet#RowCount(3), 2) 24 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount(3), 2) 25 | call utils#TestUndo(s:test_file) 26 | endfunction 27 | call testify#it('Tableize should tableize with custom delimiter correctly', function('s:TestTabelizeCustomDelimiter')) 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | concurrency: 12 | group: ${{ github.workflow }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | tests: 17 | name: Vim Table Mode Tests 18 | strategy: 19 | matrix: 20 | os: [ubuntu-latest, macos-latest] 21 | runs-on: ${{ matrix.os }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | with: 25 | path: pack/plugins/start/vim-table-mode 26 | 27 | - name: Checkout vim-testify 28 | uses: actions/checkout@v3 29 | with: 30 | repository: dhruvasagar/vim-testify 31 | path: pack/plugins/start/vim-testify 32 | 33 | - name: Install Vim or neovim 34 | uses: rhysd/action-setup-vim@v1 35 | id: vim 36 | with: 37 | neovim: true 38 | version: nightly 39 | 40 | - name: Run unit tests 41 | env: 42 | VIM: ${{ steps.vim.outputs.executable }} 43 | run: | 44 | cd ${{ github.workspace }}/pack/plugins/start/vim-table-mode 45 | echo "set packpath+=${{ github.workspace }}" > vimrc 46 | ${VIM} --headless -u vimrc +TestifySuite +qall 47 | -------------------------------------------------------------------------------- /t/config/options.vim: -------------------------------------------------------------------------------- 1 | let g:table_mode_corner = '+' 2 | let g:table_mode_separator = '|' 3 | let g:table_mode_separator_map = '' 4 | let g:table_mode_escaped_separator_regex = '\V\C\\\@1t' 8 | let g:table_mode_toggle_map = 'm' 9 | let g:table_mode_always_active = 0 10 | let g:table_mode_delimiter = ',' 11 | let g:table_mode_corner_corner = '|' 12 | let g:table_mode_align_char = ':' 13 | let g:table_mode_disable_mappings = 0 14 | 15 | let g:table_mode_motion_up_map = '{' 16 | let g:table_mode_motion_down_map = '}' 17 | let g:table_mode_motion_left_map = '[' 18 | let g:table_mode_motion_right_map = ']' 19 | 20 | let g:table_mode_cell_text_object_a_map = 'a' 21 | let g:table_mode_cell_text_object_i_map = 'i' 22 | 23 | let g:table_mode_realign_map = 'tr' 24 | let g:table_mode_delete_row_map = 'tdd' 25 | let g:table_mode_delete_column_map = 'tdc' 26 | let g:table_mode_insert_column_before_map = 'tiC' 27 | let g:table_mode_insert_column_after_map = 'tic' 28 | let g:table_mode_add_formula_map = 'tfa' 29 | let g:table_mode_eval_formula_map = 'tfe' 30 | let g:table_mode_echo_cell_map = 't?' 31 | let g:table_mode_sort_map = 'ts' 32 | let g:table_mode_tableize_map = 'tt' 33 | let g:table_mode_tableize_d_map = 'T' 34 | 35 | let g:table_mode_syntax = 1 36 | let g:table_mode_auto_align = 1 37 | let g:table_mode_update_time = 500 38 | let g:table_mode_tableize_auto_border = 0 39 | let g:table_mode_ignore_align = 0 40 | -------------------------------------------------------------------------------- /autoload/tablemode/utils.vim: -------------------------------------------------------------------------------- 1 | " Private Functions {{{1 2 | 3 | " Public Functions {{{1 4 | function! tablemode#utils#throw(string) abort "{{{2 5 | let v:errmsg = 'table-mode: ' . a:string 6 | throw v:errmsg 7 | endfunction 8 | 9 | function! tablemode#utils#line(row) "{{{2 10 | if type(a:row) == type('') 11 | return line(a:row) 12 | else 13 | return a:row 14 | endif 15 | endfunction 16 | 17 | function! tablemode#utils#strip(string) "{{{2 18 | return matchstr(a:string, '^\s*\zs.\{-}\ze\s*$') 19 | endfunction 20 | 21 | " function! tablemode#utils#strlen {{{2 22 | " To count multibyte characters accurately 23 | function! tablemode#utils#strlen(text) 24 | return strlen(substitute(a:text, '.', 'x', 'g')) 25 | endfunction 26 | 27 | function! tablemode#utils#StrDisplayWidth(string) "{{{2 28 | if exists('*strdisplaywidth') 29 | return strdisplaywidth(a:string) 30 | else 31 | " Implement the tab handling part of strdisplaywidth for vim 7.2 and 32 | " earlier - not much that can be done about handling doublewidth 33 | " characters. 34 | let rv = 0 35 | let i = 0 36 | 37 | for char in split(a:string, '\zs') 38 | if char == "\t" 39 | let rv += &ts - i 40 | let i = 0 41 | else 42 | let rv += 1 43 | let i = (i + 1) % &ts 44 | endif 45 | endfor 46 | 47 | return rv 48 | endif 49 | endfunction 50 | 51 | function! tablemode#utils#get_buffer_or_global_option(table_option) "{{{2 52 | return get(b:, a:table_option, get(g:, a:table_option)) 53 | endf 54 | 55 | function tablemode#utils#MoveToLine(line) "{{{2 56 | let offset = tablemode#utils#line(a:line) - line('.') 57 | if offset > 0 58 | execute "normal! ".offset."j" 59 | elseif offset < 0 60 | execute "normal! ".(-offset)."k" 61 | endif 62 | endfunction 63 | 64 | function! tablemode#utils#SeparatorCount(str) 65 | return tablemode#utils#strlen(substitute(a:str, '\V\C\(\\' . escape(g:table_mode_separator, '\') . '\|\[^' . escape(g:table_mode_separator, ']^-\') . ']\)', '', 'g')) 66 | endfunction 67 | -------------------------------------------------------------------------------- /t/autoload/tablemode/table/add_border_with_unicode_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table/sample_for_header_unicode.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestAddBorder() 12 | call tablemode#table#AddBorder(2) 13 | call tablemode#table#AddBorder(4) 14 | call tablemode#table#AddBorder(6) 15 | call tablemode#table#AddBorder(8) 16 | call tablemode#table#AddBorder(10) 17 | 18 | call testify#assert#assert(tablemode#table#IsHeader(3)) 19 | 20 | call testify#assert#assert(tablemode#table#IsBorder(2)) 21 | call testify#assert#assert(tablemode#table#IsBorder(4)) 22 | call testify#assert#assert(tablemode#table#IsBorder(6)) 23 | call testify#assert#assert(tablemode#table#IsBorder(8)) 24 | call testify#assert#assert(tablemode#table#IsBorder(10)) 25 | 26 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(2)), tablemode#utils#StrDisplayWidth(getline(3))) 27 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(3)), tablemode#utils#StrDisplayWidth(getline(4))) 28 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(4)), tablemode#utils#StrDisplayWidth(getline(5))) 29 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(5)), tablemode#utils#StrDisplayWidth(getline(6))) 30 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(6)), tablemode#utils#StrDisplayWidth(getline(7))) 31 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(7)), tablemode#utils#StrDisplayWidth(getline(8))) 32 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(8)), tablemode#utils#StrDisplayWidth(getline(9))) 33 | call testify#assert#equals(tablemode#utils#StrDisplayWidth(getline(9)), tablemode#utils#StrDisplayWidth(getline(10))) 34 | 35 | call utils#TestUndo(s:test_file) 36 | endfunction 37 | call testify#it('AddBorder should be able to add borders correctly with unicode characters', function('s:TestAddBorder')) 38 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/manipulation_with_unicode_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/table//sample_realign_unicode_after.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestDeleteRow() 12 | call cursor(3, 19) 13 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 4) 14 | call tablemode#spreadsheet#DeleteRow() 15 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 3) 16 | call utils#TestUndo(s:test_file) 17 | endfunction 18 | call testify#it('DeleteRow should be able to delete a row with unicode characters', function('s:TestDeleteRow')) 19 | 20 | function! s:TestDeleteColumn() 21 | call cursor(3, 19) 22 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 23 | call tablemode#spreadsheet#DeleteColumn() 24 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 25 | call utils#TestUndo(s:test_file) 26 | endfunction 27 | call testify#it('DeleteColumn should be able to delete a column with unicode characters', function('s:TestDeleteColumn')) 28 | 29 | function! s:TestInsertColumnBefore() 30 | call cursor(3, 19) 31 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 32 | call tablemode#spreadsheet#InsertColumn(0) 33 | stopinsert 34 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 35 | call utils#TestUndo(s:test_file) 36 | endfunction 37 | call testify#it('InsertColumn should be able to insert a column before the current column with unicode characters', function('s:TestInsertColumnBefore')) 38 | 39 | function! s:TestInsertColumnAfter() 40 | call cursor(3, 19) 41 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 42 | call tablemode#spreadsheet#InsertColumn(1) 43 | stopinsert 44 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 45 | call utils#TestUndo(s:test_file) 46 | endfunction 47 | call testify#it('InsertColumn should be able to insert a column after the current column with unicode characters', function('s:TestInsertColumnAfter')) 48 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/manipulation_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/sample.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestDeleteRow() 12 | call cursor(3, 3) 13 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 2) 14 | call tablemode#spreadsheet#DeleteRow() 15 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 1) 16 | call utils#TestUndo(s:test_file) 17 | endfunction 18 | call testify#it('DeleteRow should delete a row', function('s:TestDeleteRow')) 19 | 20 | function! s:TestDeleteColumn() 21 | call cursor(3, 3) 22 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 23 | call tablemode#spreadsheet#DeleteColumn() 24 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 1) 25 | call utils#TestUndo(s:test_file) 26 | endfunction 27 | call testify#it('DeleteColumn should delete a column', function('s:TestDeleteColumn')) 28 | 29 | function! s:TestInsertColumn() 30 | call cursor(3, 3) 31 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 32 | call tablemode#spreadsheet#InsertColumn(0) 33 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 34 | " InsertColumn leaves us in insert mode 35 | stopinsert 36 | call testify#assert#equals(getline('.'), '| | test11 | test12 |') 37 | call utils#TestUndo(s:test_file) 38 | endfunction 39 | call testify#it('InsertColumn should insert a new column before the current column', function('s:TestInsertColumn')) 40 | 41 | function! s:TestInserColumnAfter() 42 | call cursor(3, 3) 43 | normal! $ 44 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 45 | call tablemode#spreadsheet#InsertColumn(1) 46 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 47 | " InsertColumn leaves us in insert mode 48 | stopinsert 49 | call testify#assert#equals(getline('.'), '| test11 | test12 | |') 50 | call utils#TestUndo(s:test_file) 51 | endfunction 52 | call testify#it('InsertColumn should be able to insert a new column after the current column', function('s:TestInserColumnAfter')) 53 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/repeated_manipulations_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/big_sample.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestDeleteRowWithRange() 12 | call cursor(3, 3) 13 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 5) 14 | .,.+1 call tablemode#spreadsheet#DeleteRow() 15 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 3) 16 | call utils#TestUndo(s:test_file) 17 | endfunction 18 | call testify#it('DeleteRow should work with a range', function('s:TestDeleteRowWithRange')) 19 | 20 | function! s:TestDeleteColumnWithRange() 21 | call cursor(3, 3) 22 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 23 | .,.+1 call tablemode#spreadsheet#DeleteColumn() 24 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 25 | call utils#TestUndo(s:test_file) 26 | endfunction 27 | call testify#it('DeleteColumn should work with a range', function('s:TestDeleteColumnWithRange')) 28 | 29 | function! s:TestInsertColumnWithCountBefore() 30 | call cursor(3, 7) 31 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 32 | execute "normal! 2:\call tablemode#spreadsheet#InsertColumn(0)\" 33 | stopinsert 34 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 6) 35 | call testify#assert#equals(getline('.'), '| 1 | | | 9 | a | z |') 36 | call utils#TestUndo(s:test_file) 37 | endfunction 38 | call testify#it('InsertColumn should work with a count to add columns before current column', function('s:TestInsertColumnWithCountBefore')) 39 | 40 | function! s:TestInsertColumnWithCountAfter() 41 | call cursor(3, 7) 42 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 43 | execute "normal! 2:\call tablemode#spreadsheet#InsertColumn(1)\" 44 | stopinsert 45 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 6) 46 | call testify#assert#equals(getline('.'), '| 1 | 9 | | | a | z |') 47 | call utils#TestUndo(s:test_file) 48 | endfunction 49 | call testify#it('InsertColumn should work with a count to add columns after current column', function('s:TestInsertColumnWithCountAfter')) 50 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/manipulation_with_escaped_table_separator_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/escaped_seperator.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestDeleteRow() 12 | call cursor(3, 3) 13 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 7) 14 | call tablemode#spreadsheet#DeleteRow() 15 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 6) 16 | call testify#assert#equals(getline('.'), '| a separator. | |') 17 | call utils#TestUndo(s:test_file) 18 | endfunction 19 | call testify#it('DeleteRow should be able to delete a row with escaped table separator', function('s:TestDeleteRow')) 20 | 21 | function! s:TestDeleteColumn() 22 | call cursor(3, 3) 23 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 24 | call tablemode#spreadsheet#DeleteColumn() 25 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 1) 26 | call testify#assert#equals(getline('.'), '| It can be escaped by a \. |') 27 | call utils#TestUndo(s:test_file) 28 | endfunction 29 | call testify#it('DeleteColumn should be able to delete a column with escaped table separator', function('s:TestDeleteColumn')) 30 | 31 | function! s:TestInsertColumnBefore() 32 | call cursor(3, 3) 33 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 34 | call tablemode#spreadsheet#InsertColumn(0) 35 | stopinsert 36 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 37 | call testify#assert#equals(getline('.'), '| | The \| works as | It can be escaped by a \. |') 38 | call utils#TestUndo(s:test_file) 39 | endfunction 40 | call testify#it('InsertColumn should be able to insert a column before the current column with escaped table separator', function('s:TestInsertColumnBefore')) 41 | 42 | function! s:TestInsertColumnAfter() 43 | call cursor(3, 3) 44 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 2) 45 | call tablemode#spreadsheet#InsertColumn(1) 46 | stopinsert 47 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 48 | call testify#assert#equals(getline('.'), '| The \| works as | | It can be escaped by a \. |') 49 | call utils#TestUndo(s:test_file) 50 | endfunction 51 | call testify#it('InsertColumn should be able to insert a column after the current column with escabled table separator', function('s:TestInsertColumnAfter')) 52 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/manipulation_with_headers_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/complex_header.txt' 5 | function! s:setup() 6 | let g:table_mode_header_fillchar = '=' 7 | call utils#TestSetup(s:test_file) 8 | endfunction 9 | call testify#setup(function('s:setup')) 10 | 11 | function! s:teardown() 12 | let g:table_mode_header_fillchar = '-' 13 | bw! 14 | endfunction 15 | call testify#teardown(function('s:teardown')) 16 | 17 | function! s:TestDeleteRow() 18 | call cursor(5, 7) 19 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 5) 20 | call tablemode#spreadsheet#DeleteRow() 21 | call testify#assert#equals(tablemode#spreadsheet#RowCount('.'), 4) 22 | call testify#assert#equals(getline(5), '| 2 | 8 | b | y |') 23 | call utils#TestUndo(s:test_file) 24 | endfunction 25 | call testify#it('DeleteRow should delete a row in a table with headers', function('s:TestDeleteRow')) 26 | 27 | function! s:TestDeleteColumn() 28 | call cursor(5, 7) 29 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 30 | call tablemode#spreadsheet#DeleteColumn() 31 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 3) 32 | call testify#assert#equals(getline(5), '| 9 | a | z |') 33 | call utils#TestUndo(s:test_file) 34 | endfunction 35 | call testify#it('DeleteColumn should delete a column in a table with headers', function('s:TestDeleteColumn')) 36 | 37 | function! s:TestInsertColumn() 38 | call cursor(5, 7) 39 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 40 | call tablemode#spreadsheet#InsertColumn(0) 41 | stopinsert 42 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 5) 43 | call testify#assert#equals(getline(5), '| | 1 | 9 | a | z |') 44 | call utils#TestUndo(s:test_file) 45 | endfunction 46 | call testify#it('InsertColumn should insert a new column before the current column in a table with headers in a table with headers', function('s:TestInsertColumn')) 47 | 48 | function! s:TestInserColumnAfter() 49 | call cursor(5, 7) 50 | normal! $ 51 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 4) 52 | call tablemode#spreadsheet#InsertColumn(1) 53 | stopinsert 54 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount('.'), 5) 55 | call testify#assert#equals(getline(5), '| 1 | 9 | a | z | |') 56 | call utils#TestUndo(s:test_file) 57 | endfunction 58 | call testify#it('InsertColumn should be able to insert a new column after the current column in a table with headers', function('s:TestInserColumnAfter')) 59 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/sample.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestRowCount() 12 | call testify#assert#equals(tablemode#spreadsheet#RowCount(3), 2) 13 | call testify#assert#equals(tablemode#spreadsheet#RowCount(4), 2) 14 | endfunction 15 | call testify#it('RowCount should return the correct row count', function('s:TestRowCount')) 16 | 17 | function! s:TestRowNr() 18 | call testify#assert#equals(tablemode#spreadsheet#RowNr(3), 1) 19 | call testify#assert#equals(tablemode#spreadsheet#RowNr(4), 2) 20 | endfunction 21 | call testify#it('RowNr should return the correct row number', function('s:TestRowNr')) 22 | 23 | function! s:TestColumnCount() 24 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount(3), 2) 25 | call testify#assert#equals(tablemode#spreadsheet#ColumnCount(4), 2) 26 | endfunction 27 | call testify#it('ColumnCount should return the correct column count', function('s:TestColumnCount')) 28 | 29 | function! s:TestColumnNr() 30 | call cursor(3, 3) 31 | call testify#assert#equals(tablemode#spreadsheet#ColumnNr('.'), 1) 32 | 33 | call cursor(3, 12) 34 | call testify#assert#equals(tablemode#spreadsheet#ColumnNr('.'), 2) 35 | endfunction 36 | call testify#it('ColumnNr should return the correct column number', function('s:TestColumnNr')) 37 | 38 | function! s:TestIsFirstCell() 39 | call cursor(3, 3) 40 | call testify#assert#assert(tablemode#spreadsheet#IsFirstCell()) 41 | 42 | call cursor(3, 12) 43 | call testify#assert#assert(!tablemode#spreadsheet#IsFirstCell()) 44 | endfunction 45 | call testify#it('IsFirstCell should return true when in the first cell', function('s:TestIsFirstCell')) 46 | 47 | function! s:TestIsLastCell() 48 | call cursor(3, 3) 49 | call testify#assert#assert(!tablemode#spreadsheet#IsLastCell()) 50 | 51 | call cursor(3, 12) 52 | call testify#assert#assert(tablemode#spreadsheet#IsLastCell()) 53 | endfunction 54 | call testify#it('IsLastCell should return true when in the last cell', function('s:TestIsLastCell')) 55 | 56 | function! s:TestGetFirstRow() 57 | call testify#assert#equals(tablemode#spreadsheet#GetFirstRow(3), 3) 58 | call testify#assert#equals(tablemode#spreadsheet#GetFirstRow(4), 3) 59 | endfunction 60 | call testify#it('GetFirstRow should return the line number of the first row', function('s:TestGetFirstRow')) 61 | 62 | function! s:TestGetLastRow() 63 | call testify#assert#equals(tablemode#spreadsheet#GetLastRow(3), 4) 64 | call testify#assert#equals(tablemode#spreadsheet#GetLastRow(4), 4) 65 | endfunction 66 | call testify#it('GetLastRow should return the line number of the last row', function('s:TestGetLastRow')) 67 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/math_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/cell/sample.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestSum() 12 | call cursor(3, 3) 13 | let tests = [ 14 | \ { 15 | \ 'actual': tablemode#spreadsheet#Sum('1:2'), 16 | \ 'expected': 4.0 17 | \ }, 18 | \ { 19 | \ 'actual': tablemode#spreadsheet#Sum('1,1:1,2'), 20 | \ 'expected': 3.0 21 | \ }, 22 | \ { 23 | \ 'actual': tablemode#spreadsheet#Sum('1,1:2,2'), 24 | \ 'expected': 10.0 25 | \ }, 26 | \] 27 | call utils#TableTest(tests) 28 | 29 | call cursor(4, 7) 30 | let tests = [ 31 | \ { 32 | \ 'actual': tablemode#spreadsheet#Sum('1:2'), 33 | \ 'expected': 6.0 34 | \ }, 35 | \ { 36 | \ 'actual': tablemode#spreadsheet#Sum('2,1:2,2'), 37 | \ 'expected': 7.0 38 | \ }, 39 | \] 40 | call utils#TableTest(tests) 41 | endfunction 42 | call testify#it('Sum should return the sum of cell range', function('s:TestSum')) 43 | 44 | function! s:TestAverage() 45 | call cursor(3, 3) 46 | let tests = [ 47 | \ { 48 | \ 'actual': tablemode#spreadsheet#Average('1:2'), 49 | \ 'expected': 2.0 50 | \ }, 51 | \ { 52 | \ 'actual': tablemode#spreadsheet#Average('1,1:1,2'), 53 | \ 'expected': 1.5 54 | \ }, 55 | \ { 56 | \ 'actual': tablemode#spreadsheet#Average('1,1:2,2'), 57 | \ 'expected': 2.5 58 | \ }, 59 | \] 60 | call utils#TableTest(tests) 61 | 62 | call cursor(4, 7) 63 | let tests = [ 64 | \ { 65 | \ 'actual': tablemode#spreadsheet#Average('1:2'), 66 | \ 'expected': 3.0 67 | \ }, 68 | \ { 69 | \ 'actual': tablemode#spreadsheet#Average('2,1:2,2'), 70 | \ 'expected': 3.5 71 | \ }, 72 | \] 73 | call utils#TableTest(tests) 74 | endfunction 75 | call testify#it('Average should return the average of cell range', function('s:TestAverage')) 76 | 77 | function! s:TestMin() 78 | call cursor(3, 3) 79 | let tests = [ 80 | \ { 81 | \ 'actual': tablemode#spreadsheet#Min('1:2'), 82 | \ 'expected': 1.0 83 | \ }, 84 | \ { 85 | \ 'actual': tablemode#spreadsheet#Min('1,1:1,2'), 86 | \ 'expected': 1.0 87 | \ }, 88 | \ { 89 | \ 'actual': tablemode#spreadsheet#Min('1,1:2,2'), 90 | \ 'expected': 1.0 91 | \ }, 92 | \] 93 | call utils#TableTest(tests) 94 | 95 | call cursor(4, 7) 96 | let tests = [ 97 | \ { 98 | \ 'actual': tablemode#spreadsheet#Min('1:2'), 99 | \ 'expected': 2.0 100 | \ }, 101 | \ { 102 | \ 'actual': tablemode#spreadsheet#Min('2,1:2,2'), 103 | \ 'expected': 3.0 104 | \ }, 105 | \] 106 | call utils#TableTest(tests) 107 | endfunction 108 | call testify#it('Min should return the min of cell range', function('s:TestMin')) 109 | 110 | function! s:TestMax() 111 | call cursor(3, 3) 112 | let tests = [ 113 | \ { 114 | \ 'actual': tablemode#spreadsheet#Max('1:2'), 115 | \ 'expected': 3.0 116 | \ }, 117 | \ { 118 | \ 'actual': tablemode#spreadsheet#Max('1,1:1,2'), 119 | \ 'expected': 2.0 120 | \ }, 121 | \ { 122 | \ 'actual': tablemode#spreadsheet#Max('1,1:2,2'), 123 | \ 'expected': 4.0 124 | \ }, 125 | \] 126 | call utils#TableTest(tests) 127 | 128 | call cursor(4, 7) 129 | let tests = [ 130 | \ { 131 | \ 'actual': tablemode#spreadsheet#Max('1:2'), 132 | \ 'expected': 4.0 133 | \ }, 134 | \ { 135 | \ 'actual': tablemode#spreadsheet#Max('2,1:2,2'), 136 | \ 'expected': 4.0 137 | \ }, 138 | \] 139 | call utils#TableTest(tests) 140 | endfunction 141 | call testify#it('Max should return the max of cell range', function('s:TestMax')) 142 | -------------------------------------------------------------------------------- /autoload/tablemode/align.vim: -------------------------------------------------------------------------------- 1 | " Borrowed from Tabular 2 | " Private Functions {{{1 3 | " function! s:StripTrailingSpaces(string) - Remove all trailing spaces {{{2 4 | " from a string. 5 | function! s:StripTrailingSpaces(string) 6 | return matchstr(a:string, '^.\{-}\ze\s*$') 7 | endfunction 8 | 9 | function! s:Padding(string, length, where) "{{{3 10 | let gap_length = a:length - tablemode#utils#StrDisplayWidth(a:string) 11 | if a:where =~# 'l' 12 | return a:string . repeat(" ", gap_length) 13 | elseif a:where =~# 'r' 14 | return repeat(" ", gap_length) . a:string 15 | elseif a:where =~# 'c' 16 | let right = gap_length / 2 17 | let left = right + (right * 2 != gap_length) 18 | return repeat(" ", left) . a:string . repeat(" ", right) 19 | endif 20 | endfunction 21 | 22 | " Public Functions {{{1 23 | " function! tablemode#align#Split() - Split a string into fields and delimiters {{{2 24 | " Like split(), but include the delimiters as elements 25 | " All odd numbered elements are delimiters 26 | " All even numbered elements are non-delimiters (including zero) 27 | function! tablemode#align#Split(string, delim) 28 | let rv = [] 29 | let beg = 0 30 | 31 | let len = len(a:string) 32 | let searchoff = 0 33 | 34 | while 1 35 | let mid = match(a:string, a:delim, beg + searchoff, 1) 36 | if mid == -1 || mid == len 37 | break 38 | endif 39 | 40 | let matchstr = matchstr(a:string, a:delim, beg + searchoff, 1) 41 | let length = strlen(matchstr) 42 | 43 | if length == 0 && beg == mid 44 | " Zero-length match for a zero-length delimiter - advance past it 45 | let searchoff += 1 46 | continue 47 | endif 48 | 49 | if beg == mid 50 | let rv += [ "" ] 51 | else 52 | let rv += [ a:string[beg : mid-1] ] 53 | endif 54 | 55 | let rv += [ matchstr ] 56 | 57 | let beg = mid + length 58 | let searchoff = 0 59 | endwhile 60 | 61 | let rv += [ strpart(a:string, beg) ] 62 | 63 | return rv 64 | endfunction 65 | 66 | function! tablemode#align#alignments(lnum, ncols) "{{{2 67 | let achr = g:table_mode_align_char 68 | let alignments = [] 69 | if tablemode#table#IsBorder(a:lnum+1) 70 | let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner') 71 | let corner_corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner_corner') 72 | let hcols = tablemode#align#Split(getline(a:lnum+1), '[' . corner . corner_corner . ']') 73 | for idx in range(len(hcols)) 74 | " Right align if header 75 | call add(alignments, 'l') 76 | if hcols[idx] =~# achr . '[^'.achr.']\+' . achr 77 | let alignments[idx] = 'c' 78 | elseif hcols[idx] =~# achr . '$' 79 | let alignments[idx] = 'r' 80 | endif 81 | " if hcols[idx] !~# '[^0-9\.]' | let alignments[idx] = 'r' | endif 82 | endfor 83 | end 84 | return alignments 85 | endfunction 86 | 87 | function! tablemode#align#Align(lines) "{{{2 88 | if empty(a:lines) | return [] | endif 89 | let lines = map(a:lines, 'map(v:val, "v:key =~# \"text\" ? tablemode#align#Split(v:val, g:table_mode_escaped_separator_regex) : v:val")') 90 | 91 | for line in lines 92 | let stext = line.text 93 | if len(stext) <= 1 | continue | endif 94 | 95 | if stext[0] !~ tablemode#table#StartExpr() 96 | let stext[0] = s:StripTrailingSpaces(stext[0]) 97 | endif 98 | if len(stext) >= 2 99 | for i in range(1, len(stext)-1) 100 | let stext[i] = tablemode#utils#strip(stext[i]) 101 | endfor 102 | endif 103 | endfor 104 | 105 | let maxes = [] 106 | for line in lines 107 | let stext = line.text 108 | if len(stext) <= 1 | continue | endif 109 | for i in range(len(stext)) 110 | if i == len(maxes) 111 | let maxes += [ tablemode#utils#StrDisplayWidth(stext[i]) ] 112 | else 113 | let maxes[i] = max([ maxes[i], tablemode#utils#StrDisplayWidth(stext[i]) ]) 114 | endif 115 | endfor 116 | endfor 117 | 118 | if tablemode#utils#get_buffer_or_global_option('table_mode_ignore_align') ==# 1 119 | let alignments = [] 120 | else 121 | let alignments = tablemode#align#alignments(lines[0].lnum, len(lines[0].text)) 122 | endif 123 | 124 | for idx in range(len(lines)) 125 | let tlnum = lines[idx].lnum 126 | let tline = lines[idx].text 127 | 128 | if len(tline) <= 1 | continue | endif 129 | for jdx in range(len(tline)) 130 | " Dealing with the header being the first line 131 | if jdx >= len(alignments) | call add(alignments, 'l') | endif 132 | let field = s:Padding(tline[jdx], maxes[jdx], alignments[jdx]) 133 | let tline[jdx] = field . (jdx == 0 || jdx == len(tline) ? '' : ' ') 134 | endfor 135 | 136 | let lines[idx].text = s:StripTrailingSpaces(join(tline, '')) 137 | endfor 138 | 139 | return lines 140 | endfunction 141 | -------------------------------------------------------------------------------- /t/autoload/tablemode/spreadsheet/api/count_test.vim: -------------------------------------------------------------------------------- 1 | source t/config/options.vim 2 | source t/utils.vim 3 | 4 | let s:test_file = 't/fixtures/cell/counts.txt' 5 | function! s:setup() 6 | call utils#TestSetup(s:test_file) 7 | endfunction 8 | call testify#setup(function('s:setup')) 9 | call testify#teardown(function('utils#TestTeardown')) 10 | 11 | function! s:TestCountE() 12 | call cursor(3, 3) 13 | let tests = [ 14 | \ { 15 | \ 'actual': tablemode#spreadsheet#CountE('1:3'), 16 | \ 'expected': 1, 17 | \ }, 18 | \ { 19 | \ 'actual': tablemode#spreadsheet#CountE('1,1:1,3'), 20 | \ 'expected': 0, 21 | \ }, 22 | \ { 23 | \ 'actual': tablemode#spreadsheet#CountE('2,1:2,3'), 24 | \ 'expected': 2, 25 | \ }, 26 | \ { 27 | \ 'actual': tablemode#spreadsheet#CountE('1,1:3,3'), 28 | \ 'expected': 2, 29 | \ }, 30 | \] 31 | call utils#TableTest(tests) 32 | 33 | call cursor(5, 11) 34 | let tests = [ 35 | \ { 36 | \ 'actual': tablemode#spreadsheet#CountE('1:3'), 37 | \ 'expected': 1, 38 | \ }, 39 | \ { 40 | \ 'actual': tablemode#spreadsheet#CountE('3,1:3,3'), 41 | \ 'expected': 0, 42 | \ }, 43 | \] 44 | call utils#TableTest(tests) 45 | endfunction 46 | call testify#it('CountE should return the count of empty cells within cell range', function('s:TestCountE')) 47 | 48 | function! s:TestCountNE() 49 | call cursor(3, 3) 50 | let tests = [ 51 | \ { 52 | \ 'actual': tablemode#spreadsheet#CountNE('1:3'), 53 | \ 'expected': 2, 54 | \ }, 55 | \ { 56 | \ 'actual': tablemode#spreadsheet#CountNE('1,1:1,3'), 57 | \ 'expected': 3, 58 | \ }, 59 | \ { 60 | \ 'actual': tablemode#spreadsheet#CountNE('2,1:2,3'), 61 | \ 'expected': 1, 62 | \ }, 63 | \ { 64 | \ 'actual': tablemode#spreadsheet#CountNE('1,1:3,3'), 65 | \ 'expected': 7, 66 | \ }, 67 | \] 68 | call utils#TableTest(tests) 69 | 70 | call cursor(5, 11) 71 | let tests = [ 72 | \ { 73 | \ 'actual': tablemode#spreadsheet#CountNE('1:3'), 74 | \ 'expected': 2, 75 | \ }, 76 | \ { 77 | \ 'actual': tablemode#spreadsheet#CountNE('3,1:3,3'), 78 | \ 'expected': 3, 79 | \ }, 80 | \] 81 | call utils#TableTest(tests) 82 | endfunction 83 | call testify#it('CountNE should return the count of non-empty cells within cell range', function('s:TestCountNE')) 84 | 85 | function! s:TestPercentE() 86 | call cursor(3, 3) 87 | let tests = [ 88 | \ { 89 | \ 'actual': tablemode#spreadsheet#PercentE('1:3'), 90 | \ 'expected': 33, 91 | \ }, 92 | \ { 93 | \ 'actual': tablemode#spreadsheet#PercentE('1,1:1,3'), 94 | \ 'expected': 0, 95 | \ }, 96 | \ { 97 | \ 'actual': tablemode#spreadsheet#PercentE('2,1:2,3'), 98 | \ 'expected': 66, 99 | \ }, 100 | \ { 101 | \ 'actual': tablemode#spreadsheet#PercentE('1,1:3,3'), 102 | \ 'expected': 22, 103 | \ }, 104 | \] 105 | call utils#TableTest(tests) 106 | 107 | call cursor(5, 11) 108 | let tests = [ 109 | \ { 110 | \ 'actual': tablemode#spreadsheet#PercentE('1:3'), 111 | \ 'expected': 33, 112 | \ }, 113 | \ { 114 | \ 'actual': tablemode#spreadsheet#PercentE('3,1:3,3'), 115 | \ 'expected': 0, 116 | \ }, 117 | \] 118 | call utils#TableTest(tests) 119 | endfunction 120 | call testify#it('PercentE should return the percent count of empty cells within cell range', function('s:TestPercentE')) 121 | 122 | function! s:TestPercentNE() 123 | call cursor(3, 3) 124 | let tests = [ 125 | \ { 126 | \ 'actual': tablemode#spreadsheet#PercentNE('1:3'), 127 | \ 'expected': 66, 128 | \ }, 129 | \ { 130 | \ 'actual': tablemode#spreadsheet#PercentNE('1,1:1,3'), 131 | \ 'expected': 100, 132 | \ }, 133 | \ { 134 | \ 'actual': tablemode#spreadsheet#PercentNE('2,1:2,3'), 135 | \ 'expected': 33, 136 | \ }, 137 | \ { 138 | \ 'actual': tablemode#spreadsheet#PercentNE('1,1:3,3'), 139 | \ 'expected': 77, 140 | \ }, 141 | \] 142 | call utils#TableTest(tests) 143 | 144 | call cursor(5, 11) 145 | let tests = [ 146 | \ { 147 | \ 'actual': tablemode#spreadsheet#PercentNE('1:3'), 148 | \ 'expected': 66, 149 | \ }, 150 | \ { 151 | \ 'actual': tablemode#spreadsheet#PercentNE('3,1:3,3'), 152 | \ 'expected': 100, 153 | \ }, 154 | \] 155 | call utils#TableTest(tests) 156 | endfunction 157 | call testify#it('PercentNE should return the percent count of non-empty cells within cell range', function('s:TestPercentNE')) 158 | 159 | function! s:TestAverageNE() 160 | call cursor(3, 3) 161 | let tests = [ 162 | \ { 163 | \ 'actual': tablemode#spreadsheet#AverageNE('1:3'), 164 | \ 'expected': 2.5, 165 | \ }, 166 | \ { 167 | \ 'actual': tablemode#spreadsheet#AverageNE('1,1:1,3'), 168 | \ 'expected': 2.0, 169 | \ }, 170 | \ { 171 | \ 'actual': tablemode#spreadsheet#AverageNE('2,1:2,3'), 172 | \ 'expected': 0.0, 173 | \ }, 174 | \ { 175 | \ 'actual': tablemode#spreadsheet#AverageNE('1,1:3,3'), 176 | \ 'expected': 3.0, 177 | \ }, 178 | \] 179 | call utils#TableTest(tests) 180 | 181 | call cursor(5, 11) 182 | let tests = [ 183 | \ { 184 | \ 'actual': tablemode#spreadsheet#AverageNE('1:3'), 185 | \ 'expected': 4.5, 186 | \ }, 187 | \ { 188 | \ 'actual': tablemode#spreadsheet#AverageNE('3,1:3,3'), 189 | \ 'expected': 5.0, 190 | \ }, 191 | \] 192 | call utils#TableTest(tests) 193 | endfunction 194 | call testify#it('AverageNE should return the average of non-empty cells within cell range', function('s:TestAverageNE')) 195 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Version 4.8.0 4 | * Improved formula engine 5 | - Does not cast column values to float 6 | - Silences errors during evaluation, see `v:errmsg` for error information 7 | from last evaluation for debugging issues with formulas 8 | 9 | ## Version 4.7.6.1 10 | * Improved handling of `g:table_mode_ignore_align` configuration, now allows 11 | per buffer overrides 12 | 13 | ## Version 4.7.6 14 | * Add configuration `g:table_mode_ignore_align` 15 | 16 | ## Version 4.7.5 17 | * Improved undo 18 | 19 | ## Version 4.7.3 20 | * Adding option `g:table_mode_tableize_auto_border` to enable automatic border 21 | creation when using Tableize to create tables 22 | 23 | ## Version 4.7.2 24 | * Fix formula evaluation to respect border rows and apply formula expressions 25 | correctly 26 | 27 | ## Version 4.6.8 28 | * Upgrade rake 29 | 30 | ## Version 4.6.7 31 | * Remove auto align feature for insert mode 32 | 33 | ## Version 4.6.6 34 | * Add configuration `g:table_mode_update_time` 35 | 36 | ## Version 4.6.5 37 | * Add support for auto aligning 38 | 39 | ## Version 4.6.4.1 40 | * Added a fix for markdown commentstring 41 | 42 | ## Version 4.6.4 43 | * Added support for center aligning columns 44 | 45 | ## Version 4.6.3 46 | * Fixed tablemode#spreadsheet#LineNr() 47 | * Fixed tablemode#spreadsheet#cell#SetCell() 48 | 49 | ## Version 4.6.2 50 | * Added custom User autocmd event for tablemode activation (enabled / 51 | disabled) 52 | * Adding better header support for pandoc, headers can now have a different 53 | fillchar configured with `g:table_mode_header_fillchar` 54 | 55 | ## Version 4.6.1 56 | * Minor bug fixes 57 | 58 | ## Version 4.6.0 59 | * Added better table header support. The first line of the table if separated 60 | by a table border will be considered as the header. This also means that it 61 | will not be considered / included when evaluating table formulas and that 62 | the first line after the header would be considered the first line of the 63 | table. 64 | 65 | ## Version 4.5.0 66 | * Refactored toggled mappings 67 | * Table Syntax now gets toggled with Table Mode 68 | 69 | ## Version 4.4.2 70 | * Updated mappings to be buffer local. 71 | * Updated mappings to toggle and function only when table mode is active. 72 | 73 | ## Version 4.4.1 74 | * Added syntax for matching tables 75 | 76 | ## Version 4.4.0 77 | * Minor bug fixes 78 | * Added feature to allow using negative indices within formulas to access rows, 79 | columns relative to the last, -1 being the last. 80 | 81 | ## Version 4.3.0 82 | * Refactored some more 83 | * Fixed issue #19, hiphens in the table broke alignment 84 | * Added feature #26, you can now define column alignments in the table header 85 | 86 | ## Version 4.2.0 87 | * Refactored cells logic out to autoload/tablemode/spreadsheet/cell.vim 88 | * Refactored formula logic out to autoload/tablemode/spreadsheet/formula.vim 89 | 90 | ## Version 4.1.0 91 | * Fixed bad references within plugin 92 | * Added fixtures 93 | 94 | ## Version 4.0.0 95 | * Major refactoring of the codebase. 96 | * Improved modular tests. 97 | * Fixed long standing unicode character alignment issue. 98 | * Moved to providing \ mappings rather than configuration based mappings 99 | which can be more easily overriden by end user. 100 | 101 | ## Version 3.3.2 102 | * Added new mapping \t? to echo a cells representation for use while defining 103 | formulas. 104 | 105 | ## Version 3.3.1 106 | * Improved logic to ignore table borders (add as many as you'd like), the 107 | first row is not treated special, it is row # 1. Keep that in mind while 108 | defining Formulas 109 | * Improved test coverage 110 | 111 | ## Version 3.3 112 | * Dropped +- mapping to create table border instead now using || 113 | * You can now have a top table border (before header) as well as a bottom 114 | table border. 115 | 116 | ## Version 3.2 117 | * Added tests to test various use cases using Vspec.. 119 | * Added travis integration for automated tests. 120 | 121 | ## Version 3.1 122 | * Removed borders. You can now optionally create a table header by simply 123 | adding a header border immidiately after the header line by using the 124 | iabbrev trigger '+-'. Just type that on the line immidiately after the 125 | header and press space / \ to complete the header border. 126 | * Some Bug Fixes 127 | 128 | ## Version 3.0 129 | * Removed dependence on Tabular and added code borrowed from Tabular for 130 | aligning the table rows. 131 | * Added feature to be able to define & evaluate formulas. 132 | 133 | ## Version 2.4.0 134 | * Added Table Cell text object. 135 | * Added api to delete entire table row. 136 | * Added api to delete entire table column. 137 | 138 | ## Version 2.3.0 139 | * Refactored realignment logic. Generating borders by hand. 140 | 141 | ## Version 2.2.2 142 | * Added mapping for realigning table columns. 143 | * Added table motions to move around in the table. 144 | 145 | ## Version 2.2.1 146 | * Added feature to allow Table-Mode to work within comments. Uses 147 | 'commentstring' option of vim to identify comments, so it should work for 148 | most filetypes as long as 'commentstring' option has been set. This is 149 | usually done appropriately in filetype plugins. 150 | 151 | ## Version 2.2 152 | * Improved :Tableize to now accept a {pattern} just like :Tabular to match the 153 | delimiter. 154 | 155 | ## Version 2.1.3 : 156 | * Bug Fix #1, added new option `g:table_mode_no_border_padding` which removes 157 | padding from the border. 158 | 159 | ## Version 2.1.2 : 160 | * Bug Fixes #2, #3 & #4 161 | 162 | ## Version 2.1.1 : 163 | * Added option `g:table_mode_align` to allow setting Tabular format option for 164 | more control on how Tabular aligns text. 165 | 166 | ## Version 2.1 : 167 | * VIM loads plugins in alphabetical order and so table-mode would be loaded 168 | before Tabularize which it depends on. Hence Moved plugin into an after 169 | plugin. Checking if Tabularize is available and finish immidiately if it's 170 | not. 171 | 172 | ## Version 2.0 : 173 | * Moved bulk of code to autoload for vimscript optimisation. 174 | 175 | ## Version 1.1 : 176 | * Added Tableize command and mapping to convert existing content into a table. 177 | 178 | ## Version 1.0 : 179 | * First stable release, create tables as you type. 180 | 181 | 184 | -------------------------------------------------------------------------------- /autoload/tablemode/spreadsheet/formula.vim: -------------------------------------------------------------------------------- 1 | " Private Functions {{{1 2 | function! s:IsFormulaLine(line) "{{{2 3 | return getline(a:line) =~# 'tmf: ' 4 | endfunction 5 | 6 | function! s:IsHTMLComment(line) "{{{2 7 | return !s:IsFormulaLine(a:line) && getline(a:line) =~# '^\s*