Podcast #128: We chat with Kent C Dodds about why he loves React and discuss what life was like in the dark days before Git. Listen now.
82

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 ...


32

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 ...


32

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


22

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. As you already devised from your experimentation, this is to prevent the so-called "leaning ...


20

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 ....


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

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 ...


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 ...


17

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 ...


16

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 ...


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

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


16

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 "...


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

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

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

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 ...


14

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//...


13

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 ...


13

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

: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 ...


12

There is. For last line of a file, the address is $: :.,$s/old/new/ See :help {address} for a fill list of possible addresses.


12

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 ...


12

Based on the help file, and the Vim Wikia page on Search and replace :%s/[0-9]\+\.[0-9]\+\|[0-9]\+/0/g :%s - start a command with the range of the entire file, %, to substitute, the following patterns: [0-9]\+\.[0-9]\+ This must come first, it's the pattern that covers decimals like 1.7. In addition it will only match a number followed by a period, ...


12

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 ...


11

Ex commands work on the buffer contents; for register (or variable) contents, you need to use a corresponding Vimscript function (if it exists). For :substitute, the equivalent is substitute() (that was easy, right?) So: :let @t = substitute(@t, '_', 'test', 'g')


11

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 ...


11

Not exactly what you ask for, but you can do that: :s/foo/bar/g And then: :s//baz/g You can use that because when you use :s the searched pattern is saved in the search register. Which you can see with :reg /. Work in progress: You can speed up your workflow with: nnoremap && :s<UP><C-F>F/cT/ And use it like so: :s/foo/bar/g and ...


10

If I understand you correctly, you have a file where certain characters are represented by their decimal value in the format \uXXXX, with X being any hexadecimal character but always 4, correct? If so, you can transform those sequences into the actual values they represent by doing a clever search and replace. In this particular case, I would do: :%s/\\u\(\...


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