سؤال

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?

هل كانت مفيدة؟

المحلول

: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

نصائح أخرى

  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)

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

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top