Compare commits

..

71 Commits

Author SHA1 Message Date
Dhruva Sagar
d1908c04f3 Updated READMEs 2015-02-27 08:53:26 +05:30
Dhruva Sagar
33c00df509 Fix #56
* Fixed tablemode#spreadsheet#cell#SetCell() to accommodate the fact that we
  can have borders anywhere in the table. Using
  tablemode#spreadsheet#LineNr() to get get the line of the actual row
  in the table.
* Fixed tablemode#spreadsheet#LineNr()
2015-02-27 08:53:03 +05:30
Dhruva Sagar
3096a26db4 Merge pull request #51 from jensbodal/patch-1
File names incorrect for files to copy
2015-01-11 17:08:48 +05:30
jensbodal
acde7918e8 File names incorrect for files to copy
If you're interested I made a script to install this plugin and install pathogen.  I've never installed a plugin before and for me the instructions were not very easy to follow in order to get this working. It looks like exactly what I was looking for though, so thank you very much for putting this together.

# Script for UNIX only -- not tested on OSX or Windows

# Make necessary directories
mkdir -p ~/.vim/autoload ~/.vim/bundle ~/.vim/doc ~/.vim/plugin

# Install pathogen (https://github.com/tpope/vim-pathogen)
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim

# Install vim-table-mode plugin (https://github.com/dhruvasagar/vim-table-mode)
git clone https://github.com/dhruvasagar/vim-table-mode.git ~/.vim/bundle/vim-table-mode

# Place vim-table-mode files where they need to be
cp ~/.vim/bundle/vim-table-mode/autoload/tablemode.vim ~/.vim/autoload
cp ~/.vim/bundle/vim-table-mode/plugin/table-mode.vim ~/.vim/plugin
cp ~/.vim/bundle/vim-table-mode/doc/table-mode.txt ~/.vim/doc

# Add options to ~/.vimrc to run pathogen when vim starts
echo >> ~/.vimrc
echo \"Start pathogen manager on startup >> ~/.vimrc
echo execute pathogen\#infect\(\) >> ~/.vimrc
echo >> ~/.vimrc
echo \"Enable indent on for plugin filetypes >> ~/.vimrc
echo filetype plugin indent on >> ~/.vimrc

echo Test out vim-table-mode using :TableModeToggle or :TableModeEnable or :TableModeDisable
2015-01-10 22:05:36 -08:00
Dhruva Sagar
1e94ae39cc Merge pull request #46 from grodzik/master
Use table_mode_map_prefix for the tableize mappings
2014-12-08 18:22:05 +05:30
Paweł Tomak
84e382123d Use table_mode_map_prefix for the tableize mappings 2014-12-08 13:44:03 +01:00
Dhruva Sagar
e125870212 Fixed s:Map to not throw error for empty a:to 2014-11-21 07:02:38 +05:30
Dhruva Sagar
d5152bde5e Fixed typo #39 2014-11-20 07:21:43 +05:30
Dhruva Sagar
b22c9bf7b1 Skip empty maps 2014-11-20 07:19:23 +05:30
Dhruva Sagar
5103dae89d Updated CHANGELOG 2014-11-18 08:20:28 +05:30
Dhruva Sagar
29cae13802 Fixed #44
Added tablemode#logger#log && g:table_mode_verbose

Use logger wherever needed for logging general things, in future we can
scale this to do more things like write to a log file for debugging. It
uses g:table_mode_verbose to determine whether or not to actually log
the message.
2014-11-18 07:57:45 +05:30
Dhruva Sagar
af0254e816 Improved tablemode#table#IsHeader()
Automatically improves header border creation, especially when
overriding g:table_mode_header_fillchar #31
2014-11-18 07:48:23 +05:30
Dhruva Sagar
8810818e32 Updated docs & bumped version 2014-11-16 13:42:27 +05:30
Dhruva Sagar
bba22a4f04 Added g:table_mode_header_fillchar
* Allows configuring a separate character for header border to be used
  with pandoc
2014-11-16 13:40:14 +05:30
Dhruva Sagar
ffc734c38d Added TableModeEnabled & TableModeDisabled autocmd
* Added custom User autocmds TableModeEnabled & TableModeDisabled for
  working with other plugins like vim-pandoc #43
2014-11-15 16:38:22 +05:30
Dhruva Sagar
ea78f62565 Releasing Table Mode v4.6.1
* Added configurable table mappings.
* Updated docs & README.
2014-10-28 13:31:16 +05:30
Dhruva Sagar
7e06786708 Minor formatting 2014-10-28 08:04:39 +05:30
Dhruva Sagar
ef0eef0f35 Fixed #38
Added a mapping `<Plug>(table-mode-sort)` which is mapped by default to
`<Leader>ts` that sorts the current table by the column in which the
cursor is currently.

Also added `TableSort` command that gives you a little more control over
the sorting, you can pass in additional :sort flags like u, i, n etc and
also use it with a `!` to sort in reverse order.
2014-09-17 01:36:59 +05:30
Dhruva Sagar
c5258f7ae8 Merge pull request #37 from andrwj/master
show table-mode status
2014-08-24 07:44:46 +05:30
A.J
a3e3269658 show table-mode status 2014-08-24 07:42:51 +09:00
Dhruva Sagar
8e4a4e7dc4 Bumped the version 2014-08-15 09:43:07 +05:30
Dhruva Sagar
761a67b36b Fixed #16
Altered table mode behavior such that if there is a header line, i.e.
the first line of the table is separated by a border with the rest of
the table, then it is not taken into account for formulas and cell
arithmetic
2014-08-15 09:40:29 +05:30
Dhruva Sagar
8683146a5f Removed unnecessary code / headers 2014-08-15 07:55:19 +05:30
Dhruva Sagar
82863fa8eb Merge pull request #35 from p0deje/master
Added option to disable all mappings. Fixes #34
2014-07-25 07:27:53 +05:30
Alex Rodionov
6b89fe5c9e Fix specs 2014-07-24 19:15:36 +07:00
Alex Rodionov
67969ae5cf Set table_mode_disable_mappings to 0 by default 2014-07-23 10:23:09 +07:00
Alex Rodionov
135d571e9c Added option to disable all mappings 2014-07-23 08:59:28 +07:00
Dhruva Sagar
4c91a4efa2 Updated tests 2014-05-30 12:20:46 +05:30
Dhruva Sagar
8d9a0082f5 Updated docs 2014-05-30 12:20:38 +05:30
Dhruva Sagar
0f1254e1fe Updated table syntax to get toggled with table mode 2014-05-30 12:05:31 +05:30
Dhruva Sagar
e7e806916f Refactored toggleMapping 2014-05-30 11:49:13 +05:30
Dhruva Sagar
9336261063 Added cell text object for visual mode 2014-05-15 11:02:21 +05:30
Dhruva Sagar
a5ae0253be Added modeline to CHANGELOG 2014-05-13 11:21:11 +05:30
Dhruva Sagar
80ec86e385 Version 4.4.2
* Updated mappings to be buffer local
* Updated mappings to toggle with Table Mode
2014-05-13 11:18:42 +05:30
Dhruva Sagar
7eff1e30f1 Fixed #30
In case there is nothing to align, it was failing with an error, this
ensures it exists gracefully in this situation.
2014-05-10 15:27:36 +05:30
Dhruva Sagar
7258a56d20 Updated Table syntax to incorporate commented tables 2014-05-04 10:13:40 +05:30
Dhruva Sagar
8d3c4912a2 Added syntax for matching tables 2014-05-03 02:19:19 +05:30
Dhruva Sagar
13e1a20002 Fixing tests 2014-05-01 21:29:31 +05:30
Dhruva Sagar
d73236f964 Fixing ruby version 2014-05-01 21:21:31 +05:30
Dhruva Sagar
c5efbe1ad7 Bumped ruby version for travis 2014-05-01 21:16:56 +05:30
Dhruva Sagar
8970d5ffbb Improved tests 2014-05-01 21:14:49 +05:30
Dhruva Sagar
859eb42856 Added more tests for Realigning unicode content 2014-05-01 21:07:53 +05:30
Dhruva Sagar
d7ad97f099 Fixing tests 2014-05-01 16:56:11 +05:30
Dhruva Sagar
dbd79f2c1e Minor refactor & improved test coverage 2014-05-01 16:35:25 +05:30
Dhruva Sagar
fa568fe91b Improved test for utils 2014-04-30 23:05:19 +05:30
Dhruva Sagar
53da3fb4c2 Fixed #28
Altered border generation code to incorporate true display width of
characters, hence generate more accurate borders.
2014-04-30 21:30:44 +05:30
Dhruva Sagar
6007953f0e Fixed typo in docs 2014-04-28 14:14:26 +05:30
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
38 changed files with 1422 additions and 962 deletions

View File

@@ -1,4 +1,4 @@
language: ruby language: ruby
rvm: rvm:
- 1.9.3 - 2.1.2
script: rake ci script: rake ci

View File

@@ -1,4 +1,50 @@
# Change Log # Change Log
## Version 4.6.3
* Fixed tablemode#spreadsheet#LineNr()
* Fixed tablemode#spreadsheet#cell#SetCell()
## Version 4.6.2
* Added custom User autocmd event for tablemode activation (enabled /
disabled)
* Adding better header support for pandoc, headers can now have a different
fillchar configured with `g:table_mode_header_fillchar`
## Version 4.6.1
* Minor bug fixes
## Version 4.6.0
* Added better table header support. The first line of the table if separated
by a table border will be considered as the header. This also means that it
will not be considered / included when evaluating table formulas and that
the first line after the header would be considered the first line of the
table.
## Version 4.5.0
* Refactored toggled mappings
* Table Syntax now gets toggled with Table Mode
## Version 4.4.2
* Updated mappings to be buffer local.
* Updated mappings to toggle and function only when table mode is active.
## Version 4.4.1
* Added syntax for matching tables
## 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 ## Version 4.1.0
* Fixed bad references within plugin * Fixed bad references within plugin
* Added fixtures * Added fixtures
@@ -7,7 +53,7 @@
* Major refactoring of the codebase. * Major refactoring of the codebase.
* Improved modular tests. * Improved modular tests.
* Fixed long standing unicode character alignment issue. * Fixed long standing unicode character alignment issue.
* Moved to providing <Plug> mappings rather than configuration based mappings * Moved to providing \<Plug\> mappings rather than configuration based mappings
which can be more easily overriden by end user. which can be more easily overriden by end user.
## Version 3.3.2 ## Version 3.3.2
@@ -89,3 +135,7 @@
## Version 1.0 : ## Version 1.0 :
* First stable release, create tables as you type. * First stable release, create tables as you type.
<!--
vim: ft=markdown
-->

View File

@@ -1,4 +1,5 @@
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '2.1.2'
gem 'rake' gem 'rake'
gem 'vim-flavor', '~> 1.1' gem 'vim-flavor', '~> 1.1'

View File

@@ -1,4 +1,4 @@
# VIM Table Mode v4.1.0 [![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.6.3 [![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 An awesome automatic table creator & formatter allowing one to create neat
tables as you type. tables as you type.
@@ -25,7 +25,7 @@ There are several ways to do this
$ cd ~/.vim $ cd ~/.vim
$ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-mode $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-mode
``` ```
3. Copy autoload/todomode.vim, plugin/todo-mode.vim, doc/todo-mode.txt to 3. Copy autoload/tablemode.vim, plugin/table-mode.vim, doc/table-mode.txt to
respective ~/.vim/autoload/, ~/.vim/plugin and ~/.vim/doc under UNIX or respective ~/.vim/autoload/, ~/.vim/plugin and ~/.vim/doc under UNIX or
vimfiles/autoload/, vimfiles/plugin/ and vimfiles/doc under WINDOWS and vimfiles/autoload/, vimfiles/plugin/ and vimfiles/doc under WINDOWS and
restart VIM restart VIM
@@ -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 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. 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** : - **Format existing content into a table** :
Table Mode wouldn't justify it's name if it didn't allow formatting Table Mode wouldn't justify it's name if it didn't allow formatting
@@ -133,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 - `$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 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 - `$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 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 - 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 which are also defined by the same format as that of the target cell. You
@@ -145,7 +151,7 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
mode also provides 2 special functions `Sum` and `Average`. Both these mode also provides 2 special functions `Sum` and `Average`. Both these
functions take a range as input. A range can be of two forms : functions take a range as input. A range can be of two forms :
- `r1,r2`: This represents cells in the current column from row `r1` - `r1:r2`: This represents cells in the current column from row `r1`
through `r2`. If `r2` is negative it represents `r2` rows above the through `r2`. If `r2` is negative it represents `r2` rows above the
current row (of the target cell). current row (of the target cell).

View File

@@ -1,71 +1,117 @@
" ============================== Header ======================================
" File: autoload/tablemode.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
" Version: 4.1.0
" 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 " Private Functions {{{1
function! s:sub(str,pat,rep) abort "{{{2
return substitute(a:str,'\v\C'.a:pat,a:rep,'')
endfunction
function! s:gsub(str,pat,rep) abort "{{{2
return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
endfunction
function! s:SetBufferOptDefault(opt, val) "{{{2 function! s:SetBufferOptDefault(opt, val) "{{{2
if !exists('b:' . a:opt) if !exists('b:' . a:opt)
let b:{a:opt} = a:val let b:{a:opt} = a:val
endif endif
endfunction endfunction
function! s:IsTableModeActive() "{{{2 function! s:Map(map, to, mode) "{{{2
if g:table_mode_always_active | return 1 | endif if !empty(a:to) && !hasmapto(a:map, a:mode)
for l:mode in split(a:mode, '.\zs')
execute l:mode . 'map <buffer>' a:to a:map
endfor
endif
endfunction
call s:SetBufferOptDefault('table_mode_active', 0) function! s:UnMap(map, mode) "{{{2
return b:table_mode_active if !empty(maparg(a:map, a:mode))
for mode in split(a:mode, '.\zs')
execute l:mode . 'unmap <buffer>' a:map
endfor
endif
endfunction endfunction
function! s:ToggleMapping() "{{{2 function! s:ToggleMapping() "{{{2
if exists('b:table_mode_active') && b:table_mode_active let separator_map = g:table_mode_separator
call s:SetBufferOptDefault('table_mode_separator_map', g:table_mode_separator) " '|' is a special character, we need to map <Bar> instead
" '|' is a special character, we need to map <Bar> instead if g:table_mode_separator ==# '|' | let separator_map = '<Bar>' | endif
if g:table_mode_separator ==# '|' | let b:table_mode_separator_map = '<Bar>' | endif
execute "inoremap <silent> <buffer> " . b:table_mode_separator_map . ' ' . if !g:table_mode_disable_mappings
\ b:table_mode_separator_map . "<Esc>:call tablemode#TableizeInsertMode()<CR>a" if tablemode#IsActive()
call s:Map('<Plug>(table-mode-tableize)', separator_map, 'i')
call s:Map('<Plug>(table-mode-motion-up)', g:table_mode_motion_up_map, 'n')
call s:Map('<Plug>(table-mode-motion-down)', g:table_mode_motion_down_map, 'n')
call s:Map('<Plug>(table-mode-motion-left)', g:table_mode_motion_left_map, 'n')
call s:Map('<Plug>(table-mode-motion-right)', g:table_mode_motion_right_map, 'n')
call s:Map('<Plug>(table-mode-cell-text-object-a)', g:table_mode_cell_text_object_a_map, 'ox')
call s:Map('<Plug>(table-mode-cell-text-object-i)', g:table_mode_cell_text_object_i_map, 'ox')
call s:Map('<Plug>(table-mode-realign)', g:table_mode_realign_map, 'n')
call s:Map('<Plug>(table-mode-delete-row)', g:table_mode_delete_row_map, 'n')
call s:Map('<Plug>(table-mode-delete-column)', g:table_mode_delete_column_map, 'n')
call s:Map('<Plug>(table-mode-add-formula)', g:table_mode_add_formula_map, 'n')
call s:Map('<Plug>(table-mode-eval-formula)', g:table_mode_eval_formula_map, 'n')
call s:Map('<Plug>(table-mode-echo-cell)', g:table_mode_echo_cell_map, 'n')
call s:Map('<Plug>(table-mode-sort)', g:table_mode_sort_map, 'n')
else
call s:UnMap(separator_map, 'i')
call s:UnMap(g:table_mode_motion_up_map, 'n')
call s:UnMap(g:table_mode_motion_down_map, 'n')
call s:UnMap(g:table_mode_motion_left_map, 'n')
call s:UnMap(g:table_mode_motion_right_map, 'n')
call s:UnMap(g:table_mode_cell_text_object_a_map, 'ox')
call s:UnMap(g:table_mode_cell_text_object_i_map, 'ox')
call s:UnMap(g:table_mode_realign_map, 'n')
call s:UnMap(g:table_mode_delete_row_map, 'n')
call s:UnMap(g:table_mode_delete_column_map, 'n')
call s:UnMap(g:table_mode_add_formula_map, 'n')
call s:UnMap(g:table_mode_eval_formula_map, 'n')
call s:UnMap(g:table_mode_echo_cell_map, 'n')
call s:UnMap(g:table_mode_sort_map, 'n')
endif
endif
endfunction
function! tablemode#SyntaxEnable()
exec 'syntax match Table'
\ '/' . tablemode#table#StartExpr() . '\zs|.\+|\ze' . tablemode#table#EndExpr() . '/'
\ 'contains=TableBorder,TableSeparator,TableColumnAlign containedin=ALL'
syntax match TableSeparator /|/ contained
syntax match TableColumnAlign /:/ contained
syntax match TableBorder /[\-+]\+/ contained
hi! link TableBorder Delimiter
hi! link TableSeparator Delimiter
hi! link TableColumnAlign Type
endfunction
function! s:ToggleSyntax()
if tablemode#IsActive()
call tablemode#SyntaxEnable()
else else
silent! execute "iunmap <silent> <buffer> " . b:table_mode_separator_map syntax clear Table
syntax clear TableBorder
syntax clear TableSeparator
syntax clear TableColumnAlign
hi! link TableBorder NONE
hi! link TableSeparator NONE
hi! link TableColumnAlign NONE
endif endif
endfunction endfunction
function! s:SetActive(bool) "{{{2 function! s:SetActive(bool) "{{{2
let b:table_mode_active = a:bool let b:table_mode_active = a:bool
call s:ToggleSyntax()
call s:ToggleMapping() call s:ToggleMapping()
if tablemode#IsActive()
doautocmd User TableModeEnabled
else
doautocmd User TableModeDisabled
endif
endfunction endfunction
function! s:ConvertDelimiterToSeparator(line, ...) "{{{2 function! s:ConvertDelimiterToSeparator(line, ...) "{{{2
let gflag = 'g' let old_gdefault = &gdefault
if &gdefault | let gflag = 'gg' | endif set nogdefault
let delim = g:table_mode_delimiter let delim = g:table_mode_delimiter
if a:0 | let delim = a:1 | endif if a:0 | let delim = a:1 | endif
if delim ==# ',' if delim ==# ','
silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs,\\ze[^\'\"]*[\'\"]/__COMMA__/" . gflag silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs,\\ze[^\'\"]*[\'\"]/__COMMA__/g"
endif endif
let [cstart, cend] = [tablemode#table#GetCommentStart(), tablemode#table#GetCommentEnd()] let [cstart, cend] = [tablemode#table#GetCommentStart(), tablemode#table#GetCommentEnd()]
@@ -75,11 +121,13 @@ function! s:ConvertDelimiterToSeparator(line, ...) "{{{2
silent! execute a:line . 's/' . tablemode#table#StartExpr() . '\zs\ze' . match_char_start . silent! execute a:line . 's/' . tablemode#table#StartExpr() . '\zs\ze' . match_char_start .
\ '\|' . delim . '\|' . match_char_end . '\zs\ze' . tablemode#table#EndExpr() . '/' . \ '\|' . delim . '\|' . match_char_end . '\zs\ze' . tablemode#table#EndExpr() . '/' .
\ g:table_mode_separator . '/' . gflag \ g:table_mode_separator . '/g'
if delim ==# ',' if delim ==# ','
silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs__COMMA__\\ze[^\'\"]*[\'\"]/,/" . gflag silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs__COMMA__\\ze[^\'\"]*[\'\"]/,/g"
endif endif
let &gdefault=old_gdefault
endfunction endfunction
function! s:Tableizeline(line, ...) "{{{2 function! s:Tableizeline(line, ...) "{{{2
@@ -89,37 +137,35 @@ function! s:Tableizeline(line, ...) "{{{2
endfunction endfunction
" Public API {{{1 " Public API {{{1
function! tablemode#sid() "{{{2 function! tablemode#IsActive() "{{{2
return maparg('<SID>', 'n') if g:table_mode_always_active | return 1 | endif
endfunction
nnoremap <SID> <SID>
function! tablemode#scope() "{{{2 call s:SetBufferOptDefault('table_mode_active', 0)
return s: return b:table_mode_active
endfunction endfunction
function! tablemode#TableizeInsertMode() "{{{2 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('.') call tablemode#table#AddBorder('.')
normal! A 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 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.*')) 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 normal! 0
call search(repeat('[^' . g:table_mode_separator . ']*' . g:table_mode_separator, column) . '\s\{-\}' . repeat('.', position), 'ce', line('.')) call search(repeat('[^' . g:table_mode_separator . ']*' . g:table_mode_separator, column) . '\s\{-\}' . repeat('.', position), 'ce', line('.'))
endif endif
endfunction endfunction
function! tablemode#TableModeEnable() "{{{2 function! tablemode#Enable() "{{{2
call s:SetActive(1) call s:SetActive(1)
endfunction endfunction
function! tablemode#TableModeDisable() "{{{2 function! tablemode#Disable() "{{{2
call s:SetActive(0) call s:SetActive(0)
endfunction endfunction
function! tablemode#TableModeToggle() "{{{2 function! tablemode#Toggle() "{{{2
if g:table_mode_always_active if g:table_mode_always_active
return 1 return 1
endif endif
@@ -136,7 +182,7 @@ function! tablemode#TableizeRange(...) range "{{{2
let lnum += 1 let lnum += 1
endwhile endwhile
call tablemode#table#TableRealign(lnum - 1) call tablemode#table#Realign(lnum - 1)
endfunction endfunction
function! tablemode#TableizeByDelimiter() "{{{2 function! tablemode#TableizeByDelimiter() "{{{2

View File

@@ -1,51 +1,5 @@
" ============================== Header ======================================
" File: autoload/tablemode/align.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
" Version: 4.1.0
" 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.
" =============================================================================
" Borrowed from Tabular " Borrowed from Tabular
" Private Functions {{{1 " Private Functions {{{1
" Return the number of bytes in a string after expanding tabs to spaces. {{{2
" This expansion is done based on the current value of 'tabstop'
if exists('*strdisplaywidth')
" Needs vim 7.3
let s:Strlen = function("strdisplaywidth")
else
function! s:Strlen(string)
" Implement the tab handling part of strdisplaywidth for vim 7.2 and
" earlier - not much that can be done about handling doublewidth
" characters.
let rv = 0
let i = 0
for char in split(a:string, '\zs')
if char == "\t"
let rv += &ts - i
let i = 0
else
let rv += 1
let i = (i + 1) % &ts
endif
endfor
return rv
endfunction
endif
" function! s:StripTrailingSpaces(string) - Remove all trailing spaces {{{2 " function! s:StripTrailingSpaces(string) - Remove all trailing spaces {{{2
" from a string. " from a string.
function! s:StripTrailingSpaces(string) function! s:StripTrailingSpaces(string)
@@ -53,7 +7,7 @@ function! s:StripTrailingSpaces(string)
endfunction endfunction
function! s:Padding(string, length, where) "{{{3 function! s:Padding(string, length, where) "{{{3
let gap_length = a:length - s:Strlen(a:string) let gap_length = a:length - tablemode#utils#StrDisplayWidth(a:string)
if a:where =~# 'l' if a:where =~# 'l'
return a:string . repeat(" ", gap_length) return a:string . repeat(" ", gap_length)
elseif a:where =~# 'r' elseif a:where =~# 'r'
@@ -65,11 +19,12 @@ function! s:Padding(string, length, where) "{{{3
endif endif
endfunction endfunction
" function! s:Split() - Split a string into fields and delimiters {{{2 " Public Functions {{{1
" function! tablemode#align#Split() - Split a string into fields and delimiters {{{2
" Like split(), but include the delimiters as elements " Like split(), but include the delimiters as elements
" All odd numbered elements are delimiters " All odd numbered elements are delimiters
" All even numbered elements are non-delimiters (including zero) " All even numbered elements are non-delimiters (including zero)
function! s:Split(string, delim) function! tablemode#align#Split(string, delim)
let rv = [] let rv = []
let beg = 0 let beg = 0
@@ -108,59 +63,66 @@ function! s:Split(string, delim)
return rv return rv
endfunction endfunction
" Public Functions {{{1 function! tablemode#align#alignments(lnum, ncols) "{{{2
function! tablemode#align#sid() "{{{2 let alignments = []
return maparg('<sid>', 'n') if tablemode#table#IsBorder(a:lnum+1)
endfunction let hcols = tablemode#align#Split(getline(a:lnum+1), '[' . g:table_mode_corner . g:table_mode_corner_corner . ']')
nnoremap <sid> <sid> for idx in range(len(hcols))
" Right align if header
function! tablemode#align#scope() "{{{2 call add(alignments, 'l')
return s: 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 endfunction
function! tablemode#align#Align(lines) "{{{2 function! tablemode#align#Align(lines) "{{{2
let lines = map(a:lines, 's:Split(v:val, g:table_mode_separator)') if empty(a:lines) | return [] | endif
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 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() if stext[0] !~ tablemode#table#StartExpr()
let line[0] = s:StripTrailingSpaces(line[0]) let stext[0] = s:StripTrailingSpaces(stext[0])
endif endif
if len(line) >= 2 if len(stext) >= 2
for i in range(1, len(line)-1) for i in range(1, len(stext)-1)
let line[i] = tablemode#utils#strip(line[i]) let stext[i] = tablemode#utils#strip(stext[i])
endfor endfor
endif endif
endfor endfor
let maxes = [] let maxes = []
for line in lines for line in lines
if len(line) <= 1 | continue | endif let stext = line.text
for i in range(len(line)) if len(stext) <= 1 | continue | endif
for i in range(len(stext))
if i == len(maxes) if i == len(maxes)
let maxes += [ s:Strlen(line[i]) ] let maxes += [ tablemode#utils#StrDisplayWidth(stext[i]) ]
else else
let maxes[i] = max([ maxes[i], s:Strlen(line[i]) ]) let maxes[i] = max([ maxes[i], tablemode#utils#StrDisplayWidth(stext[i]) ])
endif endif
endfor endfor
endfor endfor
let alignments = tablemode#align#alignments(lines[0].lnum, len(lines[0].text))
for idx in range(len(lines)) 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 if len(tline) <= 1 | continue | endif
for i in range(len(line)) for jdx in range(len(tline))
if line[i] !~# '[^0-9\.]' " Dealing with the header being the first line
let field = s:Padding(line[i], maxes[i], 'r') if jdx >= len(alignments) | call add(alignments, 'l') | endif
else let field = s:Padding(tline[jdx], maxes[jdx], alignments[jdx])
let field = s:Padding(line[i], maxes[i], 'l') let tline[jdx] = field . (jdx == 0 || jdx == len(tline) ? '' : ' ')
endif
let line[i] = field . (i == 0 || i == len(line) ? '' : ' ')
endfor endfor
let lines[idx] = s:StripTrailingSpaces(join(line, '')) let lines[idx].text = s:StripTrailingSpaces(join(tline, ''))
endfor endfor
return lines return lines

View File

@@ -0,0 +1,5 @@
function! tablemode#logger#log(message)
if g:table_mode_verbose
echom message
endif
endfunction

View File

@@ -1,23 +1,3 @@
" ============================== Header ======================================
" File: autoload/tablemode/spreadsheet.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
" Version: 4.1.0
" 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 " Private Functions {{{1
function! s:Sum(list) "{{{2 function! s:Sum(list) "{{{2
let result = 0.0 let result = 0.0
@@ -37,99 +17,54 @@ function! s:Average(list) "{{{2
return s:Sum(a:list)/len(a:list) return s:Sum(a:list)/len(a:list)
endfunction 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 " Public Functions {{{1
function! tablemode#spreadsheet#sid() "{{{2
return maparg('<sid>', 'n')
endfunction
nnoremap <sid> <sid>
function! tablemode#spreadsheet#scope() "{{{2
return s:
endfunction
function! tablemode#spreadsheet#GetFirstRow(line) "{{{2 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) let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line - 1) || tablemode#table#IsATableHeader(line - 1) while !tablemode#table#IsHeader(line - 1) && (tablemode#table#IsRow(line - 1) || tablemode#table#IsBorder(line - 1))
let line -= 1 let line -= 1
endwhile endwhile
if tablemode#table#IsATableHeader(line) | let line += 1 | endif if tablemode#table#IsBorder(line) | let line += 1 | endif
return line return line
endif endif
endfunction endfunction
function! tablemode#spreadsheet#MoveToFirstRow() "{{{2 function! tablemode#spreadsheet#MoveToFirstRow() "{{{2
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow('.')
call cursor(tablemode#spreadsheet#GetFirstRow('.'), col('.')) call cursor(tablemode#spreadsheet#GetFirstRow('.'), col('.'))
endif endif
endfunction endfunction
function! tablemode#spreadsheet#GetLastRow(line) "{{{2 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) 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#IsBorder(line + 1)
let line += 1 let line += 1
endwhile endwhile
if tablemode#table#IsATableHeader(line) | let line -= 1 | endif if tablemode#table#IsBorder(line) | let line -= 1 | endif
return line return line
endif endif
endfunction endfunction
function! tablemode#spreadsheet#MoveToLastRow() "{{{2 function! tablemode#spreadsheet#MoveToLastRow() "{{{2
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow('.')
call cursor(tablemode#spreadsheet#GetLastRow('.'), col('.')) call cursor(tablemode#spreadsheet#GetLastRow('.'), col('.'))
endif endif
endfunction endfunction
function! tablemode#spreadsheet#LineNr(row) "{{{2 function! tablemode#spreadsheet#LineNr(line, row) "{{{2
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow(a:line)
let line = tablemode#spreadsheet#GetFirstRow('.') let line = tablemode#spreadsheet#GetFirstRow(a:line)
let row_nr = 0 let row_nr = 0
while tablemode#table#IsATableRow(line + 1) || tablemode#table#IsATableHeader(line + 1) while tablemode#table#IsRow(line + 1) || tablemode#table#IsBorder(line + 1)
if tablemode#table#IsATableRow(line) if tablemode#table#IsRow(line)
let row_nr += 1 let row_nr += 1
if row ==# row_nr | break | endif if a:row ==# row_nr | break | endif
endif endif
let line += 1 let line += 1
endwhile endwhile
@@ -142,8 +77,8 @@ function! tablemode#spreadsheet#RowNr(line) "{{{2
let line = tablemode#utils#line(a:line) let line = tablemode#utils#line(a:line)
let rowNr = 0 let rowNr = 0
while tablemode#table#IsATableRow(line) || tablemode#table#IsATableHeader(line) while !tablemode#table#IsHeader(line) && (tablemode#table#IsRow(line) || tablemode#table#IsBorder(line))
if tablemode#table#IsATableRow(line) | let rowNr += 1 | endif if tablemode#table#IsRow(line) | let rowNr += 1 | endif
let line -= 1 let line -= 1
endwhile endwhile
@@ -154,14 +89,14 @@ function! tablemode#spreadsheet#RowCount(line) "{{{2
let line = tablemode#utils#line(a:line) let line = tablemode#utils#line(a:line)
let [tline, totalRowCount] = [line, 0] let [tline, totalRowCount] = [line, 0]
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline) while !tablemode#table#IsHeader(tline) && (tablemode#table#IsRow(tline) || tablemode#table#IsBorder(tline))
if tablemode#table#IsATableRow(tline) | let totalRowCount += 1 | endif if tablemode#table#IsRow(tline) | let totalRowCount += 1 | endif
let tline -= 1 let tline -= 1
endwhile endwhile
let tline = line + 1 let tline = line + 1
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline) while !tablemode#table#IsHeader(tline) && (tablemode#table#IsRow(tline) || tablemode#table#IsBorder(tline))
if tablemode#table#IsATableRow(tline) | let totalRowCount += 1 | endif if tablemode#table#IsRow(tline) | let totalRowCount += 1 | endif
let tline += 1 let tline += 1
endwhile endwhile
@@ -203,143 +138,8 @@ function! tablemode#spreadsheet#MoveToStartOfCell() "{{{2
endif endif
endfunction endfunction
function! tablemode#spreadsheet#GetLastRow(line) "{{{2
if tablemode#table#IsATableRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line + 1) || tablemode#table#IsATableHeader(line + 1)
let line += 1
endwhile
if tablemode#table#IsATableHeader(line) | let line -= 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#GetFirstRow(line) "{{{2
if tablemode#table#IsATableRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsATableRow(line - 1) || tablemode#table#IsATableHeader(line - 1)
let line -= 1
endwhile
if tablemode#table#IsATableHeader(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 function! tablemode#spreadsheet#DeleteColumn() "{{{2
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow('.')
for i in range(v:count1) for i in range(v:count1)
call tablemode#spreadsheet#MoveToStartOfCell() call tablemode#spreadsheet#MoveToStartOfCell()
call tablemode#spreadsheet#MoveToFirstRow() call tablemode#spreadsheet#MoveToFirstRow()
@@ -348,201 +148,42 @@ function! tablemode#spreadsheet#DeleteColumn() "{{{2
normal! d normal! d
endfor endfor
call tablemode#table#TableRealign('.') call tablemode#table#Realign('.')
endif endif
endfunction endfunction
function! tablemode#spreadsheet#DeleteRow() "{{{2 function! tablemode#spreadsheet#DeleteRow() "{{{2
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow('.')
for i in range(v:count1) for i in range(v:count1)
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow('.')
normal! dd normal! dd
endif endif
if !tablemode#table#IsATableRow('.') if !tablemode#table#IsRow('.')
normal! k normal! k
endif endif
endfor endfor
call tablemode#table#TableRealign('.') call tablemode#table#Realign('.')
endif endif
endfunction 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 function! tablemode#spreadsheet#Sum(range, ...) abort "{{{2
let args = copy(a:000) let args = copy(a:000)
call insert(args, a:range) call insert(args, a:range)
return s:Sum(call('tablemode#spreadsheet#GetCellRange', args)) return s:Sum(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction endfunction
function! tablemode#spreadsheet#Average(range, ...) abort "{{{2 function! tablemode#spreadsheet#Average(range, ...) abort "{{{2
let args = copy(a:000) let args = copy(a:000)
call insert(args, a:range) call insert(args, a:range)
return s:Average(call('tablemode#spreadsheet#GetCellRange', args)) return s:Average(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction endfunction
function! tablemode#spreadsheet#AddFormula() "{{{2 function! tablemode#spreadsheet#Sort(bang, ...) "{{{2
let fr = input('f=') let opts = a:0 ? a:1 : ''
let row = tablemode#spreadsheet#RowNr('.') let bang = a:bang ? '!' : ''
let colm = tablemode#spreadsheet#ColumnNr('.') let [firstRow, lastRow] = [tablemode#spreadsheet#GetFirstRow('.'), tablemode#spreadsheet#GetLastRow('.')]
let indent = indent('.') call tablemode#spreadsheet#MoveToStartOfCell()
let indent_str = repeat(' ', indent) exec ':'.firstRow.','.lastRow . 'sort'.bang opts '/.*\%'.col('.').'v/'
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 endfunction

View File

@@ -0,0 +1,258 @@
" 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#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#IsBorder(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#IsBorder(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 ? a:1 : '.'
return tablemode#spreadsheet#cell#GetCells(line, a:row)
endfunction
function! tablemode#spreadsheet#cell#GetRowColumn(col, ...) abort "{{{2
let line = a:0 ? 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 ? a:1 : '.'
return tablemode#spreadsheet#cell#GetCells(line, 0, a:col)
endfunction
function! tablemode#spreadsheet#cell#GetColumnRow(row, ...) abort "{{{2
let line = a:0 ? a:1 : '.'
let col = tablemode#spreadsheet#ColumnNr('.')
return tablemode#spreadsheet#cell#GetCells(line, a:row, col)
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#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#spreadsheet#LineNr(line, row)
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#IsBorder(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#IsBorder(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#IsBorder(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#IsBorder(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,119 @@
" Private Functions {{{1
" Public Functions {{{1
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#IsBorder(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#IsBorder(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#IsBorder(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

@@ -1,34 +1,14 @@
" ============================== Header ======================================
" File: autoload/tablemode/table.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
" Version: 4.1.0
" 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 " Private Functions {{{1
function! s:HeaderBorderExpr() "{{{2 function! s:BorderExpr() "{{{2
return tablemode#table#StartExpr() . return tablemode#table#StartExpr() .
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' . \ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
\ '[' . g:table_mode_fillchar . g:table_mode_corner . ']*' . \ '[' . escape(g:table_mode_fillchar . g:table_mode_header_fillchar . g:table_mode_corner . g:table_mode_align_char, '-') . ']\+' .
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' . \ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
\ tablemode#table#EndExpr() \ tablemode#table#EndExpr()
endfunction endfunction
function! s:DefaultHeaderBorder() "{{{2 function! s:DefaultBorder() "{{{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 return g:table_mode_corner_corner . g:table_mode_fillchar . g:table_mode_corner . g:table_mode_fillchar . g:table_mode_corner_corner
else else
return '' return ''
@@ -37,19 +17,44 @@ endfunction
function! s:GenerateHeaderBorder(line) "{{{2 function! s:GenerateHeaderBorder(line) "{{{2
let line = tablemode#utils#line(a:line) 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 = '' let line_val = ''
if tablemode#table#IsATableRow(line + 1) if tablemode#table#IsRow(line + 1)
let line_val = getline(line + 1) let line_val = getline(line + 1)
endif 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) let line_val = getline(line - 1)
endif endif
if tablemode#utils#strlen(line_val) <= 1 | return s:DefaultHeaderBorder() | endif if tablemode#utils#strlen(line_val) <= 1 | return s:DefaultBorder() | 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(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') " To accurately deal with unicode double width characters
if tablemode#table#IsHeader(line - 1)
let fill_columns = map(split(border, g:table_mode_corner), 'repeat(g:table_mode_header_fillchar, tablemode#utils#StrDisplayWidth(v:val))')
else
let fill_columns = map(split(border, g:table_mode_corner), 'repeat(g:table_mode_fillchar, tablemode#utils#StrDisplayWidth(v:val))')
endif
let border = g:table_mode_corner . join(fill_columns, g:table_mode_corner) . g:table_mode_corner
let border = substitute(border, '^' . g:table_mode_corner . '\(.*\)' . g:table_mode_corner . '$', g:table_mode_corner_corner . '\1' . g:table_mode_corner_corner, '') 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() let cstartexpr = tablemode#table#StartCommentExpr()
if tablemode#utils#strlen(cstartexpr) > 0 && getline(line) =~# cstartexpr if tablemode#utils#strlen(cstartexpr) > 0 && getline(line) =~# cstartexpr
let sce = matchstr(line_val, tablemode#table#StartCommentExpr()) let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
@@ -62,18 +67,18 @@ function! s:GenerateHeaderBorder(line) "{{{2
return border return border
endif endif
else else
return s:DefaultHeaderBorder() return s:DefaultBorder()
endif endif
endfunction endfunction
" Public Functions {{{1 " Public Functions {{{1
function! tablemode#table#sid() "{{{2 function! tablemode#table#GetCommentStart() "{{{2
return maparg('<sid>', 'n') let cstring = &commentstring
endfunction if tablemode#utils#strlen(cstring) > 0
nnoremap <sid> <sid> return substitute(split(cstring, '%s')[0], '.', '\\\0', 'g')
else
function! tablemode#table#scope() "{{{2 return ''
return s: endif
endfunction endfunction
function! tablemode#table#StartCommentExpr() "{{{2 function! tablemode#table#StartCommentExpr() "{{{2
@@ -85,24 +90,6 @@ function! tablemode#table#StartCommentExpr() "{{{2
endif endif
endfunction endfunction
function! tablemode#table#EndCommentExpr() "{{{2
let cendexpr = tablemode#table#GetCommentEnd()
if tablemode#utils#strlen(cendexpr) > 0
return '.*\zs\s\+' . cendexpr . '\s*$'
else
return ''
endif
endfunction
function! tablemode#table#GetCommentStart() "{{{2
let cstring = &commentstring
if tablemode#utils#strlen(cstring) > 0
return substitute(split(cstring, '%s')[0], '.', '\\\0', 'g')
else
return ''
endif
endfunction
function! tablemode#table#GetCommentEnd() "{{{2 function! tablemode#table#GetCommentEnd() "{{{2
let cstring = &commentstring let cstring = &commentstring
if tablemode#utils#strlen(cstring) > 0 if tablemode#utils#strlen(cstring) > 0
@@ -117,6 +104,15 @@ function! tablemode#table#GetCommentEnd() "{{{2
endif endif
endfunction endfunction
function! tablemode#table#EndCommentExpr() "{{{2
let cendexpr = tablemode#table#GetCommentEnd()
if tablemode#utils#strlen(cendexpr) > 0
return '.*\zs\s\+' . cendexpr . '\s*$'
else
return ''
endif
endfunction
function! tablemode#table#StartExpr() "{{{2 function! tablemode#table#StartExpr() "{{{2
let cstart = tablemode#table#GetCommentStart() let cstart = tablemode#table#GetCommentStart()
if tablemode#utils#strlen(cstart) > 0 if tablemode#utils#strlen(cstart) > 0
@@ -135,109 +131,61 @@ function! tablemode#table#EndExpr() "{{{2
endif endif
endfunction endfunction
function! tablemode#table#IsATableRow(line) "{{{2 function! tablemode#table#IsBorder(line) "{{{2
return getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator . '[^' . return !empty(getline(a:line)) && getline(a:line) =~# s:BorderExpr()
\ g:table_mode_fillchar . ']*[^' . g:table_mode_corner . ']*$')
endfunction endfunction
function! tablemode#table#IsATableHeader(line) "{{{2 function! tablemode#table#IsHeader(line) "{{{2
return getline(a:line) =~# s:HeaderBorderExpr() let line = tablemode#utils#line(a:line)
" if line <= 0 || line > line('$') | return 0 | endif
return tablemode#table#IsRow(line)
\ && !tablemode#table#IsRow(line-1)
\ && !tablemode#table#IsRow(line-2)
\ && !tablemode#table#IsBorder(line-2)
\ && tablemode#table#IsBorder(line+1)
endfunction endfunction
function! tablemode#table#AddHeaderBorder(line) "{{{2 function! tablemode#table#IsRow(line) "{{{2
return !tablemode#table#IsBorder(a:line) && getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator)
endfunction
function! tablemode#table#AddBorder(line) "{{{2
call setline(a:line, s:GenerateHeaderBorder(a:line)) call setline(a:line, s:GenerateHeaderBorder(a:line))
endfunction endfunction
function! tablemode#table#TableRealign(line) "{{{2 function! tablemode#table#Realign(line) "{{{2
let line = tablemode#utils#line(a:line) let line = tablemode#utils#line(a:line)
let [lnums, lines] = [[], []] let lines = []
let [tline, blines] = [line, []] let [lnum, blines] = [line, []]
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline) while tablemode#table#IsRow(lnum) || tablemode#table#IsBorder(lnum)
if tablemode#table#IsATableHeader(tline) if tablemode#table#IsBorder(lnum)
call insert(blines, tline) call insert(blines, lnum)
let tline -= 1 let lnum -= 1
continue continue
endif endif
call insert(lnums, tline) call insert(lines, {'lnum': lnum, 'text': getline(lnum)})
call insert(lines, getline(tline)) let lnum -= 1
let tline -= 1
endwhile endwhile
let tline = line + 1 let lnum = line + 1
while tablemode#table#IsRow(lnum) || tablemode#table#IsBorder(lnum)
while tablemode#table#IsATableRow(tline) || tablemode#table#IsATableHeader(tline) if tablemode#table#IsBorder(lnum)
if tablemode#table#IsATableHeader(tline) call add(blines, lnum)
call insert(blines, tline) let lnum += 1
let tline += 1
continue continue
endif endif
call add(lnums, tline) call add(lines, {'lnum': lnum, 'text': getline(lnum)})
call add(lines, getline(tline)) let lnum += 1
let tline += 1
endwhile endwhile
let lines = tablemode#align#Align(lines) let lines = tablemode#align#Align(lines)
for lnum in lnums for aline in lines
let index = index(lnums, lnum) call setline(aline.lnum, aline.text)
call setline(lnum, lines[index])
endfor endfor
for bline in blines for bline in blines
call tablemode#table#AddHeaderBorder(bline) call tablemode#table#AddBorder(bline)
endfor endfor
endfunction 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

@@ -1,35 +1,6 @@
" ============================== Header ======================================
" File: autoload/tablemode/utils.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
" Version: 4.1.0
" 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 " Private Functions {{{1
" Public Functions {{{1 " Public Functions {{{1
function! tablemode#utils#sid() "{{{2
return maparg('<sid>', 'n')
endfunction
nnoremap <sid> <sid>
function! tablemode#utils#scope() "{{{2
return s:
endfunction
function! tablemode#utils#throw(string) abort "{{{2 function! tablemode#utils#throw(string) abort "{{{2
let v:errmsg = 'table-mode: ' . a:string let v:errmsg = 'table-mode: ' . a:string
throw v:errmsg throw v:errmsg
@@ -52,3 +23,27 @@ endfunction
function! tablemode#utils#strlen(text) function! tablemode#utils#strlen(text)
return strlen(substitute(a:text, '.', 'x', 'g')) return strlen(substitute(a:text, '.', 'x', 'g'))
endfunction endfunction
function! tablemode#utils#StrDisplayWidth(string) "{{{2
if exists('*strdisplaywidth')
return strdisplaywidth(a:string)
else
" Implement the tab handling part of strdisplaywidth for vim 7.2 and
" earlier - not much that can be done about handling doublewidth
" characters.
let rv = 0
let i = 0
for char in split(a:string, '\zs')
if char == "\t"
let rv += &ts - i
let i = 0
else
let rv += 1
let i = (i + 1) % &ts
endif
endfor
return rv
endif
endfunction

View File

@@ -1,7 +1,7 @@
*table-mode.txt* Table Mode for easy table formatting. v4.1.0 *table-mode.txt* Table Mode for easy table formatting
=============================================================================== ===============================================================================
Table Mode, THE AWESOME AUTOMATIC TABLE CREATOR & FORMATTER Table Mode, THE AWESOME AUTOMATIC TABLE CREATOR & FORMATTER
VERSION 4.1.0 VERSION 4.6.3
Author: Dhruva Sagar <http://dhruvasagar.com/> Author: Dhruva Sagar <http://dhruvasagar.com/>
License: MIT <http://opensource.org/licenses/MIT/> License: MIT <http://opensource.org/licenses/MIT/>
@@ -20,7 +20,7 @@ CONTENTS *table-mode-contents*
INTRODUCTION *table-mode-introduction* INTRODUCTION *table-mode-introduction*
Table Mode is simple plugin that makes building tables in vim a breeze. It is Table Mode is simple plugin that makes building tables in vim a breeze. It is
inspired from tpope's auto aligning script for creating tables in vim - inspired from tpope's auto aligning script for creating tables in vim -
https://gist.github.com/tpope/287147, which in turn utilizes the Tabular https://gist.github.com/tpope/287147, which in turn utilizes the Tabular
Plugin. Plugin.
@@ -34,6 +34,11 @@ Create Table on the fly:
each additional separator you add, it aligns the table properly, each additional separator you add, it aligns the table properly,
without having to do anything else. 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 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-toggle-map| or you can also enable it permanently
using |table-mode-always-active| if you wish though not recommended. using |table-mode-always-active| if you wish though not recommended.
@@ -52,7 +57,7 @@ Move between cells :
You can use |table-mode-map-prefix| option to define the prefix You can use |table-mode-map-prefix| option to define the prefix
mapping to be used before 'hjkl'. The left | right motions wrap around 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 the table and move to the next | previous row after the last | first
cell in the current row if one exists. cell in the current row if one exists.
Manipulation of tables: Manipulation of tables:
Tableize provides 3 easy ways to quickly manipulate tables. Tableize provides 3 easy ways to quickly manipulate tables.
@@ -99,11 +104,14 @@ Formula Expressions :
'$n': This matches the table column number 'n'. So the formula '$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 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 '$n,m': This matches the table cell n,m (row, column). So in
this case the formula would be evaluated and the result will 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 The formula can be a simple mathematical expression involving cells
which are also defined by the same format as that of the target cell. which are also defined by the same format as that of the target cell.
@@ -111,7 +119,7 @@ Formula Expressions :
special functions 'Sum' and 'Average'. Both these functions take a special functions 'Sum' and 'Average'. Both these functions take a
range as input. A range can be of two forms : range as input. A range can be of two forms :
'n,m': This represents cells in the current column from row 'n:m': This represents cells in the current column from row
'n' through 'm'. If 'm' is negative it represents 'm' row 'n' through 'm'. If 'm' is negative it represents 'm' row
above the current row (of the target cell). above the current row (of the target cell).
@@ -139,6 +147,27 @@ Overview:
|table-mode-delimiter| .......... Set the delimiter for Tableize. |table-mode-delimiter| .......... Set the delimiter for Tableize.
|table-mode-corner-corner| ...... Set the character to be used for |table-mode-corner-corner| ...... Set the character to be used for
extreme corners of the table border. 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.
|table-mode-motion-up-map| ...... Set the table motion up mapping
|table-mode-motion-down-map| .... Set the table motion down mapping
|table-mode-motion-left-map| .... Set the table motion left mapping
|table-mode-motion-right-map| ... Set the table motion right mapping
|table-mode-cell-text-object-a-map|
Set the 'a' cell text object
mapping
|table-mode-cell-text-object-i-map|
Set the 'i' cell text object
mapping
|table-mode-realign-map| ........ Set the realign mapping
|table-mode-delete-row-map| ..... Set the delete row mapping
|table-mode-delete-column-map| .. Set the delete column mapping
|table-mode-add-formula-map| .... Set the add formula mapping
|table-mode-eval-formula-map| ... Set the eval formula mapping
|table-mode-echo-cell-map| ...... Set the echo cell mapping
|table-mode-sort-map| ........... Set the table sort mapping
g:loaded_table_mode *table-mode-loaded* g:loaded_table_mode *table-mode-loaded*
Use this option to disable the plugin: > Use this option to disable the plugin: >
@@ -196,6 +225,72 @@ g:table_mode_corner_corner *table-mode-corner-corner*
corners of the table border. > corners of the table border. >
let g:table_mode_corner_corner = '|' 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 = ':'
<
g:table_mode_disable_mappings *table-mode-disable-mappings*
Set this to true to disable all mappings. >
let g:table_mode_disable_mappings = 1
<
g:table_mode_motion_up_map *table-mode-motion-up-map*
Set this to configure the mapping to move up a cell vertically. >
let g:table_mode_motion_up_map = '{<Bar>'
<
g:table_mode_motion_down_map *table-mode-motion-down-map*
Set this to configure the mapping to move down a cell vertically. >
let g:table_mode_motion_down_map = '}<Bar>'
>
g:table_mode_motion_left_map *table-mode-motion-left-map*
Set this to configure the mapping to move to the left cell. >
let g:table_mode_motion_left_map = '[<Bar>'
>
g:table_mode_motion_right_map *table-mode-motion-right-map*
Set this to configure the mapping to move to the right cell. >
let g:table_mode_motion_right_map = ']<Bar>'
>
g:table_mode_cell_text_object_a_map *table-mode-cell-text-object-a-map*
Set this to configure the mapping to define the text object for around
cell object. >
let g:table_mode_cell_text_object_a_map = 'a<Bar>'
>
g:table_mode_cell_text_object_i_map *table-mode-cell-text-object-i-map*
Set this to configure the mapping to define the text object for inner
cell object. >
let g:table_mode_cell_text_object_i_map = 'i<Bar>'
>
g:table_mode_realign_map *table-mode-realign-map*
Set this to configure the mapping for table realign. >
let g:table_mode_realign_map = '<Leader>tr'
>
g:table_mode_delete_row_map *table-mode-delete-row-map*
Set this to configure the mapping for deleting a table row. >
let g:table_mode_delete_row_map = '<Leader>tdd'
>
g:table_mode_delete_column_map *table-mode-delete-column-map*
Set this to configure the mapping for deleting a table column. >
let g:table_mode_delete_column_map = '<Leader>tdc'
>
g:table_mode_add_formula_map *table-mode-add-formula-map*
Set this to configure the mapping for adding a formula for a table
cell. >
let g:table_mode_add_formula_map = '<Leader>tfa'
>
g:table_mode_eval_formula_map *table-mode-eval-formula-map*
Set this to configure the mapping for evaluating the formula line. >
let g:table_mode_eval_formula_map = '<Leader>tfe'
>
g:table_mode_echo_cell_map *table-mode-echo-cell-map*
Set this to configure the mapping for echoing the tablemode
representation of the current cell. >
let g:table_mode_echo_cell_map = '<Leader>t?'
>
g:table_mode_sort_map *table-mode-sort-map*
Set this to configure the mapping for sorting the table mode by
current column. >
let g:table_mode_sort_map = '<Leader>ts'
>
=============================================================================== ===============================================================================
MAPPINGS *table-mode-mappings* MAPPINGS *table-mode-mappings*
@@ -207,7 +302,7 @@ MAPPINGS *table-mode-mappings*
*table-mode-mappings-toggle* *table-mode-mappings-toggle*
<Leader>tm Toggle table mode for the current buffer. You can change this <Leader>tm Toggle table mode for the current buffer. You can change this
using the |toggle-mode-options-toggle-map| option. using the |toggle-mode-options-toggle-map| option.
NOTE This is applicable only if |table-mode-always-active| is NOTE This is applicable only if |table-mode-always-active| is
not set. not set.
@@ -255,7 +350,7 @@ MAPPINGS *table-mode-mappings*
accordingly. This invokes the |TableEvalFormulaLine| command. accordingly. This invokes the |TableEvalFormulaLine| command.
|| Expands to a header border. You can change this by changing || Expands to a header border. You can change this by changing
|table-mode-separator| option. You can change the character to |table-mode-separator| option. You can change the character to
be used for te extreme corners of the border by changing be used for te extreme corners of the border by changing
|table-mode-corner-corner| option. |table-mode-corner-corner| option.
@@ -281,7 +376,7 @@ COMMANDS *table-mode-commands*
*:TableModeDisable* *:TableModeDisable*
*table-mode-:TableModeDisable* *table-mode-:TableModeDisable*
:TableModeDisable :TableModeDisable
Disables Table Mode. Disables Table Mode.
NOTE this is applicable only if |table-mode-always-active| is NOTE this is applicable only if |table-mode-always-active| is
not set. not set.

View File

@@ -1,23 +1,3 @@
" =============================================================================
" File: plugin/table-mode.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: 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.
"
" 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.
" =============================================================================
" Finish if already loaded {{{1 " Finish if already loaded {{{1
if exists('g:loaded_table_mode') if exists('g:loaded_table_mode')
finish finish
@@ -36,27 +16,53 @@ endfunction
" Set Global Defaults {{{1 " Set Global Defaults {{{1
call s:SetGlobalOptDefault('table_mode_corner', '+') call s:SetGlobalOptDefault('table_mode_corner', '+')
call s:SetGlobalOptDefault('table_mode_verbose', 0)
call s:SetGlobalOptDefault('table_mode_separator', '|') call s:SetGlobalOptDefault('table_mode_separator', '|')
call s:SetGlobalOptDefault('table_mode_fillchar', '-') call s:SetGlobalOptDefault('table_mode_fillchar', '-')
call s:SetGlobalOptDefault('table_mode_header_fillchar', '-')
call s:SetGlobalOptDefault('table_mode_map_prefix', '<Leader>t') call s:SetGlobalOptDefault('table_mode_map_prefix', '<Leader>t')
call s:SetGlobalOptDefault('table_mode_toggle_map', 'm') call s:SetGlobalOptDefault('table_mode_toggle_map', 'm')
call s:SetGlobalOptDefault('table_mode_always_active', 0) call s:SetGlobalOptDefault('table_mode_always_active', 0)
call s:SetGlobalOptDefault('table_mode_delimiter', ',') call s:SetGlobalOptDefault('table_mode_delimiter', ',')
call s:SetGlobalOptDefault('table_mode_corner_corner', '|') call s:SetGlobalOptDefault('table_mode_corner_corner', '|')
call s:SetGlobalOptDefault('table_mode_align_char', ':')
call s:SetGlobalOptDefault('table_mode_disable_mappings', 0)
call s:SetGlobalOptDefault('table_mode_motion_up_map', '{<Bar>')
call s:SetGlobalOptDefault('table_mode_motion_down_map', '}<Bar>')
call s:SetGlobalOptDefault('table_mode_motion_left_map', '[<Bar>')
call s:SetGlobalOptDefault('table_mode_motion_right_map', ']<Bar>')
call s:SetGlobalOptDefault('table_mode_cell_text_object_a_map', 'a<Bar>')
call s:SetGlobalOptDefault('table_mode_cell_text_object_i_map', 'i<Bar>')
call s:SetGlobalOptDefault('table_mode_realign_map', '<Leader>tr')
call s:SetGlobalOptDefault('table_mode_delete_row_map', '<Leader>tdd')
call s:SetGlobalOptDefault('table_mode_delete_column_map', '<Leader>tdc')
call s:SetGlobalOptDefault('table_mode_add_formula_map', '<Leader>tfa')
call s:SetGlobalOptDefault('table_mode_eval_formula_map', '<Leader>tfe')
call s:SetGlobalOptDefault('table_mode_echo_cell_map', '<Leader>t?')
call s:SetGlobalOptDefault('table_mode_sort_map', '<Leader>ts')
function! s:TableEchoCell() "{{{1 function! s:TableEchoCell() "{{{1
if tablemode#table#IsATableRow('.') if tablemode#table#IsRow('.')
echomsg '$' . tablemode#spreadsheet#RowNr('.') . ',' . tablemode#spreadsheet#ColumnNr('.') echomsg '$' . tablemode#spreadsheet#RowNr('.') . ',' . tablemode#spreadsheet#ColumnNr('.')
endif endif
endfunction endfunction
augroup TableMode
au!
autocmd Syntax * if tablemode#IsActive() | call tablemode#SyntaxEnable() | endif
augroup END
" Define Commands & Mappings {{{1 " Define Commands & Mappings {{{1
if !g:table_mode_always_active "{{{2 if !g:table_mode_always_active "{{{2
exec "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_toggle_map . exec "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_toggle_map .
\ " <Esc>:call tablemode#TableModeToggle()<CR>" \ " <Esc>:call tablemode#Toggle()<CR>"
command! -nargs=0 TableModeToggle call tablemode#TableModeToggle() command! -nargs=0 TableModeToggle call tablemode#Toggle()
command! -nargs=0 TableModeEnable call tablemode#TableModeEnable() command! -nargs=0 TableModeEnable call tablemode#Enable()
command! -nargs=0 TableModeDisable call tablemode#TableModeDisable() command! -nargs=0 TableModeDisable call tablemode#Disable()
else else
let table_mode_separator_map = g:table_mode_separator let table_mode_separator_map = g:table_mode_separator
" '|' is a special character, we need to map <Bar> instead " '|' is a special character, we need to map <Bar> instead
@@ -68,84 +74,57 @@ else
endif endif
" }}}2 " }}}2
command! -nargs=? -range Tableize <line1>,<line2>call tablemode#table#TableizeRange(<q-args>) command! -nargs=? -range Tableize <line1>,<line2>call tablemode#TableizeRange(<q-args>)
command! TableAddFormula call tablemode#spreadsheet#AddFormula() command! -nargs=? -bang TableSort call tablemode#spreadsheet#Sort(<bang>0, <q-args>)
command! TableModeRealign call tablemode#spreadsheet#TableRealign('.') command! TableAddFormula call tablemode#spreadsheet#formula#Add()
command! TableEvalFormulaLine call tablemode#spreadsheet#EvaluateFormulaLine() command! TableModeRealign call tablemode#table#Realign('.')
command! TableEvalFormulaLine call tablemode#spreadsheet#formula#EvaluateFormulaLine()
" '|' is a special character, we need to map <Bar> instead
if g:table_mode_separator ==# '|' | let separator_map = '<Bar>' | endif
execute 'inoremap <silent> <Plug>(table-mode-tableize)' separator_map . '<Esc>:call tablemode#TableizeInsertMode()<CR>a'
nnoremap <silent> <Plug>(table-mode-tableize) :Tableize<CR> nnoremap <silent> <Plug>(table-mode-tableize) :Tableize<CR>
xnoremap <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> 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-up) :<C-U>call tablemode#spreadsheet#cell#Motion('k')<CR>
nnoremap <silent> <Plug>(table-mode-motion-down) :<C-U>call tablemode#table#TableMotion('j')<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#table#TableMotion('h')<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#table#TableMotion('l')<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#spreadsheet#CellTextObject(0)<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#CellTextObject(1)<CR> onoremap <silent> <Plug>(table-mode-cell-text-object-i) :<C-U>call tablemode#spreadsheet#cell#TextObject(1)<CR>
xnoremap <silent> <Plug>(table-mode-cell-text-object-a) :<C-U>call tablemode#spreadsheet#cell#TextObject(0)<CR>
xnoremap <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#spreadsheet#DeleteRow()<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-delete-column) :call tablemode#spreadsheet#DeleteColumn()<CR>
nnoremap <silent> <Plug>(table-mode-add-formula) :call tablemode#spreadsheet#AddFormula()<CR> nnoremap <silent> <Plug>(table-mode-add-formula) :call tablemode#spreadsheet#formula#Add()<CR>
nnoremap <silent> <Plug>(table-mode-eval-formula) :call tablemode#spreadsheet#EvaluateFormulaLine()<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> nnoremap <silent> <Plug>(table-mode-echo-cell) :call <SID>TableEchoCell()<CR>
nnoremap <silent> <Plug>(table-mode-sort) :call tablemode#spreadsheet#Sort()<CR>
if !hasmapto('<Plug>(table-mode-tableize)') if !hasmapto('<Plug>(table-mode-tableize)')
nmap <Leader>tt <Plug>(table-mode-tableize) exec "nmap " . g:table_mode_map_prefix . "t <Plug>(table-mode-tableize)"
xmap <Leader>tt <Plug>(table-mode-tableize) exec "xmap " . g:table_mode_map_prefix . "t <Plug>(table-mode-tableize)"
endif endif
if !hasmapto('<Plug>(table-mode-tableize-delimiter)') if !hasmapto('<Plug>(table-mode-tableize-delimiter)')
xmap <Leader>T <Plug>(table-mode-tableize-delimiter) xmap <Leader>T <Plug>(table-mode-tableize-delimiter)
endif endif
if !hasmapto('<Plug>(table-mode-realign)') augroup TableMode "{{{1
nmap <Leader>tr <Plug>(table-mode-realign) au!
endif
if !hasmapto('<Plug>(table-mode-motion-up)')
nmap {<Bar> <Plug>(table-mode-motion-up)
endif
if !hasmapto('<Plug>(table-mode-motion-down)')
nmap }<Bar> <Plug>(table-mode-motion-down)
endif
if !hasmapto('<Plug>(table-mode-motion-left)')
nmap [<Bar> <Plug>(table-mode-motion-left)
endif
if !hasmapto('<Plug>(table-mode-motion-right)')
nmap ]<Bar> <Plug>(table-mode-motion-right)
endif
if !hasmapto('<Plug>(table-mode-cell-text-object-a)')
omap a<Bar> <Plug>(table-mode-cell-text-object-a)
endif
if !hasmapto('<Plug>(table-mode-cell-text-object-i)')
omap i<Bar> <Plug>(table-mode-cell-text-object-i)
endif
if !hasmapto('<Plug>(table-mode-delete-row)')
nmap <Leader>tdd <Plug>(table-mode-delete-row)
endif
if !hasmapto('<Plug>(table-mode-delete-column)')
nmap <Leader>tdc <Plug>(table-mode-delete-column)
endif
if !hasmapto('<Plug>(table-mode-add-formula)')
nmap <Leader>tfa <Plug>(table-mode-add-formula)
endif
if !hasmapto('<Plug>(table-mode-eval-formula)')
nmap <Leader>tfe <Plug>(table-mode-eval-formula)
endif
if !hasmapto('<Plug>(table-mode-echo-cell)')
nmap <Leader>t? <Plug>(table-mode-echo-cell)
endif
autocmd User TableModeEnabled call tablemode#logger#log('Table Mode Enabled')
autocmd User TableModeDisabled call tablemode#logger#log('Table Mode Disabled')
augroup END
" Avoiding side effects {{{1 " Avoiding side effects {{{1
let &cpo = s:save_cpo let &cpo = s:save_cpo

View File

@@ -1,14 +1,20 @@
" vim: fdm=indent " 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' describe 'Align'
it 'should align table content correctly' it 'should align table content correctly'
Expect tablemode#align#Align(readfile('t/fixtures/align/simple_before.txt')) == readfile('t/fixtures/align/simple_after.txt') Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/simple_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/simple_after.txt'))
end end
it 'should align table content with unicode characters correctly' it 'should align table content with unicode characters correctly'
Expect tablemode#align#Align(readfile('t/fixtures/align/unicode_before.txt')) == readfile('t/fixtures/align/unicode_after.txt') Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/unicode_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/unicode_after.txt'))
end end
end end

135
t/cell.vim Normal file
View File

@@ -0,0 +1,135 @@
" vim: fdm=indent
source t/config/options.vim
describe 'cell'
describe 'API'
before
new
read t/fixtures/sample.txt
end
it 'should return the cells with GetCells'
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 row with GetRow'
Expect tablemode#spreadsheet#cell#GetRow(1, 2) == ['test11', 'test12']
Expect tablemode#spreadsheet#cell#GetRow(2, 2) == ['test21', 'test22']
end
it 'should return the column with GetColumn'
Expect tablemode#spreadsheet#cell#GetColumn(1, 2) == ['test11', 'test21']
Expect tablemode#spreadsheet#cell#GetColumn(2, 2) == ['test12', 'test22']
end
it 'should return the cells in a range with GetCellRange'
" 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
read t/fixtures/sample.txt
call cursor(2, 3)
end
it 'should move left when not on first column'
call cursor(2, 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(3, 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(2, 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
read t/fixtures/sample.txt
call cursor(2, 3)
end
it 'should move a row up unless on first row'
call cursor(3, 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
end
end

View File

@@ -1,8 +0,0 @@
let g:table_mode_corner = '+'
let g:table_mode_separator = '|'
let g:table_mode_fillchar = '-'
let g:table_mode_map_prefix = '<Leader>t'
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 = '|'

27
t/config/options.vim Normal file
View File

@@ -0,0 +1,27 @@
let g:table_mode_corner = '+'
let g:table_mode_separator = '|'
let g:table_mode_fillchar = '-'
let g:table_mode_header_fillchar = '-'
let g:table_mode_map_prefix = '<Leader>t'
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 = ':'
let g:table_mode_disable_mappings = 0
let g:table_mode_motion_up_map = '{<Bar>'
let g:table_mode_motion_down_map = '}<Bar>'
let g:table_mode_motion_left_map = '[<Bar>'
let g:table_mode_motion_right_map = ']<Bar>'
let g:table_mode_cell_text_object_a_map = 'a<Bar>'
let g:table_mode_cell_text_object_i_map = 'i<Bar>'
let g:table_mode_realign_map = '<Leader>tr'
let g:table_mode_delete_row_map = '<Leader>tdd'
let g:table_mode_delete_column_map = '<Leader>tdc'
let g:table_mode_add_formula_map = '<Leader>tfa'
let g:table_mode_eval_formula_map = '<Leader>tfe'
let g:table_mode_echo_cell_map = '<Leader>t?'
let g:table_mode_sort_map = '<Leader>ts'

View File

@@ -0,0 +1,2 @@
| 1 | 2 |
| 3 | 4 |

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
| abc | 测试长度 | 长测试 |
| 长 | 测试测试测试测试 | 测试测试 |
| 测试测试 | 测试 | 测试测测试 |
| 测试测试测试 | 测试测试 | 测试 |

View File

@@ -0,0 +1,4 @@
| Title | Message |
|------:+--------:|
| t1 | msg1 |
| t2 | msg2 |

View File

@@ -0,0 +1,4 @@
| Title | Message |
|------:+--------:|
| t1 | msg1 |
| t2 | msg2 |

View File

@@ -0,0 +1,8 @@
|--------------+------------------+------------|
| 测试测试 | 测试长度 | 长测试 |
|--------------+------------------+-----------:|
| abc | 测试长度 | 长测试 |
| 长 | 测试测试测试测试 | 测试测试 |
| 测试测试 | 测试 | 测试测测试 |
| 测试测试测试 | 测试测试 | 测试 |
|--------------+------------------+------------|

View File

@@ -0,0 +1,8 @@
|--------+--------+------|
|测试测试|测试长度|长测试|
|--------+--------+-----:|
|abc|测试长度|长测试|
|长|测试测试测试测试|测试测试|
|测试测试|测试|测试测测试|
|测试测试测试|测试测试|测试|
|------------+--------+----|

View File

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

View File

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

View File

@@ -0,0 +1,4 @@
| abc | 测试长度 | 长测试 |
| 长 | 测试测试测试测试 | 测试测试 |
| 测试测试 | 测试 | 测试测测试 |
| 测试测试测试 | 测试测试 | 测试 |

View File

@@ -0,0 +1,4 @@
|abc|测试长度|长测试|
|长|测试测试测试测试|测试测试|
|测试测试|测试|测试测测试|
|测试测试测试|测试测试|测试|

View File

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

39
t/formula.vim Normal file
View File

@@ -0,0 +1,39 @@
" vim: fdm=indent
source t/config/options.vim
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:3)")
Expect tablemode#spreadsheet#cell#GetCell() == '125.0'
call cursor(8, 15)
Expect getline('.') == '/* tmf: $4,2=Sum(1:3) */'
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: $4,2=Sum(1:3) ; $5,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,7 +1,5 @@
" vim: fdm=indent " vim: fdm=indent
source t/config.vim source t/config/options.vim
call vspec#hint({'scope': 'tablemode#spreadsheet#scope()', 'sid': 'tablemode#spreadsheet#sid()'})
describe 'spreadsheet' describe 'spreadsheet'
describe 'API' describe 'API'
@@ -25,6 +23,27 @@ describe 'spreadsheet'
Expect tablemode#spreadsheet#ColumnCount(3) == 2 Expect tablemode#spreadsheet#ColumnCount(3) == 2
end end
it 'should return the column number'
call cursor(2,3)
Expect tablemode#spreadsheet#ColumnNr('.') == 1
call cursor(2,12)
Expect tablemode#spreadsheet#ColumnNr('.') == 2
end
it 'should return true when in the first cell'
call cursor(2,3)
Expect tablemode#spreadsheet#IsFirstCell() to_be_true
call cursor(2,12)
Expect tablemode#spreadsheet#IsFirstCell() to_be_false
end
it 'should return true when in the last cell'
call cursor(2,3)
Expect tablemode#spreadsheet#IsLastCell() to_be_false
call cursor(2,12)
Expect tablemode#spreadsheet#IsLastCell() to_be_true
end
it 'should return the line number of the first row' it 'should return the line number of the first row'
Expect tablemode#spreadsheet#GetFirstRow(2) == 2 Expect tablemode#spreadsheet#GetFirstRow(2) == 2
Expect tablemode#spreadsheet#GetFirstRow(3) == 2 Expect tablemode#spreadsheet#GetFirstRow(3) == 2
@@ -35,50 +54,40 @@ describe 'spreadsheet'
Expect tablemode#spreadsheet#GetLastRow(3) == 3 Expect tablemode#spreadsheet#GetLastRow(3) == 3
end end
it 'should return the cells' describe 'Math'
Expect tablemode#spreadsheet#GetCells(2, 1, 1) ==# 'test11' before
" Get Rows new
Expect tablemode#spreadsheet#GetCells(2, 1) == ['test11', 'test12'] read t/fixtures/cell/sample.txt
Expect tablemode#spreadsheet#GetCells(2, 2) == ['test21', 'test22'] end
" 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' it 'should return the sum of cell range'
" Entire table as range call cursor(1,3)
Expect tablemode#spreadsheet#GetCellRange('1,1:2,2', 2, 1) == [['test11', 'test21'], ['test12', 'test22']] Expect tablemode#spreadsheet#Sum('1:2') == 4.0
Expect tablemode#spreadsheet#Sum('1,1:1,2') == 3.0
Expect tablemode#spreadsheet#Sum('1,1:2,2') == 10.0
call cursor(2,7)
Expect tablemode#spreadsheet#Sum('1:2') == 6.0
Expect tablemode#spreadsheet#Sum('2,1:2,2') == 7.0
end
" Get Rows given different seed lines and columns it 'should return the average of cell range'
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 2, 1) == ['test11', 'test12'] call cursor(1,3)
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 2, 2) == ['test11', 'test12'] Expect tablemode#spreadsheet#Average('1:2') == 2.0
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 3, 1) == ['test11', 'test12'] Expect tablemode#spreadsheet#Average('1,1:1,2') == 1.5
Expect tablemode#spreadsheet#GetCellRange('1,1:1,2', 3, 2) == ['test11', 'test12'] Expect tablemode#spreadsheet#Average('1,1:2,2') == 5.0
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 2, 1) == ['test21', 'test22'] call cursor(2,7)
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 2, 2) == ['test21', 'test22'] Expect tablemode#spreadsheet#Average('1:2') == 3.0
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 3, 1) == ['test21', 'test22'] Expect tablemode#spreadsheet#Average('2,1:2,2') == 3.5
Expect tablemode#spreadsheet#GetCellRange('2,1:2,2', 3, 2) == ['test21', 'test22'] end
" 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']
Expect tablemode#spreadsheet#GetCellRange('1:-1', 3, 2) == ['test12']
end end
end end
describe 'Manipulations' describe 'Manipulations'
before before
new new
normal i|test11|test12| normal! ggdG
|test21|test22| read t/fixtures/sample.txt
call cursor(2, 3)
end end
it 'should delete a row successfully' it 'should delete a row successfully'

View File

@@ -1,119 +1,160 @@
" vim: fdm=indent " 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 'table'
describe 'API' describe 'IsRow'
before before
new new
read t/fixtures/sample.txt normal! ggdG
read t/fixtures/table/sample.txt
end end
it 'should return true when inside a table' it 'should be true when on a table row'
Expect tablemode#table#IsATableRow(2) to_be_true Expect tablemode#table#IsRow(2) to_be_true
Expect tablemode#table#IsRow(3) to_be_true
end end
it 'should return false when outside a table' it 'should be false when not on a table row'
Expect tablemode#table#IsATableRow(4) to_be_false Expect tablemode#table#IsRow(1) to_be_false
Expect tablemode#table#IsRow(4) to_be_false
end end
end end
describe 'Tableize' describe 'IsBorder'
before before
new new
read t/fixtures/tableize.txt normal! ggdG
read t/fixtures/table/sample_with_header.txt
end end
it 'should tableize with default delimiter' it 'should be true on a table border'
:2,3call tablemode#TableizeRange('') Expect tablemode#table#IsBorder(1) to_be_true
Expect tablemode#table#IsATableRow(2) to_be_true Expect tablemode#table#IsBorder(3) to_be_true
Expect tablemode#spreadsheet#RowCount(2) == 2 Expect tablemode#table#IsBorder(6) to_be_true
Expect tablemode#spreadsheet#ColumnCount(2) == 3
end end
it 'should tableize with given delimiter' it 'should be false when not on a table border'
:2,3call tablemode#TableizeRange('/;') Expect tablemode#table#IsBorder(2) to_be_false
Expect tablemode#table#IsATableRow(2) to_be_true Expect tablemode#table#IsBorder(4) to_be_false
Expect tablemode#spreadsheet#RowCount(2) == 2 Expect tablemode#table#IsBorder(5) to_be_false
Expect tablemode#spreadsheet#ColumnCount(2) == 2
end end
end end
describe 'Motions' describe 'IsHeader'
describe 'left or right' before
new
normal! ggdG
read t/fixtures/table/sample_with_header.txt
end
it 'should be true on the table header'
Expect tablemode#table#IsHeader(2) to_be_true
end
it 'should be false anywhere else'
Expect tablemode#table#IsHeader(1) to_be_false
Expect tablemode#table#IsHeader(4) to_be_false
Expect tablemode#table#IsHeader(5) to_be_false
Expect tablemode#table#IsHeader(6) to_be_false
Expect tablemode#table#IsHeader(7) to_be_false
end
end
describe 'AddBorder'
before
new
normal! ggdG
read t/fixtures/table/sample_for_header.txt
end
it 'should add border to line'
call tablemode#table#AddBorder(2)
Expect tablemode#table#IsHeader(1) to_be_true
Expect tablemode#table#IsBorder(2) to_be_true
end
describe 'for unicode'
before before
new new
normal! ggdG normal! ggdG
call tablemode#TableModeEnable() read t/fixtures/table/sample_for_header_unicode.txt
normal i|test11|test12|
|test21|test22|
end end
it 'should add border to line'
it 'should move left when not on first column' call tablemode#table#AddBorder(1)
call cursor(1, 12) call tablemode#table#AddBorder(3)
Expect tablemode#spreadsheet#ColumnNr('.') == 2 call tablemode#table#AddBorder(5)
call tablemode#table#TableMotion('h') call tablemode#table#AddBorder(7)
call tablemode#table#AddBorder(9)
Expect tablemode#table#IsBorder(1) to_be_true
Expect tablemode#utils#StrDisplayWidth(getline(1)) == tablemode#utils#StrDisplayWidth(getline(2))
Expect tablemode#table#IsBorder(3) to_be_true
Expect tablemode#utils#StrDisplayWidth(getline(3)) == tablemode#utils#StrDisplayWidth(getline(4))
Expect tablemode#table#IsBorder(5) to_be_true
Expect tablemode#utils#StrDisplayWidth(getline(5)) == tablemode#utils#StrDisplayWidth(getline(6))
Expect tablemode#table#IsBorder(7) to_be_true
Expect tablemode#utils#StrDisplayWidth(getline(7)) == tablemode#utils#StrDisplayWidth(getline(8))
Expect tablemode#table#IsBorder(9) to_be_true
Expect tablemode#utils#StrDisplayWidth(getline(9)) == tablemode#utils#StrDisplayWidth(getline(8))
end
end
end
describe 'Realign'
describe 'without header alignments'
describe 'for simple'
before
new
normal! ggdG
read t/fixtures/table/sample_realign_before.txt
end
it 'should be aligned properly'
call tablemode#table#Realign(1)
Expect getline(1,'$') == readfile('t/fixtures/table/sample_realign_after.txt')
end
end end
describe 'for unicode'
it 'should move to the previous row last column if it exists when on first column' before
call cursor(2, 3) new
Expect tablemode#spreadsheet#RowNr('.') == 2 normal! ggdG
Expect tablemode#spreadsheet#ColumnNr('.') == 1 read t/fixtures/table/sample_realign_unicode_before.txt
call tablemode#table#TableMotion('h') end
Expect tablemode#spreadsheet#RowNr('.') == 1
Expect tablemode#spreadsheet#ColumnNr('.') == 2
it 'should be aligned properly'
it 'should move right when not on last column' call tablemode#table#Realign(1)
Expect tablemode#spreadsheet#ColumnNr('.') == 1 Expect getline(1,'$') == readfile('t/fixtures/table/sample_realign_unicode_after.txt')
call tablemode#table#TableMotion('l') end
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#table#TableMotion('l')
Expect tablemode#spreadsheet#RowNr('.') == 2
end end
end end
describe 'with header alignments'
describe 'up or down' describe 'for simple'
before before
new new
normal! ggdG normal! ggdG
call tablemode#TableModeEnable() read t/fixtures/table/sample_header_realign_before.txt
normal i|test11|test12| end
it 'should be aligned properly'
call tablemode#table#Realign(1)
Expect getline(1,'$') == readfile('t/fixtures/table/sample_header_realign_after.txt')
end
end end
end describe 'for unicode'
before
it 'should move a row up unless on first row' new
call cursor(2, 3) normal! ggdG
Expect tablemode#spreadsheet#RowNr('.') == 2 read t/fixtures/table/sample_header_realign_unicode_before.txt
call tablemode#table#TableMotion('k') end
end it 'should be aligned properly'
call tablemode#table#Realign(1)
it 'should remain on first row when trying to move up' Expect getline(1,'$') == readfile('t/fixtures/table/sample_header_realign_unicode_after.txt')
Expect tablemode#spreadsheet#RowNr('.') == 1 end
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
end
it 'should remain on last row when trying to move down'
Expect tablemode#spreadsheet#RowNr('.') == 1
end end
end end
end end

View File

@@ -1,13 +1,11 @@
" vim: fdm=indent " vim: fdm=indent
source t/config.vim source t/config/options.vim
call vspec#hint({'scope': 'tablemode#scope()', 'sid': 'tablemode#sid()'})
describe 'tablemode' describe 'tablemode'
describe 'Activation' describe 'Activation'
describe 'tablemode#TableModeEnable()' describe 'tablemode#Enable()'
before before
call tablemode#TableModeEnable() call tablemode#Enable()
end end
it 'should enable table mode' it 'should enable table mode'
@@ -15,9 +13,9 @@ describe 'tablemode'
end end
end end
describe 'tablemode#TableModeDisable()' describe 'tablemode#Disable()'
before before
call tablemode#TableModeDisable() call tablemode#Disable()
end end
it 'should disable table mode' it 'should disable table mode'
@@ -25,13 +23,34 @@ describe 'tablemode'
end end
end end
describe 'tablemode#TableModeToggle()' describe 'tablemode#Toggle()'
it 'should toggle table mode' it 'should toggle table mode'
call tablemode#TableModeToggle() call tablemode#Toggle()
Expect b:table_mode_active to_be_true Expect b:table_mode_active to_be_true
call tablemode#TableModeToggle() call tablemode#Toggle()
Expect b:table_mode_active to_be_false Expect b:table_mode_active to_be_false
end end
end 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 end

View File

@@ -1,33 +1,45 @@
" vim: fdm=indent " vim: fdm=indent
source t/config.vim source t/config/options.vim
call vspec#hint({'scope': 'tablemode#utils#scope()', 'sid': 'tablemode#utils#sid()'}) describe 'utils'
describe 'line'
it 'should return the current line number'
Expect tablemode#utils#line('.') == line('.')
end
describe 'line' it 'should return the line number itself if it is a number'
it 'should return the current line number' Expect tablemode#utils#line(1) == 1
Expect tablemode#utils#line('.') == line('.') end
end end
it 'should return the line number itself if it is a number' describe 'strip'
Expect tablemode#utils#line(1) == 1 it 'should strip all initial or trailing whitespace from a string'
end let string = ' This is awesome '
end Expect tablemode#utils#strip(string) == 'This is awesome'
end
describe 'strip' end
it 'should strip all initial or trailing whitespace from a string'
let string = ' This is awesome ' describe 'strlen'
Expect tablemode#utils#strip(string) == 'This is awesome' it 'should return the length of a string correctly'
end let string = 'this is a test'
end Expect tablemode#utils#strlen(string) == 14
end
describe 'strlen'
it 'should return the length of a string correctly' it 'should return the length of a unicode string correctly'
let string = 'this is a test' let string = '測試 is good.'
Expect tablemode#utils#strlen(string) == 14 Expect tablemode#utils#strlen(string) == 11
end end
end
it 'should return the length of a unicode string correctly'
let string = '測試 is good.' describe 'strdisplaywidth'
Expect tablemode#utils#strlen(string) == 11 it 'should return the display width of a string correctly'
let string = 'this is a test'
Expect tablemode#utils#StrDisplayWidth(string) == 14
end
it 'should return the display width of a unicode string correctly'
let string = '測試 is good.'
Expect tablemode#utils#StrDisplayWidth(string) == 13
end
end end
end end