4

There are a lot of occasions where, by default, the key-binding C-c C-c does something useful - e.g. in org-mode or magit. I would like to take whatever function C-c C-c runs, and bind that function to something like F8, without having to know what specific function is being called under the hood.

Thus: how can I take an existing key-binding, obtain the function which that key-binding would run, and then simply run that function?

(I'm aware it would take me 5 min to just make a list of functions that I'm interested in, and bind them appropriately in the respective modes - but I would nevertheless like to know how to achieve the above)

  • 1
    Note that C-c C-c in org-mode runs a generic command (org-ctrl-c-ctrl-c) that then dispatches to different functions, depending on context. The solutions below will get you to the top-level command dispatcher, but if you want to get to the lower level dispatched function, you will have to read the org-ctrl-c-ctrl-c code. – NickD Mar 9 at 13:52
3

Trivially, with a keyboard macro:

(global-set-key (kbd "<f8>") (kbd "C-c C-c"))

n.b. That's not binding to a function; it's making <f8> issue the key sequence C-cC-c, which will in turn call whatever command it is bound to.

However as the C-cC-c sequence is reserved for major modes (refer to C-hig (elisp)Key Binding Conventions), you can trust that the local keymap will contain the binding of interest, and so you could use that to bind <f8> to the same command.

Here's an example I use to make RET do whatever M-j is bound to in any programming major mode.

(defun my-coding-config ()
  "Common behaviours for programming."
  (local-set-key (kbd "RET") (key-binding (kbd "M-j"))))

(add-hook 'prog-mode-hook 'my-coding-config)
3

To find which command C-c C-c runs, you can use key-binding, e.g.,

(key-binding (kbd "C-x C-f"))
;; => find-file

To run an interactive command from Lisp, you can use call-interactively, e.g.,

(call-interactively #'find-file)

(funcall won't work sometimes since it doesn't take care of the interactive spec.)

So maybe the following does what you want

(defun your-ctrl-c-ctrl-c ()
  (interactive)
  (let ((command (key-binding (kbd "C-c C-c"))))
    (when command
      (call-interactively command))))

(global-set-key (kbd "<f8>") #'your-ctrl-c-ctrl-c)
  • 2
    Nitpick: call-interactively only works on commands which are also functions. So in general you should rather use execute-command which should work for any command, whether it's a function or a key-sequence. – Stefan Mar 9 at 20:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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