9

Q: how do I print a message in the echo area without surrounding quotes?

Here's a simple command:

(defun test-fn ()
  (interactive)
  (message "Test message"))

When I call it as an interactive command via M-x test-fn, it prints Test message in the echo areas without surrounding quotation marks. However, when I evaluate it in elisp as (test-fn), it prints "Test message" in the echo area with surrounding quotation marks.

First of all, why is there a difference between these two use cases? Second, and more to the point, how can I call the function non-interactively and have the message print to the echo area without the surrounding quotes?

1
  • 1
    message function returns its argument. If you want test-fn to return something else then return it. Put differently the effect you see in the *Messages* buffer and in the REPL are due to different things: (1) is due to message sending a string to an output stream, (2) is due to message returning the formatted string.
    – wvxvw
    May 7, 2015 at 13:33

4 Answers 4

6

What you see printed in the echo area when evaluating the command is its return value - a string. The print syntax for strings includes quotation marks.

When you call the command non-interactively from another function/command, you shouldn't see the quotation marks:

(defun test-test-fn ()
  (interactive)
  (test-fn))

Then call M-x test-test-fn RET to test.

5

When you evaluate a function with M-:, the function gets run, and then its return value is displayed in the echo area. The return value of test-fn is the value returned by message, which is the string that was printed. Thus, though message did actually display the message, it was overwritten by M-: displaying the return value. (You can confirm that both messages appeared by looking in the *Messages* buffer.)

One way to evaluate the function without displaying its return value in the echo area is to type (test-fn) into the scratch buffer and hit C-j. The return value will be inserted into the scratch buffer instead, and the original message will be left in the echo area.

1

A slightly non-standard solution is to add line (sit-for 300) to the definition of your command

(defun test-fn ()
  (interactive)
  (message "Test message")
  (sit-for 300)
  )

The result is that when the message command is executed, it displays your message in the mini-buffer without quotes, as desired. However your command will not finish for another 300 seconds, or 5 minutes. Fortunately the sit-for command is interrupted as soon as you touch the keyboard of click the mouse, at which moment the message will be replaced by the eventual return value of the command, which happens to be nil. Thus, assuming you are continuing to use the keyboard, you will not have to wait for the full 5 minutes.

0

Key fact from the other answers:

  1. evaluated expressions log their return value in Messages
  2. commands called interactively do not log their return value in Messages
  3. when values are logged in Messages they are also displayed in the echo area, displacing anything that was already in the echo area

This can be seen in the following code:

(defun f () (interactive) 10)
(f)     ;; prints to *Messages* buffer
; M-x f ;; does not print to *Messages* buffer

Let's use this fact to create a variant of eval-last-sexp that evaluates the last sexp without logging the return value.

(defun eval-last-sexp-dont-echo ()
   (interactive)
   (eval (elisp--preceding-sexp)))

If the preceding sexp is (message "Test message") and we invoke eval-last-sexp-dont-echo interatively, it will print the message in the echo area as desired, and no return value will displace it.

Bonus:

Evaluate (message (propertize "test" 'face `(:foreground "blue"))) with eval-last-sexp-dont-echo. It should render your message in the colour blue. Consider why evaluating it with eval-last-sexp doesn't work.

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.