3

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 ()
  (interactive)
  (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

mkcms
  • 1,370
  • 12
  • 13

1 Answers1

5

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.

sds
  • 6,104
  • 22
  • 39
  • 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 Dec 20 '17 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 Dec 20 '17 at 19:40