I'm writing cucumber example tables, which are formatted like this:
| title | title |
| data | data |
| data | data |
How can I replace one of the data or title cells with a word of differing length without disturbing the layout?
I'm writing cucumber example tables, which are formatted like this:
| title | title |
| data | data |
| data | data |
How can I replace one of the data or title cells with a word of differing length without disturbing the layout?
If you were using Vim them you could use some alignment plugin, as mentioned on the question comments. Or you could use the vimwiki plugin, which provides several helpers to use tables.
As you are using VsVim, you could try to isolate the table formatting function in vimwiki/autoload/vimwiki/tbl.vim and adapt it in a VsVim plugin:
function! vimwiki#tbl#format(lnum, ...) "{{{
if !(&filetype ==? 'vimwiki')
return
endif
let line = getline(a:lnum)
if !s:is_table(line)
return
endif
if a:0 == 2
let col1 = a:1
let col2 = a:2
else
let col1 = 0
let col2 = 0
endif
let indent = s:get_indent(a:lnum)
if &expandtab
let indentstring = repeat(' ', indent)
else
let indentstring = repeat(' ', indent / &tabstop) . repeat(' ', indent % &tabstop)
endif
for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2)
let row = indentstring.row
call setline(lnum, row)
endfor
let &tw = s:textwidth
endfunction "}}}
Just copy paste the below functions (https://github.com/imbichie/vim-vimrc-/blob/master/MCCB_MCCE.vim) in your .vimrc or .gvimrc file and call the MCCB or MCCE function.
" MCCB - Move the Character to the Column from the Begin of line
" This is a function for Moving the specified Character
" in a given range of lines to a the specified Column from the Begin of the line
" NOTE 1 :- If the specified character and the first character of the line are same
" then the number of Occurrence (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range
" of lines should be less than or equal to 80, if we need more than 80
" then we need to insert more spaces by increasing the value 80 in the
" "nmap s 80i <ESC>" line inside the function
" Usage :- in command mode do it like below
" Eg 1:- :5,11call MCCB(1, '=', 8)
" The above command will move the 1st Occurrence from the begin of Character =
" to the 8th Column of the lines from 5 to 11
" Eg 2 :- :7,10call MCCB(2, '+', 12)
" The above command will move the 2nd Occurrence of Character + to the 12th
" Column of the lines from 7 to 10
function! MCCB (num_occr, mv_char, col_num) range
if (a:firstline <= a:lastline)
nmap s 80i <ESC>
let line_num = a:firstline
while line_num <= a:lastline
execute "normal " . line_num . "G0" . a:num_occr . "f" . a:mv_char . "s" . a:col_num . "|dw"
let line_num = line_num + 1
endwhile
nunmap s
else
execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
endif
endfunction
" MCCE - Move the Character to the Column from the End of line
" This is a function for Moving the specified Character
" in a given range of lines to a the specified Column from the End of the line
" NOTE 1 :- If the specified character and the last character of the line are same
" then the number of Occurrence (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range
" of lines should be less than or equal to 80, if we need more than 80
" then we need to insert more spaces by increasing the value 80 in the
" "nmap s 80i <ESC>" line inside the function
" Usage :- in command mode do it like below
" Eg 1:- :5,11call MCCE(1, ';', 20)
" The above command will move the 1st Occurrence from the End of Character ;
" to the 20th Column of the lines from 5 to 11
" Eg 2 :- :7,10call MCCE(5, ' ', 26)
" The above command will move the 5th Occurrence from the End of Character " " (white Space)
" to the 26th Column of the lines from 7 to 10
function! MCCE (num_occr, mv_char, col_num) range
if (a:firstline <= a:lastline)
nmap s 80i <ESC>
let line_num = a:firstline
while line_num <= a:lastline
execute "normal " . line_num . "G$" . a:num_occr . "F" . a:mv_char . "s" . a:col_num . "|dw"
let line_num = line_num + 1
endwhile
nunmap s
else
execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
endif
endfunction
nmap s
and nunmap s
it means that if I have s
mapped I'll loose my mapping after executing the function, am I right? If I understood it correctly I think it would be interesting to save the mapping of use 80i
directly in the execute
to avoid messing with the user configuration :-)
For what you've asked, there may be a simpler solution than employing alignment plugins. What you need is a text object for table cells:
For reference: http://learnvimscriptthehardway.stevelosh.com/chapters/15.html
onoremap ic :<c-u>normal! T\|vt\|<cr>
onoremap ac :<c-u>normal! F\|vf\|<cr>
I noticed the ic
, ac
(mnemonic: inside cell, around cell) objects are free, but you can of course change them to i|
a|
.
Then for changing the content of a cell, just press cic
or combine with whatever operator you need. (dac
: delete a cell)
For completeness, i found a mapping useful which creates a separator row:
inoremap \|\| <Esc>kyyp:s/\v[^\|]/-/g<CR>:nohlsearch<CR>
So that you can press || while starting a new row to copy the line above and essentially replace anything but pipes with a dash.
cic
(change inside cell), it collapses the cell to zero chars wide and I have to manually re-pad it with spaces, which is what I was hoping to avoid.
Commented
Feb 10, 2017 at 9:54
gaip*|
go aligned inside paragraph, split on every occurrence of |
). However, assuming you really have the layout already, and just do not want to crash it, really just use Replace Mode (as invoked by R
) when in appropriate position.
Commented
Feb 25, 2017 at 13:56
vic
and vac
don't work? Edit: it requires vnoremap
instead.
R
to overwrite text? (and possibly add some spaces)|
to get it to fire.R
. Since SpeckFlow realigns on|
can you docf|
and add your text?