Question

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

Was it helpful?

Solution

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', '"', '"')

OTHER TIPS

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>

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top