Compare commits

...

221 Commits

Author SHA1 Message Date
Dhruva Sagar
88cb2e44b6 Bump version 2020-08-02 23:28:10 +05:30
Dhruva Sagar
336262d04f Fix #184
Improve formula evaluation, support border rows
2020-08-02 23:26:27 +05:30
Dhruva Sagar
5c489b57e8 Improve documentation. Fix #183
Update the vim help documentation to match the correct mappings
& behavior
2020-07-27 19:51:11 +05:30
Dhruva Sagar
436e7d6c21 Merge pull request #182 from CaninoDev/patch-2
Update README.md
2020-07-25 01:52:55 +05:30
Dhruva Sagar
1ea7960834 Merge pull request #181 from CaninoDev/patch-1
Add instructions for installation via vim-plug
2020-07-25 01:51:52 +05:30
IanGC
ff38f4451b Update README.md
1) `it's` is a contraction of `it is`. `its` is the possessive
2) Made consistent the formatting of `[count]` as used in various locations
3) Made consistent the various `g:` formattings
4) `immidiately` is correctly spelled `immediately`
5) Shortened some sentences for clarity

As an aside, this is an immensely useful plugin. Thanks so much for contributing your code.
2020-07-24 15:48:47 -04:00
IanGC
d5b9ce4d9e Add instructions for installation via vim-plug 2020-07-24 15:26:10 -04:00
Dhruva Sagar
6404009080 Improve documentation of g:table_mode_disable_tableize_mappings 2020-05-06 20:29:11 +05:30
Dhruva Sagar
c9b13e5d30 Add config to disable tableize mappings. Fix 176 2020-05-06 20:20:53 +05:30
Dhruva Sagar
6a6f3565c3 Releasing version 4.7.0 2020-04-19 22:02:25 +05:30
Dhruva Sagar
0b1dcf2e4c Merge pull request #175 from insanum/formulas
added some new formula functions
2020-04-19 21:55:36 +05:30
Eric Davis
2e5713ae6a fixed the Average function and test case when spanning rows/columns
fixed a Vim error(E907) in Min/Max when comparing v:null to a float
fixed CountE/CountNE/PercentE/PercentNE to support spanning rows/columns
added test cases for all the new formula functions
2020-04-19 00:20:55 -07:00
Eric Davis
f755285cf3 simplified the CountE function
cleanup for HTML comment tag checks
2020-04-18 21:47:22 -07:00
Eric Davis
5cdf3c2ac1 Added the following formula functions:
- Min: get the lowest value
  - Max: get the highest value
  - CountE: count the number of empty cells
  - CountNE: count the number of non-empty cells
  - PercentE: percent of empty cells
  - PercentNE: percent of non-empty cells
  - AverageNE: average over non-empty cells

Also added a subtle tweak that ignores an HTML comment tag ('<!--')
found between the table and the starting formula line. Being able to
wrap all the formula lines with an HTML comment prevents the formulas
from being rendered in Markdown/ReST output.
2020-04-18 18:46:21 -07:00
Dhruva Sagar
29e7cb41bb Merge pull request #174 from ibbem/feature/add-columns
Add a way to insert columns
2020-04-17 20:16:39 +05:30
ibbem
46e4493b30 Start insert mode after adding a column 2020-04-13 22:34:44 +02:00
ibbem
85a5e3d4e1 Fix the column modifications on escaped separators
If a g:table_mode_separator is escaped by a backslash, the table is
aligned ignoring this instance of the g:table_mode_separator, but the
column deletion and insertion functions did not consider this behaviour.

The g:table_mode_escaped_separator regex is simplified and optimized a
little bit. Also more care is taken to prevent unexpected behaviour if
special characters are used as g:table_mode_separator.
2020-04-04 15:27:23 +02:00
ibbem
67129cd1e0 Fix column modifications if Unicode is involved 2020-04-04 15:27:23 +02:00
ibbem
0b58003b68 Add support for inserting columns #130
Two mappings are introduced to enable usage of this feature like vim's
pasting with p and P.
2020-04-04 15:27:19 +02:00
ibbem
6912880697 Include the header when deleting columns 2020-03-31 18:21:45 +02:00
Dhruva Sagar
6412352b54 Merge pull request #169 from dhruvasagar/dependabot/bundler/rake-12.3.3
Bump rake from 10.1.0 to 12.3.3
2020-03-02 00:08:27 -05:00
dependabot[bot]
a5909a01b9 Bump rake from 10.1.0 to 12.3.3
Bumps [rake](https://github.com/ruby/rake) from 10.1.0 to 12.3.3.
- [Release notes](https://github.com/ruby/rake/releases)
- [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc)
- [Commits](https://github.com/ruby/rake/compare/rake-10.1.0...v12.3.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-02-29 08:29:09 +00:00
Dhruva Sagar
0af25d72eb Update dependencies, use ruby 2.5.3 for testing 2019-12-17 14:29:38 -05:00
Dhruva Sagar
06adb63764 Trying to fix travis 2019-12-17 14:22:58 -05:00
Dhruva Sagar
aedcd8e077 Fix #161, Add documentation about :TableModeRealign and mapping to README 2019-12-17 14:08:09 -05:00
Dhruva Sagar
5ac34a22db Fix #156, improved cursor column detection 2019-12-10 16:13:23 -05:00
Dhruva Sagar
8677840826 Rename ftplugins to avoid clobbering with other ftplugins 2019-12-10 16:13:23 -05:00
Dhruva Sagar
5ec330d114 Merge pull request #158 from I-am-the-doctor/fix-delete
Fix repeated deletions of rows and columns
2019-11-16 13:11:40 -05:00
Benjamin Moosherr
d670f5e0f8 Tests for issue #157 2019-11-16 17:17:29 +01:00
Benjamin Moosherr
9781613f66 Fix issue #157
Because tablemode#spreadsheet#DeleteColumn() and
tablemode#spreadsheet#DeleteRow() take v:count1 into account, the
automatic repetition of vim has to be suppressed.
2019-11-16 17:17:07 +01:00
Dhruva Sagar
126897a6fb Merge pull request #154 from opencollective/opencollective
Activating Open Collective
2019-09-28 15:03:33 -04:00
Jess
49c41900f5 Added financial contributors to the README 2019-09-28 11:55:35 -07:00
Dhruva Sagar
934778947e Create FUNDING.yml 2019-09-05 13:28:06 -04:00
Dhruva Sagar
865563f785 Allow range for TableSort. Fix #133 2019-04-25 23:14:05 +05:30
Dhruva Sagar
a40ef26c5c Merge pull request #146 from elig0n/patch-1
Fix github repo links in documentation
2019-03-22 13:52:06 +05:30
Eliran Gonen
b6210c9392 Fix github repo links
From 'table-mode' to 'vim-table-mode'
2019-03-22 10:21:19 +02:00
Dhruva Sagar
fdfcb85fb3 Add fold marker for improved folding 2019-02-20 09:43:50 +05:30
Dhruva Sagar
229916cd00 Fix markdown ftplugin 2019-02-20 09:36:23 +05:30
Dhruva Sagar
ad9229c937 Fix #141. Allow negative row reference in formula expressions 2019-01-21 15:20:10 +05:30
Dhruva Sagar
cdf33f680f Merge pull request #137 from idbrii/auto-corner
Automatically setup table options
2019-01-02 17:11:07 +05:30
David Briscoe
5c3c30a9cc Automatically setup table options
Readme mentions settings for Markdown and ReST, but we can apply them
automatically for the current filetype. If a user is editing a no
filetype scratch buffer, they'll still need to configure these options
themselves. But this provides better defaults when editing a buffer of
these filetypes.

Adds get_buffer_or_global_option that could be used for any other
buffer-local (filetype-specific) options.
2018-12-19 12:50:47 -08:00
Dhruva Sagar
130e835ff7 Merge pull request #135 from idbrii/safer-borders
Only insert borders on blank/whitespace-only lines
2018-10-21 06:02:50 +05:30
Dhruva Sagar
a1be216c94 Update tablemode.vim 2018-10-21 05:53:36 +05:30
David Briscoe
cf11264525 Only insert borders on blank/whitespace-only lines
Fixes #45.

Require our end expr to insert a border. This prevents borders from
clobbering other text and makes it possible to use visual block to insert
a new column.
2018-05-19 06:15:36 -07:00
Dhruva Sagar
5483e163bd Merge pull request #134 from jeetsukumaran/master
Disable/restore foldmethod during realignment
2018-05-16 19:50:04 +05:30
Jeet Sukumaran
09f4336954 Disable/restore foldmethod during realignment 2018-05-15 18:07:30 -04:00
Dhruva Sagar
e646bee5c4 Fix #132
Disabling InsertLeave autocmd for realign since it is getting triggered
multiple times during realignment and causes issues while creation of
tables
2018-03-22 09:40:50 +05:30
Dhruva Sagar
d0a6405189 Fix #131. Cleanly disable auto align when table mode is disabled. 2018-03-17 08:06:45 +05:30
Dhruva Sagar
c35fd9b104 Remove CursorHoldI for auto-align. Fix #128
Since auto-align in insert mode causes snags, removing it and instead
doing it on InsertLeave instead
2018-02-13 08:34:35 +05:30
Dhruva Sagar
bdd96b05cb AutoAlign only if buffer is already modified. Fix #126 2018-01-22 16:59:50 +05:30
Dhruva Sagar
b25fe6f9f0 Fix #124
Underscores should not create an issue
2018-01-04 12:18:22 +05:30
Dhruva Sagar
322503e814 Add support for escaping the separator #118
Initial support. Alignment and border creation is fixed and is
consistent in considering the escaped table separator as part of the
column.

TODO :
* Fix syntax to reflect the above.
* Fix cell definition, motion & formula engine to incorporate this.
2017-12-28 01:04:45 +05:30
Dhruva Sagar
40fe641708 Merge pull request #123 from vbwx/master
Mappings for tableize commands
2017-10-26 07:12:22 +05:30
Bernhard Waldbrunner
1d9d512ed1 Allow dynamic prefix for all mappings 2017-10-25 21:19:32 +02:00
Dhruva Sagar
9f383b92be Play nice with vimwiki. Fix #110
In order to use vim table mode over vimwiki native table formatting
support you need to add the following vimwiki settings to your vimrc :

```vim
let g:vimwiki_table_mappings=0
let g:vimwiki_table_auto_fmt=0
```
2017-10-09 20:44:50 +05:30
Dhruva Sagar
a646b4033b Fix #122 : Disable auto align properly after disabling Table Mode 2017-07-31 06:06:22 +05:30
Dhruva Sagar
4e41af8e5f Remove Auto Align in insert mode #115
Since realigning doesn't work well in insert mode, I have removed auto
align feature for it. Auto align will now kick in once you have made
changes and get back to normal mode.
2017-04-20 10:08:18 +05:30
Dhruva Sagar
35b41e0822 Merge pull request #113 from lbischof/patch-1
Fix readme formatting
2017-04-03 10:11:58 +05:30
Lorenz Bischof
f5d4b4e46d Fix readme formatting 2017-04-02 18:17:55 +02:00
Dhruva Sagar
d4cb68e8e1 Fix for option g:table_mode_update_time 2017-03-10 06:51:47 +05:30
Dhruva Sagar
79bf3f9bb7 Add configuration option table_mode_update_time #73
This is for better experience with auto align, we override the
updatetime with the value of the configuration g:table_mode_update_time.

Once table mode is disabled prior defaults are restored.
2017-03-10 06:48:30 +05:30
Dhruva Sagar
ef66b3ec2f Revert "Also auto realign on InsertLeave #73"
This reverts commit 6584cee4a4.
2017-03-09 15:02:42 +05:30
Dhruva Sagar
6584cee4a4 Also auto realign on InsertLeave #73 2017-03-09 14:24:15 +05:30
Dhruva Sagar
1eef73fc5b Add option to auto align table while editing #73 2017-03-09 11:00:19 +05:30
Dhruva Sagar
d3b70df0a6 Merge pull request #112 from polyzen/patch-1
readme: Fix minor Vint (Vim linter) warnings
2017-03-08 16:25:11 +05:30
Daniel M. Capella
096165718e readme: Fix minor Vint (Vim linter) warnings 2017-03-08 06:59:39 +00:00
Dhruva Sagar
30a3eba816 Fix #103 : Refactored border creation
Border creation should not conflict with the contents of the row
2017-01-05 11:42:10 +05:30
Dhruva Sagar
cc0055f329 Fixed align unicode fixture
The before fixture should not have any unnecessary spaces
2017-01-04 16:15:46 +05:30
Dhruva Sagar
8d3affcf5f Minor refactor for table syntax 2017-01-04 16:03:24 +05:30
Dhruva Sagar
9edd6d7d20 Add config to disable table mode syntax
Since table mode syntax can hamper performance, it is now possible to
disable it with a global config
2017-01-04 15:49:35 +05:30
Dhruva Sagar
441c30c35a Merge pull request #98 from harriott/master
enabling toggle notification by default
2016-09-28 19:27:31 +05:30
Joseph Harriott
ebd16eef19 Merge remote-tracking branch 'gh/master' 2016-09-28 15:39:23 +02:00
Joseph Harriott
141efc3edd corrected spurious loaded_table_verbose 2016-09-28 15:29:07 +02:00
Joseph Harriott
c82bc292c5 deleted tags, as requested 2016-09-27 23:30:29 +02:00
Dhruva Sagar
8209b59215 Bumped the version 2016-09-21 14:07:59 +05:30
Dhruva Sagar
5b3b2f7c05 Updated the README
Fixed the tip
2016-09-21 14:05:56 +05:30
harriott
47f60d2972 doc adjusted for default verbose 2016-09-09 11:03:00 +02:00
harriott
0f680bfd1b 'table_mode_verbose', 1 2016-09-09 10:53:18 +02:00
harriott
19f2f5c26f reset gitignore tags 2016-09-09 10:50:30 +02:00
harriott
e07c240940 fixed logger.vim and announce g:table_mode_verbose 2016-09-09 10:39:01 +02:00
Dhruva Sagar
8bacd0ba66 Bumped ruby version for travis 2016-08-23 09:29:00 +05:30
Dhruva Sagar
8309a33aa7 Fix #90
Allow for multiple formula lines
2016-08-23 09:26:24 +05:30
Dhruva Sagar
293c847cdf Bumped ruby version for tests 2016-08-23 09:25:56 +05:30
Dhruva Sagar
96236638a8 Fix #92
Improved mappings for table mode
2016-07-11 13:39:28 +05:30
Dhruva Sagar
1d14a027a8 Merge branch 'master' of github.com:dhruvasagar/vim-table-mode 2016-07-11 13:24:27 +05:30
Dhruva Sagar
e490373435 Fix #88
Added the iabbrevs to README
2016-07-11 13:23:37 +05:30
Dhruva Sagar
b420dedbf5 Fix #88
Added the iabbrevs to README
2016-07-11 13:22:12 +05:30
Dhruva Sagar
1bf139b30d Bumped version 2016-05-09 09:07:40 +05:30
Dhruva Sagar
b613e39bd0 Fix #89
Unescape special characters () within the commmentstring
2016-05-08 15:57:13 +05:30
Dhruva Sagar
7c56d298bb Updated test for formula validation 2016-05-08 15:56:48 +05:30
Dhruva Sagar
4cf1f53430 Fix #86
Fixed issue with table formula addition when there exists one already
and the comment string is singular, i.e. no end delimiter.
2016-04-09 12:55:29 +05:30
Dhruva Sagar
01289c0752 Merge branch 'master' of github.com:dhruvasagar/vim-table-mode 2015-12-03 22:53:41 +05:30
Dhruva Sagar
2ab64777a5 Merge pull request #75 from hein09/patch-1
Fixed sort in doc
2015-12-03 21:11:39 +05:30
hein09
26b21e3454 Fixed sort in doc
Fixed sort-parts in documentation breaking the help-tag-indexing of vim
2015-12-03 15:48:18 +01:00
Dhruva Sagar
fdfa4b12c2 Add tablemode#table#IsTable 2015-11-23 14:53:05 +05:30
Dhruva Sagar
e7373c9083 Merge pull request #71 from arecarn/fix-sort
Fix sort command, and add documentation for the command and mapping.
2015-11-17 06:43:19 +01:00
Ryan Carney
6872024827 add docs for table sorting command and mapping
----
Related Issues: #38
2015-11-15 14:46:47 -08:00
Ryan Carney
50b3b01a33 fix mapping to table sort
Symptom:
when trying to sort a column using <leader>ts the following error would
be displayed:

     E119: Not enough arguments for function: tablemode#spreadsheet#Sort

Problem:
Function call tablemode#spreadsheet#Sort() was missing a arguemnts for
it's named parameter bang.

Solution:
Add a blank value of '' as the argument for the bang parameter

----
Related Issues: #38
2015-11-15 14:45:05 -08:00
Dhruva Sagar
5395c9f52b Merge pull request #65 from axil/master
Updated readme
2015-06-05 06:22:58 -07:00
Lev Maximov
13d836dbfe included header_fillchar into the rst example 2015-06-05 11:28:55 +06:00
Lev Maximov
b1e4041e43 changed the video to a more recent one 2015-06-05 02:15:11 +06:00
Lev Maximov
bba1bf8d6e restructured the headers 2015-06-05 02:15:11 +06:00
Lev Maximov
4baf9cfd2e more detailed how-to-start instructions, with pictures 2015-06-05 02:14:50 +06:00
Dhruva Sagar
8d2e013756 Updated youtube video
* Updated the youtube video link to the more recent video.
2015-06-04 10:29:49 -07:00
Dhruva Sagar
cc723fe8cd Merge pull request #61 from rafaeln/patch-1
fix table in table-mode.txt
2015-04-21 13:48:06 -07:00
rafaeln
2c06812c39 fix table in table-mode.txt
immidiately --> immediately
2015-04-21 16:13:55 -03:00
Dhruva Sagar
2471a3b1da Updated docs 2015-04-14 15:57:49 -07:00
Dhruva Sagar
74d1492f2b Add support for center alignment. Fix #57
We now have support for center alignment, simply add a header border
with the `g:table_mode_align_char` as both the first and the last
character so it would look something like `+:.....:+` to center align
the column values.
2015-04-14 15:56:09 -07:00
Dhruva Sagar
c0a6d43f21 Updated ruby version in travis 2015-03-17 15:43:02 -07:00
Dhruva Sagar
af182b1387 Updated README
* Updated documentation with regards to manual installation
2015-03-17 13:53:24 -07:00
Dhruva Sagar
757d1f95eb Updated ruby version 2015-03-17 13:50:26 -07:00
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
Dhruva Sagar
63cb175d57 Releasing v4.1.0
* Fixed bad references within plugin.
* Added fixtures for cleaner tests.
* Updated readme, changelog & doc
2014-04-07 19:15:52 +05:30
Dhruva Sagar
4eae4a659d Merge branch 'master' of github.com:dhruvasagar/vim-table-mode 2014-04-07 19:11:05 +05:30
Dhruva Sagar
5012486cbe Fixed function references in plugin 2014-04-07 19:10:26 +05:30
Dhruva Sagar
12f4c39982 Added silent! to ignore errors on disabling errors 2014-04-07 19:09:20 +05:30
Dhruva Sagar
943496c535 Added fixtures 2014-04-07 19:09:02 +05:30
Dhruva Sagar
151d489a53 Update README.md 2014-04-07 17:31:40 +05:30
Dhruva Sagar
aa5b5ef526 Update README.md 2014-04-07 16:17:27 +05:30
Dhruva Sagar
a0207b7895 Updated README & CHANGELOG 2014-04-07 15:37:38 +05:30
Dhruva Sagar
3e741ca38b Merge branch 'refactor/plug_mappings' 2014-04-07 15:25:05 +05:30
Dhruva Sagar
95fc4c3c32 Releasing v4.0.0
* Refactored complete code to be more modular.
* Fixed long standing unicode alignment issue #8.
* Testing individual components ensuring better test coverage.
2014-04-07 15:24:45 +05:30
Dhruva Sagar
70744f308c Fixing tabular align for unicode characters 2014-04-07 15:00:34 +05:30
Dhruva Sagar
de2039dd24 Removed a config by mistake 2014-04-07 12:37:48 +05:30
Dhruva Sagar
7eef29529d Removed erroneous configs 2014-04-07 12:07:36 +05:30
Dhruva Sagar
defd9531a7 Refactored spreadsheet related code out of table.vim 2014-04-07 12:05:20 +05:30
Dhruva Sagar
f20ff17b42 Updated plugin mappings 2014-04-06 11:56:30 +05:30
Dhruva Sagar
b63b0401a0 Refactored code into autoload/tablemode/table.vim 2014-04-06 03:54:32 +05:30
Dhruva Sagar
6d2ade59dc Added command TableModeRealign 2014-03-18 18:25:15 +05:30
Dhruva Sagar
0b03a88ffb Fixed tablemode#TableMotion 2014-03-18 18:21:35 +05:30
Dhruva Sagar
8e37d67505 Fixed tablemode#TableMotion, supports [count] 2014-03-18 18:20:58 +05:30
Dhruva Sagar
f2c492fe5e Fixes #20
Checking if gdefault is set and working accordingly
2014-03-12 07:52:25 +05:30
Dhruva Sagar
10ab0425f6 Fixes #17
Added a new configuration option g:table_mode_corner_corner to
correspond to the extreme corners of the table border, by default it is
set to '|' to maintain backward compatibility but it can be overriden to
anything else.
2014-01-29 11:32:30 +05:30
Dhruva Sagar
e10a2ab4da Updated README 2013-12-31 12:53:41 +05:30
Dhruva Sagar
496872f342 trying with <kbd> 2013-12-31 12:51:35 +05:30
Dhruva Sagar
af432f6ed5 Updated CHANGELOG 2013-12-31 12:34:42 +05:30
Dhruva Sagar
5c42d58d4b Updated table mode
- Bumped version
- Added new mapping \t? to echo current cells representation for
  defining formulas.
- Updated docs
2013-12-31 12:30:52 +05:30
Dhruva Sagar
1302782b55 Updated vim-flavor & tests 2013-12-31 12:22:22 +05:30
Dhruva Sagar
9935e57def Fixed motions 2013-12-11 16:15:07 +05:30
Dhruva Sagar
8993e2a454 Fixed tablemode#DeleteColumn 2013-12-11 15:50:32 +05:30
Dhruva Sagar
df41b7deff Fixed Travis Url in README 2013-12-11 15:22:52 +05:30
Dhruva Sagar
c88a913397 Fixed tests 2013-12-11 15:21:20 +05:30
Dhruva Sagar
8609ad4778 Releasing version 3.3.1
* Borders are now disregarded, so add as many as you'd like.
* Improved test coverage.
2013-12-11 12:48:25 +05:30
Dhruva Sagar
535dd9601a Fixed doc/table-mode.txt mixed indent 2013-11-13 08:49:40 +05:30
Dhruva Sagar
e94bbcc0b4 Switched to using || mapping for table border generation, more intuitive & create a minimal border on a new line without a table 2013-11-13 08:45:15 +05:30
Dhruva Sagar
a0618db019 Fixed #14, You can now have a top border (before header) and a bottom border as well (after last line) 2013-11-12 19:49:10 +05:30
Dhruva Sagar
176999f347 Allowing border creation above table row 2013-10-24 16:47:15 +05:30
Dhruva Sagar
5a6a9b3473 Fixed motions to wrap around edges incorporating table header 2013-10-07 15:07:55 +05:30
Dhruva Sagar
aa8817621c Fixed doc #11 2013-09-25 09:29:37 +05:30
Dhruva Sagar
54187d0be1 Updated Header Border to be like org-mode table header separator for consistency. 2013-09-19 16:53:28 +05:30
Dhruva Sagar
3e2eaeee5c Fixed delete column api with header changes 2013-09-19 15:03:13 +05:30
52 changed files with 2985 additions and 1283 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: vim-table-mode
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

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

View File

@@ -1,4 +1,82 @@
# Change Log
## Version 4.6.4.1
* Added a fix for markdown commentstring
## Version 4.6.4
* Added support for center aligning columns
## 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
* Fixed bad references within plugin
* Added fixtures
## Version 4.0.0
* Major refactoring of the codebase.
* Improved modular tests.
* Fixed long standing unicode character alignment issue.
* Moved to providing \<Plug\> mappings rather than configuration based mappings
which can be more easily overriden by end user.
## Version 3.3.2
* Added new mapping \t? to echo a cells representation for use while defining
formulas.
## Version 3.3.1
* Improved logic to ignore table borders (add as many as you'd like), the
first row is not treated special, it is row # 1. Keep that in mind while
defining Formulas
* Improved test coverage
## Version 3.3
* Dropped +- mapping to create table border instead now using ||
* You can now have a top table border (before header) as well as a bottom
table border.
## Version 3.2
* Added tests to test various use cases using <a
href='https://github.com/kana/vim-vspec'>Vspec</a>..
@@ -63,3 +141,7 @@
## Version 1.0 :
* First stable release, create tables as you type.
<!--
vim: ft=markdown
-->

View File

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

View File

@@ -4,9 +4,9 @@ GEM
blankslate (2.1.2.4)
parslet (1.5.0)
blankslate (~> 2.0)
rake (10.1.0)
rake (12.3.3)
thor (0.18.1)
vim-flavor (1.1.2)
vim-flavor (1.1.3)
parslet (~> 1.0)
thor (~> 0.14)
@@ -16,3 +16,9 @@ PLATFORMS
DEPENDENCIES
rake
vim-flavor (~> 1.1)
RUBY VERSION
ruby 2.5.3p105
BUNDLED WITH
2.0.1

274
README.md
View File

@@ -1,14 +1,10 @@
# VIM Table Mode [![Build Status](https://travis-ci.org/dhruvasagar/soulmate_rails.png?branch=master)](https://travis-ci.org/dhruvasagar/soulmate_rails)
# VIM Table Mode v4.7.2 [![Build Status](https://travis-ci.org/dhruvasagar/vim-table-mode.png?branch=master)](https://travis-ci.org/dhruvasagar/vim-table-mode)
An awesome automatic table creator & formatter allowing one to create neat
tables as you type.
## Change Log
See <a
href="https://github.com/dhruvasagar/vim-table-mode/blob/master/CHANGELOG.md">
CHANGELOG.md </a>
## Getting Started
## Getting Started
### Installation
There are several ways to do this
@@ -21,102 +17,185 @@ There are several ways to do this
href="https://github.com/tpope/vim-pathogen">pathogen.vim</a>, then
add a git submodule for your plugin:
```sh
```sh
$ cd ~/.vim
$ 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
respective ~/.vim/autoload/, ~/.vim/plugin and ~/.vim/doc under UNIX or
```
3. Copy all files under autoload/, plugin/, doc/ to respective
~/.vim/autoload/, ~/.vim/plugin and ~/.vim/doc under UNIX or
vimfiles/autoload/, vimfiles/plugin/ and vimfiles/doc under WINDOWS and
restart VIM
4. Alternatively, if using <a href="https://github.com/junegunn/vim-plug">vim-plug</a>, then add `Plug 'dhruvasagar/vim-table-mode'` to your ~/.vimrc.
### Usage
### Creating table on-the-fly
- **On the fly table creation** :
To start using the plugin in the on-the-fly mode use `:TableModeToggle` mapped to <kbd>\<Leader\>tm</kbd> by default (which means <kbd>\\</kbd> <kbd>t</kbd> <kbd>m</kbd> if you didn't override the <Leader> by `:let mapleader = ','` to have <kbd>,</kbd> <kbd>t</kbd> <kbd>m</kbd>).
By default the table column separator is `|` defined by the
`g:table_mode_separator` option. As soon as you type it on a new line (ignores
indentation) the script gets to work on creating a table around it. As you
type and define more columns, the table is completed, formatted and aligned
automatically on the fly.
Tip:
You can use the following to quickly enable / disable table mode in insert mode by using `||` or `__`:
> ```vim
> function! s:isAtStartOfLine(mapping)
> let text_before_cursor = getline('.')[0 : col('.')-1]
> let mapping_pattern = '\V' . escape(a:mapping, '\')
> let comment_pattern = '\V' . escape(substitute(&l:commentstring, '%s.*$', '', ''), '\')
> return (text_before_cursor =~? '^' . ('\v(' . comment_pattern . '\v)?') . '\s*\v' . mapping_pattern . '\v$')
> endfunction
>
> inoreabbrev <expr> <bar><bar>
> \ <SID>isAtStartOfLine('\|\|') ?
> \ '<c-o>:TableModeEnable<cr><bar><space><bar><left><left>' : '<bar><bar>'
> inoreabbrev <expr> __
> \ <SID>isAtStartOfLine('__') ?
> \ '<c-o>:silent! TableModeDisable<cr>' : '__'
> ```
Since this could lead to unwanted behavior I have disabled table mode by
default. You have to use `:TableModeToggle` command or the table mode
toggle mapping, which is `<Leader>tm` defined by `g:table_mode_toggle_map`
option to toggle the table mode or you can directly use `:TableModeEnable`
and `:TableModeDisable` to enable or disable the table mode. This is on a
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.
Enter the first line, delimiting columns by the `|` symbol. The plugin reacts by inserting spaces between the text and the separator if you omit them:
- **Format existing content into a table** :
| name | address | phone |
Table Mode wouldn't justify it's name if it didn't allow formatting
existing content into a table. And it does as promised. Like table creation
on the fly as you type, formatting existing content into a table is equally
simple. You can visually select multiple lines and call `:Tableize` on it,
or alternatively use the mapping `<Leader>tt` defined by the
`g:table_mode_tableize_map` option which would convert CSV (Comma Separated
Value) data into a table and use `,` defined by `g:table_mode_delimiter`
option as the delimiter.
In the second line (without leaving Insert mode), enter `|` twice. The plugin will write a properly formatted horizontal line:
| name | address | phone |
|------+---------+-------|
When you enter the subsequent lines, the plugin will automatically adjust the formatting to match the text youre entering every time you press `|`:
| name | address | phone |
|------------+---------+-------|
| John Adams |
Go on until the table is ready:
| name | address | phone |
|-----------------+--------------------------+------------|
| John Adams | 1600 Pennsylvania Avenue | 0123456789 |
|-----------------+--------------------------+------------|
| Sherlock Holmes | 221B Baker Street | 0987654321 |
|-----------------+--------------------------+------------|
Then you can return to the first line and above it enter `||`:
|-----------------+--------------------------+------------|
| name | address | phone |
|-----------------+--------------------------+------------|
| John Adams | 1600 Pennsylvania Avenue | 0123456789 |
|-----------------+--------------------------+------------|
| Sherlock Holmes | 221B Baker Street | 0987654321 |
|-----------------+--------------------------+------------|
Corner separators are adjustable:
For Markdown-compatible tables use
let g:table_mode_corner='|'
|-----------------|--------------------------|------------|
| name | address | phone |
|-----------------|--------------------------|------------|
| John Adams | 1600 Pennsylvania Avenue | 0123456789 |
|-----------------|--------------------------|------------|
| Sherlock Holmes | 221B Baker Street | 0987654321 |
|-----------------|--------------------------|------------|
To get ReST-compatible tables use
let g:table_mode_corner_corner='+'
let g:table_mode_header_fillchar='='
+-----------------+--------------------------+------------+
| name | address | phone |
+=================+==========================+============+
| John Adams | 1600 Pennsylvania Avenue | 0123456789 |
+-----------------+--------------------------+------------+
| Sherlock Holmes | 221B Baker Street | 0987654321 |
+-----------------+--------------------------+------------+
Markdown and ReST filetypes have automatically configured corners.
You can also define in a table header border how its content should be
aligned, whether center, right or left by using a `:` character defined by
`g:table_mode_align_char` option.
If you manipulate the table when table mode is disabled or copy paste a table
from clipboard from outside and it ends up being misaligned, you can realign
it using `:TableModeRealign` or using the default mapping
<kbd>\<Leader\>tr</kbd> (defined by the option `g:table_mode_relign_map`).
### Formatting existing content into a table
Table Mode wouldn't justify its name if it didn't allow formatting
existing content into a table. And it does as promised. Like table creation typing on the fly,
formatting existing content into a table is equally
simple. You can visually select multiple lines and call `:Tableize` on it.
Alternatively, the mapping <kbd>\<Leader\>tt</kbd> can be used (defined by the
option `g:table_mode_tableize_map`). This converts CSV (Comma-separated
Values) data into a table.
If however you wish to use a different delimiter, you can use the command
`:Tableize/{pattern}` in a similar fashion as you use tabular (eg.
`:Tableize/;` uses ';' as the delimiter) or use the mapping `<Leader>T`
defined by `g:table_mode_tableize_op_map` option which takes input in the
`:Tableize/{pattern}` in a similar fashion as you tabulate (e.g.
`:Tableize/;` uses ';' as the delimiter) or use the mapping <kbd>\<Leader\>T</kbd>
(defined by the option `g:table_mode_tableize_op_map`) which takes input in the
cmd-line and uses the `{pattern}` input as the delimiter.
`:Tableize` also accepts a range and so you can also call it by giving
lines manually like `:line1,line2Tableize`, but this is not very intuitive.
You can use the mapping `<Leader>T` with a `[count]` to apply it to the
`:Tableize` also accepts a range. Call it by giving
lines manually like `:line1,line2Tableize`. However this may not be intuitive.
You can use the mapping <kbd>\<Leader\>T</kbd> with a `[count]` to apply it to the
next `[count]` lines in standard vim style.
- **Move between cells** :
### Moving around
Now you can move between cells using table mode motions `<Leader>t[hjkl]`
to move left | down | up | right cells respectively. You can use
`g:table_mode_map_prefix` option to define the prefix mapping to be used
before 'hjkl'. The left | right motions wrap around the table and move to
the next | previous row after the last | first cell in the current row if
one exists.
Now you can move between cells using table mode motions <kbd>[|</kbd>,
<kbd>]|</kbd>, <kbd>{|</kbd> & <kbd>}|</kbd> to move left | right | up |
down cells respectively. The left | right motions wrap around the table
and move to the next | previous row after the last | first cell in the
current row if one exists.
- **Manipulating Table** :
### Manipulating Table
- **Cell Text Object** :
Tableize provides a text object for manipulating table cells. By default
it's `tc`, but that can be changed if you wish to by setting the
`g:table_mode_cell_text_object` option.
This is intelligent in the sense that if you use it to delete the
contents it will delete everything till the `g:table_mode_separator` so
that the cell is removed and you can enter new stuff if you wish to (had
you used 'c' operator), having to input the `g:table_mode_separator`
again to form the cell & realign it (since it can't be done from the
text object itself). However if you were to 'y' or yank the text, it
would copy the right text, i.e. the contents of the cell and nothing
else.
Tableize provides a text object for manipulating table cells. Following
the vim philosophy the you have <kbd>i|</kbd> & <kbd>a|</kbd> for the
inner and around (including the immediate right table separator) the
table cell.
- **Delete Row** :
You can use the `<Leader>tdd` mapping defined by the option
`g:table_mode_delete_row_map` to delete the current table row (provided
you are within a table row), this can be preceeded with a [count] to
delete multiple rows just like you would with 'dd'.
You can use the <kbd>\<Leader\>tdd</kbd> mapping (defined by the option
`g:table_mode_delete_row_map`) to delete the current table row (provided
you are within a table row). This can be preceeded with a `[count]` to
delete multiple rows as per Vim command grammar.
- **Delete Column** :
You can use the `<Leader>tdc` mapping defined by the option
`g:table_mode_delete_column_map` to delete the entire current column
You can use the <kbd>\<Leader\>tdc</kbd> mapping (defined by the option
`g:table_mode_delete_column_map`) to delete the entire current column
(provided you are within a table row), this can also be preceeded with a
[count] to delete multiple columns.
`[count]` to delete multiple columns.
- **Table Formulas** :
- **Insert Column** :
You can use the <kbd>\<Leader\>tic</kbd> mapping (defined by the option
`g:table_mode_insert_column_after_map`) to insert a column after the
cursor (provided you are within a table row). Of course you can use the
<kbd>\<Leader\>tiC</kbd> mapping defined by
`g:table_mode_insert_column_before_map` to insert a column before the
cursor. Both can also be preceeded with a [count] to insert multiple
columns.
## Advanced Usage: Spreadsheet Capabilities
### Table Formulas
Table Mode now has support for formulas like a spreadsheet. There are 2 ways
of defining formulas :
- You can add formulas using `:TableAddFormula` or the mapping `<Leader>tfa`
defined by the option `g:table_mode_add_formula_map` from within a table
- You can add formulas using `:TableAddFormula` or the mapping <kbd>\<Leader\>tfa</kbd>
(defined by the option `g:table_mode_add_formula_map`) from within a table
cell, which will ask for input on the cmd-line with a `f=` prompt. The
input formula will be appended to the formula line if one exists or a new
one will be created with the input formula taking the current cell as the
@@ -129,10 +208,12 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
formulas on the line separated with a ';' eg) `# tmf: $3=$2*$1;$4=$3/3.14`
You can evaluate the formula line using `:TableEvalFormulaLine` or the
mapping `<Leader>tfe` defined by the option `g:table_mode_eval_expr_map`
mapping <kbd>\<Leader\>tfe</kbd> (defined by the option `g:table_mode_eval_expr_map`)
from anywhere inside the table or while on the formula line.
- **Formula Expressions** :
NOTE: You can now use the mapping <kbd>\<Leader\>t?</kbd>
### Formula Expressions
Expressions are of the format `$target = formula`.
@@ -140,19 +221,21 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
- `$n`: This matches the table column number `n`. So the `formula` would
be evaluated for each cell in that column and the result would be placed
in it.
in it. You can use negative indice to represent column relative to the
last, -1 being the last.
- `$n,m`: This matches the table cell n,m (row, column). So in this case
the formula would be evaluated and the result will be placed in this
cell.
cell. You can also use negative values to refer to cells relative to
the size, -1 being the last (row or column).
- The `formula` can be a simple mathematical expression involving cells
which are also defined by the same format as that of the target cell. You
can use all native vim functions within the formula. Apart from that table
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
current row (of the target cell).
@@ -171,10 +254,15 @@ $ git submodule add git@github.com:dhruvasagar/vim-table-mode.git bundle/table-m
- `$5,3 = Sum(1,2:5,2)/$5,1`
- `$5,3 = Average(1,2:5,2)/$5,1`
### Demo
## Demo
<a href="http://www.youtube.com/watch?v=sK2IH1hiDkw"><img
src="https://raw.github.com/dhruvasagar/vim-table-mode/master/youtube.png"/></a>
<a href="http://www.youtube.com/watch?v=9lVQ0VJY3ps"><img
src="https://raw.github.com/axil/vim-table-mode/master/youtube.png"/></a>
## Change Log
See <a
href="https://github.com/dhruvasagar/vim-table-mode/blob/master/CHANGELOG.md">
CHANGELOG.md </a>
## Contributing
@@ -194,3 +282,33 @@ named <a href="https://gist.github.com/tpope/287147">cucumbertables.vim</a>.
Also a shout out to godlygeek who developed the incredible <a
href="http://github.com/godlygeek/tabular">Tabular</a> plugin.
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/dhruvasagar/vim-table-mode/graphs/contributors"><img src="https://opencollective.com/vim-table-mode/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/vim-table-mode/contribute)]
#### Individuals
<a href="https://opencollective.com/vim-table-mode"><img src="https://opencollective.com/vim-table-mode/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/vim-table-mode/contribute)]
<a href="https://opencollective.com/vim-table-mode/organization/0/website"><img src="https://opencollective.com/vim-table-mode/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/1/website"><img src="https://opencollective.com/vim-table-mode/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/2/website"><img src="https://opencollective.com/vim-table-mode/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/3/website"><img src="https://opencollective.com/vim-table-mode/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/4/website"><img src="https://opencollective.com/vim-table-mode/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/5/website"><img src="https://opencollective.com/vim-table-mode/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/6/website"><img src="https://opencollective.com/vim-table-mode/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/7/website"><img src="https://opencollective.com/vim-table-mode/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/8/website"><img src="https://opencollective.com/vim-table-mode/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/vim-table-mode/organization/9/website"><img src="https://opencollective.com/vim-table-mode/organization/9/avatar.svg"></a>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
" Borrowed from Tabular
" Private Functions {{{1
" function! s:StripTrailingSpaces(string) - Remove all trailing spaces {{{2
" from a string.
function! s:StripTrailingSpaces(string)
return matchstr(a:string, '^.\{-}\ze\s*$')
endfunction
function! s:Padding(string, length, where) "{{{3
let gap_length = a:length - tablemode#utils#StrDisplayWidth(a:string)
if a:where =~# 'l'
return a:string . repeat(" ", gap_length)
elseif a:where =~# 'r'
return repeat(" ", gap_length) . a:string
elseif a:where =~# 'c'
let right = gap_length / 2
let left = right + (right * 2 != gap_length)
return repeat(" ", left) . a:string . repeat(" ", right)
endif
endfunction
" Public Functions {{{1
" function! tablemode#align#Split() - Split a string into fields and delimiters {{{2
" Like split(), but include the delimiters as elements
" All odd numbered elements are delimiters
" All even numbered elements are non-delimiters (including zero)
function! tablemode#align#Split(string, delim)
let rv = []
let beg = 0
let len = len(a:string)
let searchoff = 0
while 1
let mid = match(a:string, a:delim, beg + searchoff, 1)
if mid == -1 || mid == len
break
endif
let matchstr = matchstr(a:string, a:delim, beg + searchoff, 1)
let length = strlen(matchstr)
if length == 0 && beg == mid
" Zero-length match for a zero-length delimiter - advance past it
let searchoff += 1
continue
endif
if beg == mid
let rv += [ "" ]
else
let rv += [ a:string[beg : mid-1] ]
endif
let rv += [ matchstr ]
let beg = mid + length
let searchoff = 0
endwhile
let rv += [ strpart(a:string, beg) ]
return rv
endfunction
function! tablemode#align#alignments(lnum, ncols) "{{{2
let achr = g:table_mode_align_char
let alignments = []
if tablemode#table#IsBorder(a:lnum+1)
let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner')
let corner_corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner_corner')
let hcols = tablemode#align#Split(getline(a:lnum+1), '[' . corner . corner_corner . ']')
for idx in range(len(hcols))
" Right align if header
call add(alignments, 'l')
if hcols[idx] =~# achr . '[^'.achr.']\+' . achr
let alignments[idx] = 'c'
elseif hcols[idx] =~# achr . '$'
let alignments[idx] = 'r'
endif
" if hcols[idx] !~# '[^0-9\.]' | let alignments[idx] = 'r' | endif
endfor
end
return alignments
endfunction
function! tablemode#align#Align(lines) "{{{2
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_escaped_separator_regex) : v:val")')
for line in lines
let stext = line.text
if len(stext) <= 1 | continue | endif
if stext[0] !~ tablemode#table#StartExpr()
let stext[0] = s:StripTrailingSpaces(stext[0])
endif
if len(stext) >= 2
for i in range(1, len(stext)-1)
let stext[i] = tablemode#utils#strip(stext[i])
endfor
endif
endfor
let maxes = []
for line in lines
let stext = line.text
if len(stext) <= 1 | continue | endif
for i in range(len(stext))
if i == len(maxes)
let maxes += [ tablemode#utils#StrDisplayWidth(stext[i]) ]
else
let maxes[i] = max([ maxes[i], tablemode#utils#StrDisplayWidth(stext[i]) ])
endif
endfor
endfor
let alignments = tablemode#align#alignments(lines[0].lnum, len(lines[0].text))
for idx in range(len(lines))
let tlnum = lines[idx].lnum
let tline = lines[idx].text
if len(tline) <= 1 | continue | endif
for jdx in range(len(tline))
" Dealing with the header being the first line
if jdx >= len(alignments) | call add(alignments, 'l') | endif
let field = s:Padding(tline[jdx], maxes[jdx], alignments[jdx])
let tline[jdx] = field . (jdx == 0 || jdx == len(tline) ? '' : ' ')
endfor
let lines[idx].text = s:StripTrailingSpaces(join(tline, ''))
endfor
return lines
endfunction

View File

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

View File

@@ -0,0 +1,422 @@
" Private Functions {{{1
function! s:TotalCells(list) "{{{2
let result = 0
for item in a:list
if type(item) == type([])
let result += s:TotalCells(item)
else
let result += 1
endif
endfor
return result
endfunction
function! s:Min(list) "{{{2
let found = v:false
let result = 0
for item in a:list
if empty(item)
continue
endif
if type(item) == type(1) || type(item) == type(1.0)
if found == v:false || item < result
let found = v:true
let result = item
endif
elseif type(item) == type('')
let val = str2float(item)
if found == v:false || val < result
let found = v:true
let result = val
endif
elseif type(item) == type([])
let val = s:Min(item)
if found == v:false || val < result
let found = v:true
let result = val
endif
endif
endfor
return result
endfunction
function! s:Max(list) "{{{2
let found = v:false
let result = 0
for item in a:list
if empty(item)
continue
endif
if type(item) == type(1) || type(item) == type(1.0)
if found == v:false || item > result
let found = v:true
let result = item
endif
elseif type(item) == type('')
let val = str2float(item)
if found == v:false || val > result
let found = v:true
let result = val
endif
elseif type(item) == type([])
let val = s:Max(item)
if found == v:false || val > result
let found = v:true
let result = val
endif
endif
endfor
return result
endfunction
function! s:CountE(list) "{{{2
let result = 0
for item in a:list
if empty(item)
let result += 1
elseif type(item) == type([])
let result += s:CountE(item)
endif
endfor
return result
endfunction
function! s:CountNE(list) "{{{2
let result = 0
for item in a:list
if type(item) == type([])
let result += s:CountNE(item)
elseif !empty(item)
let result += 1
endif
endfor
return result
endfunction
function! s:PercentE(list) "{{{2
return (s:CountE(a:list)*100)/s:TotalCells(a:list)
endfunction
function! s:PercentNE(list) "{{{2
return (s:CountNE(a:list)*100)/s:TotalCells(a:list)
endfunction
function! s:Sum(list) "{{{2
let result = 0.0
for item in a:list
if type(item) == type(1) || type(item) == type(1.0)
let result += item
elseif type(item) == type('')
let result += str2float(item)
elseif type(item) == type([])
let result += s:Sum(item)
endif
endfor
return result
endfunction
function! s:Average(list) "{{{2
return s:Sum(a:list)/s:TotalCells(a:list)
endfunction
function! s:AverageNE(list) "{{{2
return s:Sum(a:list)/s:CountNE(a:list)
endfunction
" Public Functions {{{1
function! tablemode#spreadsheet#GetFirstRow(line) "{{{2
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while !tablemode#table#IsHeader(line - 1) && (tablemode#table#IsRow(line - 1) || tablemode#table#IsBorder(line - 1))
let line -= 1
endwhile
if tablemode#table#IsBorder(line) | let line += 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#GetFirstRowOrHeader(line) "{{{2
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsTable(line - 1)
let line -= 1
endwhile
if tablemode#table#IsBorder(line) | let line += 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#MoveToFirstRow() "{{{2
if tablemode#table#IsRow('.')
call tablemode#utils#MoveToLine(tablemode#spreadsheet#GetFirstRow('.'))
endif
endfunction
function! tablemode#spreadsheet#MoveToFirstRowOrHeader() "{{{2
if tablemode#table#IsRow('.')
call tablemode#utils#MoveToLine(tablemode#spreadsheet#GetFirstRowOrHeader('.'))
endif
endfunction
function! tablemode#spreadsheet#GetLastRow(line) "{{{2
if tablemode#table#IsRow(a:line)
let line = tablemode#utils#line(a:line)
while tablemode#table#IsTable(line + 1)
let line += 1
endwhile
if tablemode#table#IsBorder(line) | let line -= 1 | endif
return line
endif
endfunction
function! tablemode#spreadsheet#MoveToLastRow() "{{{2
if tablemode#table#IsRow('.')
call tablemode#utils#MoveToLine(tablemode#spreadsheet#GetLastRow('.'))
endif
endfunction
function! tablemode#spreadsheet#LineNr(line, row) "{{{2
if tablemode#table#IsRow(a:line)
let line = tablemode#spreadsheet#GetFirstRow(a:line)
let row_nr = 0
while tablemode#table#IsTable(line + 1)
if tablemode#table#IsRow(line)
let row_nr += 1
if a:row ==# row_nr | break | endif
endif
let line += 1
endwhile
return line
endif
endfunction
function! tablemode#spreadsheet#RowNr(line) "{{{2
let line = tablemode#utils#line(a:line)
let rowNr = 0
while !tablemode#table#IsHeader(line) && tablemode#table#IsTable(line)
if tablemode#table#IsRow(line) | let rowNr += 1 | endif
let line -= 1
endwhile
return rowNr
endfunction
function! tablemode#spreadsheet#RowCount(line) "{{{2
let line = tablemode#utils#line(a:line)
let [tline, totalRowCount] = [line, 0]
while !tablemode#table#IsHeader(tline) && tablemode#table#IsTable(tline)
if tablemode#table#IsRow(tline) | let totalRowCount += 1 | endif
let tline -= 1
endwhile
let tline = line + 1
while !tablemode#table#IsHeader(tline) && tablemode#table#IsTable(tline)
if tablemode#table#IsRow(tline) | let totalRowCount += 1 | endif
let tline += 1
endwhile
return totalRowCount
endfunction
function! tablemode#spreadsheet#ColumnNr(pos) "{{{2
let pos = []
if type(a:pos) == type('')
let pos = [line(a:pos), col(a:pos)]
elseif type(a:pos) == type([])
let pos = a:pos
else
return 0
endif
let row_start = stridx(getline(pos[0]), g:table_mode_separator)
return tablemode#utils#SeparatorCount(getline(pos[0])[row_start:pos[1]-2])
endfunction
function! tablemode#spreadsheet#ColumnCount(line) "{{{2
return tablemode#utils#SeparatorCount(getline(tablemode#utils#line(a:line))) - 1
endfunction
function! tablemode#spreadsheet#IsFirstCell() "{{{2
return tablemode#spreadsheet#ColumnNr('.') ==# 1
endfunction
function! tablemode#spreadsheet#IsLastCell() "{{{2
return tablemode#spreadsheet#ColumnNr('.') ==# tablemode#spreadsheet#ColumnCount('.')
endfunction
function! tablemode#spreadsheet#MoveToStartOfCell() "{{{2
if getline('.')[col('.')-1] !=# g:table_mode_separator || tablemode#spreadsheet#IsLastCell()
call search(g:table_mode_escaped_separator_regex, 'b', line('.'))
endif
normal! 2l
endfunction
function! tablemode#spreadsheet#MoveToEndOfCell() "{{{2
call search(g:table_mode_escaped_separator_regex, 'z', line('.'))
normal! 2h
endfunction
function! tablemode#spreadsheet#DeleteColumn() "{{{2
if tablemode#table#IsRow('.')
for i in range(v:count1)
call tablemode#spreadsheet#MoveToStartOfCell()
call tablemode#spreadsheet#MoveToFirstRowOrHeader()
silent! execute "normal! h\<C-V>"
call tablemode#spreadsheet#MoveToEndOfCell()
normal! 2l
call tablemode#spreadsheet#MoveToLastRow()
normal! d
endfor
call tablemode#table#Realign('.')
endif
endfunction
function! tablemode#spreadsheet#DeleteRow() "{{{2
if tablemode#table#IsRow('.')
for i in range(v:count1)
if tablemode#table#IsRow('.')
normal! dd
endif
if !tablemode#table#IsRow('.')
normal! k
endif
endfor
call tablemode#table#Realign('.')
endif
endfunction
function! tablemode#spreadsheet#InsertColumn(after) "{{{2
if tablemode#table#IsRow('.')
let quantity = v:count1
call tablemode#spreadsheet#MoveToFirstRowOrHeader()
call tablemode#spreadsheet#MoveToStartOfCell()
if a:after
call tablemode#spreadsheet#MoveToEndOfCell()
normal! 3l
endif
execute "normal! h\<C-V>"
call tablemode#spreadsheet#MoveToLastRow()
normal! y
let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner')
if a:after
let cell_line = g:table_mode_separator.' '
let header_line = corner.g:table_mode_fillchar.g:table_mode_fillchar
else
let cell_line = ' '.g:table_mode_separator
let header_line = g:table_mode_fillchar.g:table_mode_fillchar.corner
endif
let cell_line = escape(cell_line, '\&')
let header_line = escape(header_line, '\&')
" This transforms the character column before or after the column separator
" into a new column with separator.
" This requires, that
" g:table_mode_separator != g:table_mode_fillchar
" && g:table_mode_separator != g:table_mode_header_fillchar
" && g:table_mode_separator != g:table_mode_align_char
call setreg(
\ '"',
\ substitute(
\ substitute(@", ' ', cell_line, 'g'),
\ '\V\C'.escape(g:table_mode_fillchar, '\')
\ .'\|'.escape(g:table_mode_header_fillchar, '\')
\ .'\|'.escape(g:table_mode_align_char, '\'),
\ header_line,
\ 'g'),
\ 'b')
if a:after
execute "normal! ".quantity."pl"
else
execute "normal! ".quantity."P"
endif
call tablemode#table#Realign('.')
startinsert
endif
endfunction
function! tablemode#spreadsheet#Min(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:Min(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#Max(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:Max(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#CountE(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:CountE(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#CountNE(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:CountNE(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#PercentE(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:PercentE(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#PercentNE(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:PercentNE(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#Sum(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:Sum(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#Average(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:Average(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#AverageNE(range, ...) abort "{{{2
let args = copy(a:000)
call insert(args, a:range)
return s:AverageNE(call('tablemode#spreadsheet#cell#GetCellRange', args))
endfunction
function! tablemode#spreadsheet#Sort(bang, ...) range "{{{2
if exists('*getcurpos')
let col = getcurpos()[4] " curswant
else
let col = col('.')
endif
let opts = a:0 ? a:1 : ''
let bang = a:bang ? '!' : ''
if a:firstline == a:lastline
let [firstRow, lastRow] = [tablemode#spreadsheet#GetFirstRow('.'), tablemode#spreadsheet#GetLastRow('.')]
else
let [firstRow, lastRow] = [a:firstline, a:lastline]
endif
call tablemode#spreadsheet#MoveToStartOfCell()
exec ':undojoin | '.firstRow.','.lastRow . 'sort'.bang opts '/.*\%'.col.'v/'
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#IsTable(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#IsTable(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,169 @@
" Private Functions {{{1
function! s:IsHTMLComment(line) "{{{2
return getline(a:line) =~# '^\s*<!--'
endfunction
function! s:IsFormulaLine(line) "{{{2
return getline(a:line) =~# 'tmf: '
endfunction
" 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
if s:IsHTMLComment(fline) | let fline += 1 | endif
let cursor_pos = [line('.'), col('.')]
if getline(fline) =~# 'tmf: '
" Comment line correctly
let line_val = getline(fline)
let start_pos = match(line_val, tablemode#table#StartCommentExpr())
let end_pos = match(line_val, tablemode#table#EndCommentExpr())
if empty(end_pos) | let end_pos = len(line_val) | endif
let line_expr = strpart(line_val, start_pos, end_pos)
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 =~# 'Min(.*)'
let expr = substitute(expr, 'Min(\([^)]*\))', 'tablemode#spreadsheet#Min("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'Max(.*)'
let expr = substitute(expr, 'Max(\([^)]*\))', 'tablemode#spreadsheet#Max("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'CountE(.*)'
let expr = substitute(expr, 'CountE(\([^)]*\))', 'tablemode#spreadsheet#CountE("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'CountNE(.*)'
let expr = substitute(expr, 'CountNE(\([^)]*\))', 'tablemode#spreadsheet#CountNE("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'PercentE(.*)'
let expr = substitute(expr, 'PercentE(\([^)]*\))', 'tablemode#spreadsheet#PercentE("\1",'.line.','.colm.')', 'g')
endif
if expr =~# 'PercentNE(.*)'
let expr = substitute(expr, 'PercentNE(\([^)]*\))', 'tablemode#spreadsheet#PercentNE("\1",'.line.','.colm.')', 'g')
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 =~# 'AverageNE(.*)'
let expr = substitute(expr, 'AverageNE(\([^)]*\))', 'tablemode#spreadsheet#AverageNE("\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 !s:IsFormulaLine(line)
if !tablemode#table#IsBorder(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
endif
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 s:IsHTMLComment(fline) | let fline += 1 | endif
if tablemode#table#IsBorder(fline) | let fline += 1 | endif
while s:IsFormulaLine(fline)
let exprs += split(matchstr(getline(fline), matchexpr), ';')
let fline += 1
endwhile
elseif s:IsFormulaLine('.')
let fline = line('.')
let line = line('.') - 1
while s:IsFormulaLine(line) | let fline = line | let line -= 1 | endwhile
if s:IsHTMLComment(line) | let line -= 1 | endif
if tablemode#table#IsBorder(line) | let line -= 1 | endif
if tablemode#table#IsRow(line)
" let exprs = split(matchstr(getline('.'), matchexpr), ';')
while s:IsFormulaLine(fline)
let exprs += split(matchstr(getline(fline), matchexpr), ';')
let fline += 1
endwhile
endif
endif
for expr in exprs
call tablemode#spreadsheet#formula#EvaluateExpr(expr, line)
endfor
endfunction

View File

@@ -0,0 +1,218 @@
" Private Functions {{{1
function! s:blank(string) "{{{2
return a:string =~# '^\s*$'
endfunction
function! s:BorderExpr() "{{{2
let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner')
let corner_corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner_corner')
let header_fillchar = tablemode#utils#get_buffer_or_global_option('table_mode_header_fillchar')
return tablemode#table#StartExpr() .
\ '[' . corner . corner_corner . ']' .
\ '[' . escape(g:table_mode_fillchar . header_fillchar . corner . g:table_mode_align_char, '-') . ']\+' .
\ '[' . corner . corner_corner . ']' .
\ tablemode#table#EndExpr()
endfunction
function! s:DefaultBorder() "{{{2
if tablemode#IsActive()
let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner')
let corner_corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner_corner')
return corner_corner . g:table_mode_fillchar . corner . g:table_mode_fillchar . corner_corner
else
return ''
endif
endfunction
function! s:GenerateHeaderBorder(line) "{{{2
let line = tablemode#utils#line(a:line)
if tablemode#table#IsRow(line - 1) || tablemode#table#IsRow(line + 1)
let line_val = ''
if tablemode#table#IsRow(line + 1)
let line_val = getline(line + 1)
endif
if tablemode#table#IsRow(line - 1) && tablemode#utils#strlen(line_val) < tablemode#utils#strlen(getline(line - 1))
let line_val = getline(line - 1)
endif
if tablemode#utils#strlen(line_val) <= 1 | return s:DefaultBorder() | endif
let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner')
let corner_corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner_corner')
let header_fillchar = tablemode#utils#get_buffer_or_global_option('table_mode_header_fillchar')
let tline = line_val[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)]
let fillchar = tablemode#table#IsHeader(line - 1) ? header_fillchar : g:table_mode_fillchar
let special_replacement = '___'
let border = substitute(tline, g:table_mode_escaped_separator_regex, special_replacement, 'g')
let seperator_match_regex = special_replacement . '\zs\(.\{-}\)\ze' . special_replacement
let border = substitute(border, seperator_match_regex, '\=repeat(fillchar, tablemode#utils#StrDisplayWidth(submatch(0)))', 'g')
let border = substitute(border, special_replacement, g:table_mode_separator, 'g')
let border = substitute(border, g:table_mode_separator, corner, 'g')
let border = substitute(border, '^' . corner . '\(.*\)' . corner . '$', corner_corner . '\1' . corner_corner, '')
" Incorporate header alignment chars
if getline(line) =~# g:table_mode_align_char
let pat = '[' . corner_corner . 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
" center align
if hcols[idx] =~# g:table_mode_align_char . '[^'.g:table_mode_align_char.']\+' . g:table_mode_align_char
let gcols[idx] = g:table_mode_align_char . gcols[idx][1:-2] . g:table_mode_align_char
elseif hcols[idx] =~# g:table_mode_align_char . '$'
let gcols[idx] = gcols[idx][:-2] . g:table_mode_align_char
else
let gcols[idx] = g:table_mode_align_char . gcols[idx][1:]
endif
endif
endfor
let border = join(gcols, '')
endif
let cstartexpr = tablemode#table#StartCommentExpr()
if tablemode#utils#strlen(cstartexpr) > 0 && getline(line) =~# cstartexpr
let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
let ece = matchstr(line_val, tablemode#table#EndCommentExpr())
return sce . border . ece
elseif getline(line) =~# tablemode#table#StartExpr()
let indent = matchstr(line_val, tablemode#table#StartExpr())
return indent . border
else
return border
endif
else
return s:DefaultBorder()
endif
endfunction
" Public Functions {{{1
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#StartCommentExpr() "{{{2
let cstartexpr = tablemode#table#GetCommentStart()
if tablemode#utils#strlen(cstartexpr) > 0
return '^\s*' . cstartexpr . '\s*'
else
return ''
endif
endfunction
function! tablemode#table#GetCommentEnd() "{{{2
let cstring = &commentstring
if tablemode#utils#strlen(cstring) > 0
let cst = split(cstring, '%s')
if len(cst) == 2
return substitute(cst[1], '[^()]', '\\\0', 'g')
else
return ''
endif
else
return ''
endif
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
let cstart = tablemode#table#GetCommentStart()
if tablemode#utils#strlen(cstart) > 0
return '^\s*\(' . cstart . '\)\?\s*'
else
return '^\s*'
endif
endfunction
function! tablemode#table#EndExpr() "{{{2
let cend = tablemode#table#GetCommentEnd()
if tablemode#utils#strlen(cend) > 0
return '\s*\(\s\+' . cend . '\)\?\s*$'
else
return '\s*$'
endif
endfunction
function! tablemode#table#IsBorder(line) "{{{2
return !s:blank(getline(a:line)) && getline(a:line) =~# s:BorderExpr()
endfunction
function! tablemode#table#IsHeader(line) "{{{2
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
function! tablemode#table#IsRow(line) "{{{2
return !tablemode#table#IsBorder(a:line) && getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator) . '[^' . g:table_mode_separator . ']\+'
endfunction
function! tablemode#table#IsTable(line) "{{{2
return tablemode#table#IsRow(a:line) || tablemode#table#IsBorder(a:line)
endfunction
function! tablemode#table#AddBorder(line) "{{{2
call setline(a:line, s:GenerateHeaderBorder(a:line))
endfunction
function! tablemode#table#Realign(line) "{{{2
let current_fm = &foldmethod " save foldmethod to be restored
setlocal foldmethod=manual " manual foldmethod while table is being aligned
let line = tablemode#utils#line(a:line)
let lines = []
let [lnum, blines] = [line, []]
while tablemode#table#IsTable(lnum)
if tablemode#table#IsBorder(lnum)
call insert(blines, lnum)
let lnum -= 1
continue
endif
call insert(lines, {'lnum': lnum, 'text': getline(lnum)})
let lnum -= 1
endwhile
let lnum = line + 1
while tablemode#table#IsTable(lnum)
if tablemode#table#IsBorder(lnum)
call add(blines, lnum)
let lnum += 1
continue
endif
call add(lines, {'lnum': lnum, 'text': getline(lnum)})
let lnum += 1
endwhile
let lines = tablemode#align#Align(lines)
for aline in lines
call setline(aline.lnum, aline.text)
endfor
for bline in blines
call tablemode#table#AddBorder(bline)
endfor
" restore foldmethod
execute "setlocal foldmethod=" . current_fm
endfunction

View File

@@ -0,0 +1,66 @@
" Private Functions {{{1
" Public Functions {{{1
function! tablemode#utils#throw(string) abort "{{{2
let v:errmsg = 'table-mode: ' . a:string
throw v:errmsg
endfunction
function! tablemode#utils#line(row) "{{{2
if type(a:row) == type('')
return line(a:row)
else
return a:row
endif
endfunction
function! tablemode#utils#strip(string) "{{{2
return matchstr(a:string, '^\s*\zs.\{-}\ze\s*$')
endfunction
" function! tablemode#utils#strlen {{{2
" To count multibyte characters accurately
function! tablemode#utils#strlen(text)
return strlen(substitute(a:text, '.', 'x', 'g'))
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
function! tablemode#utils#get_buffer_or_global_option(table_option) "{{{2
return get(b:, a:table_option, get(g:, a:table_option))
endf
function tablemode#utils#MoveToLine(line) "{{{2
let offset = tablemode#utils#line(a:line) - line('.')
if offset > 0
execute "normal! ".offset."j"
elseif offset < 0
execute "normal! ".(-offset)."k"
endif
endfunction
function! tablemode#utils#SeparatorCount(str)
return tablemode#utils#strlen(substitute(a:str, '\V\C\(\\' . escape(g:table_mode_separator, '\') . '\|\[^' . escape(g:table_mode_separator, ']^-\') . ']\)', '', 'g'))
endfunction

View File

@@ -1,7 +1,7 @@
*table-mode.txt* Table Mode for easy table formatting. v3.2
*table-mode.txt* Table Mode for easy table formatting
===============================================================================
Table Mode, THE AWESOME AUTOMATIC TABLE CREATOR & FORMATTER
VERSION 3.2
VERSION 4.7.2
Author: Dhruva Sagar <http://dhruvasagar.com/>
License: MIT <http://opensource.org/licenses/MIT/>
@@ -20,7 +20,7 @@ CONTENTS *table-mode-contents*
INTRODUCTION *table-mode-introduction*
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
Plugin.
@@ -29,11 +29,16 @@ GETTING STARTED *table-mode-getting-started*
Create Table on the fly:
Using Table Mode is dead simple. You simply start typing on a new line
with the table separator - |g:table-mode-separator|, and you just type
with the table separator - |table-mode-separator|, and you just type
away! The plugin does the rest automatically for you as you type. With
each additional separator you add, it aligns the table properly,
without having to do anything else.
Table Mode now supports gfm style tables and allows to define column
alignments with the aid of placing ':' (configured using
|g:table_mode_align_char|) on the table header border appropriately to
align content left or right.
The table mode is disabled by default and you can enter table mode
using |table-mode-toggle-map| or you can also enable it permanently
using |table-mode-always-active| if you wish though not recommended.
@@ -48,11 +53,10 @@ Tableize content:
Move between cells :
Now you can move between cells using table mode motions
'<Leader>t[hjkl]' to move left | down | up | right cells respectively.
You can use |table-mode-map-prefix| option to define the prefix
mapping to be used before 'hjkl'. The left | right motions wrap around
the table and move to the next | previous row after the last | first
cell in the current row if one exists.
'[|, ]|, {|, }|' to move left | down | up | right cells respectively.
The left | right motions wrap around the table and move to the next
| previous row after the last | first cell in the current row if one
exists.
Manipulation of tables:
Tableize provides 3 easy ways to quickly manipulate tables.
@@ -70,6 +74,10 @@ Manipulation of tables:
3. Delete Row : Delete an entire table row using
|table-mode-delete-row-map|
4. Insert Column : Insert a table column either before the cursor
using |table-mode-insert-column-before-map| or after the cusor using
|table-mode-insert-column-after-map|.
Table Formulas:
Table Mode now has support for formulas like a spreadsheet. There
are 2 ways of defining formulas :
@@ -81,7 +89,7 @@ Table Formulas:
input formula will be appended to the formula line if one
exists or a new one will be created with the input formula
taking the current cell as the target cell. The formula line
is evaluated immidiately to reflect the results.
is evaluated immediately to reflect the results.
You can directly also add / manipulate formula expressions in
the formula line. The formula line is a commented line right
@@ -99,19 +107,25 @@ Formula Expressions :
'$n': This matches the table column number 'n'. So the formula
would be evaluated for each cell in that column and the result
would be placed in it.
would be placed in it. You can use negative indice to
represent column relative to the last, -1 being the last.
'$n,m': This matches the table cell n,m (row, column). So in
this case the formula would be evaluated and the result will
be placed in this cell.
be placed in this cell. You can also use negative values to
refer to cells relative to the size, -1 being the last (row or
column).
The formula can be a simple mathematical expression involving cells
which are also defined by the same format as that of the target cell.
Apart from basic mathematical expressions, table mode also provides
special functions 'Sum' and 'Average'. Both these functions take a
range as input. A range can be of two forms :
special functions 'Min', 'Max', 'CountE' (number of empty cells),
'CountNE' (number of non-empty cells), 'PercentE' (percent of empty
cells), 'PercentNE' (percent of non-empty cells), 'Sum', 'Average',
and 'AverageNE' (average over non-empty cells). All these functions
take a 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
above the current row (of the target cell).
@@ -130,6 +144,7 @@ OPTIONS *table-mode-options*
Overview:
|table-mode-loaded| ............. Disable the plugin.
|table-mode-verbose| ............ Notify when Enabled/Disabled.
|table-mode-corner| ............. Set corner character.
|table-mode-separator| .......... Set separator character.
|table-mode-fillchar| ........... Set table fillchar character.
@@ -137,25 +152,53 @@ Overview:
|table-mode-toggle-map| ......... Set table mode toggle mapping.
|table-mode-always-active| ...... Set table mode to always enabled.
|table-mode-delimiter| .......... Set the delimiter for Tableize.
|table-mode-tableize-map| ....... Set mapping for Tableize.
|table-mode-tableize-op-map| .... Set mapping for Tableize with input.
|table-mode-realign-map| ........ Set mapping for table realigning.
|table-mode-cell-text-object| ... Set mapping for table cell object.
|table-mode-delete-row-map| ..... Set mapping for deleting table row.
|table-mode-delete-column-map| .. Set mapping for deleting table
column.
|table-mode-add-formula-map| .... Define a new table formula for the
current cell.
|table-mode-eval-expr-map| ...... Evaluate formula line and update
table.
|table-mode-corner-corner| ...... Set the character to be used for
extreme corners of the table border.
|table-mode-align-char|.......... Set the alignment character which
can be added to the table header
border to control alignment of that
column.
|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-insert-column-before-map|
Set the insert column before the
cursor mapping
|table-mode-insert-column-after-map|
Set the insert column after the
cursor 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
|table-mode-syntax| ............. Control table mode syntax
|table-mode-auto-align| ......... Set if the table mode should auto
align as you type
g:loaded_table_mode *table-mode-loaded*
Use this option to disable the plugin: >
let g:loaded_table_mode = 1
<
g:table_mode_verbose *table-mode-verbose*
Use this option to disable notifications: >
let g:table_mode_verbose = 0
<
g:table_mode_corner *table-mode-corner*
Use this option to define the table corner character: >
let g:table_mode_corner = '+'
<
Or only in the current buffer: >
let b:table_mode_corner = '+'
<
g:table_mode_separator *table-mode-separator*
Use this option to define the table column separator character: >
@@ -169,13 +212,13 @@ g:table_mode_fillchar *table-mode-fillchar*
let g:table_mode_fillchar = '-'
<
g:table_mode_map_prefix *table-mode-map-prefix*
g:table_mode_map_prefix *table-mode-map-prefix*
Use this option to define the table mode mapping prefix that will be
prefixed for all other table mode mappings. >
let g:table_mode_map_prefix = '<Leader>t'
<
g:table_mode_toggle_map *table-mode-toggle-map*
g:table_mode_toggle_map *table-mode-toggle-map*
Use this option to define the mapping for toggling the table mode: >
let g:table_mode_toggle_map = 'm'
<
@@ -184,7 +227,7 @@ g:table_mode_toggle_map *table-mode-toggle-map*
NOTE you will need to use the |table-mode-map-prefix| before this to
get the desired effect.
g:table_mode_always_active *table-mode-always-active*
g:table_mode_always_active *table-mode-always-active*
Use this option to permanently enable the table mode: >
let g:table_mode_always_active = 0
<
@@ -200,77 +243,121 @@ g:table_mode_delimiter *table-mode-delimiter*
|table-mode-commands-tableize| >
let g:table_mode_delimiter = ','
<
g:table_mode_tableize_map *table-mode-tableize-map*
Use this option to define the mapping to invoke |:Tableize| with
default delimiter, i.e. |:Tableize| without input. >
let g:table_mode_tableize_map = 't'
g:table_mode_corner_corner *table-mode-corner-corner*
Use this option to define the character to be used for the extreme
corners of the table border. >
let g:table_mode_corner_corner = '|'
<
Or only in the current buffer: >
let b: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_insert_column_before_map *table-mode-insert-column-before-map*
Set this to configure the mapping for inserting a table column before
the cursor. >
let g:table_mode_insert_column_before_map = '<Leader>tiC'
>
g:table_mode_insert_column_after_map *table-mode-insert-column-after-map*
Set this to configure the mapping for inserting a table column after
the cursor. >
let g:table_mode_insert_column_after_map = '<Leader>tic'
>
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'
>
g:table_mode_tableize_map *table-mode-tableize-map*
Set this to configure the mapping for converting the visual selection
to a table. >
let g:table_mode_tableize_map = '<Leader>tt'
>
g:table_mode_tableize_d_map *table-mode-tableize-d-map*
Set this to configure the mapping for converting the visual selection
to a table, asking the user for a delimiter. >
let g:table_mode_tableize_d_map = '<Leader>T'
>
g:table_mode_syntax *table-mode-syntax*
Control whether table mode should define table syntax definitions or
not. >
let g:table_mode_syntax = 1
<
g:table_mode_auto_align *table-mode-auto-align*
Set if the table mode should auto align as you type when table mode is
active. >
let g:table_mode_auto_align = 1
<
g:table_mode_tableize_op_map *table-mode-tableize-op-map*
Use this option to define the mapping to invoke |:Tableize| with input
parameter. This option will ask for command-line input {pattern} that
defines the delimiter. >
let g:table_mode_tableize_op_map = '<Leader>T'
g:table_mode_update_time *table-mode-update-time*
Set the value of updatetime to be used when table mode is active,
used in combination with |table-mode-auto-align|. >
let g:table_mode_update_time = 500
<
g:table_mode_realign_map *table-mode-realign-map*
Use this option to define the mapping for realigning table columns.
This is useful in case you make edits to an existing table. >
let g:table_mode_realign_map = 'r'
g:table_mode_disable_tableize_mappings *table-mode-disable-tableize-mappings*
Disables mappings for tableize. >
let g:table_mode_disable_tableize_mappings = 0
<
NOTE you will need to use the |table-mode-map-prefix| before this to
get the desired effect.
g:table_mode_cell_text_object *table-mode-cell-text-object*
Use this option to define the table mode cell text object. >
let g:table_mode_cell_text_object = 'tc'
<
This text object automatically selects different text depending on the
context.
If you delete the cell using either the 'd' or the 'c'
operator, it will delete cell contents along with the table separator.
In case you do it with 'c' while you add new content for the cell, you
will have to re-add the |table-mode-separator|, which will trigger the
re-alignment of the table again and format it correctly.
If you simply want to yank the table content, this text object will
select only the table cell contents, without the padding (extra space
around the text) or the |table-mode-separator|.
g:table_mode_delete_row_map *table-mode-delete-row-map*
Use this option to define the mapping for deletion of the entire table
row. You can delete multiple rows by preceeding this with a [count]. >
let g:table_mode_delete_column_map = 'dd'
<
NOTE you will need to use the |table-mode-map-prefix| before this to
get the desired effect.
g:table_mode_delete_column_map *table-mode-delete-column-map*
Use this option to define the mapping for deletion of the entire table
column. You can delete multiple columns to the right by preceeding
this with a [count] >
let g:table_mode_delete_column_map = 'dc'
<
NOTE you will need to use the |table-mode-map-prefix| before this to
get the desired effect.
g:table_mode_add_formula_map *table-mode-add-formula-map*
Use this option to define the mapping for invoking |TableAddFormula|
command. >
let g:table_mode_add_formula_map = 'fa'
<
NOTE you will need to use the |table-mode-map-prefix| before this to
get the desired effect.
g:table_mode_eval_expr_map *table-mode-eval-expr-map*
Use this option to define the mapping for invoking
|TableEvalFormulaLine| command. >
let g:table_mode_eval_expr_map = 'fe'
<
NOTE you will need to use the |table-mode-map-prefix| before this to
get the desired effect.
===============================================================================
MAPPINGS *table-mode-mappings*
@@ -282,9 +369,9 @@ MAPPINGS *table-mode-mappings*
*table-mode-mappings-toggle*
<Leader>tm Toggle table mode for the current buffer. You can change this
using the |toggle-mode-options-toggle-map| option.
NOTE This is applicable only if
|table-mode-always-active| is not set.
NOTE This is applicable only if |table-mode-always-active| is
not set.
*table-mode-mappings-trigger*
| Trigger table creation in table mode. You can change this
@@ -293,70 +380,89 @@ MAPPINGS *table-mode-mappings*
<Leader>tt Triggers |table-mode-commands-tableize| on the visually
selected content.
*table-mode-mappings-op-trigger*
*table-mode-mappings-op-trigger*
<Leader>T Triggers |table-mode-commands-tableize| on the visually
selected asking for user to input the delimiter.
*table-mode-mappings-realign*
<Leader>tr Realigns table columns
*table-mode-mappings-motions*
<Leader>t[hjkl] Move to previous | below | above | right cell in the table.
<Leader>t? Echo the current table cells representation for defining
formulas.
*table-mode-mappings-delete-row*
*table-mode-mappings-motions*
[| Move to previous cell
]| Move to next cell
{| Move to the cell above
}| Move to the cell below
*table-mode-mappings-delete-row*
<Leader>tdd Delete the entire table row you are on or multiple rows using
a [count]. You can change this using |table-mode-delete-row-map|
option.
*table-mode-mappings-delete-column*
*table-mode-mappings-delete-column*
<Leader>tdc Delete entire table column you are within. You can preceed it
with a [count] to delete multiple columns to the right. You
can change this using |table-mode-delete-column-map| option.
*table-mode-mappings-add-formula*
*table-mode-mappings-insert-column-before*
<Leader>tiC Insert a table column before the column you are within. You can
preceed it with a [count] to insert multiple columns. You can
change this using |table-mode-insert-column-before-map| option.
*table-mode-mappings-insert-column-after*
<Leader>tic Insert a table column after the column you are within. You can
preceed it with a [count] to insert multiple columns. You can
change this using |table-mode-insert-column-after-map| option.
*table-mode-mappings-add-formula*
<Leader>tfa Add a fomula for the current table cell. This invokes
|TableAddFormula| command.
*table-mode-mappings-evaluate-formula-line*
*table-mode-mappings-evaluate-formula-line*
<Leader>tfe Evaluate the formula line which is a commented line right
after the table beginning with 'tmf:'. If one exists this
would evaluate the formula line and update the table
accordingly. This invokes the |TableEvalFormulaLine| command.
+- Expands to a header border, the line immidiately above this
will be considered as the table header. You can change this by
changing |table-mode-corner| and |table-mode-fillchar|
options. This is an iabbrev so is triggered when you press
space or <CR> after typing the mapping.
*table-mode-mappings-sort-column*
<Leader>ts Sort a column under the cursor. This invokes |TableSort|
|| Expands to a header border. You can change this by changing
|table-mode-separator| option. You can change the character to
be used for the extreme corners of the border by changing
|table-mode-corner-corner| option.
===============================================================================
COMMANDS *table-mode-commands*
*:TableModeToggle*
*table-mode-:TableModeToggle*
*:TableModeToggle*
*table-mode-:TableModeToggle*
:TableModeToggle
Toggles the table mode. Same effect as |toggle-mode-mappings-toggle|.
NOTE this is applicable only if |table-mode-always-active| is
not set.
*:TableModeEnable*
*table-mode-:TableModeEnable*
*:TableModeEnable*
*table-mode-:TableModeEnable*
:TableModeEnable
Enables Table Mode.
NOTE this is applicable only if |table-mode-always-active| is
not set.
*:TableModeDisable*
*table-mode-:TableModeDisable*
*:TableModeDisable*
*table-mode-:TableModeDisable*
:TableModeDisable
Disables Table Mode.
Disables Table Mode.
NOTE this is applicable only if |table-mode-always-active| is
not set.
*:Tableize*
*:Tableize*
*table-mode-:Tableize*
:Tableize
This converts the current line into a table if it consists of
@@ -372,31 +478,44 @@ COMMANDS *table-mode-commands*
NOTE this is optional, by default without the expression it will
tableize the content using |table-mode-delimiter| as the delimiter.
*:TableAddFormula*
*table-mode-:TableAddFormula*
*:TableModeRealign*
*table-mode-:TableModeRealign*
:TableModeRealign
This command triggers |table-mode-mappings-realign|
*:TableAddFormula*
*table-mode-:TableAddFormula*
:TableAddFormula
This command is for defining a formula for the current table cell. It
takes input on the cmd-line with a 'f=' prompt and appends it to the
formula line if it exists or adds a new formula line with the
expression using the current cell as the target and the input formula.
*:TableEvalFormulaLine*
*table-mode-:TableEvalFormulaLine*
*:TableEvalFormulaLine*
*table-mode-:TableEvalFormulaLine*
:TableEvalFormulaLine
This command when invoked from anywhere within the table or directly
on the formula line evaluates it and updates the table accordingly.
*:TableSort*
*table-mode-:TableSort*
:TableSort[!] [i][u][r][n][x][o]
This command sorts column under the cursor and inherits the same flags
as the |:sort| command.
With [!] the order is reversed.
===============================================================================
CONTRIBUTING *table-mode-contributing*
If you want to take a stab at it, by all means, send me a pull request on
Github (http://github.com/dhruvasagar/table-mode) or get in touch with me
Github (http://github.com/dhruvasagar/vim-table-mode) or get in touch with me
directly via e-mail at dhruva 'dot' sagar 'at' gmail.com.
===============================================================================
REPORT ISSUES *table-mode-report-issues*
If you discover any issues, please report them at
http://github.com/dhruvasagar/table-mode/issues.
http://github.com/dhruvasagar/vim-table-mode/issues.
vim:tw=78:ts=8:ft=help:norl:ai
vim:tw=78:ts=8:ft=help:norl:ai:et

View File

@@ -0,0 +1 @@
let b:table_mode_corner = '|'

View File

@@ -0,0 +1,2 @@
let b:table_mode_corner_corner = '+'
let b:table_mode_header_fillchar = '='

View File

@@ -1,24 +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.2
" Note: This plugin was heavily inspired by the 'CucumberTables.vim'
" (https://gist.github.com/tpope/287147) plugin by Tim Pope and
" uses a small amount of code from it.
"
" 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
if exists('g:loaded_table_mode')
finish
@@ -37,35 +16,56 @@ endfunction
" Set Global Defaults {{{1
call s:SetGlobalOptDefault('table_mode_corner', '+')
call s:SetGlobalOptDefault('table_mode_verbose', 1)
call s:SetGlobalOptDefault('table_mode_separator', '|')
call s:SetGlobalOptDefault('table_mode_escaped_separator_regex', '\V\C\\\@1<!'.escape(g:table_mode_separator, '\'))
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_toggle_map', 'm')
call s:SetGlobalOptDefault('table_mode_always_active', 0)
call s:SetGlobalOptDefault('table_mode_delimiter', ',')
call s:SetGlobalOptDefault('table_mode_tableize_map', 't')
call s:SetGlobalOptDefault('table_mode_tableize_op_map', '<Leader>T')
call s:SetGlobalOptDefault('table_mode_realign_map', 'r')
call s:SetGlobalOptDefault('table_mode_cell_text_object', 'tc')
call s:SetGlobalOptDefault('table_mode_delete_row_map', 'dd')
call s:SetGlobalOptDefault('table_mode_delete_column_map', 'dc')
call s:SetGlobalOptDefault('table_mode_add_formula_map', 'fa')
call s:SetGlobalOptDefault('table_mode_eval_expr_map', 'fe')
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_disable_tableize_mappings', 0)
function! s:TableMotion() "{{{1
let direction = nr2char(getchar())
for i in range(v:count1)
call tablemode#TableMotion(direction)
endfor
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', g:table_mode_map_prefix.'r')
call s:SetGlobalOptDefault('table_mode_delete_row_map', g:table_mode_map_prefix.'dd')
call s:SetGlobalOptDefault('table_mode_delete_column_map', g:table_mode_map_prefix.'dc')
call s:SetGlobalOptDefault('table_mode_insert_column_before_map', g:table_mode_map_prefix.'iC')
call s:SetGlobalOptDefault('table_mode_insert_column_after_map', g:table_mode_map_prefix.'ic')
call s:SetGlobalOptDefault('table_mode_add_formula_map', g:table_mode_map_prefix.'fa')
call s:SetGlobalOptDefault('table_mode_eval_formula_map', g:table_mode_map_prefix.'fe')
call s:SetGlobalOptDefault('table_mode_echo_cell_map', g:table_mode_map_prefix.'?')
call s:SetGlobalOptDefault('table_mode_sort_map', g:table_mode_map_prefix.'s')
call s:SetGlobalOptDefault('table_mode_tableize_map', g:table_mode_map_prefix.'t')
call s:SetGlobalOptDefault('table_mode_tableize_d_map', '<Leader>T')
call s:SetGlobalOptDefault('table_mode_syntax', 1)
call s:SetGlobalOptDefault('table_mode_auto_align', 1)
call s:SetGlobalOptDefault('table_mode_update_time', 500)
function! s:TableEchoCell() "{{{1
if tablemode#table#IsRow('.')
echomsg '$' . tablemode#spreadsheet#RowNr('.') . ',' . tablemode#spreadsheet#ColumnNr('.')
endif
endfunction
" Define Commands & Mappings {{{1
if !g:table_mode_always_active "{{{2
exec "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_toggle_map .
\ " <Esc>:call tablemode#TableModeToggle()<CR>"
command! -nargs=0 TableModeToggle call tablemode#TableModeToggle()
command! -nargs=0 TableModeEnable call tablemode#TableModeEnable()
command! -nargs=0 TableModeDisable call tablemode#TableModeDisable()
exec "nnoremap <silent>" g:table_mode_map_prefix . g:table_mode_toggle_map ":<C-U>call tablemode#Toggle()<CR>"
command! -nargs=0 TableModeToggle call tablemode#Toggle()
command! -nargs=0 TableModeEnable call tablemode#Enable()
command! -nargs=0 TableModeDisable call tablemode#Disable()
else
let table_mode_separator_map = g:table_mode_separator
" '|' is a special character, we need to map <Bar> instead
@@ -78,31 +78,60 @@ endif
" }}}2
command! -nargs=? -range Tableize <line1>,<line2>call tablemode#TableizeRange(<q-args>)
command! -nargs=? -bang -range TableSort <line1>,<line2>call tablemode#spreadsheet#Sort(<bang>0, <q-args>)
command! TableAddFormula call tablemode#spreadsheet#formula#Add()
command! TableModeRealign call tablemode#table#Realign('.')
command! TableEvalFormulaLine call tablemode#spreadsheet#formula#EvaluateFormulaLine()
command! TableAddFormula call tablemode#AddFormula()
command! TableEvalFormulaLine call tablemode#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'
execute "xnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_tableize_map .
\ " :Tableize<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_tableize_map .
\ " :Tableize<CR>"
execute "xnoremap <silent> " . g:table_mode_tableize_op_map .
\ " :<C-U>call tablemode#TableizeByDelimiter()<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_realign_map .
\ " :call tablemode#TableRealign('.')<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix .
\ " :call <SID>TableMotion()<CR>"
execute "onoremap <silent> " . g:table_mode_cell_text_object .
\ " :<C-U>call tablemode#CellTextObject()<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_delete_row_map .
\ " :call tablemode#DeleteRow()<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_delete_column_map .
\ " :call tablemode#DeleteColumn()<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_add_formula_map .
\ " :TableAddFormula<CR>"
execute "nnoremap <silent> " . g:table_mode_map_prefix . g:table_mode_eval_expr_map .
\ " :TableEvalFormulaLine<CR>"
nnoremap <silent> <Plug>(table-mode-tableize) :Tableize<CR>
xnoremap <silent> <Plug>(table-mode-tableize) :Tableize<CR>
xnoremap <silent> <Plug>(table-mode-tableize-delimiter) :<C-U>call tablemode#TableizeByDelimiter()<CR>
nnoremap <silent> <Plug>(table-mode-realign) :call tablemode#table#Realign('.')<CR>
nnoremap <silent> <Plug>(table-mode-motion-up) :<C-U>call tablemode#spreadsheet#cell#Motion('k')<CR>
nnoremap <silent> <Plug>(table-mode-motion-down) :<C-U>call tablemode#spreadsheet#cell#Motion('j')<CR>
nnoremap <silent> <Plug>(table-mode-motion-left) :<C-U>call tablemode#spreadsheet#cell#Motion('h')<CR>
nnoremap <silent> <Plug>(table-mode-motion-right) :<C-U>call tablemode#spreadsheet#cell#Motion('l')<CR>
onoremap <silent> <Plug>(table-mode-cell-text-object-a) :<C-U>call tablemode#spreadsheet#cell#TextObject(0)<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) :<C-U>call tablemode#spreadsheet#DeleteRow()<CR>
nnoremap <silent> <Plug>(table-mode-delete-column) :<C-U>call tablemode#spreadsheet#DeleteColumn()<CR>
nnoremap <silent> <Plug>(table-mode-insert-column-before) :<C-U>call tablemode#spreadsheet#InsertColumn(0)<CR>
nnoremap <silent> <Plug>(table-mode-insert-column-after) :<C-U>call tablemode#spreadsheet#InsertColumn(1)<CR>
nnoremap <silent> <Plug>(table-mode-add-formula) :call tablemode#spreadsheet#formula#Add()<CR>
nnoremap <silent> <Plug>(table-mode-eval-formula) :call tablemode#spreadsheet#formula#EvaluateFormulaLine()<CR>
nnoremap <silent> <Plug>(table-mode-echo-cell) :call <SID>TableEchoCell()<CR>
nnoremap <silent> <Plug>(table-mode-sort) :call tablemode#spreadsheet#Sort('')<CR>
if !g:table_mode_disable_tableize_mappings
if !hasmapto('<Plug>(table-mode-tableize)')
exec "nmap" g:table_mode_tableize_map "<Plug>(table-mode-tableize)"
exec "xmap" g:table_mode_tableize_map "<Plug>(table-mode-tableize)"
endif
if !hasmapto('<Plug>(table-mode-tableize-delimiter)')
exec "xmap" g:table_mode_tableize_d_map "<Plug>(table-mode-tableize-delimiter)"
endif
endif
augroup TableMode "{{{1
au!
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
let &cpo = s:save_cpo

20
t/align.vim Normal file
View File

@@ -0,0 +1,20 @@
" vim: fdm=indent
source t/config/options.vim
function! ConvertLines2Dict(lines)
let lines = []
for idx in range(len(a:lines))
call insert(lines, {"lnum": idx+1, "text": a:lines[idx]})
endfor
return lines
endfunction
describe 'Align'
it 'should align table content correctly'
Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/simple_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/simple_after.txt'))
end
it 'should align table content with unicode characters correctly'
Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/unicode_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/unicode_after.txt'))
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

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

@@ -0,0 +1,36 @@
let g:table_mode_corner = '+'
let g:table_mode_separator = '|'
let g:table_mode_escaped_separator_regex = '\V\C\\\@1<!|'
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_insert_column_before_map = '<Leader>tiC'
let g:table_mode_insert_column_after_map = '<Leader>tic'
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'
let g:table_mode_tableize_map = '<Leader>tt'
let g:table_mode_tableize_d_map = '<Leader>T'
let g:table_mode_syntax = 1
let g:table_mode_auto_align = 1
let g:table_mode_update_time = 500

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,7 @@
|---+---+---+---|
| 1 | 9 | a | z |
| 2 | 8 | b | y |
| 3 | 7 | c | x |
| 4 | 6 | d | w |
| 5 | 5 | e | v |
|---+---+---+---|

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
|----------+----------+----------+----------|
| counting | backward | alphabet | backward |
|:========:+:=========+=========:+==========|
| 1 | 9 | a | z |
| 2 | 8 | b | y |
| 3 | 7 | c | x |
| 4 | 6 | d | w |
| 5 | 5 | e | v |
|----------+----------+----------+----------|

View File

@@ -0,0 +1,9 @@
|-------------------+---------------------------|
| The \| works as | It can be escaped by a \. |
| a separator. | |
| | |
| Escaping \ with | This feature would |
| a \ doesn't work. | be unnecessary, because |
| | a separator must be |
| | preceded by a space. |
|-------------------+---------------------------|

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

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

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

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 @@
| S. No | Title | Message |
|-------+:------+:-------:|
| 1 | t1 | msg1 |
| 2 | t2 | msg2 |

View File

@@ -0,0 +1,4 @@
|S. No|Title|Message|
|-----+:----+:-----:|
|1|t1|msg1|
|2|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 |
|--------+---------|

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

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

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

341
t/spreadsheet.vim Normal file
View File

@@ -0,0 +1,341 @@
" vim: fdm=indent
source t/config/options.vim
describe 'spreadsheet'
describe 'API'
before
new
read t/fixtures/sample.txt
end
it 'should return the row count'
Expect tablemode#spreadsheet#RowCount(2) == 2
Expect tablemode#spreadsheet#RowCount(3) == 2
end
it 'should return the row number'
Expect tablemode#spreadsheet#RowNr(2) == 1
Expect tablemode#spreadsheet#RowNr(3) == 2
end
it 'should return the column count'
Expect tablemode#spreadsheet#ColumnCount(2) == 2
Expect tablemode#spreadsheet#ColumnCount(3) == 2
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'
Expect tablemode#spreadsheet#GetFirstRow(2) == 2
Expect tablemode#spreadsheet#GetFirstRow(3) == 2
end
it 'should return the line nuber of the last row'
Expect tablemode#spreadsheet#GetLastRow(2) == 3
Expect tablemode#spreadsheet#GetLastRow(3) == 3
end
describe 'Math'
before
new
read t/fixtures/cell/sample.txt
end
it 'should return the sum of cell range'
call cursor(1,3)
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
it 'should return the average of cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#Average('1:2') == 2.0
Expect tablemode#spreadsheet#Average('1,1:1,2') == 1.5
Expect tablemode#spreadsheet#Average('1,1:2,2') == 2.5
call cursor(2,7)
Expect tablemode#spreadsheet#Average('1:2') == 3.0
Expect tablemode#spreadsheet#Average('2,1:2,2') == 3.5
end
it 'should return the min of cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#Min('1:2') == 1.0
Expect tablemode#spreadsheet#Min('1,1:1,2') == 1.0
Expect tablemode#spreadsheet#Min('1,1:2,2') == 1.0
call cursor(2,7)
Expect tablemode#spreadsheet#Min('1:2') == 2.0
Expect tablemode#spreadsheet#Min('2,1:2,2') == 3.0
end
it 'should return the max of cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#Max('1:2') == 3.0
Expect tablemode#spreadsheet#Max('1,1:1,2') == 2.0
Expect tablemode#spreadsheet#Max('1,1:2,2') == 4.0
call cursor(2,7)
Expect tablemode#spreadsheet#Max('1:2') == 4.0
Expect tablemode#spreadsheet#Max('2,1:2,2') == 4.0
end
end
describe 'Count'
before
new
read t/fixtures/cell/counts.txt
end
it 'should return the count of empty cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#CountE('1:3') == 1
Expect tablemode#spreadsheet#CountE('1,1:1,3') == 0
Expect tablemode#spreadsheet#CountE('2,1:2,3') == 2
Expect tablemode#spreadsheet#CountE('1,1:3,3') == 2
call cursor(3,11)
Expect tablemode#spreadsheet#CountE('1:3') == 1
Expect tablemode#spreadsheet#CountE('3,1:3,3') == 0
end
it 'should return the count of not-empty cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#CountNE('1:3') == 2
Expect tablemode#spreadsheet#CountNE('1,1:1,3') == 3
Expect tablemode#spreadsheet#CountNE('2,1:2,3') == 1
Expect tablemode#spreadsheet#CountNE('1,1:3,3') == 7
call cursor(3,11)
Expect tablemode#spreadsheet#CountNE('1:3') == 2
Expect tablemode#spreadsheet#CountNE('3,1:3,3') == 3
end
it 'should return the percent count of empty cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#PercentE('1:3') == 33
Expect tablemode#spreadsheet#PercentE('1,1:1,3') == 0
Expect tablemode#spreadsheet#PercentE('2,1:2,3') == 66
Expect tablemode#spreadsheet#PercentE('1,1:3,3') == 22
call cursor(3,11)
Expect tablemode#spreadsheet#PercentE('1:3') == 33
Expect tablemode#spreadsheet#PercentE('3,1:3,3') == 0
end
it 'should return the percent count of not-empty cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#PercentNE('1:3') == 66
Expect tablemode#spreadsheet#PercentNE('1,1:1,3') == 100
Expect tablemode#spreadsheet#PercentNE('2,1:2,3') == 33
Expect tablemode#spreadsheet#PercentNE('1,1:3,3') == 77
call cursor(3,11)
Expect tablemode#spreadsheet#PercentNE('1:3') == 66
Expect tablemode#spreadsheet#PercentNE('3,1:3,3') == 100
end
it 'should return the average of not-empty cell range'
call cursor(1,3)
Expect tablemode#spreadsheet#AverageNE('1:3') == 2.5
Expect tablemode#spreadsheet#AverageNE('1,1:1,3') == 2.0
Expect tablemode#spreadsheet#AverageNE('2,1:2,3') == 0.0
Expect tablemode#spreadsheet#AverageNE('1,1:3,3') == 3.0
call cursor(3,11)
Expect tablemode#spreadsheet#AverageNE('1:3') == 4.5
Expect tablemode#spreadsheet#AverageNE('3,1:3,3') == 5.0
end
end
end
describe 'Manipulations'
before
new
normal! ggdG
read t/fixtures/sample.txt
call cursor(2, 3)
end
it 'should delete a row successfully'
Expect tablemode#spreadsheet#RowCount('.') == 2
call tablemode#spreadsheet#DeleteRow()
Expect tablemode#spreadsheet#RowCount('.') == 1
end
it 'should successfully delete column'
Expect tablemode#spreadsheet#ColumnCount('.') == 2
call tablemode#spreadsheet#DeleteColumn()
Expect tablemode#spreadsheet#ColumnCount('.') == 1
end
it 'should successfully insert a column before the cursor'
Expect tablemode#spreadsheet#ColumnCount('.') == 2
call tablemode#spreadsheet#InsertColumn(0)
Expect tablemode#spreadsheet#ColumnCount('.') == 3
Expect getline('.') == '| | test11 | test12 |'
end
it 'should successfully insert a column after the cursor'
normal! $
Expect tablemode#spreadsheet#ColumnCount('.') == 2
call tablemode#spreadsheet#InsertColumn(1)
Expect tablemode#spreadsheet#ColumnCount('.') == 3
Expect getline('.') == '| test11 | test12 | |'
end
end
describe 'Manipulation of tables with headers'
before
new
normal! ggdG
let g:table_mode_header_fillchar = '='
read t/fixtures/complex_header.txt
call cursor(4, 7)
end
it 'should successfully delete a row '
Expect tablemode#spreadsheet#RowCount('.') == 5
call tablemode#spreadsheet#DeleteRow()
Expect tablemode#spreadsheet#RowCount('.') == 4
Expect getline(4) == '| 2 | 8 | b | y |'
end
it 'should successfully delete a column'
Expect tablemode#spreadsheet#ColumnCount('.') == 4
call tablemode#spreadsheet#DeleteColumn()
Expect tablemode#spreadsheet#ColumnCount('.') == 3
Expect getline(4) == '| 9 | a | z |'
end
it 'should successfully insert a column before the cursor'
Expect tablemode#spreadsheet#ColumnCount('.') == 4
call tablemode#spreadsheet#InsertColumn(0)
Expect tablemode#spreadsheet#ColumnCount('.') == 5
Expect getline(4) == '| | 1 | 9 | a | z |'
end
it 'should successfully insert a column after the cursor'
normal! $
Expect tablemode#spreadsheet#ColumnCount('.') == 4
call tablemode#spreadsheet#InsertColumn(1)
Expect tablemode#spreadsheet#ColumnCount('.') == 5
Expect getline(4) == '| 1 | 9 | a | z | |'
end
end
describe 'Repeated Manipulations'
before
new
normal! ggdG
read t/fixtures/big_sample.txt
call cursor(2, 3)
end
it 'should delete multiple rows correctly'
Expect tablemode#spreadsheet#RowCount('.') == 5
.,.+1 call tablemode#spreadsheet#DeleteRow()
Expect tablemode#spreadsheet#RowCount('.') == 3
end
it 'should delete multiple columns correctly'
Expect tablemode#spreadsheet#ColumnCount('.') == 4
.,.+1 call tablemode#spreadsheet#DeleteColumn()
Expect tablemode#spreadsheet#ColumnCount('.') == 2
end
it 'should insert multiple columns before the cursor correctly'
call cursor(2, 7)
Expect tablemode#spreadsheet#ColumnCount('.') == 4
execute "normal! 2:\<C-u>call tablemode#spreadsheet#InsertColumn(0)\<CR>"
Expect tablemode#spreadsheet#ColumnCount('.') == 6
Expect getline('.') == '| 1 | | | 9 | a | z |'
end
it 'should insert multiple columns after the cursor correctly'
call cursor(2, 7)
Expect tablemode#spreadsheet#ColumnCount('.') == 4
execute "normal! 2:\<C-u>call tablemode#spreadsheet#InsertColumn(1)\<CR>"
Expect tablemode#spreadsheet#ColumnCount('.') == 6
Expect getline('.') == '| 1 | 9 | | | a | z |'
end
end
describe 'Unicode table separators'
before
new
normal! ggdG
read t/fixtures/table/sample_realign_unicode_after.txt
call cursor(2, 19)
end
it 'should not prevent the deletion of rows'
Expect tablemode#spreadsheet#RowCount('.') == 4
call tablemode#spreadsheet#DeleteRow()
Expect tablemode#spreadsheet#RowCount('.') == 3
end
it 'should not prevent the deletion of columns'
Expect tablemode#spreadsheet#ColumnCount('.') == 3
call tablemode#spreadsheet#DeleteColumn()
Expect tablemode#spreadsheet#ColumnCount('.') == 2
end
it 'should not prevent the insertion of columns before the cursor'
Expect tablemode#spreadsheet#ColumnCount('.') == 3
call tablemode#spreadsheet#InsertColumn(1)
Expect tablemode#spreadsheet#ColumnCount('.') == 4
end
it 'should not prevent the insertion of columns after the cursor'
Expect tablemode#spreadsheet#ColumnCount('.') == 3
call tablemode#spreadsheet#InsertColumn(1)
Expect tablemode#spreadsheet#ColumnCount('.') == 4
end
end
describe 'Escaped table separators'
before
new
normal! ggdG
read t/fixtures/escaped_seperator.txt
call cursor(2, 3)
end
it 'should not prevent the deletion of rows'
Expect tablemode#spreadsheet#RowCount('.') == 7
call tablemode#spreadsheet#DeleteRow()
Expect tablemode#spreadsheet#RowCount('.') == 6
Expect getline('.') == '| a separator. | |'
end
it 'should not prevent the deletion of columns'
Expect tablemode#spreadsheet#ColumnCount('.') == 2
call tablemode#spreadsheet#DeleteColumn()
Expect tablemode#spreadsheet#ColumnCount('.') == 1
Expect getline('.') == '| It can be escaped by a \. |'
end
it 'should not prevent the insertion of columns'
Expect tablemode#spreadsheet#ColumnCount('.') == 2
call tablemode#spreadsheet#InsertColumn(1)
Expect tablemode#spreadsheet#ColumnCount('.') == 3
Expect getline('.') == '| The \| works as | | It can be escaped by a \. |'
end
end
end

184
t/table.vim Normal file
View File

@@ -0,0 +1,184 @@
" vim: fdm=indent
source t/config/options.vim
describe 'table'
describe 'IsRow'
before
new
normal! ggdG
read t/fixtures/table/sample.txt
end
it 'should be true when on a table row'
Expect tablemode#table#IsRow(2) to_be_true
Expect tablemode#table#IsRow(3) to_be_true
end
it 'should be false when not on a table row'
Expect tablemode#table#IsRow(1) to_be_false
Expect tablemode#table#IsRow(4) to_be_false
end
end
describe 'IsBorder'
before
new
normal! ggdG
read t/fixtures/table/sample_with_header.txt
end
it 'should be true on a table border'
Expect tablemode#table#IsBorder(1) to_be_true
Expect tablemode#table#IsBorder(3) to_be_true
Expect tablemode#table#IsBorder(6) to_be_true
end
it 'should be false when not on a table border'
Expect tablemode#table#IsBorder(2) to_be_false
Expect tablemode#table#IsBorder(4) to_be_false
Expect tablemode#table#IsBorder(5) to_be_false
end
end
describe 'IsTable'
before
new normal! ggdG
read t/fixtures/table/sample_with_header.txt
end
it 'should be true on a table row'
Expect tablemode#table#IsTable(2) to_be_true
Expect tablemode#table#IsTable(4) to_be_true
Expect tablemode#table#IsTable(5) to_be_true
end
it 'should be true when on a table border'
Expect tablemode#table#IsTable(1) to_be_true
Expect tablemode#table#IsTable(3) to_be_true
Expect tablemode#table#IsTable(6) to_be_true
end
it 'should not be true when not on a table'
Expect tablemode#table#IsTable(7) to_be_false
end
end
describe 'IsHeader'
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
new
normal! ggdG
read t/fixtures/table/sample_for_header_unicode.txt
end
it 'should add border to line'
call tablemode#table#AddBorder(1)
call tablemode#table#AddBorder(3)
call tablemode#table#AddBorder(5)
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
describe 'for unicode'
before
new
normal! ggdG
read t/fixtures/table/sample_realign_unicode_before.txt
end
it 'should be aligned properly'
call tablemode#table#Realign(1)
Expect getline(1,'$') == readfile('t/fixtures/table/sample_realign_unicode_after.txt')
end
end
end
describe 'with header alignments'
describe 'for simple'
before
new
normal! ggdG
read t/fixtures/table/sample_header_realign_before.txt
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
describe 'for unicode'
before
new
normal! ggdG
read t/fixtures/table/sample_header_realign_unicode_before.txt
end
it 'should be aligned properly'
call tablemode#table#Realign(1)
Expect getline(1,'$') == readfile('t/fixtures/table/sample_header_realign_unicode_after.txt')
end
end
end
end
end

View File

@@ -1,26 +1,11 @@
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_tableize_map = 't'
let g:table_mode_tableize_op_map = '<Leader>T'
let g:table_mode_realign_map = 'r'
let g:table_mode_cell_text_object = 'tc'
let g:table_mode_delete_row_map = 'dd'
let g:table_mode_delete_column_map = 'dc'
let g:table_mode_add_formula_map = 'fa'
let g:table_mode_eval_expr_map = 'fe'
call vspec#hint({'scope': 'tablemode#scope()', 'sid': 'tablemode#sid()'})
" vim: fdm=indent
source t/config/options.vim
describe 'tablemode'
describe 'Activation'
describe 'tablemode#TableModeEnable()'
describe 'tablemode#Enable()'
before
call tablemode#TableModeEnable()
call tablemode#Enable()
end
it 'should enable table mode'
@@ -28,9 +13,9 @@ describe 'tablemode'
end
end
describe 'tablemode#TableModeDisable()'
describe 'tablemode#Disable()'
before
call tablemode#TableModeDisable()
call tablemode#Disable()
end
it 'should disable table mode'
@@ -38,125 +23,34 @@ describe 'tablemode'
end
end
describe 'tablemode#TableModeToggle()'
describe 'tablemode#Toggle()'
it 'should toggle table mode'
call tablemode#TableModeToggle()
call tablemode#Toggle()
Expect b:table_mode_active to_be_true
call tablemode#TableModeToggle()
call tablemode#Toggle()
Expect b:table_mode_active to_be_false
end
end
end
describe 'API'
before
normal! ggdG
call tablemode#TableModeEnable()
normal! i
|test11|test12|
|test21|test22|
end
it 'should return true when inside a table'
Expect tablemode#IsATableRow(2) to_be_true
end
it 'should return false when outside a table'
Expect tablemode#IsATableRow(4) to_be_false
end
it 'should return the row count'
Expect tablemode#RowCount(2) == 2
Expect tablemode#RowCount(3) == 2
end
it 'should return the row number'
Expect tablemode#RowNr(2) == 1
Expect tablemode#RowNr(3) == 2
end
it 'should return the column count'
Expect tablemode#ColumnCount(2) == 2
Expect tablemode#ColumnCount(3) == 2
end
it 'should return the line number of the first row'
Expect tablemode#GetFirstRow(2) == 2
Expect tablemode#GetFirstRow(3) == 2
end
it 'should return the line nuber of the last row'
Expect tablemode#GetLastRow(2) == 3
Expect tablemode#GetLastRow(3) == 3
end
it 'should return the cells'
Expect Call('s:GetCells', 2, 1, 1) ==# 'test11'
" Get Rows
Expect Call('s:GetCells', 2, 1) == ['test11', 'test12']
Expect Call('s:GetCells', 2, 2) == ['test21', 'test22']
" Get Columns
Expect Call('s:GetCells', 2, 0, 1) == ['test11', 'test21']
Expect Call('s:GetCells', 2, 0, 2) == ['test12', 'test22']
end
it 'should return the cells in a range'
" Entire table as range
Expect Call('s:GetCellRange', '1,1:2,2', 2, 1) == [['test11', 'test21'], ['test12', 'test22']]
" Get Rows given different seed lines and columns
Expect Call('s:GetCellRange', '1,1:1,2', 2, 1) == ['test11', 'test12']
Expect Call('s:GetCellRange', '1,1:1,2', 2, 2) == ['test11', 'test12']
Expect Call('s:GetCellRange', '1,1:1,2', 3, 1) == ['test11', 'test12']
Expect Call('s:GetCellRange', '1,1:1,2', 3, 2) == ['test11', 'test12']
Expect Call('s:GetCellRange', '2,1:2,2', 2, 1) == ['test21', 'test22']
Expect Call('s:GetCellRange', '2,1:2,2', 2, 2) == ['test21', 'test22']
Expect Call('s:GetCellRange', '2,1:2,2', 3, 1) == ['test21', 'test22']
Expect Call('s:GetCellRange', '2,1:2,2', 3, 2) == ['test21', 'test22']
" Get Columns given different seed lines and column
Expect Call('s:GetCellRange', '1:2', 2, 1) == ['test11', 'test21']
Expect Call('s:GetCellRange', '1:2', 2, 2) == ['test12', 'test22']
Expect Call('s:GetCellRange', '1:2', 3, 1) == ['test11', 'test21']
Expect Call('s: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 Call('s:GetCellRange', '1:-1', 2, 1) == ['test11']
Expect Call('s:GetCellRange', '1:-1', 3, 1) == ['test11']
Expect Call('s:GetCellRange', '1:-1', 2, 2) == ['test12']
Expect Call('s:GetCellRange', '1:-1', 3, 2) == ['test12']
end
describe 'Tableize'
before
describe 'Tableize'
before
new
read t/fixtures/tableize.txt
end
it 'should tableize with default delimiter'
:2,3call tablemode#TableizeRange('')
end
it 'should tableize with default delimiter'
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('/;')
end
it 'should tableize with given delimiter'
:2,3call tablemode#TableizeRange('/;')
Expect tablemode#IsATableRow(2) to_be_true
Expect tablemode#RowCount(2) == 2
Expect tablemode#ColumnCount(2) == 2
end
end
describe 'Motions'
it 'should work'
TODO
end
end
Expect tablemode#table#IsRow(2) to_be_true
Expect tablemode#spreadsheet#RowCount(2) == 2
Expect tablemode#spreadsheet#ColumnCount(2) == 2
end
end
end

45
t/utils.vim Normal file
View File

@@ -0,0 +1,45 @@
" vim: fdm=indent
source t/config/options.vim
describe 'utils'
describe 'line'
it 'should return the current line number'
Expect tablemode#utils#line('.') == line('.')
end
it 'should return the line number itself if it is a number'
Expect tablemode#utils#line(1) == 1
end
end
describe 'strip'
it 'should strip all initial or trailing whitespace from a string'
let string = ' This is awesome '
Expect tablemode#utils#strip(string) == 'This is awesome'
end
end
describe 'strlen'
it 'should return the length of a string correctly'
let string = 'this is a test'
Expect tablemode#utils#strlen(string) == 14
end
it 'should return the length of a unicode string correctly'
let string = '測試 is good.'
Expect tablemode#utils#strlen(string) == 11
end
end
describe 'strdisplaywidth'
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 43 KiB