In evil mode, the r command, evil-replace, waits for a replacement character to be typed and replaces the current character with it. Sometimes I hit r by mistake and wish to cancel, so I hit C-g. Instead of cancelling the evil-replace, however, it replaces the current character with the escape code ^G which I then have to undo.

Is there a way to make C-g cancel the evil-replace, like esc does?

Update: this is now built in to evil. See https://github.com/emacs-evil/evil/pull/1111. The answers below now only apply to legacy evil versions.

2 Answers 2


I was able to accomplish this using advice (I know that's not ideal, and I'm new to advice, so the code that follows probably isn't great)

(defun replace-control-g-with-nil (char)
  "Make C-g read as nil so that `r C-g` cancels the replace."
  (let ((control-g-char ?\a))
    (if (eq char control-g-char)
          (message "Quit")  ; Without calling message, the cursor stays looking like replace
          nil)              ; Returning nil cancels the evil-replace

(advice-add 'evil-read-key :filter-return 'replace-control-g-with-nil)
  • 1
    You can get the control-g-char with ?\C-g as well, might be a bit clearer.
    – npostavs
    Commented Jan 22, 2018 at 12:39

Sure. If you inspect evil-replace-state-map with F1 v, you'll notice it has ESC bound to evil-normal-state. You can do the same for C-g as well:

(eval-after-load 'evil-maps
  '(define-key evil-replace-state-map (kbd "C-g") 'evil-normal-state))
  • It looks like evil-replace-state-map is for when you hit R to replace multiple characters. Unfortunately key bindings there don't affect the single character r behavior Commented Oct 23, 2017 at 21:15

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.