Patch 9.0.0288

6 views
Skip to first unread message

Bram Moolenaar

unread,
Aug 27, 2022, 4:30:47 PM8/27/22
to vim...@googlegroups.com

Patch 9.0.0288
Problem: When 'cmdheight' is zero some messages are not displayed.
Solution: Use a popup notification window.
Files: runtime/doc/options.txt, src/popupwin.c, src/proto/popupwin.pro,
src/feature.h, src/structs.h, src/time.c, src/proto/time.pro,
src/message.c, src/proto/message.pro, src/screen.c,
src/testdir/test_messages.vim


*** ../vim-9.0.0287/runtime/doc/options.txt 2022-08-26 16:58:46.135489352 +0100
--- runtime/doc/options.txt 2022-08-27 16:57:47.541146693 +0100
***************
*** 1763,1769 ****
page can have a different value.

When 'cmdheight' is zero, there is no command-line unless it is being
! used. Any messages will cause the |hit-enter| prompt.

*'cmdwinheight'* *'cwh'*
'cmdwinheight' 'cwh' number (default 7)
--- 1789,1799 ----
page can have a different value.

When 'cmdheight' is zero, there is no command-line unless it is being
! used. Informative messages will be displayed in a popup notification
! window at the bottom if the window, using the MessageWindow highlight
! group {only if compiled with the +popupwin and +timers features},
! otherwise they will not be displayed. Other messages will cause the
! |hit-enter| prompt. Expect some other unexpected behavior too.

*'cmdwinheight'* *'cwh'*
'cmdwinheight' 'cwh' number (default 7)
*** ../vim-9.0.0287/src/popupwin.c 2022-08-14 14:16:07.999582175 +0100
--- src/popupwin.c 2022-08-27 18:43:29.590734722 +0100
***************
*** 412,426 ****
}

#if defined(FEAT_TIMERS)
static void
! popup_add_timeout(win_T *wp, int time)
{
char_u cbbuf[50];
char_u *ptr = cbbuf;
typval_T tv;

vim_snprintf((char *)cbbuf, sizeof(cbbuf),
! "(_) => popup_close(%d)", wp->w_id);
if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
{
wp->w_popup_timer = create_timer(time, 0);
--- 412,431 ----
}

#if defined(FEAT_TIMERS)
+ /*
+ * Add a timer to "wp" with "time".
+ * If "close" is true use popup_close(), otherwise popup_hide().
+ */
static void
! popup_add_timeout(win_T *wp, int time, int close)
{
char_u cbbuf[50];
char_u *ptr = cbbuf;
typval_T tv;

vim_snprintf((char *)cbbuf, sizeof(cbbuf),
! close ? "(_) => popup_close(%d)" : "(_) => popup_hide(%d)",
! wp->w_id);
if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
{
wp->w_popup_timer = create_timer(time, 0);
***************
*** 669,675 ****

if (syn_name2id((char_u *)linehl) == 0)
linehl = "PmenuSel";
! sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL, NULL);
}

sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
--- 674,681 ----

if (syn_name2id((char_u *)linehl) == 0)
linehl = "PmenuSel";
! sign_define_by_name(sign_name, NULL, (char_u *)linehl,
! NULL, NULL, NULL, NULL);
}

sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
***************
*** 905,911 ****
// Add timer to close the popup after some time.
nr = dict_get_number(dict, "time");
if (nr > 0)
! popup_add_timeout(wp, nr);
#endif

di = dict_find(dict, (char_u *)"moved", -1);
--- 911,917 ----
// Add timer to close the popup after some time.
nr = dict_get_number(dict, "time");
if (nr > 0)
! popup_add_timeout(wp, nr, TRUE);
#endif

di = dict_find(dict, (char_u *)"moved", -1);
***************
*** 1289,1294 ****
--- 1295,1303 ----
if (wp->w_winrow >= Rows)
wp->w_winrow = Rows - 1;
}
+ if (wp->w_popup_pos == POPPOS_BOTTOM)
+ // assume that each buffer line takes one screen line
+ wp->w_winrow = MAX(Rows - wp->w_buffer->b_ml.ml_line_count - 1, 0);

if (!use_wantcol)
center_hor = TRUE;
***************
*** 1649,1654 ****
--- 1658,1664 ----
TYPE_ATCURSOR,
TYPE_BEVAL,
TYPE_NOTIFICATION,
+ TYPE_MESSAGE_WIN, // similar to TYPE_NOTIFICATION
TYPE_DIALOG,
TYPE_MENU,
TYPE_PREVIEW, // preview window
***************
*** 1656,1661 ****
--- 1666,1680 ----
} create_type_T;

/*
+ * Return TRUE if "type" is TYPE_NOTIFICATION or TYPE_MESSAGE_WIN.
+ */
+ static int
+ popup_is_notification(create_type_T type)
+ {
+ return type == TYPE_NOTIFICATION || type == TYPE_MESSAGE_WIN;
+ }
+
+ /*
* Make "buf" empty and set the contents to "text".
* Used by popup_create() and popup_settext().
*/
***************
*** 1914,1919 ****
--- 1933,1953 ----
#endif

/*
+ * Set the color for a notification window.
+ */
+ static void
+ popup_update_color(win_T *wp, create_type_T type)
+ {
+ char *hiname = type == TYPE_MESSAGE_WIN
+ ? "MessageWindow" : "PopupNotification";
+ int nr = syn_name2id((char_u *)hiname);
+
+ set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
+ (char_u *)(nr == 0 ? "WarningMsg" : hiname),
+ OPT_FREE|OPT_LOCAL, 0);
+ }
+
+ /*
* popup_create({text}, {options})
* popup_atcursor({text}, {options})
* etc.
***************
*** 1928,1934 ****
int new_buffer;
buf_T *buf = NULL;
dict_T *d = NULL;
- int nr;
int i;

if (argvars != NULL)
--- 1962,1967 ----
***************
*** 1975,1981 ****
{
if (dict_has_key(d, "tabpage"))
tabnr = (int)dict_get_number(d, "tabpage");
! else if (type == TYPE_NOTIFICATION)
tabnr = -1; // notifications are global by default
else
tabnr = 0;
--- 2008,2014 ----
{
if (dict_has_key(d, "tabpage"))
tabnr = (int)dict_get_number(d, "tabpage");
! else if (popup_is_notification(type))
tabnr = -1; // notifications are global by default
else
tabnr = 0;
***************
*** 2101,2107 ****
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
wp->w_popup_close = POPCLOSE_NONE;

! if (type == TYPE_NOTIFICATION)
{
win_T *twp, *nextwin;
int height = buf->b_ml.ml_line_count + 3;
--- 2134,2140 ----
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
wp->w_popup_close = POPCLOSE_NONE;

! if (popup_is_notification(type))
{
win_T *twp, *nextwin;
int height = buf->b_ml.ml_line_count + 3;
***************
*** 2140,2149 ****
wp->w_popup_padding[1] = 1;
wp->w_popup_padding[3] = 1;

! nr = syn_name2id((char_u *)"PopupNotification");
! set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
! (char_u *)(nr == 0 ? "WarningMsg" : "PopupNotification"),
! OPT_FREE|OPT_LOCAL, 0);
}

if (type == TYPE_DIALOG || type == TYPE_MENU)
--- 2173,2179 ----
wp->w_popup_padding[1] = 1;
wp->w_popup_padding[3] = 1;

! popup_update_color(wp, type);
}

if (type == TYPE_DIALOG || type == TYPE_MENU)
***************
*** 2203,2210 ****
apply_options(wp, d, TRUE);

#ifdef FEAT_TIMERS
! if (type == TYPE_NOTIFICATION && wp->w_popup_timer == NULL)
! popup_add_timeout(wp, 3000);
#endif

popup_adjust_position(wp);
--- 2233,2240 ----
apply_options(wp, d, TRUE);

#ifdef FEAT_TIMERS
! if (popup_is_notification(type) && wp->w_popup_timer == NULL)
! popup_add_timeout(wp, 3000, type == TYPE_NOTIFICATION);
#endif

popup_adjust_position(wp);
***************
*** 4408,4413 ****
--- 4438,4523 ----
}
#endif

+ #if defined(HAS_MESSAGE_WINDOW) || defined(PROTO)
+
+ // Window used for messages when 'winheight' is zero.
+ static win_T *message_win = NULL;
+
+ /*
+ * Get the message window.
+ * Returns NULL if something failed.
+ */
+ win_T *
+ popup_get_message_win(void)
+ {
+ if (message_win == NULL)
+ {
+ int i;
+
+ message_win = popup_create(NULL, NULL, TYPE_MESSAGE_WIN);
+
+ if (message_win == NULL)
+ return NULL;
+
+ // use the full screen width
+ message_win->w_width = Columns;
+
+ // position at bottom of screen
+ message_win->w_popup_pos = POPPOS_BOTTOM;
+ message_win->w_wantcol = 1;
+ message_win->w_minwidth = 9999;
+
+ // no padding, border at the top
+ for (i = 0; i < 4; ++i)
+ message_win->w_popup_padding[i] = 0;
+ for (i = 1; i < 4; ++i)
+ message_win->w_popup_border[i] = 0;
+
+ if (message_win->w_popup_timer != NULL)
+ message_win->w_popup_timer->tr_keep = TRUE;
+ }
+ return message_win;
+ }
+
+ /*
+ * If the message window is not visible: show it
+ * If the message window is visible: reset the timeout
+ */
+ void
+ popup_show_message_win(void)
+ {
+ if (message_win != NULL)
+ {
+ if ((message_win->w_popup_flags & POPF_HIDDEN) != 0)
+ {
+ // the highlight may have changed.
+ popup_update_color(message_win, TYPE_MESSAGE_WIN);
+ popup_show(message_win);
+ }
+ else if (message_win->w_popup_timer != NULL)
+ timer_start(message_win->w_popup_timer);
+ }
+ }
+
+ int
+ popup_message_win_visible(void)
+ {
+ return message_win != NULL
+ && (message_win->w_popup_flags & POPF_HIDDEN) == 0;
+ }
+
+ /*
+ * If the message window is visible: hide it.
+ */
+ void
+ popup_hide_message_win(void)
+ {
+ if (message_win != NULL)
+ popup_hide(message_win);
+ }
+
+ #endif
+
/*
* Close any popup for a text property associated with "win".
* Return TRUE if a popup was closed.
*** ../vim-9.0.0287/src/proto/popupwin.pro 2022-06-27 23:15:19.000000000 +0100
--- src/proto/popupwin.pro 2022-08-27 14:14:30.084468674 +0100
***************
*** 62,67 ****
--- 62,71 ----
void popup_close_preview(void);
void popup_hide_info(void);
void popup_close_info(void);
+ win_T *popup_get_message_win(void);
+ void popup_show_message_win(void);
+ int popup_message_win_visible(void);
+ void popup_hide_message_win(void);
int popup_win_closed(win_T *win);
void popup_set_title(win_T *wp);
void popup_update_preview_title(void);
*** ../vim-9.0.0287/src/feature.h 2022-08-26 17:52:47.886406161 +0100
--- src/feature.h 2022-08-27 13:27:09.088667917 +0100
***************
*** 1064,1069 ****
--- 1064,1076 ----
# define FEAT_PROP_POPUP
#endif

+ /*
+ * +message_window use a popup for messages when 'cmdheight' is zero
+ */
+ #if defined(FEAT_PROP_POPUP) && defined(FEAT_TIMERS)
+ # define HAS_MESSAGE_WINDOW
+ #endif
+
#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME)
// Can limit syntax highlight time to 'redrawtime'.
# define SYN_TIME_LIMIT 1
*** ../vim-9.0.0287/src/structs.h 2022-08-26 22:36:32.480565634 +0100
--- src/structs.h 2022-08-27 15:18:40.750176557 +0100
***************
*** 2569,2574 ****
--- 2569,2575 ----
proftime_T tr_due; // when the callback is to be invoked
char tr_firing; // when TRUE callback is being called
char tr_paused; // when TRUE callback is not invoked
+ char tr_keep; // when TRUE keep timer after it fired
int tr_repeat; // number of times to repeat, -1 forever
long tr_interval; // msec
callback_T tr_callback;
***************
*** 2605,2610 ****
--- 2606,2612 ----
POPPOS_BOTRIGHT,
POPPOS_TOPRIGHT,
POPPOS_CENTER,
+ POPPOS_BOTTOM, // bottom of popup at bottom of screen
POPPOS_NONE
} poppos_T;

*** ../vim-9.0.0287/src/time.c 2022-07-23 09:52:00.341814264 +0100
--- src/time.c 2022-08-27 13:49:00.156757678 +0100
***************
*** 464,474 ****
timer->tr_repeat = repeat - 1;
timer->tr_interval = msec;

! profile_setlimit(msec, &timer->tr_due);
return timer;
}

/*
* Invoke the callback of "timer".
*/
static void
--- 464,484 ----
timer->tr_repeat = repeat - 1;
timer->tr_interval = msec;

! timer_start(timer);
return timer;
}

/*
+ * (Re)start a timer.
+ */
+ void
+ timer_start(timer_T *timer)
+ {
+ profile_setlimit(timer->tr_interval, &timer->tr_due);
+ timer->tr_paused = FALSE;
+ }
+
+ /*
* Invoke the callback of "timer".
*/
static void
***************
*** 603,610 ****
else
{
this_due = -1;
! remove_timer(timer);
! free_timer(timer);
}
}
if (this_due > 0 && (next_due == -1 || next_due > this_due))
--- 613,625 ----
else
{
this_due = -1;
! if (timer->tr_keep)
! timer->tr_paused = TRUE;
! else
! {
! remove_timer(timer);
! free_timer(timer);
! }
}
}
if (this_due > 0 && (next_due == -1 || next_due > this_due))
***************
*** 826,831 ****
--- 841,847 ----
else
{
int paused = (int)tv_get_bool(&argvars[1]);
+
timer = find_timer((int)tv_get_number(&argvars[0]));
if (timer != NULL)
timer->tr_paused = paused;
*** ../vim-9.0.0287/src/proto/time.pro 2022-06-27 23:15:27.000000000 +0100
--- src/proto/time.pro 2022-08-27 13:55:36.099318843 +0100
***************
*** 9,14 ****
--- 9,15 ----
void f_strptime(typval_T *argvars, typval_T *rettv);
long proftime_time_left(proftime_T *due, proftime_T *now);
timer_T *create_timer(long msec, int repeat);
+ void timer_start(timer_T *timer);
long check_due_timer(void);
void stop_timer(timer_T *timer);
int set_ref_in_timer(int copyID);
*** ../vim-9.0.0287/src/message.c 2022-08-22 15:19:12.732328943 +0100
--- src/message.c 2022-08-27 20:47:18.903862418 +0100
***************
*** 954,961 ****
int n;
int room;

! // If something unexpected happened "room" may be negative, check for that
! // just in case.
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)
--- 954,961 ----
int n;
int room;

! // 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,1426 ****
--- 1421,1441 ----
#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,1450 ****
}
#endif

! if (!msg_scroll && full_screen) // overwrite last message
{
msg_row = cmdline_row;
msg_col =
--- 1459,1478 ----
}
#endif

! 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,2200 ****
--- 2223,2268 ----
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,2220 ****
--- 2283,2325 ----
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,2258 ****
* ourselves).
*/
if (t_col > 0)
// output postponed text
! 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();

msg_row = Rows - 2;
if (msg_col >= Columns) // can happen after screen resize
--- 2349,2377 ----
* ourselves).
*/
if (t_col > 0)
+ {
// output postponed text
! #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;

! #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,2302 ****
// 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;
if (p_more && lines_left == 0 && State != MODE_HITRETURN
&& !msg_no_more && !exmode_active)
{
--- 2404,2428 ----
// store text for scrolling back
store_sb_text(&sb_str, s, attr, &sb_col, TRUE);

! #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,2329 ****
&& 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);

if (wrap && p_more && !recurse)
// store text for scrolling back
--- 2448,2466 ----
&& msg_col + t_col >= Columns - 1);
if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
|| *s == '\t' || *s == BELL))
+ {
// output any postponed text
! #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,2337 ****

if (*s == '\n') // go to next line
{
! msg_didout = FALSE; // remember that line is empty
#ifdef FEAT_RIGHTLEFT
if (cmdmsg_rl)
msg_col = Columns - 1;
--- 2468,2487 ----

if (*s == '\n') // go to next line
{
! #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,2349 ****
--- 2494,2500 ----
else if (*s == '\r') // go to column 0
{
msg_col = 0;
+ where = PUT_TRUNC;
}
else if (*s == '\b') // go to previous char
{
***************
*** 2352,2360 ****
}
else if (*s == TAB) // translate Tab into spaces
{
! do
! msg_screen_putchar(' ', attr);
! while (msg_col & 7);
}
else if (*s == BELL) // beep (from ":sh")
vim_beep(BO_SH);
--- 2503,2516 ----
}
else if (*s == TAB) // translate Tab into spaces
{
! #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,2409 ****

// output any postponed text
if (t_col > 0)
! t_puts(&t_col, t_s, s, attr);
if (p_more && !recurse)
store_sb_text(&sb_str, s, attr, &sb_col, FALSE);

--- 2559,2577 ----

// output any postponed text
if (t_col > 0)
! {
! #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,2436 ****
--- 2599,2608 ----
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.
*** ../vim-9.0.0287/src/proto/message.pro 2022-07-28 12:34:06.527917764 +0100
--- src/proto/message.pro 2022-08-27 14:14:38.608460926 +0100
***************
*** 23,28 ****
--- 23,29 ----
void wait_return(int redraw);
void set_keep_msg(char_u *s, int attr);
void set_keep_msg_from_hist(void);
+ int use_message_window(void);
void msg_start(void);
void msg_starthere(void);
void msg_putchar(int c);
*** ../vim-9.0.0287/src/screen.c 2022-08-26 16:58:46.139489368 +0100
--- src/screen.c 2022-08-27 17:52:56.821625921 +0100
***************
*** 4211,4220 ****
int nwr_save;
int sub_attr;

! do_mode = ((p_smd && msg_silent == 0)
&& ((State & MODE_INSERT)
|| restart_edit != NUL
! || VIsual_active));
if (do_mode || reg_recording != 0)
{
if (skip_showmode())
--- 4211,4220 ----
int nwr_save;
int sub_attr;

! do_mode = p_smd && msg_silent == 0 && p_ch > 0
&& ((State & MODE_INSERT)
|| restart_edit != NUL
! || VIsual_active);
if (do_mode || reg_recording != 0)
{
if (skip_showmode())
*** ../vim-9.0.0287/src/testdir/test_messages.vim 2022-08-11 14:13:14.862778345 +0100
--- src/testdir/test_messages.vim 2022-08-27 19:01:49.971950399 +0100
***************
*** 392,409 ****
set cmdheight=0
set showcmd
redraw!

echo 'test echo'
! call assert_equal(116, screenchar(&lines, 1))
redraw!

echomsg 'test echomsg'
! call assert_equal(116, screenchar(&lines, 1))
redraw!

! call feedkeys(":ls\<CR>", "xt")
! call assert_equal(':ls', Screenline(&lines - 1))
! redraw!

let char = getchar(0)
call assert_match(char, 0)
--- 392,422 ----
set cmdheight=0
set showcmd
redraw!
+ let using_popupwin = has('timers') && has('popupwin')

echo 'test echo'
! if using_popupwin
! redraw
! call assert_equal('test echo', Screenline(&lines))
! else
! call assert_equal(116, screenchar(&lines, 1))
! endif
redraw!

echomsg 'test echomsg'
! if using_popupwin
! redraw
! call assert_equal('test echomsg', Screenline(&lines))
! else
! call assert_equal(116, screenchar(&lines, 1))
! endif
redraw!

! if !using_popupwin
! call feedkeys(":ls\<CR>", "xt")
! call assert_equal(':ls', Screenline(&lines))
! redraw!
! endif

let char = getchar(0)
call assert_match(char, 0)
***************
*** 420,425 ****
--- 433,441 ----
call assert_equal('otherstring', getline(1))

call feedkeys("g\<C-g>", "xt")
+ if using_popupwin
+ redraw
+ endif
call assert_match(
\ 'Col 1 of 11; Line 1 of 1; Word 1 of 1',
\ Screenline(&lines))
*** ../vim-9.0.0287/src/version.c 2022-08-27 21:24:22.709002324 +0100
--- src/version.c 2022-08-27 21:26:22.755363314 +0100
***************
*** 709,710 ****
--- 709,712 ----
{ /* Add new patch number below this line */
+ /**/
+ 288,
/**/

--
Behold the warranty! The bold print giveth and the fine print taketh.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Bram Moolenaar

unread,
Aug 27, 2022, 4:42:05 PM8/27/22
to vim...@googlegroups.com, Bram Moolenaar

I wrote:

> Patch 9.0.0288
> Problem: When 'cmdheight' is zero some messages are not displayed.
> Solution: Use a popup notification window.

Until now, when setting 'cmdheight' to zero quite a few messages were not
displayed at all. This patch attempts to show these messages in a popup
window, which will disappear after three seconds. Like a popup
notification.

This is tricky stuff. Let me know if something doesn't work well, with
a reproducible example.

This way of showing messages may be useful for other purposes as well,
even when 'cmdheight' is non-zero. At least to avoid the hit-return
prompt. Maybe this variant to popup_notification() should be added?
perhaps the messages would be displayed just above the command line (so
that when you re typing that is not interrupted).

--
No children may attend school with their breath smelling of "wild onions."
[real standing law in West Virginia, United States of America]
Reply all
Reply to author
Forward
0 new messages