1
0
forked from aniani/vim

patch 9.1.0908: not possible to configure :messages

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

closes: #16068

Co-authored-by: h_east <h.east.727@gmail.com>
Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2024-12-06 17:26:25 +01:00
parent ee9bc68f03
commit 51d4d84d6a
18 changed files with 311 additions and 181 deletions

View File

@@ -16,6 +16,7 @@
#include "vim.h"
static void add_msg_hist(char_u *s, int len, int attr);
static void check_msg_hist(void);
static void hit_return_msg(void);
static void msg_home_replace_attr(char_u *fname, int attr);
static void msg_puts_attr_len(char *str, int maxlen, int attr);
@@ -51,6 +52,21 @@ struct msg_hist
static struct msg_hist *first_msg_hist = NULL;
static struct msg_hist *last_msg_hist = NULL;
static int msg_hist_len = 0;
static int msg_hist_max = 500; // The default max value is 500
// flags obtained from the 'messagesopt' option
#define MESSAGES_HIT_ENTER 0x001
#define MESSAGES_WAIT 0x002
#define MESSAGES_HISTORY 0x004
// 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 = MESSAGES_HIT_ENTER | MESSAGES_HISTORY;
static int msg_wait = 0;
static FILE *verbose_fd = NULL;
static int verbose_did_open = FALSE;
@@ -1060,14 +1076,76 @@ delete_first_msg(void)
return OK;
}
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)
{
char_u *p;
int messages_flags_new = 0;
int messages_wait_new = 0;
int messages_history_new = 0;
p = p_meo;
while (*p != NUL)
{
if (STRNCMP(p, MESSAGES_OPT_HIT_ENTER,
STRLEN_LITERAL(MESSAGES_OPT_HIT_ENTER)) == 0)
{
p += STRLEN_LITERAL(MESSAGES_OPT_HIT_ENTER);
messages_flags_new |= MESSAGES_HIT_ENTER;
}
else if (STRNCMP(p, MESSAGES_OPT_WAIT,
STRLEN_LITERAL(MESSAGES_OPT_WAIT)) == 0
&& VIM_ISDIGIT(p[STRLEN_LITERAL(MESSAGES_OPT_WAIT)]))
{
p += STRLEN_LITERAL(MESSAGES_OPT_WAIT);
messages_wait_new = getdigits(&p);
messages_flags_new |= MESSAGES_WAIT;
}
else if (STRNCMP(p, MESSAGES_OPT_HISTORY,
STRLEN_LITERAL(MESSAGES_OPT_HISTORY)) == 0
&& VIM_ISDIGIT(p[STRLEN_LITERAL(MESSAGES_OPT_HISTORY)]))
{
p += STRLEN_LITERAL(MESSAGES_OPT_HISTORY);
messages_history_new = getdigits(&p);
messages_flags_new |= MESSAGES_HISTORY;
}
if (*p != ',' && *p != NUL)
return FAIL;
if (*p == ',')
++p;
}
// Either "wait" or "hit-enter" is required
if (!(messages_flags_new & (MESSAGES_HIT_ENTER | MESSAGES_WAIT)))
return FAIL;
// "history" must be set
if (!(messages_flags_new & MESSAGES_HISTORY))
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.
*/
@@ -1228,118 +1306,127 @@ wait_return(int redraw)
if (need_check_timestamps)
check_timestamps(FALSE);
hit_return_msg();
do
if (msg_flags & MESSAGES_HIT_ENTER)
{
// Remember "got_int", if it is set vgetc() probably returns a
// CTRL-C, but we need to loop then.
had_got_int = got_int;
hit_return_msg();
// Don't do mappings here, we put the character back in the
// typeahead buffer.
++no_mapping;
++allow_keys;
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;
// Temporarily disable Recording. If Recording is active, the
// character will be recorded later, since it will be added to the
// typebuf after the loop
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;
// 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
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;
#ifdef FEAT_CLIPBOARD
// Strange way to allow copying (yanking) a modeless selection at
// the hit-enter prompt. Use CTRL-Y, because the same is used in
// Cmdline-mode and it's harmless when there is no selection.
if (c == Ctrl_Y && clip_star.state == SELECT_DONE)
{
clip_copy_modeless_selection(TRUE);
c = K_IGNORE;
}
#endif
/*
* 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 && !p_cp)
{
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|| c == K_UP || c == K_PAGEUP)
// Strange way to allow copying (yanking) a modeless selection at
// the hit-enter prompt. Use CTRL-Y, because the same is used in
// Cmdline-mode and it's harmless when there is no selection.
if (c == Ctrl_Y && clip_star.state == SELECT_DONE)
{
if (msg_scrolled > Rows)
// scroll back to show older messages
do_more_prompt(c);
else
{
msg_didout = FALSE;
c = K_IGNORE;
msg_col =
#ifdef FEAT_RIGHTLEFT
cmdmsg_rl ? Columns - 1 :
#endif
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();
}
}
else if (msg_scrolled > Rows - 2
&& (c == 'j' || c == 'd' || c == 'f'
|| c == K_DOWN || c == K_PAGEDOWN))
clip_copy_modeless_selection(TRUE);
c = K_IGNORE;
}
} while ((had_got_int && c == Ctrl_C)
|| c == K_IGNORE
#ifdef FEAT_GUI
|| c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR
}
#endif
|| 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
|| (!mouse_has(MOUSE_RETURN)
&& mouse_row < msg_row
&& (c == K_LEFTMOUSE
|| c == K_MIDDLEMOUSE
|| c == K_RIGHTMOUSE
|| c == K_X1MOUSE
|| c == K_X2MOUSE))
);
ui_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)
(void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C)
/*
* 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 && !p_cp)
{
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 =
#ifdef FEAT_RIGHTLEFT
cmdmsg_rl ? Columns - 1 :
#endif
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();
}
}
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
#ifdef FEAT_GUI
|| c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR
#endif
|| 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
|| (!mouse_has(MOUSE_RETURN)
&& mouse_row < msg_row
&& (c == K_LEFTMOUSE
|| c == K_MIDDLEMOUSE
|| c == K_RIGHTMOUSE
|| c == K_X1MOUSE
|| c == K_X2MOUSE))
);
ui_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)
(void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
else if (vim_strchr((char_u *)"\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);
do_redraw = TRUE; // need a redraw even though there is
// typeahead
}
}
else
{
// 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);
do_redraw = TRUE; // need a redraw even though there is
// typeahead
c = CAR;
// Wait to allow the user to verify the output.
do_sleep(msg_wait, TRUE);
}
}
redir_off = FALSE;