I want to create a command that, when you call it for the first time, it's executed normally, but when you repeat it with C-x z, some other command is executed and the original command is never called.

I tried defining it like that (I want forward-line to be called when repeating foo):

(defun foo ()
  (message "foo")
  (setq this-command 'forward-line))

but M-x foo and then C-x z just displays "foo" twice and never calls 'forward-line

1 Answer 1


If you look at the source code for repeat (C-h k C-x z and then click on the repeat.el link in the *Help* buffer), you will see that the command to be repeated is stored in the variable last-repeatable-command, which is taken from real-this-command (as per its doc).

Note the comment in the repeat function:

       ;; Beware: messing with `real-this-command' is *bad*, but we
       ;; need it so `last-repeatable-command' can be recognized
       ;; later (bug#12232).

I am not sure what you are doing is right.

E.g., in your specific case, C-u 234 down will repeat next-line 234 times.

  • Changing this-command to last-repeatable-command didn't work, but when I looked at the doc of the latter, it mentioned that the value of this variable is taken from real-this-command. I replaced this-command with real-this-command and it works exactly how I want. Thanks!
    – mkcms
    Commented Dec 20, 2017 at 19:25
  • I know that it's kind of a hack, actually I solved it by splitting the main command into two functions and then calling one of them depending on the return value of repeat-is-really-this-command.
    – mkcms
    Commented Dec 20, 2017 at 19:40

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.