8

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>
2
  • 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
    Commented Jul 7, 2016 at 23:47
  • Use s instead of i to delete a character and go to insert mode.
    – Shahbaz
    Commented Jul 10, 2016 at 4:42

4 Answers 4

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.

4
  • 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)? Commented Jul 7, 2016 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... Commented Jul 7, 2016 at 16:13
  • 8
    Using cw for a single character is too much typing. Just use s.
    – Kevin
    Commented Jul 7, 2016 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
    Commented Jul 7, 2016 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.

6
  • 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. Commented Jul 7, 2016 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
    Commented Jul 7, 2016 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. Commented Jul 7, 2016 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
    Commented Jul 7, 2016 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
    Commented Jul 7, 2016 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.

2
  • 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. Commented Jul 7, 2016 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
    Commented Jul 7, 2016 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->^["
4
  • 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
    Commented Jul 7, 2016 at 16:33
  • @grochmal: I didn't think about this but this is clever :-)
    – statox
    Commented Jul 7, 2016 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).
    – xenia
    Commented Jul 7, 2016 at 19:41
  • @loovjo: you're right I'll edit that, thanks!
    – statox
    Commented Jul 7, 2016 at 19:50

Your Answer

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

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