From 0b58003b68b11410eaa109df2df37af3a6127228 Mon Sep 17 00:00:00 2001 From: ibbem Date: Tue, 31 Mar 2020 19:56:31 +0200 Subject: [PATCH] Add support for inserting columns #130 Two mappings are introduced to enable usage of this feature like vim's pasting with p and P. --- README.md | 10 ++++++ autoload/tablemode.vim | 4 +++ autoload/tablemode/spreadsheet.vim | 51 ++++++++++++++++++++++++++++++ doc/table-mode.txt | 30 ++++++++++++++++++ plugin/table-mode.vim | 4 +++ t/config/options.vim | 2 ++ t/spreadsheet.vim | 46 +++++++++++++++++++++++++++ 7 files changed, 147 insertions(+) diff --git a/README.md b/README.md index 806f46d..15a881c 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,16 @@ it using `:TableModeRealign` or using the default mapping (provided you are within a table row), this can also be preceeded with a [count] to delete multiple columns. + - **Insert Column** : + + You can use the \tic 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 + \tiC 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 diff --git a/autoload/tablemode.vim b/autoload/tablemode.vim index 5354db3..e00c0d8 100644 --- a/autoload/tablemode.vim +++ b/autoload/tablemode.vim @@ -40,6 +40,8 @@ function! s:ToggleMapping() "{{{2 call s:Map('(table-mode-realign)', g:table_mode_realign_map, 'n') call s:Map('(table-mode-delete-row)', g:table_mode_delete_row_map, 'n') call s:Map('(table-mode-delete-column)', g:table_mode_delete_column_map, 'n') + call s:Map('(table-mode-insert-column-before)', g:table_mode_insert_column_before_map, 'n') + call s:Map('(table-mode-insert-column-after)', g:table_mode_insert_column_after_map, 'n') call s:Map('(table-mode-add-formula)', g:table_mode_add_formula_map, 'n') call s:Map('(table-mode-eval-formula)', g:table_mode_eval_formula_map, 'n') call s:Map('(table-mode-echo-cell)', g:table_mode_echo_cell_map, 'n') @@ -57,6 +59,8 @@ function! s:ToggleMapping() "{{{2 call s:UnMap(g:table_mode_realign_map, 'n') call s:UnMap(g:table_mode_delete_row_map, 'n') call s:UnMap(g:table_mode_delete_column_map, 'n') + call s:UnMap(g:table_mode_insert_column_before_map, 'n') + call s:UnMap(g:table_mode_insert_column_after_map, 'n') call s:UnMap(g:table_mode_add_formula_map, 'n') call s:UnMap(g:table_mode_eval_formula_map, 'n') call s:UnMap(g:table_mode_echo_cell_map, 'n') diff --git a/autoload/tablemode/spreadsheet.vim b/autoload/tablemode/spreadsheet.vim index 4bebec3..5d7d87d 100644 --- a/autoload/tablemode/spreadsheet.vim +++ b/autoload/tablemode/spreadsheet.vim @@ -187,6 +187,57 @@ function! tablemode#spreadsheet#DeleteRow() "{{{2 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 + execute "normal! f".g:table_mode_separator + endif + execute "normal! h\" + 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."p2l" + else + execute "normal! ".quantity."Pl" + endif + + call tablemode#table#Realign('.') + endif +endfunction + function! tablemode#spreadsheet#Sum(range, ...) abort "{{{2 let args = copy(a:000) call insert(args, a:range) diff --git a/doc/table-mode.txt b/doc/table-mode.txt index 5afd671..ae9a407 100644 --- a/doc/table-mode.txt +++ b/doc/table-mode.txt @@ -75,6 +75,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 : @@ -165,6 +169,12 @@ Overview: |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 @@ -286,6 +296,16 @@ 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 = '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 = '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 = '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. > @@ -379,6 +399,16 @@ MAPPINGS *table-mode-mappings* with a [count] to delete multiple columns to the right. You can change this using |table-mode-delete-column-map| option. + *table-mode-mappings-insert-column-before* +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* +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* tfa Add a fomula for the current table cell. This invokes |TableAddFormula| command. diff --git a/plugin/table-mode.vim b/plugin/table-mode.vim index f266f4a..099d316 100644 --- a/plugin/table-mode.vim +++ b/plugin/table-mode.vim @@ -40,6 +40,8 @@ call s:SetGlobalOptDefault('table_mode_cell_text_object_i_map', 'i') 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.'?') @@ -102,6 +104,8 @@ xnoremap (table-mode-cell-text-object-i) :call tablemode#spr nnoremap (table-mode-delete-row) :call tablemode#spreadsheet#DeleteRow() nnoremap (table-mode-delete-column) :call tablemode#spreadsheet#DeleteColumn() +nnoremap (table-mode-insert-column-before) :call tablemode#spreadsheet#InsertColumn(0) +nnoremap (table-mode-insert-column-after) :call tablemode#spreadsheet#InsertColumn(1) nnoremap (table-mode-add-formula) :call tablemode#spreadsheet#formula#Add() nnoremap (table-mode-eval-formula) :call tablemode#spreadsheet#formula#EvaluateFormulaLine() diff --git a/t/config/options.vim b/t/config/options.vim index fa3fbdd..a330d7e 100644 --- a/t/config/options.vim +++ b/t/config/options.vim @@ -22,6 +22,8 @@ let g:table_mode_cell_text_object_i_map = 'i' let g:table_mode_realign_map = 'tr' let g:table_mode_delete_row_map = 'tdd' let g:table_mode_delete_column_map = 'tdc' +let g:table_mode_insert_column_before_map = 'tiC' +let g:table_mode_insert_column_after_map = 'tic' let g:table_mode_add_formula_map = 'tfa' let g:table_mode_eval_formula_map = 'tfe' let g:table_mode_echo_cell_map = 't?' diff --git a/t/spreadsheet.vim b/t/spreadsheet.vim index fbcd31f..c60073b 100644 --- a/t/spreadsheet.vim +++ b/t/spreadsheet.vim @@ -101,6 +101,21 @@ describe 'spreadsheet' 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' @@ -125,6 +140,21 @@ describe 'spreadsheet' 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' @@ -146,5 +176,21 @@ describe 'spreadsheet' .,.+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:\call tablemode#spreadsheet#InsertColumn(0)\" + 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:\call tablemode#spreadsheet#InsertColumn(1)\" + Expect tablemode#spreadsheet#ColumnCount('.') == 6 + Expect getline('.') == '| 1 | 9 | | | a | z |' + end end end