Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vim - surround text with function call

Tags:

vim

surround

I want to wrap some code :

myObj.text;

with a function call where the code is passed as an argument.

console.log(myObj.text);

I've thought about using surround.vim to do that but didn't manage to do it.

Any idea if it's possible ? I

like image 326
Florian F Avatar asked Jul 27 '17 15:07

Florian F


3 Answers

With Surround in normal mode:

ysiwfconsole.log<CR>

With Surround in visual mode:

Sfconsole.log<CR>

Without Surround in normal mode:

ciwconsole.log(<C-r>")<Esc>

Without Surround in visual mode:

cconsole.log(<C-r>")<Esc>

But that's not very scalable. A mapping would certainly be more useful since you will almost certainly need to do it often:

xnoremap <key> cconsole.log(<C-r>")<Esc>
nnoremap <key> ciwconsole.log(<C-r>")<Esc>

which brings us back to Surround, which already does that—and more—very elegantly.

like image 177
romainl Avatar answered Nov 08 '22 11:11

romainl


I know and use two different ways to accomplish this:


Variant 1:

  1. Select the text you want to wrap in visual mode (hit v followed by whatever movements are appropriate).

  2. Replace that text by hitting c, then type your function call console.log(). (The old text is not gone, it's just moved into a register, from where it will be promptly retrieved in step 3.) Hit <esc> while you are behind the closing parenthese, that should leave you on the ) character.

  3. Paste the replaced text into the parentheses by hitting P (this inserts before the character you are currently on, so right between the ( and the )).

The entire sequence is v<movement>c<functionName>()<esc>P.


Variant 2:

Alternatively to leaving insert mode and pasting from normal mode, you can just as well paste directly from insertion mode by hitting <ctrl>R followed by ".

The entire sequence is v<movement>c<functionName>(<ctrl>R")<esc>.

like image 6
cmaster - reinstate monica Avatar answered Nov 08 '22 11:11

cmaster - reinstate monica


You can use substitution instruction combined with visual mode

To change bar to foo(bar):

  1. press v and select text you want (plus one more character) to surround with function call (^v$ will select whole text on current line including the newline character at the end)

  2. type :s/\%V.*\%V/foo\(&\)/<CR>

Explanation:

  • s/a/b/g means 'substitute first match of a with b on current line'
  • \%V.*\%V matches visual selection without last character
  • & means 'matched text' (bar in this case)
  • foo\(&\) gives 'matched text surrounded with foo(...) '
  • <CR> means 'press enter'

Notes

  • For this to work you have to visually select also next character after bar (^v$ selects also the newline character at the end, so it's fine)
  • might be some problems with multiline selections, haven't checked it yet
  • when I press : in visual mode, it puts '<,'> in command line, but that doesn't interfere with rest of the command (it even prevents substitution, when selected text appears also somewhere earlier on current line) - :'<,'>s/... still works
like image 1
Przemysław Czechowski Avatar answered Nov 08 '22 11:11

Przemysław Czechowski