diff --git a/CHANGELOG.md b/CHANGELOG.md index a10a3e4..a203902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ # Change Log +## Version 2.4.0 +* Added Table Cell text object. +* Added api to delete entire table row. +* Added api to delete entire table column. + +## Version 2.3.0 +* Refactored realignment logic. Generating borders by hand. + ## Version 2.2.2 * Added mapping for realigning table columns. * Added table motions to move around in the table. diff --git a/after/plugin/table-mode.vim b/after/plugin/table-mode.vim index 5cc1735..a5c37b4 100644 --- a/after/plugin/table-mode.vim +++ b/after/plugin/table-mode.vim @@ -4,7 +4,7 @@ " Author: Dhruva Sagar " License: MIT (http://www.opensource.org/licenses/MIT) " Website: http://github.com/dhruvasagar/vim-table-mode -" Version: 2.3.0 +" Version: 2.4.0 " 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. @@ -58,6 +58,9 @@ call s:SetGlobalOptDefault('table_mode_tableize_op_map', 'T') call s:SetGlobalOptDefault('table_mode_align', 'l1') call s:SetGlobalOptDefault('table_mode_realign_map', 'tr') call s:SetGlobalOptDefault('table_mode_motion_prefix', 't') +call s:SetGlobalOptDefault('table_mode_cell_text_object', 'tc') +call s:SetGlobalOptDefault('table_mode_delete_row_map', 'tdd') +call s:SetGlobalOptDefault('table_mode_delete_column_map', 'tdc') "}}}1 function! s:TableMotion() "{{{1 @@ -69,7 +72,7 @@ endfunction " }}}1 " Define Commands & Mappings {{{1 -if !g:table_mode_always_active +if !g:table_mode_always_active "{{{2 exec "nnoremap " . g:table_mode_toggle_map . \ " :call tablemode#TableModeToggle()" command! -nargs=0 TableModeToggle call tablemode#TableModeToggle() @@ -84,14 +87,21 @@ else \ table_mode_separator_map . ":call tablemode#TableizeInsertMode()a" unlet table_mode_separator_map endif +" }}}2 command! -nargs=? -range Tableize ,call tablemode#TableizeRange() + execute "xnoremap " . g:table_mode_tableize_map . " :Tableize" execute "nnoremap " . g:table_mode_tableize_map . " :Tableize" execute "xnoremap " . g:table_mode_tableize_op_map . " :call tablemode#TableizeByDelimiter()" execute "nnoremap " . g:table_mode_realign_map . " :call tablemode#TableRealign('.')" execute "nnoremap " . g:table_mode_motion_prefix . " :call TableMotion()" + +execute "onoremap " . g:table_mode_cell_text_object . " :call tablemode#CellTextObject()" + +execute "nnoremap " . g:table_mode_delete_row_map . " :call tablemode#DeleteRow()" +execute "nnoremap " . g:table_mode_delete_column_map . " :call tablemode#DeleteColumn()" "}}}1 " Avoiding side effects {{{1 diff --git a/autoload/tablemode.vim b/autoload/tablemode.vim index 2f0d5c5..3a2e074 100644 --- a/autoload/tablemode.vim +++ b/autoload/tablemode.vim @@ -4,7 +4,7 @@ " Author: Dhruva Sagar " License: MIT (http://www.opensource.org/licenses/MIT) " Website: http://github.com/dhruvasagar/vim-table-mode -" Version: 2.3.0 +" Version: 2.4.0 " 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. @@ -93,13 +93,17 @@ function! s:SetActive(bool) "{{{2 endfunction " }}}2 -function! s:GenerateBorder(line) "{{{2 - let line = 0 +function! s:Line(line) "{{{2 if type(a:line) == type('') - let line = line(a:line) + return line(a:line) else - let line = a:line + return a:line endif +endfunction +" }}}2 + +function! s:GenerateBorder(line) "{{{2 + let line = s:Line(a:line) let border = substitute(getline(line)[stridx(getline(line), g:table_mode_separator):-1], g:table_mode_separator, g:table_mode_corner, 'g') let border = substitute(border, '[^' . g:table_mode_corner . ']', g:table_mode_fillchar, 'g') @@ -118,27 +122,28 @@ endfunction " }}}2 function! s:UpdateLineBorder(line) "{{{2 - let cline = a:line + let line = s:Line(a:line) + let hf = s:StartExpr() . g:table_mode_corner . '[' . g:table_mode_corner . \ g:table_mode_fillchar . ']*' . g:table_mode_corner . '\?\s*$' - let border = s:GenerateBorder(cline) + let border = s:GenerateBorder(line) - let [prev_line, next_line] = [getline(cline-1), getline(cline+1)] + let [prev_line, next_line] = [getline(line-1), getline(line+1)] if next_line =~# hf - if next_line !=# border - call setline(cline+1, border) + if s:Strlen(border) > s:Strlen(s:GenerateBorder(line + s:RowGap())) || !tablemode#IsATableRow(line + s:RowGap()) + call setline(line+1, border) endif else - call append(cline, border) + call append(line, border) endif if prev_line =~# hf - if prev_line !=# border - call setline(cline-1, border) + if s:Strlen(border) > s:Strlen(s:GenerateBorder(line - s:RowGap())) || !tablemode#IsATableRow(line - s:RowGap()) + call setline(line-1, border) endif else - call append(cline-1, border) + call append(line-1, border) endif endfunction " }}}2 @@ -166,12 +171,58 @@ endfunction " }}}2 function! s:IsFirstCell() "{{{2 - return tablemode#TableColumnNr('.') ==# 1 + return tablemode#ColumnNr('.') ==# 1 endfunction " }}}2 function! s:IsLastCell() "{{{2 - return tablemode#TableColumnNr('.') ==# tablemode#ColumnCount('.') + return tablemode#ColumnNr('.') ==# tablemode#ColumnCount('.') +endfunction +" }}}2 + +function! s:MoveToFirstRow() "{{{2 + if tablemode#IsATableRow('.') + let line = s:Line('.') + while line > 0 + if !tablemode#IsATableRow(line) + break + endif + let line = line - s:RowGap() + endwhile + call cursor(line + s:RowGap(), col('.')) + endif +endfunction +" }}}2 + +function! s:MoveToLastRow() "{{{2 + if tablemode#IsATableRow('.') + let line = s:Line('.') + while line <= line('$') + if !tablemode#IsATableRow(line) + break + endif + let line = line + s:RowGap() + endwhile + call cursor(line - s:RowGap(), col('.')) + endif +endfunction +" }}}2 + +function! s:MoveToStartOfCell() "{{{2 + if getline('.')[col('.')-1] ==# g:table_mode_separator && !s:IsLastCell() + normal! 2l + else + execute 'normal! F' . g:table_mode_separator . '2l' + endif +endfunction +" }}}2 + +function! s:RowGap() "{{{2 + if g:table_mode_border + return 2 + else + return 1 + endif endfunction " }}}2 @@ -246,9 +297,6 @@ function! tablemode#TableRealign(line) "{{{2 let line = a:line endif - let rowCount = 1 - if g:table_mode_border | let rowCount = 2 | endif - let [lnums, lines] = [[], []] let tline = line while tline > 0 @@ -258,10 +306,10 @@ function! tablemode#TableRealign(line) "{{{2 else break endif - let tline = tline - rowCount + let tline = tline - s:RowGap() endwhile - let tline = line + rowCount + let tline = line + s:RowGap() while tline <= line('$') if tablemode#IsATableRow(tline) call add(lnums, tline) @@ -269,7 +317,7 @@ function! tablemode#TableRealign(line) "{{{2 else break endif - let tline = tline + rowCount + let tline = tline + s:RowGap() endwhile call tabular#TabularizeStrings(lines, g:table_mode_separator) @@ -277,6 +325,7 @@ function! tablemode#TableRealign(line) "{{{2 for lnum in lnums let index = index(lnums, lnum) call setline(lnum, lines[index]) + undojoin call s:UpdateLineBorder(lnum) endfor endfunction @@ -288,15 +337,7 @@ endfunction " }}}2 function! tablemode#RowCount(line) "{{{2 - let line = 0 - if type(a:line) == type('') - let line = line(a:line) - else - let line = a:line - endif - - let rowCount = 1 - if g:table_mode_border | let rowCount = 2 | endif + let line = s:Line(a:line) let [tline, totalRowCount] = [line, 0] while tline > 0 @@ -305,17 +346,17 @@ function! tablemode#RowCount(line) "{{{2 else break endif - let tline = tline - rowCount + let tline = tline - s:RowGap() endwhile - let tline = line + rowCount + let tline = line + s:RowGap() while tline <= line('$') if tablemode#IsATableRow(tline) let totalRowCount = totalRowCount + 1 else break endif - let tline = tline + rowCount + let tline = tline + s:RowGap() endwhile return totalRowCount @@ -323,15 +364,7 @@ endfunction " }}}2 function! tablemode#RowNr(line) "{{{2 - let line = 0 - if type(a:line) == type('') - let line = line(a:line) - else - let line = a:line - endif - - let rowCount = 1 - if g:table_mode_border | let rowCount = 2 | endif + let line = s:Line(a:line) let rowNr = 0 while line > 0 @@ -340,7 +373,7 @@ function! tablemode#RowNr(line) "{{{2 else break endif - let line = line - rowCount + let line = line - s:RowGap() endwhile return rowNr @@ -348,12 +381,7 @@ endfunction " }}}2 function! tablemode#ColumnCount(line) "{{{2 - let line = 0 - if type(a:line) == type('') - let line = line(a:line) - else - let line = a:line - endif + let line = s:Line(a:line) return s:Strlen(substitute(getline(line), '[^' . g:table_mode_separator . ']', '', 'g'))-1 endfunction @@ -375,12 +403,9 @@ endfunction function! tablemode#TableMotion(direction) "{{{2 if tablemode#IsATableRow('.') - let rowCount = 1 - if g:table_mode_border | let rowCount = 2 | endif - if a:direction ==# 'l' if s:IsLastCell() - if !tablemode#IsATableRow(line('.') + rowCount) | return | endif + if !tablemode#IsATableRow(line('.') + s:RowGap()) | return | endif call tablemode#TableMotion('j') normal! 0 endif @@ -393,7 +418,7 @@ function! tablemode#TableMotion(direction) "{{{2 endif elseif a:direction ==# 'h' if s:IsFirstCell() - if !tablemode#IsATableRow(line('.') - rowCount) | return | endif + if !tablemode#IsATableRow(line('.') - s:RowGap()) | return | endif call tablemode#TableMotion('k') normal! $ endif @@ -405,12 +430,62 @@ function! tablemode#TableMotion(direction) "{{{2 execute 'normal! 2F' . g:table_mode_separator . '2l' endif elseif a:direction ==# 'j' - if tablemode#IsATableRow(line('.') + rowCount) | execute 'normal ' . rowCount . 'j' | endif + if tablemode#IsATableRow(line('.') + s:RowGap()) | execute 'normal ' . s:RowGap() . 'j' | endif elseif a:direction ==# 'k' - if tablemode#IsATableRow(line('.') - rowCount) | execute 'normal ' . rowCount . 'k' | endif + if tablemode#IsATableRow(line('.') - s:RowGap()) | execute 'normal ' . s:RowGap() . 'k' | endif endif endif endfunction " }}}2 +function! tablemode#CellTextObject() "{{{2 + if tablemode#IsATableRow('.') + call s:MoveToStartOfCell() + + if v:operator ==# 'y' + normal! v + call search('[^' . g:table_mode_separator . ']\ze\s*' . g:table_mode_separator) + else + execute 'normal! vf' . g:table_mode_separator + endif + endif +endfunction +" }}}2 + +function! tablemode#DeleteColumn() "{{{2 + if tablemode#IsATableRow('.') + for i in range(v:count1) + call s:MoveToFirstRow() + call s:MoveToStartOfCell() + silent! execute "normal! h\f" . g:table_mode_separator + call s:MoveToLastRow() + normal! d + endfor + + call tablemode#TableRealign('.') + endif +endfunction +" }}}2 + +function! tablemode#DeleteRow() "{{{2 + if tablemode#IsATableRow('.') + for i in range(v:count1) + if tablemode#RowCount('.') ==# 1 + normal! kVjjd + else + normal! kVjd + endif + + if tablemode#IsATableRow(line('.')+1) + normal! j + else + normal! k + endif + endfor + + call tablemode#TableRealign('.') + endif +endfunction +" }}}2 + " }}}1 diff --git a/doc/table-mode.txt b/doc/table-mode.txt index 24f8df4..d17dbad 100644 --- a/doc/table-mode.txt +++ b/doc/table-mode.txt @@ -1,7 +1,7 @@ -*table-mode.txt* Table Mode for easy table formatting. v2.3.0 +*table-mode.txt* Table Mode for easy table formatting. v2.4.0 =============================================================================== Table Mode, THE AWESOME AUTOMATIC TABLE CREATOR & FORMATTER - VERSION 2.3.0 + VERSION 2.4.0 Author: Dhruva Sagar License: MIT @@ -34,21 +34,40 @@ make sure it is installed and loaded. =============================================================================== GETTING STARTED *table-mode-getting-started* -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 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. +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 + 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. -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 -|g:table-mode-always-active| if you wish. + 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 |g:table-mode-always-active| if you wish. -Table Mode allows for creation of tables within comments, it looks at the -'commentstring' setting to identify whether the current line is commented. + Table Mode allows for creation of tables within comments, it looks at + the 'commentstring' setting to identify whether the current line is + commented. -Table Mode enables conversion of delimited text into tables. Again like table -creation, this is also applicable within comments. +Tableize content: + Table Mode enables conversion of delimited text into tables. Again + like table creation, this is also applicable within comments. + +Manipulation of tables: + Tableize provides 3 easy ways to quickly manipulate tables. + + 1. Cell Text Object : A text object for table cell + defined by |table-mode-cell-text-object|. You can use it with an + operator (d,c,y) to manipulate it easily. If you delete the cell using + this, it will delete the table separator along with it so if you type + out some new stuff, you will have to re-add it, which triggers a + re-alignment and the table would be formatted again. + + 2. Delete Column : Delete an entire table column using + |table-mode-delete-column-map| . + + 3. Delete Row : Delete an entire table row using + |table-mode-delete-row-map| =============================================================================== OPTIONS *table-mode-options* @@ -69,6 +88,10 @@ Overview: |table-mode-no-border-padding| .. Set for no border padding. |table-mode-realign-map| ........ Set mapping for table realigning. |table-mode-motion-prefix| ...... Set prefix for table mode motions. + |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. g:table_mode_loaded *table-mode-loaded* Use this option to disable the plugin: > @@ -163,6 +186,36 @@ g:table_mode_motion_prefix *table-mode-motion-prefix* may also be preceeded with a [count]. The 'h', 'l' (left and right motions) wrap around the table row and move to the previous rows last column, next rows first column respectively if one exists. + +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 = 'tdd' + +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 = 'tdc' +< + =============================================================================== MAPPINGS *table-mode-mappings* @@ -189,6 +242,17 @@ MAPPINGS *table-mode-mappings* *table-mode-mappings-motions* t[hjkl] Move to previous | below | above | right cell in the table. + + *table-mode-mappings-delete-row* +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* +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. + =============================================================================== COMMANDS *table-mode-commands* @@ -244,4 +308,4 @@ REPORT ISSUES *table-mode-report-issues* If you discover any issues, please report them at http://github.com/dhruvasagar/table-mode/issues. - vim:tw=78:ts=8:ft=help:norl: + vim:tw=78:ts=8:ft=help:norl:ai