Cheeso
Cheeso

Reputation: 192457

elisp message-box: can I include newlines in the text, and if so, how?

Using the message-box fn, I can display a modal dialog.

I know this is annoying and not always a good user experience. Flymake's use of the message-box to warn when a flymake check has failed, seems a good example of that. But put the user experience issue aside for the purposes of this question. Assume that I am sensible enough to use message-box responsibly.

How can I format the text displayed by the message box? The simplest case is, how can I tell message box to display multiple lines of text. If I have a longish message, it results in a very wide message box. (Another UI problem exhibited in the Flymake usage).

See here for an example. this code:

(message-box (concat "You need to get an \"api key\".<NL>"
             "Then, set it in your .emacs with the appropriate statement."))

results in this UI:

enter image description here

I'd like a newline in place of the <NL>. I tried using \n and \r and \r\n, none of those worked. I also tried \x000D and \x000A.

Even better than simple line breaks, I'd like to be able to format the text. Italic, bold, or whatever. Are there options? Nothing is mentioned in the doc on this.

I looked in the source to try to figure this out but could not find message2, which is called by message-box, and I'm not sure I'd learn anything anyway by just looking at source.

Upvotes: 1

Views: 718

Answers (2)

Cheeso
Cheeso

Reputation: 192457

hack workaround on Windows for bug #11138.

(defun multiline-message-box (msg)
  "display a multiline message box on Windows.

According to bug #11138, when passing a message with newlines to
`message-box' on Windows, the rendered message-box appears all on
one line.

This function can work around that problem.
"
  (flet ((ok (&optional p1 &rest args) t))

    (let ((parts (split-string msg "\n"))
          (menu-1 (make-sparse-keymap "Attention"))
          c)

      (define-key menu-1 [menu-1-ok-event]
        `(menu-item ,(purecopy "OK")
                    ok
                    :keys ""))
      (define-key menu-1 [separator-1] menu-bar-separator)

      ;; add lines in reverse order
      (setq c (length parts))
      (while (> c 0)
        (setq c (1- c))
        (define-key menu-1 (vector (intern (format "menu-1-fake-event-%d" c)))
          `(menu-item ,(purecopy (nth c parts))
                      nil
                      :keys ""
                      :enable t)))
      (x-popup-menu t menu-1))))


(multiline-message-box "Hello!\nI must be going!\nThis is line 3.")

Upvotes: 0

Trey Jackson
Trey Jackson

Reputation: 74430

Use \n. That does the trick:

(message-box (concat "You need to get an \"api key\".\n"
                     "Then, set it in your .emacs with the appropriate statement."))

Upvotes: 3

Related Questions