95

I actually have a pretty similar workflow to yours, (copying and pasting blocks that are similar, then using :s to change variable names) especially when I'm writing lots of lines that are similar except for which variable they use. But there are a couple things I do that you might find useful. General vim things The first thing that will help you is ...


49

:'<,'>s/\%V\ /\,0x/g %V matches inside the visual area. See :help %V.


36

To edit file non-interactively using ex (vi is the visual mode for ex), you can use +{command} or -c {command} parameters which allows you to execute the vi commands after the first file has been read. The ex is a standard command-line editor (similar to ed). There is also vipe (a Vim command pipe editor) should be used which is part of moreutils package ...


29

Just to be clear… I believe you asked for this to be the result of the substitution? ############################################################################### # Trackpad, mouse, keyboard, Bluetooth accessories, and input # ############################################################################### running "Trackpad: enable tap to ...


26

Yes! Use the c flag for :substitute. From :help substitute: [c] Confirm each substitution. Vim highlights the matching string (with hl-IncSearch). You can type: :s_c 'y' to substitute this match 'l' to substitute this match and then quit ("last") 'n' to skip this match ...


26

From :help :global: Instead of the '/' which surrounds the {pattern}, you can use any other single byte character, but not an alphabetic character, '', '"' or '|'. This is useful if you want to include a '/' in the search pattern or replacement string. Also see :help pattern-delimiter. As you already devised from your experimentation, this is to ...


23

The c_CTRL-R family of maps can improve your workflow quite a bit: You need not type variable names when using :s/, just use CTRL-R CTRL-W to insert the word under the cursor into the command line (caveat: this does not escape special characters, like * does). After making a small change using ce, you can search for the old word using / CTRL-R -. Then use ....


22

In addition to what Carpetsmoker said: The &incsearch (set incsearch) setting in Vim is really useful. You can use it together with a useful and little known trick. The trick is to try out your complex regex by just using the / or ? command. Vim will use the &incsearch setting to show matches interactively. Once you're happy with the regex, you can ...


19

This can be handled by the :Subvert from the abolish plugin: One time I had an application with a domain model called "facility" that needed to be renamed to "building". So, a simple search and replace, right? :%s/facility/building/g Oh, but the case variants! :%s/Facility/Building/g :%s/FACILITY/BUILDING/g Wait, the plural is more than "...


19

The implementation of :s//c is fixed; what you're looking for is replacement with a Vimscript expression (:help sub-replace-expr). You can query a single-digit via getchar(), or prompt for longer numbers via input(): :%s/person:/\=get(['woman', 'man'], getchar() - char2nr(1), submatch(0)) . ':'/ :%s/person:/\=get(['woman', 'man'], input('Your choice: ') - 1,...


18

There’s \%V for that, see :h %V: %V Match inside the Visual area. When Visual mode has already been stopped match in the area that gv would reselect. This is a /zero-width match. To make sure the whole pattern is inside the Visual area put it at the start and end of the pattern, e.g.: > /%Vfoo.*bar%V To replace foo by bar in the selection only,...


18

I would use \zs :%s/.*\zspattern/replacement/ A little bit of explanation: . represents any single character * represents greedy matching (as many as possible) In Vim you can use zero-width anchors \zs and \ze to define the start and the end of the searched pattern, which you wish to match. Anything before \zs and after \ze in your pattern will remain ...


18

Michaels Geddes' plugin keepcase (GitHub) has all you need: :%SubstituteCase/\cterm/word/g Other syntax elements from :substitute are also supported.


18

:let @a=1 | %s/search/\='replace'.(@a+setreg('a',@a+1))/g But beware, it will overwrite your register a. I think it is a little bit more straight forward than luc's answer, but maybe his is faster. If this solution is somehow worse than his, I would love to hear any feedback why his answer is better. Any feedback to improve the answer will be highly ...


17

Maybe you, or a plugin, had enabled the option 'gdefault'. This option adds the flag g automatically whenever you perform a substitution. So, when you manually add the flag g while 'gdefault' is enabled, it's as if you had 2 g flags which has the same effect as none. Therefore, Vim only substitutes the first occurrence of the pattern on every line. By ...


16

Performing a substitution on several consecutive lines is pretty easy: :2,11s/^/word / but a range can't cover non-consecutive lines. With a bit of creativity, though, it is entirely possible to work around that "limitation". Indeed, you can repeat the last substitution with :& or :&& (the former will not preserve the original flags, the ...


16

You need substitution with a state. I remember having provided a (/several?) complete solution for this kind of problems on SO. Here is another way to proceed (1). Now, I'll proceed into 2 steps: a dummy list variable I need for the dirty and convoluted trick I'll employ a substitution where I insert the len of this dummy array I'm filling on each ...


16

Yes, this is a long answer. That's because I try to cover the sometimes intimidating sub-replace expression as clearly as I can. Don't be frightened...please dive in! :) This can be looked at as a search-replace where the search is multi-level or nested. That is, first you need to match part of the line (i.e. quoted text in this case). Then you need to match ...


15

Here are a few ways to do it. 1 | $color = "#fff"; 2 | function PickColor () { 3 | $color = "#bbb"; 4 | $newColors = ["#000", "#fbf", $color]; 5 | foreach ($newColors as $c) { 6 | if ($c == "#fff") { 7 | break; 8 | } 9 | } 10 | } 11 | $differentColor = $color; I've modified your example to include line ...


15

I would use something like: :s/^#\s\+\(.\{-}\):/running "\1":/ ^# to match the # character anchored at the start of the line (this answers question 1) \s\+ to match any whitespace one or more times \( to start a group (this answers question 2) .\{-}\ to match any character 0 or more times in a non-greedy way; this is diffferent from .* in that it tries to ...


15

I think the following command should work : :%s/^\(.*\)\(\n\1\)\+$/\1/ Explanation : We use the substitution command on the whole file to change pattern into string : :%s/pattern/string/ Here pattern is ^\(.*\)\(\n\1\)\+$ and string is \1. pattern can be broken down like this : ^\(subpattern1\)\(subpattern2\)\+$ ^ and $ match respectively a ...


15

You could try the following command: :let c=0 | g/^* /let c+=1 | s//\=c.'. ' First it initializes the variable c (let c=0), then it executes the global command g which looks for the pattern ^* (a beginning of line, followed by an asterisk and a space). Whenever a line containing this pattern is found, the global command executes the command: let c+=1 | s//...


15

You could use the following solution: First use v$ to select the text from the cursor to the end of the line. Then use the following command: :s/\%V\ /_/g The \%V indicate to change the text in the previously visually selected area, see :h /\%V. If I take your example: function my_function(argument, another argument, but there are spaces) If my cursor ...


15

You can just use the usual workflow search and replace: /original cwreplaced n.n. You can take also advantage of the gn motion: /original<CR> cgnreplaced<ESC> ..... cgn will change the next matched pattern, so instead of using n.n. to go to next and repeat you can just .. which means replace next. gn means "search for next occurence and ...


15

I think you want to do @: which replays the last ex command. See :h @: Note that this command can be called from normal mode and from visual mode. Also in this case it is not useful but you can also prefix it with a count. Edit In the comments @Antony pointed out an interesting command: :& (:h :&): & can be used in normal mode to repeat the ...


15

There are a couple more methods that (to my surprise!) haven't been mentioned yet. Using the gn Command gn works like the n command, except that in addition to jumping to the match, it enters visual mode, with the entire match selected. So to change a word (or anything you can match with a regular expression!) first search for it1, and then press cgn ...


14

Here is a simplistic implementation of your function, written with substitute(): function! AddSpaceBeforeEqualInWholeBuffer() let l = 1 for line in getline(1,"$") call setline(l, substitute(line, '\([^= ]\)=', '\1 =', "g")) let l = l + 1 endfor endfunction Adjust the search pattern to taste.


14

Posting this so it can have an answer on our SE, but this is this source with full explanation. Here's a good way to use a single regex to do multiple substitutions: :%s/foo\|bar/\={'foo':'bar','bar':'foo'}[submatch(0)]/g See :help sub-replace-expression and :help Dictionary for Vim's documentation on how this works.


13

In general you can match the Nth occurrence of something using \zs and \{N}. There's an example given at :help \zs. In your case the command would be: :%s/\(.\{-}\zstemp\.\)\{2}//


Only top voted, non community-wiki answers of a minimum length are eligible