10

Quite often I find myself in need of performing a substitution that will have matches sparsed all over a large file and with non-trivial search and replacement expressions.

For example, say I have some function calls like okFunction(arg1, arg2 arg3). The args will differ with every function call, of course. Now say I have discovered a better function that doesn't need arg2. I can easily adjust the entire file with

:%s/\<okFunction(\(\w\+\), \(\w\+\), \(\w\+\))/betterFunction(\1, \3)/gc

Although conceptually simple, I'm not sure I have got the syntax right in this rather long pattern. The c flag really helps here, but the problem is that when asking for confirmation, vim will not show what the match will be replaced with. I mean, it will show the replacement expression, but not the evaluated result. If I confirm the substitution with y, vim will immediately jump to the next match and I won't be abe to see if I made any mistakes.

I have found the vim-over plugin that partially solves the problem, but only if all mathes are visible on the screen when you are typing the command. Once you hit enter, the behavior is the exact same I described above and I don't get a preview.

So, is there a way to get vim to evaluate the replacement expression when asking for confirmation on substitute commands?

5
  • 2
    that is a whishlist item in the vim-bug tracker (sorry don't find it currently) Dec 14, 2016 at 15:19
  • 2
    For what it's worth I usually use the substitution on the first line to replace without the %, check that the result is what I was expecting and then use the substitution with % (it's only a few keystrokes: :<up><c-b>%). Clearly a preview option would be much more efficient than that. While no patch is available maybe one could wrap the substitution in a vimscript function with this kind of option but that sounds like a lot of work...
    – statox
    Dec 14, 2016 at 16:38
  • 2
    @ChristianBrabandt Found it. It's as of yet with unclassified priority...
    – Vitor Eiji
    Dec 14, 2016 at 19:50
  • 2
    @VitorEiji that was not the one I was thinking of. But it doesn't actually matter, since it is not currently possible. Neovim provides the 'inccommand' option, that might work (or not, I don't really now) Dec 14, 2016 at 21:26
  • Evil previews the substitution; I don't know how it does it, though.
    – Geremia
    Apr 10, 2019 at 21:30

1 Answer 1

3

One workaround is macros. Highlight all problem areas and do the substitution on one line at a time. Then decide if you want it or not. Once your done n to the next area.

For your case specifically:

  1. Search for areas: /\<okFunction(\(\w\+\), \(\w\+\), \(\w\+\))
  2. Start recording a macro qq.
  3. Apply :s/\<okFunction(\(\w\+\), \(\w\+\), \(\w\+\))/betterFunction(\1, \3)/g
  4. Stop recording macro q
  5. Either undo (u) or go to next search result (n).
  6. Apply macro @q.
  7. Repeat steps 5 and 6 as needed.

Obviously not quite what you were looking for, but this usually what I do.

4
  • thats cool! I never realised that when you do a search with / it also behaves as a visual selection - nice. Dec 18, 2016 at 7:56
  • @the_velour_fog "/...behaves as a visual selection." Actually it doesn't. The reason why this works is because :s// acts on the current line and using n takes you to the next occurrence.
    – Tumbler41
    Dec 19, 2016 at 16:37
  • 1
    If you don't specify a pattern for :s/pattern/replacement it'll use the last search string, so in step 3 you can actually apply :s//betterFunction(\1, \3)/g to save some typing.
    – Haegin
    Dec 19, 2016 at 19:52
  • @Tumbler41 ah, thanks for clarifying. Yes I also do this basic technique of search, then apply macro, I usually populate the arglist first and use :vimgrep /pattern/ ## then apply macro, that way if it turns out my pattern is actually matching consistently and the macro thing is too tedious, I can then quickly revert to :argdo %s/.../..../gc and start flying through the operation Dec 19, 2016 at 23:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.