11

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?

Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • 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 '14 at 13:21

4 Answers4

8

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)))
abo-abo
  • 13,943
  • 1
  • 29
  • 43
7

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)."
  (interactive
   (let ((fn (function-called-at-point))
         (enable-recursive-minibuffers t)
         val)
     (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))
    (save-excursion
      (with-help-window (help-buffer)
        (prin1 function)
        (princ " is ")
        (describe-function-1 function)
        (with-current-buffer standard-output
          (buffer-string))))))

(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.

WalterGR
  • 203
  • 1
  • 11
Drew
  • 75,699
  • 9
  • 109
  • 225
6

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))))
link0ff
  • 1,081
  • 5
  • 14
  • What if the looked-up function is not `(interactive)`? – mbork Nov 22 '14 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 '14 at 17:07
  • Ah, I missed that. Thanks for the explanation! – mbork Nov 22 '14 at 20:11
1

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.

xuchunyang
  • 14,302
  • 1
  • 18
  • 39