Allow redirecting `message' output to a different buffer

* doc/lispref/display.texi (Logging Messages): Document it.
* src/xdisp.c (message_dolog): Add sanity checking.
(syms_of_xdisp): Make Vmessages_buffer_name into a defvar
(bug#27170).
This commit is contained in:
Lars Ingebrigtsen 2022-01-29 17:23:48 +01:00
parent bddd9c5f68
commit 43a5f22857
4 changed files with 34 additions and 6 deletions

View file

@ -612,6 +612,16 @@ how to display a message and prevent it from being logged:
@end example
@end defopt
@defvar messages-buffer-name
This variable has the name of the buffer where messages should be
logged to, and defaults to @file{*Messages*}. Some packages may find
it useful to temporarily redirect the output to a different buffer
(perhaps to write the buffer out to a log file later), and they can
bind this variable to a different buffer name. (Note that this buffer
(if it doesn't exist already), will be created and put into
@code{messages-buffer-mode}.)
@end defvar
To make @file{*Messages*} more convenient for the user, the logging
facility combines successive identical messages. It also combines
successive related messages for the sake of two cases: question

View file

@ -1023,6 +1023,10 @@ functions.
* Lisp Changes in Emacs 29.1
** New variable 'messages-buffer-name'.
This variable (defaulting to "*Messages*") allows packages to override
where messages are logged.
+++
** New function 'readablep'.
This function says whether an object can be written out and then

View file

@ -741,10 +741,6 @@ int update_mode_lines;
static bool line_number_displayed;
/* The name of the *Messages* buffer, a string. */
static Lisp_Object Vmessages_buffer_name;
/* Current, index 0, and last displayed echo area message. Either
buffers from echo_buffers, or nil to indicate no message. */
@ -11378,6 +11374,10 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
old_deactivate_mark = Vdeactivate_mark;
oldbuf = current_buffer;
/* Sanity check, in case the variable has been set to something
invalid. */
if (! STRINGP (Vmessages_buffer_name))
Vmessages_buffer_name = build_string ("*Messages*");
/* Ensure the Messages buffer exists, and switch to it.
If we created it, set the major-mode. */
bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
@ -35626,8 +35626,13 @@ be let-bound around code that needs to disable messages temporarily. */);
staticpro (&echo_area_buffer[0]);
staticpro (&echo_area_buffer[1]);
Vmessages_buffer_name = build_pure_c_string ("*Messages*");
staticpro (&Vmessages_buffer_name);
DEFVAR_LISP ("messages-buffer-name", Vmessages_buffer_name,
doc: /* The name of the buffer where messages are logged.
This is normally \"\*Messages*\", but can be rebound by packages that
wish to redirect messages to a different buffer. (If the buffer
doesn't exist, it will be created and put into
`messages-buffer-mode'.) */);
Vmessages_buffer_name = build_string ("*Messages*");
mode_line_proptrans_alist = Qnil;
staticpro (&mode_line_proptrans_alist);

View file

@ -170,4 +170,13 @@ int main () {
(should (equal (get-display-property 2 'height) 2.0))
(should (equal (get-display-property 2 'space-width) 20))))
(ert-deftest test-messages-buffer-name ()
(should
(equal
(let ((messages-buffer-name "test-message"))
(message "foo")
(with-current-buffer messages-buffer-name
(buffer-string)))
"foo\n")))
;;; xdisp-tests.el ends here