It's quite common that I'll look through a command's documentation with C-h f, and then invoke the command with M-x immediately afterwards.

Right now, the shortest way I've found to “invoke the last view command” is to copy its name (either from the help buffer or from the history) and yank it into M-x's minibuffer prompt.

What I would really like is for command names given to describe-function to be part of the history of execute-extended-command. So I could just do M-x M-p RET.

What's the easiest way of doing this?

  • 1
    Not an answer, but would improve your workflow: have you heard of smex and helm-M-x ? the former is in MELPA, the latter is included in helm, in MELPA.
    – Ehvince
    Nov 14, 2014 at 13:21

4 Answers 4


The "easiest way" is to just define your own version of describe-function, and bind that to C-h f.

Take the vanilla code, and change only the call to completing-read so that it uses the same history list that M-x (execute-extended-command) uses, which is extended-command-history.

(defun my-describe-function (function)
  "Display the full documentation of FUNCTION (a symbol)."
   (let ((fn (function-called-at-point))
         (enable-recursive-minibuffers t)
     (setq val (completing-read
                (if fn
                    (format "Describe function (default %s): " fn)
                  "Describe function: ")
                obarray 'fboundp t nil
                'extended-command-history ; <======================
                (and fn (symbol-name fn))))
     (list (if (equal val "") fn (intern val)))))
  (if (null function)
      (message "You didn't specify a function")
    (help-setup-xref (list #'describe-function function)
                     (called-interactively-p 'interactive))
      (with-help-window (help-buffer)
        (prin1 function)
        (princ " is ")
        (describe-function-1 function)
        (with-current-buffer standard-output

(global-set-key "\C-hf" 'my-describe-function)

How did I find the original code? C-h f describe-function, C-h k M-x, C-h f execute-extended-command. In the code for execute-extended-command I saw that it reads the command name using read-extended-command, and that calls completing-read passing extended-command-history as the HISTORY argument.


I can add not an exact answer to your question, but a workflow that eliminates the need for it.

I use smex instead of execute-extended-command. Once in the minibuffer of smex:

  • RET calls execute-extended-command
  • C-h f calls smex-describe-function
  • M-. calls smex-find-function

I don't like the default bindings, so I've customized them:

(eval-after-load 'smex
  `(defun smex-prepare-ido-bindings ()
     (define-key ido-completion-map (kbd "TAB") 'minibuffer-complete)
     (define-key ido-completion-map (kbd "C-,") 'smex-describe-function)
     (define-key ido-completion-map (kbd "C-w") 'smex-where-is)
     (define-key ido-completion-map (kbd "C-.") 'smex-find-function)
     (define-key ido-completion-map (kbd "C-a") 'move-beginning-of-line)
     (define-key ido-completion-map "\C-i" 'smex-helm)))

Please note that it's very easy to invoke the command from its Help buffer. After typing C-h f just type M-x M-n RET. This works because in a new Help buffer the command name is at the top of the buffer under the cursor, and M-n retrieves it to the minibuffer.

However, if you want to add a command to extended-command-history every time you visit its documentation, then you can do this with a small advice:

(defun describe-function-extended-command-history (function)
  "Add command name to the history."
  (when (commandp function)
    (add-to-history 'extended-command-history (symbol-name function))))

(advice-add 'describe-function :before #'describe-function-extended-command-history)

or using the new macro define-advice just added in 25.0.50:

(define-advice describe-function (:before (function))
  "Add command name to the history."
  (when (commandp function)
    (add-to-history 'extended-command-history (symbol-name function))))
  • What if the looked-up function is not (interactive)?
    – mbork
    Nov 22, 2014 at 11:01
  • (commandp function) checks that the looked-up function is interactive because only commands should be added to extended-command-history. So if the looked-up function is not interactive, it's not added to extended-command-history.
    – link0ff
    Nov 22, 2014 at 17:07
  • Ah, I missed that. Thanks for the explanation!
    – mbork
    Nov 22, 2014 at 20:11

If you use helm-M-x, there is no need to type C-h f to look up commands's documentation, just use C-j or C-z while running helm-M-x to toggle the display of documentation.

See also Helm M-x's features.

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.