Parsa
Parsa

Reputation: 1065

Multiline search/replace in Vim without escaping

It's a very typical for me to copy a text to clipboard, and replace all occurrences of that text with something else. I have no clue how to use Vim's :substitute to do so. You can insert the content of a register with Ctrl+RCtrl+Rregister, but you would still have to escape the text, and I couldn't find any reasonable way to do it with a multiline text.

Say you want to replace FROM @SERVER: PING :/\SERVER<CR>command: ping, source: None, target: @SERVER, arguments: ['@SERVER'] which you already have in register q with ACK @SERVER1 in the text below:

Sample text:

FROM @SERVER: PING :/\SERVER
command: ping, source: None, target: @SERVER, arguments: ['@SERVER']
TO @SERVER: PONG SERVER
FROM @SERVER: PING :/\SERVER
command: ping, source: None, target: @SERVER, arguments: ['@SERVER']
TO @SERVER: PONG /\SERVER
FROM SERVER: user2 PRIVMSG !CNL :#user1: what's up?
command: pubmsg, source: #user2, target: !CNL, arguments: ["#user1: what's up?"]
FROM @SERVER: PING :/\SERVER
command: ping, source: None, target: @SERVER, arguments: ['@SERVER']
TO @SERVER: PONG /\SERVER
FROM @SERVER: PING :/\SERVER
command: ping, source: None, target: @SERVER, arguments: ['@SERVER']
TO @SERVER: PONG /\SERVER

Upvotes: 0

Views: 336

Answers (1)

Ingo Karkat
Ingo Karkat

Reputation: 172510

With the first two lines of your example in the default register (e.g. via y2$), you can build a replacement command like this:

:%s/\V<C-r>=substitute(escape(@@, '/\'), '\n', '\\n', 'g')<CR>/REPLACEMENT/g

What it does:

  • literal matching via \V
  • backslashes still need to be escaped, and the / separator of :substitute, too
  • a newline needs to be translated to the \n regular expression atom
  • all of that is inserted into the command-line via <C-r> and the expression register

Upvotes: 3

Related Questions