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

@@ -26,6 +26,7 @@
#include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/fileio.h"
#include "nvim/garray.h"
@@ -94,6 +95,16 @@ static char *confirm_msg_tail; // tail of confirm_msg
MessageHistoryEntry *first_msg_hist = NULL;
MessageHistoryEntry *last_msg_hist = NULL;
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 bool verbose_did_open = false;
@@ -1038,14 +1049,69 @@ int delete_first_msg(void)
return OK;
}
void check_msg_hist(void)
static void check_msg_hist(void)
{
// 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();
}
}
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
void ex_messages(exarg_T *eap)
FUNC_ATTR_NONNULL_ALL
@@ -1209,83 +1275,88 @@ void wait_return(int redraw)
cmdline_row = Rows - 1;
}
hit_return_msg(true);
if (msg_flags & kOptMoptFlagHitEnter) {
hit_return_msg(true);
do {
// Remember "got_int", if it is set vgetc() probably returns a
// CTRL-C, but we need to loop then.
had_got_int = got_int;
do {
// Remember "got_int", if it is set vgetc() probably returns a
// CTRL-C, but we need to loop then.
had_got_int = got_int;
// Don't do mappings here, we put the character back in the
// typeahead buffer.
no_mapping++;
allow_keys++;
// Don't do mappings here, we put the character back in the
// typeahead buffer.
no_mapping++;
allow_keys++;
// Temporarily disable Recording. If Recording is active, the
// character will be recorded later, since it will be added to the
// typebuf after the loop
const int save_reg_recording = reg_recording;
save_scriptout = scriptout;
reg_recording = 0;
scriptout = NULL;
c = safe_vgetc();
if (had_got_int && !global_busy) {
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;
// Temporarily disable Recording. If Recording is active, the
// character will be recorded later, since it will be added to the
// typebuf after the loop
const int save_reg_recording = reg_recording;
save_scriptout = scriptout;
reg_recording = 0;
scriptout = NULL;
c = safe_vgetc();
if (had_got_int && !global_busy) {
got_int = false;
}
}
} 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();
no_mapping--;
allow_keys--;
reg_recording = save_reg_recording;
scriptout = save_scriptout;
// 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
// 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;
}
}
} 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;