Is it possible to delete the current visual block selection and all other occurences from the current buffer?
-
2It is possible, but can be tricky (and it certainly involves vimscript). One would have to transform the block selection into a regular expression that takes into account each row of the selection, so that you would have to have each row matched, in turn, in consecutive lines; what might be tricky is the requirement of strict column alignment matching, if that too is desired.– VanLaserNov 13, 2016 at 11:44
2 Answers
It's probably not completely reliable, but you could try this:
xno <silent> mbc :<C-U>call <SID>move_blocks(1)<CR>
xno <silent> mbd :<C-U>call <SID>move_blocks(0)<CR>
fu! s:move_blocks(clean_them_only) abort
let view = winsaveview()
let block = s:get_its_text()
call cursor(1,1)
while s:you_find_a(block)
let orig_pos = getpos('.')
call s:remove_it(block, a:clean_them_only)
call setpos('.', orig_pos)
endwhile
if !a:clean_them_only
sil! exe "keepj keepp %s/\<C-A>//g"
endif
call winrestview(view)
endfu
fu! s:get_its_text() abort
let unnamed_reg_contents = getreg('"')
let unnamed_reg_type = getregtype('"')
sil norm! gvy
let block = split(@", "\n")
call setreg('"', unnamed_reg_contents, unnamed_reg_type)
return block
endfu
fu! s:you_find_a(block) abort
let block = a:block
let pattern_first_line = '\V'.escape(block[0],'\')
let found_its_first_line = search(pattern_first_line, 'cW')
while found_its_first_line
let orig_pos = getpos('.')
let idx_line = line('.')+1
let start_col = col('.')
let rest_of_block = block[1:]
if !s:is_complete(rest_of_block, idx_line, start_col)
let found_its_first_line = search(pattern_first_line, 'W')
continue
endif
call setpos('.', orig_pos)
return 1
endwhile
return 0
endfu
fu! s:is_complete(rest_of_block, idx_line, start_col) abort
let orig_pos = getpos('.')
let idx_line = a:idx_line
let start_col = a:start_col
let rest_of_block = a:rest_of_block
let rest_is_there_too = 1
for text in rest_of_block
let pattern_subsequent_line = '\V\%'.idx_line.'l\%'.start_col.'c'.
\ escape(text,'\')
if !search(pattern_subsequent_line, 'W')
let rest_is_there_too = 0
break
endif
let idx_line += 1
endfor
call setpos('.', orig_pos)
return rest_is_there_too
endfu
fu! s:remove_it(block, clean_them_only) abort
let block = a:block
let idx_line = line('.')
let start_col = col('.')
for text in block
let pattern_block_line = '\V\%'.idx_line.'l\%'.start_col.'c'.escape(text,'\')
let replacement = '\=repeat("'.
\ (a:clean_them_only?' ':"\<C-A>").
\ '",'.len(text).')'
sil! exe 'keepj keepp '.idx_line.
\ 's/'.pattern_block_line.'/'.replacement.'/'
let idx_line += 1
endfor
endfu
It installs 2 mappings in visual mode triggered by the mbc
and mbd
key sequences.
To use it, you would have to visually select the block you want to remove and hit mbc
to replace all occurrences with spaces, or hit mbd
to remove them entirely.
I didn't test it very long, and only on this sample text:
debitis Elit sit distinctio saepe debitis voluptatibus eveniet. Pariatur accusantium
Eius cumque hic eligendi magnam? Eius ducimus maxime fugiat sed eum. Earum at cumque
quisquam at quia nulla Nihil porro quisquam impedit est?
Elit sit distinctio saepe debitis voluptatibus eveniet. Pariatur accusantium
cumque hic eligendi magnam? Eius ducimus maxime fugiat sed eum. Earum at cumque
at quia nulla Nihil porro quisquam impedit est?
Elit sit distinctio saepe debitis voluptatibus eveniet. Pariatur accusantium
cumque hic eligendi magnam? ducimus maxime fugiat debitis sed eum. Earum at cumque
debitis at quia nulla Nihi quisquam impedit est? Eius
Eius quisquam
quisquam Elit sit distinctio saepe debitis voluptatibus eveniet. Pariatur accusantium
cumque hic eligendi debitis magnam? Eius ducimus maxime fugiat sed eum. Earum at cumque
at quia nulla Nihil Eius porro quisquam impedit est?
quisquam
Elit sit distinctio saepe debitis voluptatibus eveniet. Pariatur accusantium debitis
cumque hic eligendi magnam? Eius ducimus maxime fugiat sed eum. Earum at cumque Eius
at quia nulla Nihil porro quisquam impedit est? quisquam
I tried to remove this block:
debitis
Eius
quisquam
But there may be cases where it won't, I don't know.
-
Not sure if I'm doing wrong but I don't get it working. Also, e.g.
vic
does nothing for me, at least not visible :D Apr 7, 2017 at 17:19
You could do something like
visual
around the block you want to delete, hit y
to yank, and then do :%s/<C-R>"//
to replace all instances of it with empty text.
-
Have you tried this? If you did, you would see that it won't work. Nov 13, 2016 at 6:25
-
-
2Ok. Well, If you select a visual block with
<c-v>
that spans multiple rows, then your suggestion will not work. Nov 14, 2016 at 21:14