6

A lot of operator like delete, change, indent, switch-case accept a motion to apply on.

For example, let say I want to replace the current word with all letter a, I do:

viwra

Compared to the imagined:

riwa

Why isn't it the same for the replace command?

It's obviously by design, do you know the reason behind this choice?

9
  • Because it already takes another argument?
    – Toothrot
    May 17, 2016 at 14:52
  • Makes sens, but it's strange that vim does not accept a {motion} followed by something else (if that's the explanation)
    – nobe4
    May 17, 2016 at 14:59
  • 1
    I think you mean viwra. Uppercase 'R' replaces the whole line regardless of what's visually selected.
    – ddrscott
    May 17, 2016 at 15:03
  • 6
    r is a command, not an operator. Operators operate on a text-object or motion but that's not the case for r, like i or a or o.
    – romainl
    May 17, 2016 at 15:05
  • 1
    Wouldn't graiw be better? Would be similar to g~iw. I don't think the behaviour you want is better than being able to replace the current character with two keystrokes.
    – Toothrot
    May 17, 2016 at 15:14

3 Answers 3

4

Actually. There is no reason, apart from things being as they are, that would be against an r operator. The simple fact that viwra works means that riwa could work. The reason is simply a historical one, but there is nothing against an alternative implementation. It can help 'filling' some area defined by a motion/text-object with a single character.

I think the main idea against it was that e.g. ri to replace the current character with i was found more useful (= often needed) than an operator which for that case would need more letters (rli would have probably sufficed for the above example: 'replace' operation + 'move one char to the right' motion + replacement char).

But what's nice with Vim is that anybody can come up with this alternative :) rri as "replace all chars in line with i" doesn't look too bad :)

2

Replace is a specific type of situation, that I don't believe is equivalent to the others you listed that take motions. r can take an optional count, but the action is the same. 3ra replaces 3 characters with the letter "a". In its current state, adding a motion would only allow for the repetition of the replace action. You could "replace word with the letter 'a'" but anything else would be the equivalent to just doing a change.

You can achieve the same outcome using visual selection. viwra would do a "Visual selection in word, replace with 'a'". You'll notice that a lot of other actions that only provide counts, have the same sort of "visual selection replacement for motion".

R version of replace is a mode so there wouldn't be any type of motion, similar to how there is no motion for any other mode.

2

Not an answer, but a piece of code I used to "simulate" the functionality of an operator with r:

function! ROperator()
  call inputsave()
  let l:replace_pattern = input('Replace > ')
  call inputrestore()

  if len(l:replace_pattern) != 3
    throw "Bad pattern size (expected 3)"
  endif

  let l:motion = strpart(replace_pattern, 0, 2)
  let l:char = strpart(replace_pattern, 2, 2)

  execute "normal! v".l:motion."r".l:char

endfunction

nnoremap gr :call ROperator()<CR>

This can be used like so ([] is the cursor position):

 This is a se[n]tence.

 griw*

 This is a **[*]****.
3
  • How can this be extended to be dot-repeated without entering the character again? Could the plugin repeat.vim from tpope be helpful?
    – Hotschke
    Jul 26, 2017 at 11:40
  • I don't think it is, as it is using a normal mode command and from superuser.com/a/429921/367359 it doesn't seem it's possible... But I haven't had a look at repeat.vim though, it could work...
    – nobe4
    Jul 26, 2017 at 17:04
  • Have a look into the LaTeX plugin vimtex. This supports dot repeat for the command change surrounding environment (default map cse) which also takes input from the commandline. It uses tpope's repeat.vim. However, I couldn't figure out how to re-use the code from https://github.com/lervag/vimtex/blob/master/autoload/vimtex/env.vim, in particular of <plug>(vimtex-env-change).
    – Hotschke
    Jul 27, 2017 at 10:46

Your Answer

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

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