5

The description of C-x C-e mentions:

...Interactively, with a non '-' prefix argument, print output into current buffer.

I understand this to mean this logic is triggered when I issue C-u C-x C-e, but how would I bind this to C-c c? How do I specify the prefix in the binding?

Same for C-SPC:

With prefix argument (e.g., C-u C-SPC), jump to the mark, and set the mark from position popped off the local mark ring (this does not affect the global mark ring).

My normal binding looks like this:

(global-set-key (kbd "C-c ,") 'pop-global-mark)
young_souvlaki
  • 526
  • 2
  • 13
  • Does this answer your question? [How to apply \`call-interactively\` to an interactive command that accepts the universal argument?](https://emacs.stackexchange.com/questions/21626/how-to-apply-call-interactively-to-an-interactive-command-that-accepts-the-uni) – Drew Sep 24 '20 at 18:43

2 Answers2

5

C-u invokes the function universal-argument, and you want to ensure that eval-last-sexp is called as if you invoked it interactively, which is done with call-interactively. You can simulate universal-argument by let-binding current-prefix-arg.

Putting that all together for C-u C-x C-e:

(global-set-key (kbd "C-c c") (lambda ()
                                (interactive)
                                (let ((current-prefix-arg 1))
                                  (call-interactively #'eval-last-sexp))))

For C-u C-SPC:

(global-set-key (kbd "C-c ,") (lambda ()
                                (interactive)
                                (let ((current-prefix-arg '(4)))
                                  (call-interactively #'set-mark-command))))

Strictly speaking, as @NickD points out, current-prefix-arg should be bound to '(4) to be exactly equivalent to C-u, but for eval-last-sexp that doesn't matter.

young_souvlaki
  • 526
  • 2
  • 13
rpluim
  • 4,605
  • 8
  • 22
  • 1
    If you want to emulate `C-u`, then `current-prefix-arg` should be set to `(4)` - no? `1` emulates `C-u 1`. – NickD Sep 24 '20 at 12:42
  • It depends on the function you're calling. If it just checks whether or not there is a prefix arg, it doesn't matter. I'll clarify the answer – rpluim Sep 24 '20 at 12:46
0

@rpluim gives us the answer and inspires me to produce this handy-dandy Lisp macro. (I'm only presenting it as an "answer" to get the formatting)

(cl-defmacro ph/defprefixed (command &key (prefix 4) no-read-only)
  `(defun ,(intern (format "ph/prefixed-%s" command)) ()
     ,(format "Execute `%s' with prefix argument." command)
     (interactive ,(when no-read-only "*"))
     (let ((current-prefix-arg (list ,prefix)))
       (call-interactively (function ,command)))))

Used thus:

(ph/defprefixed set-mark-command)

it expands to this:

(defun ph/prefixed-set-mark-command ()
  "Execute `set-mark-command' with prefix argument."
  (interactive nil) ; nil is ignored
  (let
    ((current-prefix-arg (list 4)))
    (call-interactively
        (function set-mark-command))))

And thus:

(ph/defprefixed eval-last-sexp :no-read-only t)

Expansion:

(defun ph/prefixed-eval-last-sexp ()
  "Execute `eval-last-sexp' with prefix argument."
  (interactive "*")
  (let
    ((current-prefix-arg (list 4)))
    (call-interactively
        (function eval-last-sexp))))
Phil Hudson
  • 1,651
  • 10
  • 13