summaryrefslogtreecommitdiffstats
path: root/src/message.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-08-27 21:30:03 +0100
committerBram Moolenaar <Bram@vim.org>2022-08-27 21:30:03 +0100
commit9198de3ae2bd20ac51d580c44f2b43c282c1e773 (patch)
tree5a101dfee6a8a29a9000443cdf61a2e822a9f2c5 /src/message.c
parentaebc6ef7cdc5d4d0627a711ff66e6fe8d67f9d87 (diff)
patch 9.0.0288: when 'cmdheight' is zero some messages are not displayedv9.0.0288
Problem: When 'cmdheight' is zero some messages are not displayed. Solution: Use a popup notification window.
Diffstat (limited to 'src/message.c')
-rw-r--r--src/message.c220
1 files changed, 196 insertions, 24 deletions
diff --git a/src/message.c b/src/message.c
index 46cf1e0272..00ad2c7d30 100644
--- a/src/message.c
+++ b/src/message.c
@@ -954,8 +954,8 @@ msg_may_trunc(int force, char_u *s)
int n;
int room;
- // If something unexpected happened "room" may be negative, check for that
- // just in case.
+ // If 'cmdheight' is zero or something unexpected happened "room" may be
+ // negative.
room = (int)(Rows - cmdline_row - 1) * Columns + sc_col - 1;
if (room > 0 && (force || (shortmess(SHM_TRUNC) && !exmode_active))
&& (n = (int)STRLEN(s) - room) > 0 && p_ch > 0)
@@ -1421,6 +1421,21 @@ set_keep_msg_from_hist(void)
#endif
/*
+ * Return TRUE when the message popup window should be used.
+ */
+ int
+use_message_window(void)
+{
+#ifdef HAS_MESSAGE_WINDOW
+ // TRUE if there is no command line showing ('cmdheight' is zero and not
+ // already editing or showing a message) use a popup window for messages.
+ return p_ch == 0 && cmdline_row >= Rows;
+#else
+ return FALSE;
+#endif
+}
+
+/*
* Prepare for outputting characters in the command line.
*/
void
@@ -1444,7 +1459,20 @@ msg_start(void)
}
#endif
- if (!msg_scroll && full_screen) // overwrite last message
+ if (use_message_window())
+ {
+ if (popup_message_win_visible() && msg_col > 0)
+ {
+ win_T *wp = popup_get_message_win();
+
+ curbuf = wp->w_buffer;
+ ml_append(wp->w_buffer->b_ml.ml_line_count,
+ (char_u *)"", (colnr_T)0, FALSE);
+ curbuf = curwin->w_buffer;
+ }
+ msg_col = 0;
+ }
+ else if (!msg_scroll && full_screen) // overwrite last message
{
msg_row = cmdline_row;
msg_col =
@@ -2195,6 +2223,46 @@ msg_puts_attr_len(char *str, int maxlen, int attr)
need_fileinfo = FALSE;
}
+// values for "where"
+#define PUT_APPEND 0 // append to "lnum"
+#define PUT_TRUNC 1 // replace "lnum"
+#define PUT_BELOW 2 // add below "lnum"
+ //
+#ifdef HAS_MESSAGE_WINDOW
+
+/*
+ * Put text "t_s" until "s" in the message window.
+ * "where" specifies where to put the text.
+ */
+ static void
+put_msg_win(win_T *wp, int where, char_u *t_s, char_u *end, linenr_T lnum)
+{
+ int c = *end;
+
+ *end = NUL;
+ if (where == PUT_BELOW)
+ ml_append_buf(wp->w_buffer, lnum, t_s, (colnr_T)0, FALSE);
+ else
+ {
+ char_u *newp;
+
+ curbuf = wp->w_buffer;
+ if (where == PUT_APPEND)
+ newp = concat_str(ml_get(lnum), t_s);
+ else
+ newp = vim_strnsave(t_s, end - t_s);
+ ml_replace(lnum, newp, FALSE);
+ curbuf = curwin->w_buffer;
+ }
+ redraw_win_later(wp, UPD_NOT_VALID);
+
+ // set msg_col so that a newline is written if needed
+ msg_col = STRLEN(t_s);
+
+ *end = c;
+}
+#endif
+
/*
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
@@ -2215,6 +2283,43 @@ msg_puts_display(
int sb_col = msg_col;
int wrap;
int did_last_char;
+ int where = PUT_APPEND;
+#ifdef HAS_MESSAGE_WINDOW
+ win_T *msg_win = NULL;
+ linenr_T lnum = 1;
+
+ if (use_message_window())
+ {
+ msg_win = popup_get_message_win();
+
+ if (msg_win != NULL)
+ {
+ if (!popup_message_win_visible())
+ {
+ if (*str == NL)
+ {
+ // When not showing the message window and the output
+ // starts with a NL show the message normally.
+ msg_win = NULL;
+ }
+ else
+ {
+ // currently hidden, make it empty
+ curbuf = msg_win->w_buffer;
+ while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0)
+ ml_delete(1);
+ curbuf = curwin->w_buffer;
+ }
+ }
+ else
+ {
+ lnum = msg_win->w_buffer->b_ml.ml_line_count;
+ if (msg_col == 0)
+ where = PUT_TRUNC;
+ }
+ }
+ }
+#endif
did_wait_return = FALSE;
while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
@@ -2244,15 +2349,29 @@ msg_puts_display(
* ourselves).
*/
if (t_col > 0)
+ {
// output postponed text
- t_puts(&t_col, t_s, s, attr);
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win != NULL)
+ {
+ put_msg_win(msg_win, where, t_s, s, lnum);
+ t_col = 0;
+ where = PUT_BELOW;
+ }
+ else
+#endif
+ t_puts(&t_col, t_s, s, attr);
+ }
// When no more prompt and no more room, truncate here
if (msg_no_more && lines_left == 0)
break;
- // Scroll the screen up one line.
- msg_scroll_up();
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win == NULL)
+#endif
+ // Scroll the screen up one line.
+ msg_scroll_up();
msg_row = Rows - 2;
if (msg_col >= Columns) // can happen after screen resize
@@ -2285,18 +2404,25 @@ msg_puts_display(
// store text for scrolling back
store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
- inc_msg_scrolled();
- need_wait_return = TRUE; // may need wait_return in main()
- redraw_cmdline = TRUE;
- if (cmdline_row > 0 && !exmode_active)
- --cmdline_row;
-
- /*
- * If screen is completely filled and 'more' is set then wait
- * for a character.
- */
- if (lines_left > 0)
- --lines_left;
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win == NULL)
+ {
+#endif
+ inc_msg_scrolled();
+ need_wait_return = TRUE; // may need wait_return in main()
+ redraw_cmdline = TRUE;
+ if (cmdline_row > 0 && !exmode_active)
+ --cmdline_row;
+
+ /*
+ * If screen is completely filled and 'more' is set then wait
+ * for a character.
+ */
+ if (lines_left > 0)
+ --lines_left;
+#ifdef HAS_MESSAGE_WINDOW
+ }
+#endif
if (p_more && lines_left == 0 && State != MODE_HITRETURN
&& !msg_no_more && !exmode_active)
{
@@ -2322,8 +2448,19 @@ msg_puts_display(
&& msg_col + t_col >= Columns - 1);
if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
|| *s == '\t' || *s == BELL))
+ {
// output any postponed text
- t_puts(&t_col, t_s, s, attr);
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win != NULL)
+ {
+ put_msg_win(msg_win, where, t_s, s, lnum);
+ t_col = 0;
+ where = PUT_BELOW;
+ }
+ else
+#endif
+ t_puts(&t_col, t_s, s, attr);
+ }
if (wrap && p_more && !recurse)
// store text for scrolling back
@@ -2331,7 +2468,20 @@ msg_puts_display(
if (*s == '\n') // go to next line
{
- msg_didout = FALSE; // remember that line is empty
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win != NULL)
+ {
+ // Ignore a NL when the buffer is empty, it is used to scroll
+ // up the text.
+ if ((msg_win->w_buffer->b_ml.ml_flags & ML_EMPTY) == 0)
+ {
+ put_msg_win(msg_win, PUT_BELOW, t_s, t_s, lnum);
+ ++lnum;
+ }
+ }
+ else
+#endif
+ msg_didout = FALSE; // remember that line is empty
#ifdef FEAT_RIGHTLEFT
if (cmdmsg_rl)
msg_col = Columns - 1;
@@ -2344,6 +2494,7 @@ msg_puts_display(
else if (*s == '\r') // go to column 0
{
msg_col = 0;
+ where = PUT_TRUNC;
}
else if (*s == '\b') // go to previous char
{
@@ -2352,9 +2503,14 @@ msg_puts_display(
}
else if (*s == TAB) // translate Tab into spaces
{
- do
- msg_screen_putchar(' ', attr);
- while (msg_col & 7);
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win != NULL)
+ msg_col = (msg_col + 7) % 8;
+ else
+#endif
+ do
+ msg_screen_putchar(' ', attr);
+ while (msg_col & 7);
}
else if (*s == BELL) // beep (from ":sh")
vim_beep(BO_SH);
@@ -2403,7 +2559,19 @@ msg_puts_display(
// output any postponed text
if (t_col > 0)
- t_puts(&t_col, t_s, s, attr);
+ {
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win != NULL)
+ put_msg_win(msg_win, where, t_s, s, lnum);
+ else
+#endif
+ t_puts(&t_col, t_s, s, attr);
+ }
+
+#ifdef HAS_MESSAGE_WINDOW
+ if (msg_win != NULL)
+ popup_show_message_win();
+#endif
if (p_more && !recurse)
store_sb_text(&sb_str, s, attr, &sb_col, FALSE);
@@ -2431,6 +2599,10 @@ message_filtered(char_u *msg)
static void
msg_scroll_up(void)
{
+#ifdef HAS_MESSAGE_WINDOW
+ if (use_message_window())
+ return;
+#endif
#ifdef FEAT_GUI
// Remove the cursor before scrolling, ScreenLines[] is going
// to become invalid.