From: Dante Catalfamo Subject: mg: Add *Messages* buffer To: "tech@openbsd.org" Date: Fri, 19 Jun 2026 16:41:59 -0400 Hello tech, I was trying to debug an issue in mg and noticed that it doesn't keep track of minibuffer messages like Emacs does. I use that feature pretty often in cases where the message I want to read gets replaced by another before I get a change to see it. I wrote a diff that adds the *Messages* buffer and populates it when any messages are displayed. The exception is that it doesn't log user input prompts, also like Emacs. It's a pretty small patch, hopefully it's acceptable. Thanks, Dante diff --git usr.bin/mg/echo.c usr.bin/mg/echo.c index ec178d3c859..95fa27a0ee4 100644 --- usr.bin/mg/echo.c +++ usr.bin/mg/echo.c @@ -22,6 +22,8 @@ #include "key.h" #include "macro.h" +#define NOEBUF 512 + static char *veread(const char *, char *, size_t, int, va_list) __attribute__((__format__ (printf, 1, 0))); static int complt(int, int, char *, size_t, int, int *); @@ -32,10 +34,15 @@ static void eputi(int, int); static void eputl(long, int); static void eputs(const char *); static void eputc(char); +static void eflush(void); static struct list *copy_list(struct list *); int epresf = FALSE; /* stuff in echo line flag */ +char ebuf[NOEBUF]; /* *Messages* output buffer */ +int noebuf = 0; /* Buffer count */ +int einread = FALSE; /* Currently in a read prompt */ + /* * Erase the echo line. */ @@ -177,9 +184,11 @@ eread(const char *fmt, char *buf, size_t nbuf, int flag, ...) va_list ap; char *rep; + einread = TRUE; va_start(ap, flag); rep = veread(fmt, buf, nbuf, flag, ap); va_end(ap); + einread = FALSE; return (rep); } @@ -835,6 +844,7 @@ ewprintf(const char *fmt, ...) va_end(ap); tteeol(); ttflush(); + eflush(); epresf = TRUE; } @@ -979,8 +989,40 @@ eputc(char c) ttputc(c); ++ttcol; } + + if (einread == FALSE) { + ebuf[noebuf++] = c; + if (noebuf >= NOEBUF-1) { + eflush(); + } + } } +/* + * Flush the message line to the *Messages* buffer + */ +static void eflush(void) { + struct buffer *buf; + struct mgwin *win; + + if (noebuf == 0) { + return; + } + + ebuf[noebuf] = '\0'; + buf = bfind("*Messages*", TRUE); + buf->b_flag |= BFREADONLY; + addlinef(buf, "%s", ebuf); + noebuf = 0; + + for (win = wheadp; win != NULL; win = win->w_wndp) { + if (win->w_bufp == buf) { + win->w_rflag |= WFFULL; + } + } +} + + void free_file_list(struct list *lp) {