vim-patch:9.1.0908: not possible to configure :messages (#31492)

Problem:  not possible to configure :messages
Solution: add the 'messagesopt' option (Shougo Matsushita)

closes: vim/vim#16068

51d4d84d6a

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
Co-authored-by: h_east <h.east.727@gmail.com>
This commit is contained in:
zeertzjq
2024-12-07 10:17:36 +08:00
committed by GitHub
parent 517ecb85f5
commit ec94c2704f
18 changed files with 360 additions and 163 deletions

View File

@@ -27,7 +27,7 @@ depends on the 'shortmess' option.
Clear messages, keeping only the {count} most Clear messages, keeping only the {count} most
recent ones. recent ones.
The number of remembered messages is fixed at 200. The number of remembered messages is determined by the 'messagesopt' option.
*g<* *g<*
The "g<" command can be used to see the last page of previous command output. The "g<" command can be used to see the last page of previous command output.
@@ -789,6 +789,7 @@ If you accidentally hit <Enter> or <Space> and you want to see the displayed
text then use |g<|. This only works when 'more' is set. text then use |g<|. This only works when 'more' is set.
To reduce the number of hit-enter prompts: To reduce the number of hit-enter prompts:
- Set 'messagesopt'.
- Set 'cmdheight' to 2 or higher. - Set 'cmdheight' to 2 or higher.
- Add flags to 'shortmess'. - Add flags to 'shortmess'.
- Reset 'showcmd' and/or 'ruler'. - Reset 'showcmd' and/or 'ruler'.

View File

@@ -25,6 +25,7 @@ EXPERIMENTS
OPTIONS OPTIONS
• 'jumpoptions' flag "unload" has been renamed to "clean". • 'jumpoptions' flag "unload" has been renamed to "clean".
• The `msghistory` option has been removed in favor of 'messagesopt'.
============================================================================== ==============================================================================
BREAKING CHANGES *news-breaking* BREAKING CHANGES *news-breaking*
@@ -248,7 +249,7 @@ LUA
OPTIONS OPTIONS
• 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|. • 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|.
• 'msghistory' controls maximum number of messages to remember. • 'messagesopt' configures |:messages| and |hit-enter| prompt.
• 'tabclose' controls which tab page to focus when closing a tab page. • 'tabclose' controls which tab page to focus when closing a tab page.
PERFORMANCE PERFORMANCE

View File

@@ -3197,7 +3197,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global global
A history of ":" commands, and a history of previous search patterns A history of ":" commands, and a history of previous search patterns
is remembered. This option decides how many entries may be stored in is remembered. This option decides how many entries may be stored in
each of these histories (see |cmdline-editing| and 'msghistory' for each of these histories (see |cmdline-editing| and 'messagesopt' for
the number of messages to remember). the number of messages to remember).
The maximum value is 10000. The maximum value is 10000.
@@ -4045,6 +4045,25 @@ A jump table for the options with a short description can be found at |Q_op|.
generated from a list of items, e.g., the Buffers menu. Changing this generated from a list of items, e.g., the Buffers menu. Changing this
option has no direct effect, the menu must be refreshed first. option has no direct effect, the menu must be refreshed first.
*'messagesopt'* *'mopt'*
'messagesopt' 'mopt' string (default "hit-enter,history:500")
global
Option settings when outputting messages. It can consist of the
following items. Items must be separated by a comma.
hit-enter Use |hit-enter| prompt when the message is longer than
'cmdheight' size.
wait:{n} Ignored when "hit-enter" is present. Instead of using
|hit-enter| prompt, will simply wait for {n}
milliseconds so the user has a chance to read the
message, use 0 to disable sleep (but then the user may
miss an important message).
history:{n} Determines how many entries are remembered in the
|:messages| history. The maximum value is 10000.
Setting it to zero clears the message history.
*'mkspellmem'* *'msm'* *'mkspellmem'* *'msm'*
'mkspellmem' 'msm' string (default "460000,2000,500") 'mkspellmem' 'msm' string (default "460000,2000,500")
global global
@@ -4290,13 +4309,6 @@ A jump table for the options with a short description can be found at |Q_op|.
Defines the maximum time in msec between two mouse clicks for the Defines the maximum time in msec between two mouse clicks for the
second click to be recognized as a multi click. second click to be recognized as a multi click.
*'msghistory'* *'mhi'*
'msghistory' 'mhi' number (default 500)
global
Determines how many entries are remembered in the |:messages| history.
The maximum value is 10000.
Setting it to zero clears the message history.
*'nrformats'* *'nf'* *'nrformats'* *'nf'*
'nrformats' 'nf' string (default "bin,hex") 'nrformats' 'nf' string (default "bin,hex")
local to buffer local to buffer

View File

@@ -3016,7 +3016,7 @@ vim.go.hid = vim.go.hidden
--- A history of ":" commands, and a history of previous search patterns --- A history of ":" commands, and a history of previous search patterns
--- is remembered. This option decides how many entries may be stored in --- is remembered. This option decides how many entries may be stored in
--- each of these histories (see `cmdline-editing` and 'msghistory' for --- each of these histories (see `cmdline-editing` and 'messagesopt' for
--- the number of messages to remember). --- the number of messages to remember).
--- The maximum value is 10000. --- The maximum value is 10000.
--- ---
@@ -4084,6 +4084,28 @@ vim.o.mis = vim.o.menuitems
vim.go.menuitems = vim.o.menuitems vim.go.menuitems = vim.o.menuitems
vim.go.mis = vim.go.menuitems vim.go.mis = vim.go.menuitems
--- Option settings when outputting messages. It can consist of the
--- following items. Items must be separated by a comma.
---
--- hit-enter Use `hit-enter` prompt when the message is longer than
--- 'cmdheight' size.
---
--- wait:{n} Ignored when "hit-enter" is present. Instead of using
--- `hit-enter` prompt, will simply wait for {n}
--- milliseconds so the user has a chance to read the
--- message, use 0 to disable sleep (but then the user may
--- miss an important message).
---
--- history:{n} Determines how many entries are remembered in the
--- `:messages` history. The maximum value is 10000.
--- Setting it to zero clears the message history.
---
--- @type string
vim.o.messagesopt = "hit-enter,history:500"
vim.o.mopt = vim.o.messagesopt
vim.go.messagesopt = vim.o.messagesopt
vim.go.mopt = vim.go.messagesopt
--- Parameters for `:mkspell`. This tunes when to start compressing the --- Parameters for `:mkspell`. This tunes when to start compressing the
--- word tree. Compression can be slow when there are many words, but --- word tree. Compression can be slow when there are many words, but
--- it's needed to avoid running out of memory. The amount of memory used --- it's needed to avoid running out of memory. The amount of memory used
@@ -4379,16 +4401,6 @@ vim.o.mouset = vim.o.mousetime
vim.go.mousetime = vim.o.mousetime vim.go.mousetime = vim.o.mousetime
vim.go.mouset = vim.go.mousetime vim.go.mouset = vim.go.mousetime
--- Determines how many entries are remembered in the `:messages` history.
--- The maximum value is 10000.
--- Setting it to zero clears the message history.
---
--- @type integer
vim.o.msghistory = 500
vim.o.mhi = vim.o.msghistory
vim.go.msghistory = vim.o.msghistory
vim.go.mhi = vim.go.msghistory
--- This defines what bases Vim will consider for numbers when using the --- This defines what bases Vim will consider for numbers when using the
--- CTRL-A and CTRL-X commands for adding to and subtracting from a number --- CTRL-A and CTRL-X commands for adding to and subtracting from a number
--- respectively; see `CTRL-A` for more info on these commands. --- respectively; see `CTRL-A` for more info on these commands.

View File

@@ -626,8 +626,8 @@ call <SID>AddOption("terse", gettext("add 's' flag in 'shortmess' (don't show se
call <SID>BinOptionG("terse", &terse) call <SID>BinOptionG("terse", &terse)
call <SID>AddOption("shortmess", gettext("list of flags to make messages shorter")) call <SID>AddOption("shortmess", gettext("list of flags to make messages shorter"))
call <SID>OptionG("shm", &shm) call <SID>OptionG("shm", &shm)
call <SID>AddOption("msghistory", gettext("how many messages are remembered")) call <SID>AddOption("messagesopt", gettext("Option settings when outputting messages"))
call append("$", " \tset mhi=" . &mhi) call <SID>OptionG("mopt", &mopt)
call <SID>AddOption("showcmd", gettext("show (partial) command keys in location given by 'showcmdloc'")) call <SID>AddOption("showcmd", gettext("show (partial) command keys in location given by 'showcmdloc'"))
let &sc = s:old_sc let &sc = s:old_sc
call <SID>BinOptionG("sc", &sc) call <SID>BinOptionG("sc", &sc)

View File

@@ -6101,12 +6101,18 @@ static void ex_sleep(exarg_T *eap)
default: default:
semsg(_(e_invarg2), eap->arg); return; semsg(_(e_invarg2), eap->arg); return;
} }
do_sleep(len); do_sleep(len, false);
} }
/// Sleep for "msec" milliseconds, but return early on CTRL-C. /// Sleep for "msec" milliseconds, but return early on CTRL-C.
void do_sleep(int64_t msec) ///
/// @param hide_cursor hide the cursor if true
void do_sleep(int64_t msec, bool hide_cursor)
{ {
if (hide_cursor) {
ui_busy_start();
}
ui_flush(); // flush before waiting ui_flush(); // flush before waiting
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, msec, got_int); LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, msec, got_int);
@@ -6115,6 +6121,10 @@ void do_sleep(int64_t msec)
if (got_int) { if (got_int) {
vpeekc(); vpeekc();
} }
if (hide_cursor) {
ui_busy_stop();
}
} }
/// ":winsize" command (obsolete). /// ":winsize" command (obsolete).

View File

@@ -47,7 +47,9 @@ end
--- @param s string --- @param s string
--- @return string --- @return string
local lowercase_to_titlecase = function(s) local lowercase_to_titlecase = function(s)
return s:sub(1, 1):upper() .. s:sub(2) return table.concat(vim.tbl_map(function(word) --- @param word string
return word:sub(1, 1):upper() .. word:sub(2)
end, vim.split(s, '[-_]')))
end end
-- Generate options enum file -- Generate options enum file
@@ -177,7 +179,7 @@ for _, option in ipairs(options_meta) do
vars_w( vars_w(
(' kOpt%sFlag%s = 0x%02x,'):format( (' kOpt%sFlag%s = 0x%02x,'):format(
opt_name, opt_name,
lowercase_to_titlecase(flag_name), lowercase_to_titlecase(flag_name:gsub(':$', '')),
enum_values[flag_name] enum_values[flag_name]
) )
) )

View File

@@ -26,6 +26,7 @@
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/ex_cmds_defs.h" #include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h" #include "nvim/ex_eval.h"
#include "nvim/fileio.h" #include "nvim/fileio.h"
#include "nvim/garray.h" #include "nvim/garray.h"
@@ -94,6 +95,16 @@ static char *confirm_msg_tail; // tail of confirm_msg
MessageHistoryEntry *first_msg_hist = NULL; MessageHistoryEntry *first_msg_hist = NULL;
MessageHistoryEntry *last_msg_hist = NULL; MessageHistoryEntry *last_msg_hist = NULL;
static int msg_hist_len = 0; static int msg_hist_len = 0;
static int msg_hist_max = 500; // The default max value is 500
// args in 'messagesopt' option
#define MESSAGES_OPT_HIT_ENTER "hit-enter"
#define MESSAGES_OPT_WAIT "wait:"
#define MESSAGES_OPT_HISTORY "history:"
// The default is "hit-enter,history:500"
static int msg_flags = kOptMoptFlagHitEnter | kOptMoptFlagHistory;
static int msg_wait = 0;
static FILE *verbose_fd = NULL; static FILE *verbose_fd = NULL;
static bool verbose_did_open = false; static bool verbose_did_open = false;
@@ -1038,14 +1049,69 @@ int delete_first_msg(void)
return OK; return OK;
} }
void check_msg_hist(void) static void check_msg_hist(void)
{ {
// Don't let the message history get too big // Don't let the message history get too big
while (msg_hist_len > 0 && msg_hist_len > p_mhi) { while (msg_hist_len > 0 && msg_hist_len > msg_hist_max) {
(void)delete_first_msg(); (void)delete_first_msg();
} }
} }
int messagesopt_changed(void)
{
int messages_flags_new = 0;
int messages_wait_new = 0;
int messages_history_new = 0;
char *p = p_meo;
while (*p != NUL) {
if (strnequal(p, S_LEN(MESSAGES_OPT_HIT_ENTER))) {
p += STRLEN_LITERAL(MESSAGES_OPT_HIT_ENTER);
messages_flags_new |= kOptMoptFlagHitEnter;
} else if (strnequal(p, S_LEN(MESSAGES_OPT_WAIT))
&& ascii_isdigit(p[STRLEN_LITERAL(MESSAGES_OPT_WAIT)])) {
p += STRLEN_LITERAL(MESSAGES_OPT_WAIT);
messages_wait_new = getdigits_int(&p, false, INT_MAX);
messages_flags_new |= kOptMoptFlagWait;
} else if (strnequal(p, S_LEN(MESSAGES_OPT_HISTORY))
&& ascii_isdigit(p[STRLEN_LITERAL(MESSAGES_OPT_HISTORY)])) {
p += STRLEN_LITERAL(MESSAGES_OPT_HISTORY);
messages_history_new = getdigits_int(&p, false, INT_MAX);
messages_flags_new |= kOptMoptFlagHistory;
}
if (*p != ',' && *p != NUL) {
return FAIL;
}
if (*p == ',') {
p++;
}
}
// Either "wait" or "hit-enter" is required
if (!(messages_flags_new & (kOptMoptFlagHitEnter | kOptMoptFlagWait))) {
return FAIL;
}
// "history" must be set
if (!(messages_flags_new & kOptMoptFlagHistory)) {
return FAIL;
}
// "history" must be <= 10000
if (messages_history_new > 10000) {
return FAIL;
}
msg_flags = messages_flags_new;
msg_wait = messages_wait_new;
msg_hist_max = messages_history_new;
check_msg_hist();
return OK;
}
/// :messages command implementation /// :messages command implementation
void ex_messages(exarg_T *eap) void ex_messages(exarg_T *eap)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
@@ -1209,83 +1275,88 @@ void wait_return(int redraw)
cmdline_row = Rows - 1; cmdline_row = Rows - 1;
} }
hit_return_msg(true); if (msg_flags & kOptMoptFlagHitEnter) {
hit_return_msg(true);
do { do {
// Remember "got_int", if it is set vgetc() probably returns a // Remember "got_int", if it is set vgetc() probably returns a
// CTRL-C, but we need to loop then. // CTRL-C, but we need to loop then.
had_got_int = got_int; had_got_int = got_int;
// Don't do mappings here, we put the character back in the // Don't do mappings here, we put the character back in the
// typeahead buffer. // typeahead buffer.
no_mapping++; no_mapping++;
allow_keys++; allow_keys++;
// Temporarily disable Recording. If Recording is active, the // Temporarily disable Recording. If Recording is active, the
// character will be recorded later, since it will be added to the // character will be recorded later, since it will be added to the
// typebuf after the loop // typebuf after the loop
const int save_reg_recording = reg_recording; const int save_reg_recording = reg_recording;
save_scriptout = scriptout; save_scriptout = scriptout;
reg_recording = 0; reg_recording = 0;
scriptout = NULL; scriptout = NULL;
c = safe_vgetc(); c = safe_vgetc();
if (had_got_int && !global_busy) { if (had_got_int && !global_busy) {
got_int = false; got_int = false;
}
no_mapping--;
allow_keys--;
reg_recording = save_reg_recording;
scriptout = save_scriptout;
// Allow scrolling back in the messages.
// Also accept scroll-down commands when messages fill the screen,
// to avoid that typing one 'j' too many makes the messages
// disappear.
if (p_more) {
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|| c == K_UP || c == K_PAGEUP) {
if (msg_scrolled > Rows) {
// scroll back to show older messages
do_more_prompt(c);
} else {
msg_didout = false;
c = K_IGNORE;
msg_col = 0;
}
if (quit_more) {
c = CAR; // just pretend CR was hit
quit_more = false;
got_int = false;
} else if (c != K_IGNORE) {
c = K_IGNORE;
hit_return_msg(false);
}
} else if (msg_scrolled > Rows - 2
&& (c == 'j' || c == 'd' || c == 'f'
|| c == K_DOWN || c == K_PAGEDOWN)) {
c = K_IGNORE;
} }
} no_mapping--;
} while ((had_got_int && c == Ctrl_C) allow_keys--;
|| c == K_IGNORE reg_recording = save_reg_recording;
|| c == K_LEFTDRAG || c == K_LEFTRELEASE scriptout = save_scriptout;
|| c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
|| c == K_RIGHTDRAG || c == K_RIGHTRELEASE
|| c == K_MOUSELEFT || c == K_MOUSERIGHT
|| c == K_MOUSEDOWN || c == K_MOUSEUP
|| c == K_MOUSEMOVE);
os_breakcheck();
// Avoid that the mouse-up event causes visual mode to start. // Allow scrolling back in the messages.
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE // Also accept scroll-down commands when messages fill the screen,
|| c == K_X1MOUSE || c == K_X2MOUSE) { // to avoid that typing one 'j' too many makes the messages
jump_to_mouse(MOUSE_SETPOS, NULL, 0); // disappear.
} else if (vim_strchr("\r\n ", c) == NULL && c != Ctrl_C) { if (p_more) {
// Put the character back in the typeahead buffer. Don't use the if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
// stuff buffer, because lmaps wouldn't work. || c == K_UP || c == K_PAGEUP) {
ins_char_typebuf(vgetc_char, vgetc_mod_mask, true); if (msg_scrolled > Rows) {
do_redraw = true; // need a redraw even though there is // scroll back to show older messages
// typeahead do_more_prompt(c);
} else {
msg_didout = false;
c = K_IGNORE;
msg_col = 0;
}
if (quit_more) {
c = CAR; // just pretend CR was hit
quit_more = false;
got_int = false;
} else if (c != K_IGNORE) {
c = K_IGNORE;
hit_return_msg(false);
}
} else if (msg_scrolled > Rows - 2
&& (c == 'j' || c == 'd' || c == 'f'
|| c == K_DOWN || c == K_PAGEDOWN)) {
c = K_IGNORE;
}
}
} while ((had_got_int && c == Ctrl_C)
|| c == K_IGNORE
|| c == K_LEFTDRAG || c == K_LEFTRELEASE
|| c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
|| c == K_RIGHTDRAG || c == K_RIGHTRELEASE
|| c == K_MOUSELEFT || c == K_MOUSERIGHT
|| c == K_MOUSEDOWN || c == K_MOUSEUP
|| c == K_MOUSEMOVE);
os_breakcheck();
// Avoid that the mouse-up event causes visual mode to start.
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
|| c == K_X1MOUSE || c == K_X2MOUSE) {
jump_to_mouse(MOUSE_SETPOS, NULL, 0);
} else if (vim_strchr("\r\n ", c) == NULL && c != Ctrl_C) {
// Put the character back in the typeahead buffer. Don't use the
// stuff buffer, because lmaps wouldn't work.
ins_char_typebuf(vgetc_char, vgetc_mod_mask, true);
do_redraw = true; // need a redraw even though there is typeahead
}
} else {
c = CAR;
// Wait to allow the user to verify the output.
do_sleep(msg_wait, true);
} }
} }
redir_off = false; redir_off = false;

View File

@@ -812,7 +812,7 @@ static void normal_get_additional_char(NormalState *s)
// There is a busy wait here when typing "f<C-\>" and then // There is a busy wait here when typing "f<C-\>" and then
// something different from CTRL-N. Can't be avoided. // something different from CTRL-N. Can't be avoided.
while ((s->c = vpeekc()) <= 0 && towait > 0) { while ((s->c = vpeekc()) <= 0 && towait > 0) {
do_sleep(towait > 50 ? 50 : towait); do_sleep(towait > 50 ? 50 : towait, false);
towait -= 50; towait -= 50;
} }
if (s->c > 0) { if (s->c > 0) {
@@ -5561,7 +5561,7 @@ static void nv_g_cmd(cmdarg_T *cap)
// "gs": Goto sleep. // "gs": Goto sleep.
case 's': case 's':
do_sleep(cap->count1 * 1000); do_sleep(cap->count1 * 1000, false);
break; break;
// "ga": Display the ascii value of the character under the // "ga": Display the ascii value of the character under the

View File

@@ -2199,13 +2199,6 @@ static const char *did_set_modified(optset_T *args)
return NULL; return NULL;
} }
/// Process the updated 'msghistory' option value.
static const char *did_set_msghistory(optset_T *args FUNC_ATTR_UNUSED)
{
check_msg_hist();
return NULL;
}
/// Process the updated 'number' or 'relativenumber' option value. /// Process the updated 'number' or 'relativenumber' option value.
static const char *did_set_number_relativenumber(optset_T *args) static const char *did_set_number_relativenumber(optset_T *args)
{ {
@@ -2886,13 +2879,6 @@ static const char *validate_num_option(OptIndex opt_idx, OptInt *newval, char *e
return e_invarg; return e_invarg;
} }
break; break;
case kOptMsghistory:
if (value < 0) {
return e_positive;
} else if (value > 10000) {
return e_invarg;
}
break;
case kOptPyxversion: case kOptPyxversion:
if (value == 0) { if (value == 0) {
*newval = 3; *newval = 3;

View File

@@ -448,6 +448,7 @@ EXTERN OptInt p_mfd; ///< 'maxfuncdepth'
EXTERN OptInt p_mmd; ///< 'maxmapdepth' EXTERN OptInt p_mmd; ///< 'maxmapdepth'
EXTERN OptInt p_mmp; ///< 'maxmempattern' EXTERN OptInt p_mmp; ///< 'maxmempattern'
EXTERN OptInt p_mis; ///< 'menuitems' EXTERN OptInt p_mis; ///< 'menuitems'
EXTERN char *p_meo; ///< 'messagesopt'
EXTERN char *p_msm; ///< 'mkspellmem' EXTERN char *p_msm; ///< 'mkspellmem'
EXTERN int p_ml; ///< 'modeline' EXTERN int p_ml; ///< 'modeline'
EXTERN int p_mle; ///< 'modelineexpr' EXTERN int p_mle; ///< 'modelineexpr'
@@ -464,7 +465,6 @@ EXTERN OptInt p_mousescroll_vert INIT( = MOUSESCROLL_VERT_DFLT);
EXTERN OptInt p_mousescroll_hor INIT( = MOUSESCROLL_HOR_DFLT); EXTERN OptInt p_mousescroll_hor INIT( = MOUSESCROLL_HOR_DFLT);
EXTERN OptInt p_mouset; ///< 'mousetime' EXTERN OptInt p_mouset; ///< 'mousetime'
EXTERN int p_more; ///< 'more' EXTERN int p_more; ///< 'more'
EXTERN OptInt p_mhi; ///< 'msghistory'
EXTERN char *p_nf; ///< 'nrformats' EXTERN char *p_nf; ///< 'nrformats'
EXTERN char *p_opfunc; ///< 'operatorfunc' EXTERN char *p_opfunc; ///< 'operatorfunc'
EXTERN char *p_para; ///< 'paragraphs' EXTERN char *p_para; ///< 'paragraphs'

View File

@@ -4094,7 +4094,7 @@ return {
desc = [=[ desc = [=[
A history of ":" commands, and a history of previous search patterns A history of ":" commands, and a history of previous search patterns
is remembered. This option decides how many entries may be stored in is remembered. This option decides how many entries may be stored in
each of these histories (see |cmdline-editing| and 'msghistory' for each of these histories (see |cmdline-editing| and 'messagesopt' for
the number of messages to remember). the number of messages to remember).
The maximum value is 10000. The maximum value is 10000.
]=], ]=],
@@ -5448,6 +5448,38 @@ return {
type = 'number', type = 'number',
varname = 'p_mis', varname = 'p_mis',
}, },
{
abbreviation = 'mopt',
cb = 'did_set_messagesopt',
defaults = { if_true = 'hit-enter,history:500' },
values = { 'hit-enter', 'wait:', 'history:' },
flags = true,
deny_duplicates = true,
desc = [=[
Option settings when outputting messages. It can consist of the
following items. Items must be separated by a comma.
hit-enter Use |hit-enter| prompt when the message is longer than
'cmdheight' size.
wait:{n} Ignored when "hit-enter" is present. Instead of using
|hit-enter| prompt, will simply wait for {n}
milliseconds so the user has a chance to read the
message, use 0 to disable sleep (but then the user may
miss an important message).
history:{n} Determines how many entries are remembered in the
|:messages| history. The maximum value is 10000.
Setting it to zero clears the message history.
]=],
expand_cb = 'expand_set_messagesopt',
full_name = 'messagesopt',
list = 'onecommacolon',
scope = { 'global' },
short_desc = N_('options for outputting messages'),
type = 'string',
varname = 'p_meo',
},
{ {
abbreviation = 'msm', abbreviation = 'msm',
cb = 'did_set_mkspellmem', cb = 'did_set_mkspellmem',
@@ -5892,21 +5924,6 @@ return {
type = 'number', type = 'number',
varname = 'p_mouset', varname = 'p_mouset',
}, },
{
abbreviation = 'mhi',
cb = 'did_set_msghistory',
defaults = { if_true = 500 },
desc = [=[
Determines how many entries are remembered in the |:messages| history.
The maximum value is 10000.
Setting it to zero clears the message history.
]=],
full_name = 'msghistory',
scope = { 'global' },
short_desc = N_('how many messages are remembered'),
type = 'number',
varname = 'p_mhi',
},
{ {
abbreviation = 'nf', abbreviation = 'nf',
cb = 'did_set_nrformats', cb = 'did_set_nrformats',

View File

@@ -1682,6 +1682,24 @@ const char *did_set_matchpairs(optset_T *args)
return NULL; return NULL;
} }
/// Process the updated 'messagesopt' option value.
const char *did_set_messagesopt(optset_T *args FUNC_ATTR_UNUSED)
{
if (messagesopt_changed() == FAIL) {
return e_invarg;
}
return NULL;
}
int expand_set_messagesopt(optexpand_T *args, int *numMatches, char ***matches)
{
return expand_set_opt_string(args,
opt_mopt_values,
ARRAY_SIZE(opt_mopt_values) - 1,
numMatches,
matches);
}
/// The 'mkspellmem' option is changed. /// The 'mkspellmem' option is changed.
const char *did_set_mkspellmem(optset_T *args FUNC_ATTR_UNUSED) const char *did_set_mkspellmem(optset_T *args FUNC_ATTR_UNUSED)
{ {

View File

@@ -689,4 +689,43 @@ describe('messages', function()
]]) ]])
os.remove('b.txt') os.remove('b.txt')
end) end)
-- oldtest: Test_messagesopt_wait()
it('&messagesopt "wait"', function()
screen = Screen.new(45, 6)
command('set cmdheight=1')
-- Check hit-enter prompt
command('set messagesopt=hit-enter,history:500')
feed(":echo 'foo' | echo 'bar' | echo 'baz'\n")
screen:expect([[
|
{3: }|
foo |
bar |
baz |
{6:Press ENTER or type command to continue}^ |
]])
feed('<CR>')
-- Check no hit-enter prompt when "wait:" is set
command('set messagesopt=wait:100,history:500')
feed(":echo 'foo' | echo 'bar' | echo 'baz'\n")
screen:expect({
grid = [[
|
{1:~ }|
{3: }|
foo |
bar |
baz |
]],
timeout = 100,
})
screen:expect([[
^ |
{1:~ }|*4
|
]])
end)
end) end)

View File

@@ -117,7 +117,6 @@ let test_values = {
"\ 'imstyle': [[0, 1], [-1, 2, 999]], "\ 'imstyle': [[0, 1], [-1, 2, 999]],
\ 'lines': [[2, 24, 1000], [-1, 0, 1]], \ 'lines': [[2, 24, 1000], [-1, 0, 1]],
\ 'linespace': [[-1, 0, 2, 4, 999], ['']], \ 'linespace': [[-1, 0, 2, 4, 999], ['']],
\ 'msghistory': [[0, 1, 100, 10000], [-1, 10001]],
\ 'numberwidth': [[1, 4, 8, 10, 11, 20], [-1, 0, 21]], \ 'numberwidth': [[1, 4, 8, 10, 11, 20], [-1, 0, 21]],
\ 'regexpengine': [[0, 1, 2], [-1, 3, 999]], \ 'regexpengine': [[0, 1, 2], [-1, 3, 999]],
\ 'report': [[0, 1, 2, 9999], [-1]], \ 'report': [[0, 1, 2, 9999], [-1]],
@@ -264,6 +263,11 @@ let test_values = {
\ 'eol:\\u21b5', 'eol:\\U000021b5', 'eol:x,space:y'], \ 'eol:\\u21b5', 'eol:\\U000021b5', 'eol:x,space:y'],
\ ['xxx', 'eol:']], \ ['xxx', 'eol:']],
\ 'matchpairs': [['', '(:)', '(:),<:>'], ['xxx']], \ 'matchpairs': [['', '(:)', '(:),<:>'], ['xxx']],
\ 'messagesopt': [['hit-enter,history:1', 'hit-enter,history:10000',
\ 'history:100,wait:100', 'history:0,wait:0',
\ 'hit-enter,history:1,wait:1'],
\ ['xxx', 'history:500', 'hit-enter,history:-1',
\ 'hit-enter,history:10001', 'hit-enter']],
\ 'mkspellmem': [['10000,100,12'], ['', 'xxx', '10000,100']], \ 'mkspellmem': [['10000,100,12'], ['', 'xxx', '10000,100']],
\ 'mouse': [['', 'n', 'v', 'i', 'c', 'h', 'a', 'r', 'nvi'], \ 'mouse': [['', 'n', 'v', 'i', 'c', 'h', 'a', 'r', 'nvi'],
\ ['xxx', 'n,v,i']], \ ['xxx', 'n,v,i']],

View File

@@ -4181,30 +4181,4 @@ func Test_cd_bslash_completion_windows()
let &shellslash = save_shellslash let &shellslash = save_shellslash
endfunc endfunc
func Test_msghistory()
" After setting 'msghistory' to 2 and outputting a message 4 times with
" :echomsg, is the number of output lines of :messages 2?
set msghistory=2
echomsg 'foo'
echomsg 'bar'
echomsg 'baz'
echomsg 'foobar'
call assert_equal(['baz', 'foobar'], GetMessages())
" When the number of messages is 10 and 'msghistory' is changed to 5, is the
" number of output lines of :messages 5?
set msghistory=10
for num in range(1, 10)
echomsg num
endfor
set msghistory=5
call assert_equal(5, len(GetMessages()))
" Check empty list
set msghistory=0
call assert_true(empty(GetMessages()))
set msghistory&
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -216,6 +216,7 @@ endfunc
" Test more-prompt (see :help more-prompt). " Test more-prompt (see :help more-prompt).
func Test_message_more() func Test_message_more()
CheckRunVimInTerminal CheckRunVimInTerminal
let buf = RunVimInTerminal('', {'rows': 6}) let buf = RunVimInTerminal('', {'rows': 6})
call term_sendkeys(buf, ":call setline(1, range(1, 100))\n") call term_sendkeys(buf, ":call setline(1, range(1, 100))\n")
@@ -611,4 +612,50 @@ func Test_cmdheight_zero()
tabonly tabonly
endfunc endfunc
func Test_messagesopt_history()
" After setting 'messagesopt' "history" to 2 and outputting a message 4 times
" with :echomsg, is the number of output lines of :messages 2?
set messagesopt=hit-enter,history:2
echomsg 'foo'
echomsg 'bar'
echomsg 'baz'
echomsg 'foobar'
call assert_equal(['baz', 'foobar'], GetMessages())
" When the number of messages is 10 and 'messagesopt' "history" is changed to
" 5, is the number of output lines of :messages 5?
set messagesopt=hit-enter,history:10
for num in range(1, 10)
echomsg num
endfor
set messagesopt=hit-enter,history:5
call assert_equal(5, len(GetMessages()))
" Check empty list
set messagesopt=hit-enter,history:0
call assert_true(empty(GetMessages()))
set messagesopt&
endfunc
func Test_messagesopt_wait()
CheckRunVimInTerminal
let buf = RunVimInTerminal('', {'rows': 6, 'cols': 45})
call term_sendkeys(buf, ":set cmdheight=1\n")
" Check hit-enter prompt
call term_sendkeys(buf, ":set messagesopt=hit-enter,history:500\n")
call term_sendkeys(buf, ":echo 'foo' | echo 'bar' echo 'baz'\n")
call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))})
" Check no hit-enter prompt when "wait:" is set
call term_sendkeys(buf, ":set messagesopt=wait:100,history:500\n")
call term_sendkeys(buf, ":echo 'foo' | echo 'bar' echo 'baz'\n")
call WaitForAssert({-> assert_equal(' 0,0-1 All', term_getline(buf, 6))})
" clean up
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -644,6 +644,10 @@ func Test_set_completion_string_values()
" call feedkeys(":set hl=8b i\<Left>\<Left>\<Tab>\<C-B>\"\<CR>", 'xt') " call feedkeys(":set hl=8b i\<Left>\<Left>\<Tab>\<C-B>\"\<CR>", 'xt')
" call assert_equal("\"set hl=8bi i", @:) " call assert_equal("\"set hl=8bi i", @:)
" messagesopt
call assert_equal(['history:', 'hit-enter', 'wait:'],
\ getcompletion('set messagesopt+=', 'cmdline')->sort())
" "
" Test flag lists " Test flag lists
" "
@@ -743,7 +747,6 @@ func Test_set_option_errors()
call assert_fails('set backupcopy=', 'E474:') call assert_fails('set backupcopy=', 'E474:')
call assert_fails('set regexpengine=3', 'E474:') call assert_fails('set regexpengine=3', 'E474:')
call assert_fails('set history=10001', 'E474:') call assert_fails('set history=10001', 'E474:')
call assert_fails('set msghistory=10001', 'E474:')
call assert_fails('set numberwidth=21', 'E474:') call assert_fails('set numberwidth=21', 'E474:')
call assert_fails('set colorcolumn=-a', 'E474:') call assert_fails('set colorcolumn=-a', 'E474:')
call assert_fails('set colorcolumn=a', 'E474:') call assert_fails('set colorcolumn=a', 'E474:')
@@ -757,7 +760,6 @@ func Test_set_option_errors()
endif endif
call assert_fails('set helpheight=-1', 'E487:') call assert_fails('set helpheight=-1', 'E487:')
call assert_fails('set history=-1', 'E487:') call assert_fails('set history=-1', 'E487:')
call assert_fails('set msghistory=-1', 'E487:')
call assert_fails('set report=-1', 'E487:') call assert_fails('set report=-1', 'E487:')
call assert_fails('set shiftwidth=-1', 'E487:') call assert_fails('set shiftwidth=-1', 'E487:')
call assert_fails('set sidescroll=-1', 'E487:') call assert_fails('set sidescroll=-1', 'E487:')
@@ -2517,6 +2519,7 @@ func Test_string_option_revert_on_failure()
\ ['lispoptions', 'expr:1', 'a123'], \ ['lispoptions', 'expr:1', 'a123'],
\ ['listchars', 'tab:->', 'tab:'], \ ['listchars', 'tab:->', 'tab:'],
\ ['matchpairs', '<:>', '<:'], \ ['matchpairs', '<:>', '<:'],
\ ['messagesopt', 'hit-enter,history:100', 'a123'],
\ ['mkspellmem', '100000,1000,100', '100000'], \ ['mkspellmem', '100000,1000,100', '100000'],
\ ['mouse', 'nvi', 'z'], \ ['mouse', 'nvi', 'z'],
\ ['mousemodel', 'extend', 'a123'], \ ['mousemodel', 'extend', 'a123'],