You can create a blockwise text object to do this kind of job, if you bound it to ic
, you can copy with yic
, select it with vic
, no count needed. But it's not easy, feel free to skip it and use some existing plugins, forgot the plugin name, you can google it.
Text object can be created directly or from a motion. I prefer motion in this case, there has no vertical word style motion in vim, you must create it by yourself. B Layer gives some good idea on how to do it here. My code is based on his:
" vertical E,W,B. it's too much trouble to implement e,w,b.
function! misc#mo#vertical_motion(motion)
" changed from https://vi.stackexchange.com/questions/15151/move-to-the-first-last-non-whitespace-character-of-the-column-vertical-w-b-e
let curcol = virtcol('.')
let nextcol = curcol + 1
if a:motion ==# 'E'
" %dv : restrict virtual column
" \S.* : start from non-blank character
" (\n.*%%<%dv$|\n.*%%%dv\s|%%$)
" \n.*%%<%dv$ : next line that's too short
" \n.*%%%dv\s : next line that's empty in this column
" %%$ : end of file
let pattern = printf('\v%%%dv\S.*(\n.*%%<%dv$|\n.*%%%dv\s|%%$)', curcol, nextcol, curcol)
let flag = 'W'
elseif a:motion == 'B'
let pattern = printf('\v^.*(%%<%dv$|%%%dv\s.*)\n.*\zs%%%dv\S', nextcol, curcol, curcol)
let flag = 'bW'
elseif a:motion == 'W'
let pattern = printf('\v^.*(%%<%dv$|%%%dv\s.*)\n.*\zs%%%dv\S', nextcol, curcol, curcol)
let flag = 'W'
else
echohl ErrorMsg | echo 'Not a valid motion: ' . a:motion | echohl None
endif
call search(pattern, flag)
endfunction
I bind these motions to sequence starts with ,
:
nnoremap ,e :call misc#mo#vertical_motion('E')<cr>
nnoremap ,w :call misc#mo#vertical_motion('W')<cr>
nnoremap ,b :call misc#mo#vertical_motion('B')<cr>
vnoremap ,e :<c-u>exec 'norm! gv' <bar> call misc#mo#vertical_motion('E')<cr>
vnoremap ,w :<c-u>exec 'norm! gv' <bar> call misc#mo#vertical_motion('W')<cr>
vnoremap ,b :<c-u>exec 'norm! gv' <bar> call misc#mo#vertical_motion('B')<cr>
onoremap ,e :normal v,e<cr>
onoremap ,w :normal v,w<cr>
onoremap ,b :normal v,b<cr>
After that, it's trivial to create text object:
function! misc#to#verticalE() abort
exec "norm! \<c-v>"
call misc#mo#vertical_motion('E')
endfunction
vnoremap ic :<c-u>call misc#to#verticalE()<cr>
onoremap ic :normal vic<cr>
:line,line yank
, paste them, and delete (possibly via:subsitute
) all the characters except a specific column. Can write an answer later perhaps.