Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim - capture in between slashes?

Is there a motion for capturing text in between / or \? I know there is motions for other symbols ---

ci" - Capture 'text' inside "text"

vi( - Visual capture int var inside foo(int var)

di[ - Delete word [word] into []

The only workaround I can find is by using Vim Surround, and using it to change surrounding \ into " (cs\"), and then working from there. However, not only is it that kind of tedious, but the plugin only supports backslashes, not forward.

like image 202
dook Avatar asked May 14 '14 22:05

dook


3 Answers

You could write your own text-object for this pretty easily.

onoremap <silent> i/ :<C-U>normal! T/vt/<CR> " inside /
onoremap <silent> a/ :<C-U>normal! F/vf/<CR> " around /

For it to work with visual mode :

xnoremap <silent> i/ :<C-U>normal! T/vt/<CR> " inside /
xnoremap <silent> a/ :<C-U>normal! F/vf/<CR> " around /

Similarly you could also do for \

Edit: Added info comments.

like image 199
Dhruva Sagar Avatar answered Oct 19 '22 19:10

Dhruva Sagar


Here's one way to do it with a mapping:

  nnoremap H mal??e+1<Enter>mb//<Enter>y`b`a

This mapping will yank everything between two occurrences of the last search pattern.

Place it in your .vimrc file to make it permanent.

Usage for your question:

  • search for forward slash: /\/ (note the backslash escape character)
  • position cursor between two slashes (or on second slash)
  • press H

Everything between the last / and the next / will get yanked.

Explanation:

  nnoremap H mal??e+1<Enter>mb//<Enter>y`b`a

 - nnoremap H      map H in normal mode, ignoring other mappings    
 - ma              place a mark (named a) at the current cursor location
 - l               move the cursor one char to the right
 - ??e+1<Enter>    move to 1 character after END of prev occurrence of last search pattern
 - mb              place a mark (named b) at the current cursor location
 - //<Enter>       go to the beginning of the next occurrence of the last search pattern
 - y`b             yank to the location of the mark named x (note: ` = "back tick")
 - `a              go to the mark named `a`

Example input:

This is a *funky* string
  • search for *
  • position cursor between two asterisks (or on 2nd asterisk)
  • press H

The word funky will be in the yank buffer.

You can use words as delimeters!

Example input:

<br>
Capture all this text.
<br>
  • search for <br>
  • press H in normal mode when between <br>s (or on 2nd <br>)

You can use regexes, too!

Example input:

<p>
Capture this paragraph.
</p>
  • search for <.\?p> (or <\/\{,1}p> to be more correct)
  • press H in normal mode when inside the paragraph (or on closing <p> tag)

...

A better approach might be to use a register to remember a delimiter, so you can use this mapping quickly and/or repeatedly. In other words, you could store / or \ or <\?p> in a register and use that to quickly capture text between your stored delimiter.

like image 3
jahroy Avatar answered Oct 19 '22 20:10

jahroy


there is no built-in text object with slash. However there are plugins support customized text-object, like: targets

like image 2
Kent Avatar answered Oct 19 '22 20:10

Kent