28

In Vim, when I run a substitution command like

:%s/foo/bar/g

it replaces all occurrences of foo with bar in the entire buffer. When it completes, the cursor moves to the last location where foo was replaced with bar.

How can I run :%s/foo/bar/g without having the cursor leave its original location where it was before the substitution command was issued?

Is there some option I can set in the .vimrc file?

ib.
  • 27,830
  • 11
  • 80
  • 100
platypus
  • 1,165
  • 5
  • 27
  • 47

3 Answers3

38

When the :substitute command is run, prior to any replacements being carried out, the current position of the cursor is stored in the jump list (see :help jumplist).

In order to return to the position before the latest jump, one can use the `` or '' Normal-mode commands. The former jumps exactly to the stored position; the latter jumps to the first non-whitespace character on the line the stored position belongs to.

It is possible to both invoke a substitution command and move the cursor back afterwards, at once, by issuing the command

:%s/pat/str/g|norm!``

or, if jumping to the containing line is sufficient, by using the command

:%s/pat/str/g|''

It is not necessary to preface '' with norm! in the latter command, because the '' address is allowed by the range syntax of Ex commands and refers to the same line the Normal-mode command '' jumps to (see :help :range); both just look into the contents of the ' psudo-mark.

ib.
  • 27,830
  • 11
  • 80
  • 100
  • Nice try. But not elegant. shoud use `Ctrl-o`. – mattn May 07 '12 at 02:56
  • 1
    @mattn: According to what criterion using `Ctrl`+`O` is elegant, while `\`\`` is not? The latter command is not longer than the former one in terms of keystrokes; both of them lead to the same cursor movement in this case. Why do you find pressing `\`\`` (instead of `Ctrl`+`O`) inelegant? – ib. May 07 '12 at 08:47
  • It's simple answer. longer than c-o. And your command update jumplist. If I use your way, I'll use g`. :) – mattn May 10 '12 at 05:54
  • Ah, I mistaken. I'll use keepjumps. – mattn May 10 '12 at 05:54
  • 1
    @mattn: Excuse me? `\`\`` is longer than `Ctrl`+`O`?! Also, `Ctrl`+`O` updates the jump list too! (See `:help jumplist` or just try yourself.) So `\`\`` and `Ctrl`+`O` are apace of each other with regard to both modifying the jump list and the number of keys to press. According to these criteria one command does not excel the other. Do you still consider one of them more elegant? If so, for what reason? – ib. May 10 '12 at 06:48
  • 7
    @ib. `and` @mattn I think it is mostly a matter of taste. To me \`\` trumps (easier to type, expresses register use, and logically connects to `:''`, `:g//copy ''` and stuff. I don't no who downvoted this answer, but I certainly think a disagreement of taste shouldn't be reason for downvoting. – sehe May 10 '12 at 09:20
  • 1
    I beleaved that accept two or more commands like replacements like ':%s/a/b/g|%s/c/d/g' with go back to original cursor position. but not. Hmm, It's same advantage. – mattn May 14 '12 at 10:07
27

I just type Ctrl+O after the replace to get back to the previous location.

john-jones
  • 7,490
  • 18
  • 53
  • 86
Steve Jorgensen
  • 11,725
  • 1
  • 33
  • 43
2

It's old, but for anyone coming across this question, I wanted to share my solution since it will work correctly even if nothing is substituted:

:exe 'norm m`' | %s/pattern/substitution/eg | norm g``

exe is needed since norm treats the bar as an argument.

frippe
  • 1,329
  • 1
  • 8
  • 15