0

Want to find a way to do in vim what I usually do in other text editors. It's really hard to describe the problem, so I've created a gif and attached it to this question.

Initial document state:

inv/stage  
inv/production  
inv/test  
inv/robot  

I want to cut all invs, remove / before the word, add . after the word, and paste what had been cut. So in the end, the state of the document is:

stage.inv  
production.inv  
test.inv  
robot.inv  

enter image description here

1 Answers1

3

Here are several options:

  • A single substitute command. :[range]substitute,inv/\(\w\+\),\1.inv, (note the use of , as separator to avoid escaping the slash in inv/). If the inv was variable, use :s,\(\w\+\)/\(\w\+\),\2.\1, (and \v very magic mode makes some of those backslashes unnecessary).

  • A macro. Record qq0df/A.<esc>px and replay using any of @q+j@@ or :[range]normal! @q (where [range] selects your content; easiest in this case is vip:).

  • A recursive macro. Clear the register qqq and then record qq0df/A.<esc>pxj@q. Now replay once @q. Will stop at the end of the buffer or on a line not containing /, whichever comes first.

  • A single normal command. Similar to the macro, especially the :[range]normal! @q version. Just use :[range]normal! 0df/A.<esc>px, only this time you need to type the escape literally (using <C-v><esc>). Again, in this case, vip: gets you started with the :[range].

  • A global command. Avoid the range with :global,inv/, and either normal! or substitute afterwards.


You can cut the first bit with visual block mode, since it's so regular: <C-v>f/4jd. But pasting it won't work like you think, so then you're left with A.inv<esc> followed by repeating j. on each line. That's a bit slow to me: it took me longer to come up with than any of the 4 options above, and is slower to actually perform on anything more than one or two lines.

D. Ben Knoble
  • 26,070
  • 3
  • 29
  • 65