0

I am tidying up my vimrc.

Mission:
- Copy content inside single-quotes (and preferably after the slash)
- Paste them below line 1

1: Name:
2: 
3: Bundle 'tpope/vim-rails'
4: Bundle 'tpope/vim-endwise'
5: Bundle 'mileszs/ack.vim'
6: Bundle 'scrooloose/nerdcommenter'
7: Bundle 'kana/vim-textobj-entire'
8: Bundle 'kana/vim-textobj-user'

I know about the

:{source_address}t{target_address}

Ex command, and I know it accepts patterns. However, I am still not able to get it just right. I am also fairly new to regexes so bear with me. I tried something along the lines of (on a visual selection

:'<,'>/\/.*\'t1

Where I attempt to match a pattern that:

  • Starts with a /
  • May contain stuff in the middle .*
  • Ends with a '

Obviously I am off by some degree. Any ideas?

krystah
  • 3,136
  • 1
  • 22
  • 38

4 Answers4

2

:t copy the whole line, not the matchstr

to achieve what you want, you need matchstr() function.

this line will do the similar thing, but in reverse order. Hope it is ok for you:

:'<,'>g/\/.*'/call append(1,matchstr(getline('.'),@/))

for example, if I just select the first two "Bundle" lines, and execute the cmd, I get:

1: Name:
/vim-endwise'
/vim-rails'
2: 
3: Bundle 'tpope/vim-rails'
4: Bundle 'tpope/vim-endwise'
.... (other lines)

you see that the order was in reverse.

To keep the order you have options :

  • write script with list
  • select those "reversed" lines, and do '<,'>g/.*/m1
  • assign the matchstr to reg x, and 2put! x
Kent
  • 173,042
  • 30
  • 210
  • 270
  • Would you care to explain your append-parameters? From what I can make of it: Param 1: Destination. Param 2: Content. Content here being the result of the matchstr-function, which here basically gets the current line ., and returns whatever corresponds with the pattern from the previous search @/ Is that correct? – krystah Dec 11 '13 at 12:12
  • yes, it did something like that. you can `:h append(` and `:h matchstr(` to get detailed para info. @krystah – Kent Dec 11 '13 at 12:15
2
  1. Yank the block.
  2. Put it where you want it.
  3. Remove what you don't want.

Assuming the cursor is somewhere on line 1:

:3,8t.
:'[,norm dt/$x

Explanation:

  • '[ and '] mark the beginning and the end of the latest change.
  • We want the range to start on the first Bundle line so we start it with the '[ mark. We could simply use 2 instead, but that's less "magical".
  • It ends with the current line which we can omit because it's the default value.
  • We use :normal to execute normal mode commands from the command-line.
  • We delete until the first / (dt/) and delete the last char on the line ($x) in one go.

Another way:

:3,8t.
v'[
:'<,'>s/.*\/\(.*\)'/\1 ('<,'> being inserted automatically)
romainl
  • 158,436
  • 18
  • 236
  • 264
  • This works, but I was attempting to make a precise extraction from the string, as I already knew how to process the String when I had already moved it. Just my laziness. Nice heads up on the '[ :) – krystah Dec 11 '13 at 12:26
0

The problem with what you're doing is that ex commands work on lines, not on parts of lines like you're thinking. You can't use the :t command directly like that to copy what you need.

There's probably a way to do exactly what you're thinking, but here's what I would do to accomplish what you want: copy all of lines 3-8, paste them below line 1, and then isolate the text you're interested in.

There's a bunch of ways to copy a range of lines. If you need help with that, comment and ask.

Now how do we isolate the part in the quotes after the slash? We can just do a substitution, using basically the same pattern you wrote:

:'<,'>s/.*\/\(.*\)'/\1
pandubear
  • 1,297
  • 10
  • 17
0

The :t / :copy commands (as most Ex commands) always copy entire lines, not parts of it. For that, you need :substitute, and use side effects in its replace expression to gather them in a register. The Copy the search results into clipboard Vim Tips Wiki page explains this.

With my ExtractMatches plugin, this is quite easy to do, though:

:3,$YankMatchesToReg#/\zs.*\ze'#
:1put

This uses the /.*' pattern, and restricts the match (with the \zs and \ze atoms) to exclude the leading slash and trailing quote.

Without the plugin, it's probably easier to copy the full lines and then prune the undesired content with :s, as shown in @pandubear's answer.

Ingo Karkat
  • 154,018
  • 15
  • 205
  • 275