mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
fix(messages): recognize cmdline one_key/number prompt State (#34206)
Problem: Since48e2a736
, prompt messages are handled by an actual active cmdline, resulting in `State` no longer being equal to `MODE_CONFIRM` which is used in some places. E.g. to specify the current `mode()` or to re-emit a confirm message. Solution: Replace `MODE_CONFIRM` with a new `MODE_CMDLINE` sub-mode when `ccline.one_key/mouse_used` is set. Use it to avoid clearing mouse_used prompt messages, and to re-emit one_key messages (when ext_messages is inactive, for which this is unnecessary). (cherry picked from commite876a739ee
)
This commit is contained in:

committed by
github-actions[bot]
![github-actions[bot]](/assets/img/avatar_default.png)
parent
adf31505d8
commit
89959ab9dc
@@ -268,12 +268,19 @@ void screenclear(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unlike cmdline "one_key" prompts, the message part of the prompt is not stored
|
||||||
|
/// to be re-emitted: avoid clearing the prompt from the message grid.
|
||||||
|
static bool cmdline_number_prompt(void)
|
||||||
|
{
|
||||||
|
return !ui_has(kUIMessages) && State == MODE_CMDLINE && get_cmdline_info()->mouse_used != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/// Set dimensions of the Nvim application "screen".
|
/// Set dimensions of the Nvim application "screen".
|
||||||
void screen_resize(int width, int height)
|
void screen_resize(int width, int height)
|
||||||
{
|
{
|
||||||
// Avoid recursiveness, can happen when setting the window size causes
|
// Avoid recursiveness, can happen when setting the window size causes
|
||||||
// another window-changed signal.
|
// another window-changed signal.
|
||||||
if (updating_screen || resizing_screen) {
|
if (updating_screen || resizing_screen || cmdline_number_prompt()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +357,7 @@ void screen_resize(int width, int height)
|
|||||||
resizing_autocmd = false;
|
resizing_autocmd = false;
|
||||||
redraw_all_later(UPD_CLEAR);
|
redraw_all_later(UPD_CLEAR);
|
||||||
|
|
||||||
if (State != MODE_ASKMORE && State != MODE_EXTERNCMD && State != MODE_CONFIRM) {
|
if (State != MODE_ASKMORE && State != MODE_EXTERNCMD) {
|
||||||
screenclear();
|
screenclear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,8 +373,11 @@ void screen_resize(int width, int height)
|
|||||||
// - While editing the command line, only redraw that. TODO: lies
|
// - While editing the command line, only redraw that. TODO: lies
|
||||||
// - in Ex mode, don't redraw anything.
|
// - in Ex mode, don't redraw anything.
|
||||||
// - Otherwise, redraw right now, and position the cursor.
|
// - Otherwise, redraw right now, and position the cursor.
|
||||||
if (State == MODE_ASKMORE || State == MODE_EXTERNCMD || State == MODE_CONFIRM
|
if (State == MODE_ASKMORE || State == MODE_EXTERNCMD || exmode_active
|
||||||
|| exmode_active) {
|
|| (State == MODE_CMDLINE && get_cmdline_info()->one_key)) {
|
||||||
|
if (State == MODE_CMDLINE) {
|
||||||
|
update_screen();
|
||||||
|
}
|
||||||
if (msg_grid.chars) {
|
if (msg_grid.chars) {
|
||||||
msg_grid_validate();
|
msg_grid_validate();
|
||||||
}
|
}
|
||||||
@@ -453,7 +463,7 @@ int update_screen(void)
|
|||||||
|
|
||||||
// Postpone the redrawing when it's not needed and when being called
|
// Postpone the redrawing when it's not needed and when being called
|
||||||
// recursively.
|
// recursively.
|
||||||
if (!redrawing() || updating_screen) {
|
if (!redrawing() || updating_screen || cmdline_number_prompt()) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +502,7 @@ int update_screen(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the screen was scrolled up when displaying a message, scroll it down
|
// if the screen was scrolled up when displaying a message, scroll it down
|
||||||
if (msg_scrolled || msg_grid_invalid) {
|
if ((msg_scrolled || msg_grid_invalid) && !cmdline_number_prompt()) {
|
||||||
clear_cmdline = true;
|
clear_cmdline = true;
|
||||||
int valid = MAX(Rows - msg_scrollsize(), 0);
|
int valid = MAX(Rows - msg_scrollsize(), 0);
|
||||||
if (msg_grid.chars) {
|
if (msg_grid.chars) {
|
||||||
@@ -699,6 +709,7 @@ int update_screen(void)
|
|||||||
if (still_may_intro) {
|
if (still_may_intro) {
|
||||||
intro_message(false);
|
intro_message(false);
|
||||||
}
|
}
|
||||||
|
repeat_message();
|
||||||
|
|
||||||
decor_providers_invoke_end();
|
decor_providers_invoke_end();
|
||||||
|
|
||||||
|
@@ -3701,12 +3701,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
|
|
||||||
if (subflags.do_ask && cmdpreview_ns <= 0) {
|
if (subflags.do_ask && cmdpreview_ns <= 0) {
|
||||||
int typed = 0;
|
int typed = 0;
|
||||||
|
|
||||||
// change State to MODE_CONFIRM, so that the mouse works
|
|
||||||
// properly
|
|
||||||
int save_State = State;
|
int save_State = State;
|
||||||
State = MODE_CONFIRM;
|
|
||||||
setmouse(); // disable mouse in xterm
|
|
||||||
curwin->w_cursor.col = regmatch.startpos[0].col;
|
curwin->w_cursor.col = regmatch.startpos[0].col;
|
||||||
|
|
||||||
if (curwin->w_p_crb) {
|
if (curwin->w_p_crb) {
|
||||||
|
@@ -2200,7 +2200,6 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
|
|||||||
&& !(p_paste && (State & (MODE_INSERT | MODE_CMDLINE)))
|
&& !(p_paste && (State & (MODE_INSERT | MODE_CMDLINE)))
|
||||||
&& !(State == MODE_HITRETURN && (tb_c1 == CAR || tb_c1 == ' '))
|
&& !(State == MODE_HITRETURN && (tb_c1 == CAR || tb_c1 == ' '))
|
||||||
&& State != MODE_ASKMORE
|
&& State != MODE_ASKMORE
|
||||||
&& State != MODE_CONFIRM
|
|
||||||
&& !at_ins_compl_key()) {
|
&& !at_ins_compl_key()) {
|
||||||
int mlen;
|
int mlen;
|
||||||
int nolmaplen;
|
int nolmaplen;
|
||||||
|
@@ -41,8 +41,6 @@ int ask_yesno(const char *const str)
|
|||||||
const int save_State = State;
|
const int save_State = State;
|
||||||
|
|
||||||
no_wait_return++;
|
no_wait_return++;
|
||||||
State = MODE_CONFIRM; // Mouse behaves like with :confirm.
|
|
||||||
setmouse(); // Disable mouse in xterm.
|
|
||||||
snprintf(IObuff, IOSIZE, _("%s (y/n)?"), str);
|
snprintf(IObuff, IOSIZE, _("%s (y/n)?"), str);
|
||||||
char *prompt = xstrdup(IObuff);
|
char *prompt = xstrdup(IObuff);
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "nvim/ex_cmds_defs.h"
|
#include "nvim/ex_cmds_defs.h"
|
||||||
#include "nvim/ex_docmd.h"
|
#include "nvim/ex_docmd.h"
|
||||||
#include "nvim/ex_eval.h"
|
#include "nvim/ex_eval.h"
|
||||||
|
#include "nvim/ex_getln.h"
|
||||||
#include "nvim/fileio.h"
|
#include "nvim/fileio.h"
|
||||||
#include "nvim/garray.h"
|
#include "nvim/garray.h"
|
||||||
#include "nvim/garray_defs.h"
|
#include "nvim/garray_defs.h"
|
||||||
@@ -3051,13 +3052,17 @@ void msg_moremsg(bool full)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Repeat the message for the current mode: MODE_ASKMORE, MODE_EXTERNCMD,
|
/// Repeat the message for the current mode: MODE_ASKMORE, MODE_EXTERNCMD,
|
||||||
/// MODE_CONFIRM or exmode_active.
|
/// confirm() prompt or exmode_active.
|
||||||
void repeat_message(void)
|
void repeat_message(void)
|
||||||
{
|
{
|
||||||
|
if (ui_has(kUIMessages)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (State == MODE_ASKMORE) {
|
if (State == MODE_ASKMORE) {
|
||||||
msg_moremsg(true); // display --more-- message again
|
msg_moremsg(true); // display --more-- message again
|
||||||
msg_row = Rows - 1;
|
msg_row = Rows - 1;
|
||||||
} else if (State == MODE_CONFIRM) {
|
} else if (State == MODE_CMDLINE && confirm_msg != NULL) {
|
||||||
display_confirm_msg(); // display ":confirm" message again
|
display_confirm_msg(); // display ":confirm" message again
|
||||||
msg_row = Rows - 1;
|
msg_row = Rows - 1;
|
||||||
} else if (State == MODE_EXTERNCMD) {
|
} else if (State == MODE_EXTERNCMD) {
|
||||||
@@ -3527,8 +3532,6 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
|
|||||||
int oldState = State;
|
int oldState = State;
|
||||||
|
|
||||||
msg_silent = 0; // If dialog prompts for input, user needs to see it! #8788
|
msg_silent = 0; // If dialog prompts for input, user needs to see it! #8788
|
||||||
State = MODE_CONFIRM;
|
|
||||||
setmouse();
|
|
||||||
|
|
||||||
// Since we wait for a keypress, don't make the
|
// Since we wait for a keypress, don't make the
|
||||||
// user press RETURN as well afterwards.
|
// user press RETURN as well afterwards.
|
||||||
@@ -3585,6 +3588,8 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
|
|||||||
}
|
}
|
||||||
|
|
||||||
xfree(hotkeys);
|
xfree(hotkeys);
|
||||||
|
xfree(confirm_msg);
|
||||||
|
confirm_msg = NULL;
|
||||||
|
|
||||||
msg_silent = save_msg_silent;
|
msg_silent = save_msg_silent;
|
||||||
State = oldState;
|
State = oldState;
|
||||||
@@ -3665,7 +3670,6 @@ static char *console_dialog_alloc(const char *message, const char *buttons, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now allocate space for the strings
|
// Now allocate space for the strings
|
||||||
xfree(confirm_msg);
|
|
||||||
confirm_msg = xmalloc((size_t)msg_len);
|
confirm_msg = xmalloc((size_t)msg_len);
|
||||||
snprintf(confirm_msg, (size_t)msg_len, "\n%s\n", message);
|
snprintf(confirm_msg, (size_t)msg_len, "\n%s\n", message);
|
||||||
|
|
||||||
|
@@ -184,12 +184,12 @@ void get_mode(char *buf)
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (State == MODE_HITRETURN || State == MODE_ASKMORE
|
if (State == MODE_HITRETURN || State == MODE_ASKMORE || State == MODE_SETWSIZE
|
||||||
|| State == MODE_SETWSIZE || State == MODE_CONFIRM) {
|
|| (State == MODE_CMDLINE && get_cmdline_info()->one_key)) {
|
||||||
buf[i++] = 'r';
|
buf[i++] = 'r';
|
||||||
if (State == MODE_ASKMORE) {
|
if (State == MODE_ASKMORE) {
|
||||||
buf[i++] = 'm';
|
buf[i++] = 'm';
|
||||||
} else if (State == MODE_CONFIRM) {
|
} else if (State == MODE_CMDLINE) {
|
||||||
buf[i++] = '?';
|
buf[i++] = '?';
|
||||||
}
|
}
|
||||||
} else if (State == MODE_EXTERNCMD) {
|
} else if (State == MODE_EXTERNCMD) {
|
||||||
|
@@ -41,5 +41,4 @@ enum {
|
|||||||
MODE_SETWSIZE = 0x4000, ///< window size has changed
|
MODE_SETWSIZE = 0x4000, ///< window size has changed
|
||||||
MODE_EXTERNCMD = 0x5000, ///< executing an external command
|
MODE_EXTERNCMD = 0x5000, ///< executing an external command
|
||||||
MODE_SHOWMATCH = 0x6000 | MODE_INSERT, ///< show matching paren
|
MODE_SHOWMATCH = 0x6000 | MODE_INSERT, ///< show matching paren
|
||||||
MODE_CONFIRM = 0x7000, ///< ":confirm" prompt
|
|
||||||
};
|
};
|
||||||
|
@@ -590,8 +590,8 @@ void ui_check_mouse(void)
|
|||||||
checkfor = MOUSE_INSERT;
|
checkfor = MOUSE_INSERT;
|
||||||
} else if (State & MODE_CMDLINE) {
|
} else if (State & MODE_CMDLINE) {
|
||||||
checkfor = MOUSE_COMMAND;
|
checkfor = MOUSE_COMMAND;
|
||||||
} else if (State == MODE_CONFIRM || State == MODE_EXTERNCMD) {
|
} else if (State == MODE_EXTERNCMD) {
|
||||||
checkfor = ' '; // don't use mouse for ":confirm" or ":!cmd"
|
checkfor = ' '; // don't use mouse for ":!cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
// mouse should be active if at least one of the following is true:
|
// mouse should be active if at least one of the following is true:
|
||||||
|
@@ -2170,6 +2170,11 @@ describe('API', function()
|
|||||||
feed('<F2>')
|
feed('<F2>')
|
||||||
eq({ mode = 'n', blocking = false }, api.nvim_get_mode())
|
eq({ mode = 'n', blocking = false }, api.nvim_get_mode())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('returns "c" during number prompt', function()
|
||||||
|
feed('ifoo<Esc>z=')
|
||||||
|
eq({ mode = 'c', blocking = false }, api.nvim_get_mode())
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('RPC (K_EVENT)', function()
|
describe('RPC (K_EVENT)', function()
|
||||||
|
@@ -1106,7 +1106,7 @@ describe('cmdline redraw', function()
|
|||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('silent prompt', function()
|
it('prompt with silent mapping and screen update', function()
|
||||||
command([[nmap <silent> T :call confirm("Save changes?", "&Yes\n&No\n&Cancel")<CR>]])
|
command([[nmap <silent> T :call confirm("Save changes?", "&Yes\n&No\n&Cancel")<CR>]])
|
||||||
feed('T')
|
feed('T')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
@@ -1116,6 +1116,31 @@ describe('cmdline redraw', function()
|
|||||||
{6:Save changes?} |
|
{6:Save changes?} |
|
||||||
{6:[Y]es, (N)o, (C)ancel: }^ |
|
{6:[Y]es, (N)o, (C)ancel: }^ |
|
||||||
]])
|
]])
|
||||||
|
command('call setline(1, "foo") | redraw')
|
||||||
|
screen:expect([[
|
||||||
|
foo |
|
||||||
|
{3: }|
|
||||||
|
|
|
||||||
|
{6:Save changes?} |
|
||||||
|
{6:[Y]es, (N)o, (C)ancel: }^ |
|
||||||
|
]])
|
||||||
|
feed('Y')
|
||||||
|
screen:expect([[
|
||||||
|
^foo |
|
||||||
|
{1:~ }|*3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
screen:try_resize(75, screen._height)
|
||||||
|
feed(':call inputlist(["foo", "bar"])<CR>')
|
||||||
|
screen:expect([[
|
||||||
|
foo |
|
||||||
|
{3: }|
|
||||||
|
foo |
|
||||||
|
bar |
|
||||||
|
Type number and <Enter> or click with the mouse (q or empty cancels): ^ |
|
||||||
|
]])
|
||||||
|
command('redraw')
|
||||||
|
screen:expect_unchanged()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('substitute confirm prompt does not scroll', function()
|
it('substitute confirm prompt does not scroll', function()
|
||||||
|
Reference in New Issue
Block a user