6

Is there a function I could use to quickly copy the message in the echo area (if any) into my working buffer? Should I define the shortcut for that function with define-key or global-set-key or some other way?

4
  • Are you sure the minibuffer is what you want to copy? Which buffers to you want to act on exactly: from the minibuffer associated with the current window to the current buffer? Sep 6, 2014 at 22:36
  • @Gilles correct; my use case is that I want to do a C-c+z (which I've bound to show-file-name) and then copy that content (i.e. the current file name) to my current buffer. Or that I can type in the buffer an expression like (/ 30.0 7.0), hit C-x C-e and copy the result to my buffer without having to copy the digits with the mouse. Sep 6, 2014 at 22:49
  • 1
    So what you want then isn't the minibuffer contents. The minibuffer is where you type stuff, e.g. a file name when opening a file with C-x C-f. Messages from Emacs also appear in the echo area but they're called messages. Sep 6, 2014 at 23:07
  • @Gilles I guess you're right. I was confused because of it being the same spot. Thanks for updating the question. Sep 6, 2014 at 23:14

1 Answer 1

10

The function current-message returns the message that is currently displayed in the echo area, if any. You can insert it with (insert (current-message)). However, anything that causes something else to occupy the echo area will cause current-message to return nil.

Messages from Emacs are archived in the *Messages* buffer. It would be more useful to grab the last line from there. This isn't perfectly reliable since it's possible to have a multi-line message, but that's rare: the message function is meant for short messages that fit in one line.

The following function inserts the last message (more precisely, the last line from the *Messages* buffer. With a prefix argument, it returns older messages: 1 for the latest message, 2 for the next-to-last one, etc. The argument 0 inserts (current-message) if any.

(defun last-message (&optional num)
  (or num (setq num 1))
  (if (= num 0)
      (current-message)
    (save-excursion
      (set-buffer "*Messages*")
      (save-excursion
    (forward-line (- 1 num))
    (backward-char)
    (let ((end (point)))
      (forward-line 0)
      (buffer-substring-no-properties (point) end))))))
(defun insert-last-message (&optional num)
  (interactive "*p")
  (insert (last-message num)))

Bind it to a key in the normal way. For example, if you want the command available on C-c m at all times:

(global-set-key "\C-cm" 'insert-last-message)

There may be easier ways than invoking two custom commands to insert the file name, see the Emacs wiki.

To insert the output from evaluating a Lisp snippet with C-x C-e, pass a prefix argument: C-u C-x C-e.

3
  • 1
    Good but would be nice if it handled multi-line messages. Aug 6, 2018 at 14:50
  • I multi-line messages would be great, but I think that it would be even cooler to be able to cycle among the previous messages!
    – Nisba
    Aug 30, 2018 at 15:02
  • You could also change the function to push the last few lines of the messages buffer to a list and present it with completing-read (optionally, only do the completing-read when prefixed with a universal argument). Nov 24, 2022 at 11:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .