7

Sometimes I need to replace . with -> when fixing code.

Usually search and replace cannot be used because there will be many (hundreds of) dots (.) and only a few ones of them must be changed.

However, I find the ones that need to be changed when I am going through a make changelist.

Using the repetition operator does not quite work because if I change one instance and then repeat with the dot command, then I get this:

structBlah->.memberBlah

If I then use x to delete the extraneous dot, then paste and dot no longer work because the last change was a delete.

So, basically the problem is that the repetition operator repeats a motion and an edit, whereas here we need to repeat two edits: a delete and an insert.

Is there any convenient way to do this? One idea I had was to maybe use a macro like this:

xi-><ESC>
  • What commands are you using to make the first change? My first naive try, a<BS>-><Esc> (likewise i<Del>-><Esc>) commands are perfectly repeatable for me. – Random832 Jul 7 '16 at 23:47
  • Use s instead of i to delete a character and go to insert mode. – Shahbaz Jul 10 '16 at 4:42
8

The cw(change word) command will solve your problem.

Put your cursor on the period and type cw-><Escape>

something.somethingelse

turns into

something->somethingelse

and the . operator will still work, because cw is one operation that does both the deletion and substitution.

  • 1
    I never thought of using change word on a single character. That makes perfect sense. I did not know that a period is considered a "word". Is there a "change character" command (delete character and enter input mode)? – Tyler Durden Jul 7 '16 at 16:07
  • 1
    @Tyler Durden Change is actually a command which can be followed by any movement, much like the delete command (d). So you could type cl to change the character to the left, c2l to change 2 characters, c$ to change to the end of the line, ct; to change to semicolon, etc... – DoYouEvenCodeBro Jul 7 '16 at 16:13
  • 8
    Using cw for a single character is too much typing. Just use s. – Kevin Jul 7 '16 at 16:29
  • 1
    @Tyler Durden Haha, did you even try my solution? It does the same thing with less key strokes. Substitute s for cw and you have it. – Tumbler41 Jul 7 '16 at 16:29
11

You could use the s operator, which deletes the character under your cursor and puts you in insert mode. You can then type the replacement and later use . to repeat the whole replacement. Workflow becomes:

  1. /\. to highlight all periods.
  2. n to first dot
  3. s-> and then Esc. This will replace the dot and insert the text with a single operation.
  4. n to next dot
  5. . to change when needed.

:h s for more info.

  • As I said in my question, this is not practical because there are hundreds of dots and only a few specific places where the replacement needs to be done. – Tyler Durden Jul 7 '16 at 13:48
  • 3
    Ok, well at that point your problem becomes a filtering problem, which is not what you asked. I tried to answer your question about two edits. Now it can be done in one. I recommend you edit your question if the problem is actually finding which dots to replace, – Tumbler41 Jul 7 '16 at 13:55
  • 1
    I specifically said in my question "...search and replace cannot be used because there will be many (hundreds of) dots (.) and only a few select ones of them must be changed". The change list is being used to find the instances where the change must be made, as it says in my question. – Tyler Durden Jul 7 '16 at 13:58
  • 1
    Then make the change once with the s solution proposed above, and you can use it on the next item on your change list. – nobe4 Jul 7 '16 at 14:02
  • 2
    @TylerDurden This is not a search and replace; @tumbler41 suggested to use search and n to help find them, but the key optimisation here is to use s-> Esc. Those four keystrokes create the textual change you needed, and you can use . to repeat that action wherever you want. – Desty Jul 7 '16 at 16:56
7

I recommande using the substitute command:

:%s/\./->/gc

This will:

:%s     substitute over all lines
/\.     match dot
/->     replace by arrow
/g      replace all on lines
c       ask for confirmation

This will go through all . of your file and asking each time if you want to substitute.

Press y for substitute, n to go to the next dot.

see :h :s_c for all options.

  • 1
    As I said, this is not practical because there are hundreds of dots and only a few specific places where the replacement needs to be done. – Tyler Durden Jul 7 '16 at 13:48
  • 1
    You can replace :% with :g/.../ to only substitute on matching lines, with :'<,'> for the currently selected lines, or with :. or : for the current line, and use @: to repeat the command on specific lines that you navigate to in some other way. – deltab Jul 7 '16 at 16:42
7

If you don't want to use a substitution or the dot command as suggested by the other answers your best bet is probably to create a macro which you can use when your cursor is next to a dot.

You can record the macro

qaf.vc->^[q

Which will go to the following dot on the line (f.) visually select it (v) and replace it (c->).

Now when you navigate your code and you spot a dot which should be changed you can call the macro with @a.

You can even put that in your .vimrc to keep the macro between you different coding sessions:

let @a="f.vc->^["

Edit @grochmal suggested in the comments to use a second register to have a backward moving macro which seems pretty useful:

let @e="F.vc->^["
  • This is what I would do. The only difference is that I would use two registers let @q="F.vc->^[" and let @w="f.vc->^["", and have a previous dot and a next dot command. – grochmal Jul 7 '16 at 16:33
  • @grochmal: I didn't think about this but this is clever :-) – statox Jul 7 '16 at 16:40
  • Don't you need an <ESC> before the q in the macro? (I don't have access to an computer , so I haven't tested it). – Loovjo Jul 7 '16 at 19:41
  • @loovjo: you're right I'll edit that, thanks! – statox Jul 7 '16 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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