Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select text between double quotes over multiple lines in VIM

Let's say I have the following text:

"test 1
test 2
test 3"

I want to select everything between the quotes. I have used vi", but it does not work, it works only when the text is on a single line. On the other hand when when I have something like this:

(test1,
test 2)

and I type vi( it selects the entire text.

Any pointers would be greatly appreciated. Thanks

like image 664
Mihai Vinaga Avatar asked Feb 13 '14 12:02

Mihai Vinaga


4 Answers

The text objects that are delimited by identical characters (", ') only work within a line, because otherwise it would be difficult to determine what's the right scope to select.

If you want such a multi-line text object, you have to define your own alternative. Plugins like kana/vim-textobj-user or my own CountJump plugin help you with that.

With the latter, this can be as simple as this to override the built-in i' / a' / i" / a":

call CountJump#TextObject#MakeWithCountSearch('', "'", 'ai', 'v', "'", "'")
call CountJump#TextObject#MakeWithCountSearch('', '"', 'ai', 'v', '"', '"')
like image 131
Ingo Karkat Avatar answered Nov 11 '22 23:11

Ingo Karkat


The built in quote and double quote text object do not cross line boundaries. However you can use a search with vim's operators. e.g.

y/"<cr>
c/"<cr>FOO<esc>
d?"<cr>
like image 4
Peter Rincker Avatar answered Nov 11 '22 23:11

Peter Rincker


The vim-textobj-quotes plugin does exactly what you are looking for: https://github.com/beloglazov/vim-textobj-quotes

It provides text objects for the closest pairs of quotes of any type and supports quotes spanning multiple lines. Using only iq or aq it allows you to operate on the content of single ('), double ("), or back (`) quotes that currently surround the cursor, are in front of the cursor, or behind (in that order of preference). In other words, it jumps forward or backwards when needed to reach the quotes.

Please have a look at the github page linked above for more details.

like image 1
Anton Beloglazov Avatar answered Nov 11 '22 23:11

Anton Beloglazov


You can create the following mappings:

" Visual
nnoremap <silent> vi" ?"<CR><space>v/"<CR><BS>
nnoremap <silent> vi' ?'<CR><space>v/'<CR><BS>
nnoremap <silent> vi` ?`<CR><space>v/`<CR><BS>
nnoremap <silent> va" ?"<CR>v/"<CR>
nnoremap <silent> va' ?'<CR>v/'<CR>
nnoremap <silent> va` ?`<CR>v/`<CR>

" Delete
nnoremap <silent> di" ?"<CR><space>v/"<CR><BS>d
nnoremap <silent> di' ?'<CR><space>v/'<CR><BS>d
nnoremap <silent> di` ?`<CR><space>v/`<CR><BS>d
nnoremap <silent> da" ?"<CR>v/"<CR>d
nnoremap <silent> da' ?'<CR>v/'<CR>d
nnoremap <silent> da` ?`<CR>v/`<CR>d

" Change
nnoremap <silent> ci" ?"<CR><space>v/"<CR><BS>c
nnoremap <silent> ci' ?'<CR><space>v/'<CR><BS>c
nnoremap <silent> ci` ?`<CR><space>v/`<CR><BS>c
nnoremap <silent> ca" ?"<CR>v/"<CR>c
nnoremap <silent> ca' ?'<CR>v/'<CR>c
nnoremap <silent> ca` ?`<CR>v/`<CR>c

Source: https://gist.github.com/eruizc-dev/78964fa83b57dca687ec1bd0d1690aa9

like image 1
Emiliano Ruiz Avatar answered Nov 11 '22 22:11

Emiliano Ruiz