mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 12:45:17 -07:00
feat(ui): use commandline for prompt "messages"
Problem: Prompts are emitted as messages events, where cmdline events are more appropriate. The user input is also emitted as message events in fast context, so cannot be displayed with vim.ui_attach(). Solution: Ask for user input through cmdline prompts.
This commit is contained in:
parent
0dd933265f
commit
378edbbd34
@ -1086,9 +1086,8 @@ vim.ui_attach({ns}, {options}, {callback}) *vim.ui_attach()*
|
|||||||
|ui-popupmenu| and the sections below for event format for respective
|
|ui-popupmenu| and the sections below for event format for respective
|
||||||
events.
|
events.
|
||||||
|
|
||||||
Callbacks for `msg_show` events are executed in |api-fast| context unless
|
Callbacks for `msg_show` events are executed in |api-fast| context;
|
||||||
Nvim will wait for input, in which case messages should be shown
|
showing the message should be scheduled.
|
||||||
immediately.
|
|
||||||
|
|
||||||
Excessive errors inside the callback will result in forced detachment.
|
Excessive errors inside the callback will result in forced detachment.
|
||||||
|
|
||||||
|
@ -791,7 +791,6 @@ must handle.
|
|||||||
"" (empty) Unknown (consider a |feature-request|)
|
"" (empty) Unknown (consider a |feature-request|)
|
||||||
"bufwrite" |:write| message
|
"bufwrite" |:write| message
|
||||||
"confirm" |confirm()| or |:confirm| dialog
|
"confirm" |confirm()| or |:confirm| dialog
|
||||||
"confirm_sub" |:substitute| confirm dialog |:s_c|
|
|
||||||
"emsg" Error (|errors|, internal error, |:throw|, …)
|
"emsg" Error (|errors|, internal error, |:throw|, …)
|
||||||
"echo" |:echo| message
|
"echo" |:echo| message
|
||||||
"echomsg" |:echomsg| message
|
"echomsg" |:echomsg| message
|
||||||
@ -800,7 +799,6 @@ must handle.
|
|||||||
"lua_error" Error in |:lua| code
|
"lua_error" Error in |:lua| code
|
||||||
"lua_print" |print()| from |:lua| code
|
"lua_print" |print()| from |:lua| code
|
||||||
"rpc_error" Error response from |rpcrequest()|
|
"rpc_error" Error response from |rpcrequest()|
|
||||||
"number_prompt" Number input prompt (|inputlist()|, |z=|, …)
|
|
||||||
"return_prompt" |press-enter| prompt after a multiple messages
|
"return_prompt" |press-enter| prompt after a multiple messages
|
||||||
"quickfix" Quickfix navigation message
|
"quickfix" Quickfix navigation message
|
||||||
"search_cmd" Entered search command
|
"search_cmd" Entered search command
|
||||||
|
@ -233,9 +233,8 @@ function vim.wait(time, callback, interval, fast_only) end
|
|||||||
--- {callback} receives event name plus additional parameters. See |ui-popupmenu|
|
--- {callback} receives event name plus additional parameters. See |ui-popupmenu|
|
||||||
--- and the sections below for event format for respective events.
|
--- and the sections below for event format for respective events.
|
||||||
---
|
---
|
||||||
--- Callbacks for `msg_show` events are executed in |api-fast| context unless
|
--- Callbacks for `msg_show` events are executed in |api-fast| context; showing
|
||||||
--- Nvim will wait for input, in which case messages should be shown
|
--- the message should be scheduled.
|
||||||
--- immediately.
|
|
||||||
---
|
---
|
||||||
--- Excessive errors inside the callback will result in forced detachment.
|
--- Excessive errors inside the callback will result in forced detachment.
|
||||||
---
|
---
|
||||||
|
@ -351,7 +351,7 @@ static int check_mtime(buf_T *buf, FileInfo *file_info)
|
|||||||
msg_silent = 0; // Must give this prompt.
|
msg_silent = 0; // Must give this prompt.
|
||||||
// Don't use emsg() here, don't want to flush the buffers.
|
// Don't use emsg() here, don't want to flush the buffers.
|
||||||
msg(_("WARNING: The file has been changed since reading it!!!"), HLF_E);
|
msg(_("WARNING: The file has been changed since reading it!!!"), HLF_E);
|
||||||
if (ask_yesno(_("Do you really want to write to it"), true) == 'n') {
|
if (ask_yesno(_("Do you really want to write to it")) == 'n') {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
msg_scroll = false; // Always overwrite the file message now.
|
msg_scroll = false; // Always overwrite the file message now.
|
||||||
|
@ -153,8 +153,7 @@ void do_debug(char *cmd)
|
|||||||
debug_break_level = -1;
|
debug_break_level = -1;
|
||||||
|
|
||||||
xfree(cmdline);
|
xfree(cmdline);
|
||||||
cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL,
|
cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL, CALLBACK_NONE, false, NULL);
|
||||||
CALLBACK_NONE);
|
|
||||||
|
|
||||||
debug_break_level = n;
|
debug_break_level = n;
|
||||||
if (typeahead_saved) {
|
if (typeahead_saved) {
|
||||||
|
@ -3554,10 +3554,10 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Ask for choice.
|
// Ask for choice.
|
||||||
bool mouse_used;
|
bool mouse_used = false;
|
||||||
int selected = prompt_for_number(&mouse_used);
|
int selected = prompt_for_input(NULL, 0, false, &mouse_used);
|
||||||
if (mouse_used) {
|
if (mouse_used) {
|
||||||
selected -= lines_left;
|
selected = tv_list_len(argvars[0].vval.v_list) - (cmdline_row - mouse_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
rettv->vval.v_number = selected;
|
rettv->vval.v_number = selected;
|
||||||
|
@ -3708,12 +3708,9 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
// Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
|
// Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
|
||||||
while (subflags.do_ask) {
|
while (subflags.do_ask) {
|
||||||
if (exmode_active) {
|
if (exmode_active) {
|
||||||
char *prompt;
|
|
||||||
char *resp;
|
|
||||||
colnr_T sc, ec;
|
|
||||||
|
|
||||||
print_line_no_prefix(lnum, subflags.do_number, subflags.do_list);
|
print_line_no_prefix(lnum, subflags.do_number, subflags.do_list);
|
||||||
|
|
||||||
|
colnr_T sc, ec;
|
||||||
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
|
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
|
||||||
curwin->w_cursor.col = MAX(regmatch.endpos[0].col - 1, 0);
|
curwin->w_cursor.col = MAX(regmatch.endpos[0].col - 1, 0);
|
||||||
|
|
||||||
@ -3725,10 +3722,11 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
ec += numw;
|
ec += numw;
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt = xmallocz((size_t)ec + 1);
|
char *prompt = xmallocz((size_t)ec + 1);
|
||||||
memset(prompt, ' ', (size_t)sc);
|
memset(prompt, ' ', (size_t)sc);
|
||||||
memset(prompt + sc, '^', (size_t)(ec - sc) + 1);
|
memset(prompt + sc, '^', (size_t)(ec - sc) + 1);
|
||||||
resp = getcmdline_prompt(-1, prompt, 0, EXPAND_NOTHING, NULL, CALLBACK_NONE);
|
char *resp = getcmdline_prompt(-1, prompt, 0, EXPAND_NOTHING, NULL,
|
||||||
|
CALLBACK_NONE, false, NULL);
|
||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
xfree(prompt);
|
xfree(prompt);
|
||||||
if (resp != NULL) {
|
if (resp != NULL) {
|
||||||
@ -3803,27 +3801,20 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
msg_scroll = 0; // truncate msg when
|
msg_scroll = 0; // truncate msg when
|
||||||
// needed
|
// needed
|
||||||
msg_no_more = true;
|
msg_no_more = true;
|
||||||
msg_ext_set_kind("confirm_sub");
|
|
||||||
// Same highlight as wait_return().
|
|
||||||
smsg(HLF_R, _("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
|
|
||||||
msg_no_more = false;
|
msg_no_more = false;
|
||||||
msg_scroll = i;
|
msg_scroll = i;
|
||||||
if (!ui_has(kUIMessages)) {
|
|
||||||
ui_cursor_goto(msg_row, msg_col);
|
|
||||||
}
|
|
||||||
RedrawingDisabled = temp;
|
|
||||||
|
|
||||||
no_mapping++; // don't map this key
|
snprintf(IObuff, IOSIZE, _("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
|
||||||
allow_keys++; // allow special keys
|
char *prompt = xstrdup(IObuff);
|
||||||
typed = plain_vgetc();
|
typed = prompt_for_input(prompt, HLF_R, true, NULL);
|
||||||
no_mapping--;
|
xfree(prompt);
|
||||||
allow_keys--;
|
|
||||||
|
|
||||||
// clear the question
|
// clear the question
|
||||||
msg_didout = false; // don't scroll up
|
msg_didout = false; // don't scroll up
|
||||||
msg_col = 0;
|
msg_col = 0;
|
||||||
gotocmdline(true);
|
gotocmdline(true);
|
||||||
p_lz = save_p_lz;
|
p_lz = save_p_lz;
|
||||||
|
RedrawingDisabled = temp;
|
||||||
|
|
||||||
// restore the line
|
// restore the line
|
||||||
if (orig_line != NULL) {
|
if (orig_line != NULL) {
|
||||||
@ -4809,7 +4800,7 @@ void ex_oldfiles(exarg_T *eap)
|
|||||||
// File selection prompt on ":browse oldfiles"
|
// File selection prompt on ":browse oldfiles"
|
||||||
if (cmdmod.cmod_flags & CMOD_BROWSE) {
|
if (cmdmod.cmod_flags & CMOD_BROWSE) {
|
||||||
quit_more = false;
|
quit_more = false;
|
||||||
nr = prompt_for_number(false);
|
nr = prompt_for_input(NULL, 0, false, NULL);
|
||||||
msg_starthere();
|
msg_starthere();
|
||||||
if (nr > 0 && nr <= tv_list_len(l)) {
|
if (nr > 0 && nr <= tv_list_len(l)) {
|
||||||
const char *const p = tv_list_find_str(l, nr - 1);
|
const char *const p = tv_list_find_str(l, nr - 1);
|
||||||
|
@ -2202,7 +2202,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
errormsg = _("E493: Backwards range given");
|
errormsg = _("E493: Backwards range given");
|
||||||
goto doend;
|
goto doend;
|
||||||
}
|
}
|
||||||
if (ask_yesno(_("Backwards range given, OK to swap"), false) != 'y') {
|
if (ask_yesno(_("Backwards range given, OK to swap")) != 'y') {
|
||||||
goto doend;
|
goto doend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ typedef struct {
|
|||||||
int indent;
|
int indent;
|
||||||
int c;
|
int c;
|
||||||
bool gotesc; // true when <ESC> just typed
|
bool gotesc; // true when <ESC> just typed
|
||||||
int do_abbr; // when true check for abbr.
|
bool do_abbr; // when true check for abbr.
|
||||||
char *lookfor; // string to match
|
char *lookfor; // string to match
|
||||||
int lookforlen;
|
int lookforlen;
|
||||||
int hiscnt; // current history line in use
|
int hiscnt; // current history line in use
|
||||||
@ -131,17 +131,17 @@ typedef struct {
|
|||||||
// to jump to next match
|
// to jump to next match
|
||||||
int histype; // history type to be used
|
int histype; // history type to be used
|
||||||
incsearch_state_T is_state;
|
incsearch_state_T is_state;
|
||||||
int did_wild_list; // did wild_list() recently
|
bool did_wild_list; // did wild_list() recently
|
||||||
int wim_index; // index in wim_flags[]
|
int wim_index; // index in wim_flags[]
|
||||||
int save_msg_scroll;
|
int save_msg_scroll;
|
||||||
int save_State; // remember State when called
|
int save_State; // remember State when called
|
||||||
int prev_cmdpos;
|
int prev_cmdpos;
|
||||||
char *save_p_icm;
|
char *save_p_icm;
|
||||||
int some_key_typed; // one of the keys was typed
|
bool some_key_typed; // one of the keys was typed
|
||||||
// mouse drag and release events are ignored, unless they are
|
// mouse drag and release events are ignored, unless they are
|
||||||
// preceded with a mouse down event
|
// preceded with a mouse down event
|
||||||
int ignore_drag_release;
|
bool ignore_drag_release;
|
||||||
int break_ctrl_c;
|
bool break_ctrl_c;
|
||||||
expand_T xpc;
|
expand_T xpc;
|
||||||
OptInt *b_im_ptr;
|
OptInt *b_im_ptr;
|
||||||
buf_T *b_im_ptr_buf; ///< buffer where b_im_ptr is valid
|
buf_T *b_im_ptr_buf; ///< buffer where b_im_ptr is valid
|
||||||
@ -1851,6 +1851,12 @@ static int command_line_browse_history(CommandLineState *s)
|
|||||||
|
|
||||||
static int command_line_handle_key(CommandLineState *s)
|
static int command_line_handle_key(CommandLineState *s)
|
||||||
{
|
{
|
||||||
|
// For one key prompt, avoid putting ESC and Ctrl_C onto cmdline.
|
||||||
|
// For all other keys, just put onto cmdline and exit.
|
||||||
|
if (ccline.one_key && s->c != ESC && s->c != Ctrl_C) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
// Big switch for a typed command line character.
|
// Big switch for a typed command line character.
|
||||||
switch (s->c) {
|
switch (s->c) {
|
||||||
case K_BS:
|
case K_BS:
|
||||||
@ -2001,6 +2007,12 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
}
|
}
|
||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
case K_LEFTMOUSE:
|
case K_LEFTMOUSE:
|
||||||
|
// Return on left click above number prompt
|
||||||
|
if (ccline.mouse_used && mouse_row < cmdline_row) {
|
||||||
|
*ccline.mouse_used = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FALLTHROUGH;
|
||||||
case K_RIGHTMOUSE:
|
case K_RIGHTMOUSE:
|
||||||
command_line_left_right_mouse(s);
|
command_line_left_right_mouse(s);
|
||||||
return command_line_not_changed(s);
|
return command_line_not_changed(s);
|
||||||
@ -2158,6 +2170,14 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
}
|
}
|
||||||
return command_line_not_changed(s);
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
// Number prompts use the mouse and return on 'q' press
|
||||||
|
if (ccline.mouse_used) {
|
||||||
|
*ccline.cmdbuff = NUL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FALLTHROUGH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Normal character with no special meaning. Just set mod_mask
|
// Normal character with no special meaning. Just set mod_mask
|
||||||
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
|
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
|
||||||
@ -2178,6 +2198,7 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
return command_line_changed(s);
|
return command_line_changed(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
// put the character in the command line
|
// put the character in the command line
|
||||||
if (IS_SPECIAL(s->c) || mod_mask != 0) {
|
if (IS_SPECIAL(s->c) || mod_mask != 0) {
|
||||||
put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true);
|
put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true);
|
||||||
@ -2186,7 +2207,7 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
IObuff[j] = NUL; // exclude composing chars
|
IObuff[j] = NUL; // exclude composing chars
|
||||||
put_on_cmdline(IObuff, j, true);
|
put_on_cmdline(IObuff, j, true);
|
||||||
}
|
}
|
||||||
return command_line_changed(s);
|
return ccline.one_key ? 0 : command_line_changed(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int command_line_not_changed(CommandLineState *s)
|
static int command_line_not_changed(CommandLineState *s)
|
||||||
@ -2724,8 +2745,11 @@ static void abandon_cmdline(void)
|
|||||||
if (msg_scrolled == 0) {
|
if (msg_scrolled == 0) {
|
||||||
compute_cmdrow();
|
compute_cmdrow();
|
||||||
}
|
}
|
||||||
msg("", 0);
|
// Avoid overwriting key prompt
|
||||||
redraw_cmdline = true;
|
if (!ccline.one_key) {
|
||||||
|
msg("", 0);
|
||||||
|
redraw_cmdline = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getcmdline() - accept a command line starting with firstc.
|
/// getcmdline() - accept a command line starting with firstc.
|
||||||
@ -2764,11 +2788,13 @@ char *getcmdline(int firstc, int count, int indent, bool do_concat FUNC_ATTR_UNU
|
|||||||
/// @param[in] xp_context Type of expansion.
|
/// @param[in] xp_context Type of expansion.
|
||||||
/// @param[in] xp_arg User-defined expansion argument.
|
/// @param[in] xp_arg User-defined expansion argument.
|
||||||
/// @param[in] highlight_callback Callback used for highlighting user input.
|
/// @param[in] highlight_callback Callback used for highlighting user input.
|
||||||
|
/// @param[in] one_key Return after one key press for button prompt.
|
||||||
|
/// @param[in] mouse_used Set to true when returning after right mouse click.
|
||||||
///
|
///
|
||||||
/// @return [allocated] Command line or NULL.
|
/// @return [allocated] Command line or NULL.
|
||||||
char *getcmdline_prompt(const int firstc, const char *const prompt, const int hl_id,
|
char *getcmdline_prompt(const int firstc, const char *const prompt, const int hl_id,
|
||||||
const int xp_context, const char *const xp_arg,
|
const int xp_context, const char *const xp_arg,
|
||||||
const Callback highlight_callback)
|
const Callback highlight_callback, bool one_key, bool *mouse_used)
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
|
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
|
||||||
{
|
{
|
||||||
const int msg_col_save = msg_col;
|
const int msg_col_save = msg_col;
|
||||||
@ -2789,11 +2815,14 @@ char *getcmdline_prompt(const int firstc, const char *const prompt, const int hl
|
|||||||
ccline.xp_arg = (char *)xp_arg;
|
ccline.xp_arg = (char *)xp_arg;
|
||||||
ccline.input_fn = (firstc == '@');
|
ccline.input_fn = (firstc == '@');
|
||||||
ccline.highlight_callback = highlight_callback;
|
ccline.highlight_callback = highlight_callback;
|
||||||
|
ccline.one_key = one_key;
|
||||||
|
ccline.mouse_used = mouse_used;
|
||||||
|
|
||||||
int msg_silent_saved = msg_silent;
|
int msg_silent_saved = msg_silent;
|
||||||
msg_silent = 0;
|
msg_silent = 0;
|
||||||
|
|
||||||
char *const ret = (char *)command_line_enter(firstc, 1, 0, false);
|
char *const ret = (char *)command_line_enter(firstc, 1, 0, false);
|
||||||
|
ccline.redraw_state = kCmdRedrawNone;
|
||||||
|
|
||||||
if (did_save_ccline) {
|
if (did_save_ccline) {
|
||||||
restore_cmdline(&save_ccline);
|
restore_cmdline(&save_ccline);
|
||||||
@ -4790,7 +4819,7 @@ void get_user_input(const typval_T *const argvars, typval_T *const rettv, const
|
|||||||
const int save_ex_normal_busy = ex_normal_busy;
|
const int save_ex_normal_busy = ex_normal_busy;
|
||||||
ex_normal_busy = 0;
|
ex_normal_busy = 0;
|
||||||
rettv->vval.v_string = getcmdline_prompt(secret ? NUL : '@', p, get_echo_hl_id(),
|
rettv->vval.v_string = getcmdline_prompt(secret ? NUL : '@', p, get_echo_hl_id(),
|
||||||
xp_type, xp_arg, input_callback);
|
xp_type, xp_arg, input_callback, false, NULL);
|
||||||
ex_normal_busy = save_ex_normal_busy;
|
ex_normal_busy = save_ex_normal_busy;
|
||||||
callback_free(&input_callback);
|
callback_free(&input_callback);
|
||||||
|
|
||||||
|
@ -65,4 +65,6 @@ struct cmdline_info {
|
|||||||
char special_char; ///< last putcmdline char (used for redraws)
|
char special_char; ///< last putcmdline char (used for redraws)
|
||||||
bool special_shift; ///< shift of last putcmdline char
|
bool special_shift; ///< shift of last putcmdline char
|
||||||
CmdRedraw redraw_state; ///< needed redraw for external cmdline
|
CmdRedraw redraw_state; ///< needed redraw for external cmdline
|
||||||
|
bool one_key; ///< return after one key press for button prompt
|
||||||
|
bool *mouse_used; ///< mouse clicked in prompt
|
||||||
};
|
};
|
||||||
|
148
src/nvim/input.c
148
src/nvim/input.c
@ -7,6 +7,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "nvim/ascii_defs.h"
|
#include "nvim/ascii_defs.h"
|
||||||
|
#include "nvim/ex_getln.h"
|
||||||
#include "nvim/getchar.h"
|
#include "nvim/getchar.h"
|
||||||
#include "nvim/gettext_defs.h"
|
#include "nvim/gettext_defs.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
@ -34,44 +35,36 @@
|
|||||||
/// No other characters are accepted, the message is repeated until a valid
|
/// No other characters are accepted, the message is repeated until a valid
|
||||||
/// reply is entered or <C-c> is hit.
|
/// reply is entered or <C-c> is hit.
|
||||||
///
|
///
|
||||||
/// @param[in] str Prompt: question to ask user. Is always followed by
|
/// @param[in] str Prompt: question to ask user. Is always followed by " (y/n)?".
|
||||||
/// " (y/n)?".
|
|
||||||
/// @param[in] direct Determines what function to use to get user input. If
|
|
||||||
/// true then input_get() will be used, otherwise vgetc().
|
|
||||||
/// I.e. when direct is true then characters are obtained
|
|
||||||
/// directly from the user without buffers involved.
|
|
||||||
///
|
///
|
||||||
/// @return 'y' or 'n'. Last is also what will be returned in case of interrupt.
|
/// @return 'y' or 'n'. Last is also what will be returned in case of interrupt.
|
||||||
int ask_yesno(const char *const str, const bool direct)
|
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.
|
State = MODE_CONFIRM; // Mouse behaves like with :confirm.
|
||||||
setmouse(); // Disable mouse in xterm.
|
setmouse(); // Disable mouse in xterm.
|
||||||
no_mapping++;
|
snprintf(IObuff, IOSIZE, _("%s (y/n)?"), str);
|
||||||
allow_keys++; // no mapping here, but recognize keys
|
char *prompt = xstrdup(IObuff);
|
||||||
|
|
||||||
int r = ' ';
|
int r = ' ';
|
||||||
while (r != 'y' && r != 'n') {
|
while (r != 'y' && r != 'n') {
|
||||||
// same highlighting as for wait_return()
|
// same highlighting as for wait_return()
|
||||||
smsg(HLF_R, "%s (y/n)?", str);
|
r = prompt_for_input(prompt, HLF_R, true, NULL);
|
||||||
if (direct) {
|
|
||||||
r = get_keystroke(NULL);
|
|
||||||
} else {
|
|
||||||
r = plain_vgetc();
|
|
||||||
}
|
|
||||||
if (r == Ctrl_C || r == ESC) {
|
if (r == Ctrl_C || r == ESC) {
|
||||||
r = 'n';
|
r = 'n';
|
||||||
|
if (!ui_has(kUIMessages)) {
|
||||||
|
msg_putchar(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msg_putchar(r); // Show what you typed.
|
|
||||||
ui_flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
need_wait_return = msg_scrolled;
|
||||||
no_wait_return--;
|
no_wait_return--;
|
||||||
State = save_State;
|
State = save_State;
|
||||||
setmouse();
|
setmouse();
|
||||||
no_mapping--;
|
xfree(prompt);
|
||||||
allow_keys--;
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -157,105 +150,42 @@ int get_keystroke(MultiQueue *events)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a number from the user.
|
/// Ask the user for input through a cmdline prompt.
|
||||||
/// When "mouse_used" is not NULL allow using the mouse.
|
|
||||||
///
|
///
|
||||||
/// @param colon allow colon to abort
|
/// @param one_key Return from cmdline after one key press.
|
||||||
int get_number(int colon, bool *mouse_used)
|
/// @param mouse_used When not NULL, allow using the mouse to press a number.
|
||||||
|
int prompt_for_input(char *prompt, int hl_id, bool one_key, bool *mouse_used)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int ret = one_key ? ESC : 0;
|
||||||
int typed = 0;
|
char *kmsg = keep_msg ? xstrdup(keep_msg) : NULL;
|
||||||
|
|
||||||
if (mouse_used != NULL) {
|
if (prompt == NULL) {
|
||||||
*mouse_used = false;
|
if (mouse_used != NULL) {
|
||||||
}
|
prompt = _("Type number and <Enter> or click with the mouse (q or empty cancels):");
|
||||||
|
} else {
|
||||||
// When not printing messages, the user won't know what to type, return a
|
prompt = _("Type number and <Enter> (q or empty cancels):");
|
||||||
// zero (as if CR was hit).
|
|
||||||
if (msg_silent != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
no_mapping++;
|
|
||||||
allow_keys++; // no mapping here, but recognize keys
|
|
||||||
while (true) {
|
|
||||||
ui_cursor_goto(msg_row, msg_col);
|
|
||||||
int c = safe_vgetc();
|
|
||||||
if (ascii_isdigit(c)) {
|
|
||||||
if (vim_append_digit_int(&n, c - '0') == FAIL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
msg_putchar(c);
|
|
||||||
typed++;
|
|
||||||
} else if (c == K_DEL || c == K_KDEL || c == K_BS || c == Ctrl_H) {
|
|
||||||
if (typed > 0) {
|
|
||||||
msg_puts("\b \b");
|
|
||||||
typed--;
|
|
||||||
}
|
|
||||||
n /= 10;
|
|
||||||
} else if (mouse_used != NULL && c == K_LEFTMOUSE) {
|
|
||||||
*mouse_used = true;
|
|
||||||
n = mouse_row + 1;
|
|
||||||
break;
|
|
||||||
} else if (n == 0 && c == ':' && colon) {
|
|
||||||
stuffcharReadbuff(':');
|
|
||||||
if (!exmode_active) {
|
|
||||||
cmdline_row = msg_row;
|
|
||||||
}
|
|
||||||
skip_redraw = true; // skip redraw once
|
|
||||||
do_redraw = false;
|
|
||||||
break;
|
|
||||||
} else if (c == Ctrl_C || c == ESC || c == 'q') {
|
|
||||||
n = 0;
|
|
||||||
break;
|
|
||||||
} else if (c == CAR || c == NL) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
no_mapping--;
|
|
||||||
|
cmdline_row = msg_row;
|
||||||
|
ui_flush();
|
||||||
|
|
||||||
|
no_mapping++; // don't map prompt input
|
||||||
|
allow_keys++; // allow special keys
|
||||||
|
char *resp = getcmdline_prompt(-1, prompt, hl_id, EXPAND_NOTHING, NULL,
|
||||||
|
CALLBACK_NONE, one_key, mouse_used);
|
||||||
allow_keys--;
|
allow_keys--;
|
||||||
return n;
|
no_mapping--;
|
||||||
}
|
|
||||||
|
|
||||||
/// Ask the user to enter a number.
|
if (resp) {
|
||||||
///
|
ret = one_key ? (int)(*resp) : atoi(resp);
|
||||||
/// When "mouse_used" is not NULL allow using the mouse and in that case return
|
xfree(resp);
|
||||||
/// the line number.
|
|
||||||
int prompt_for_number(bool *mouse_used)
|
|
||||||
{
|
|
||||||
msg_ext_set_kind("number_prompt");
|
|
||||||
// When using ":silent" assume that <CR> was entered.
|
|
||||||
if (mouse_used != NULL) {
|
|
||||||
msg_puts(_("Type number and <Enter> or click with the mouse "
|
|
||||||
"(q or empty cancels): "));
|
|
||||||
} else {
|
|
||||||
msg_puts(_("Type number and <Enter> (q or empty cancels): "));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the state such that text can be selected/copied/pasted and we still
|
if (kmsg != NULL) {
|
||||||
// get mouse events.
|
set_keep_msg(kmsg, keep_msg_hl_id);
|
||||||
int save_cmdline_row = cmdline_row;
|
xfree(kmsg);
|
||||||
cmdline_row = 0;
|
|
||||||
int save_State = State;
|
|
||||||
State = MODE_ASKMORE; // prevents a screen update when using a timer
|
|
||||||
// May show different mouse shape.
|
|
||||||
setmouse();
|
|
||||||
|
|
||||||
int i = get_number(true, mouse_used);
|
|
||||||
if (KeyTyped) {
|
|
||||||
// don't call wait_return() now
|
|
||||||
if (msg_row > 0) {
|
|
||||||
cmdline_row = msg_row - 1;
|
|
||||||
}
|
|
||||||
need_wait_return = false;
|
|
||||||
msg_didany = false;
|
|
||||||
msg_didout = false;
|
|
||||||
} else {
|
|
||||||
cmdline_row = save_cmdline_row;
|
|
||||||
}
|
}
|
||||||
State = save_State;
|
|
||||||
// May need to restore mouse shape.
|
|
||||||
setmouse();
|
|
||||||
|
|
||||||
return i;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -805,8 +805,7 @@ void ml_recover(bool checkext)
|
|||||||
// list the names of the swapfiles
|
// list the names of the swapfiles
|
||||||
recover_names(fname, true, NULL, 0, NULL);
|
recover_names(fname, true, NULL, 0, NULL);
|
||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
msg_puts(_("Enter number of swap file to use (0 to quit): "));
|
i = prompt_for_input(_("Enter number of swap file to use (0 to quit): "), 0, false, NULL);
|
||||||
i = get_number(false, NULL);
|
|
||||||
if (i < 1 || i > len) {
|
if (i < 1 || i > len) {
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ static int confirm_msg_used = false; // displaying confirm_msg
|
|||||||
# include "message.c.generated.h"
|
# include "message.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
static char *confirm_msg = NULL; // ":confirm" message
|
static char *confirm_msg = NULL; // ":confirm" message
|
||||||
static char *confirm_msg_tail; // tail of confirm_msg
|
static char *confirm_buttons; // ":confirm" buttons sent to cmdline as prompt
|
||||||
|
|
||||||
MessageHistoryEntry *first_msg_hist = NULL;
|
MessageHistoryEntry *first_msg_hist = NULL;
|
||||||
MessageHistoryEntry *last_msg_hist = NULL;
|
MessageHistoryEntry *last_msg_hist = NULL;
|
||||||
@ -2296,7 +2296,7 @@ static void msg_puts_display(const char *str, int maxlen, int hl_id, int recurse
|
|||||||
if (p_more && lines_left == 0 && State != MODE_HITRETURN
|
if (p_more && lines_left == 0 && State != MODE_HITRETURN
|
||||||
&& !msg_no_more && !exmode_active) {
|
&& !msg_no_more && !exmode_active) {
|
||||||
if (do_more_prompt(NUL)) {
|
if (do_more_prompt(NUL)) {
|
||||||
s = confirm_msg_tail;
|
s = confirm_buttons;
|
||||||
}
|
}
|
||||||
if (quit_more) {
|
if (quit_more) {
|
||||||
return;
|
return;
|
||||||
@ -2788,7 +2788,7 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen)
|
|||||||
/// When at hit-enter prompt "typed_char" is the already typed character,
|
/// When at hit-enter prompt "typed_char" is the already typed character,
|
||||||
/// otherwise it's NUL.
|
/// otherwise it's NUL.
|
||||||
///
|
///
|
||||||
/// @return true when jumping ahead to "confirm_msg_tail".
|
/// @return true when jumping ahead to "confirm_buttons".
|
||||||
static bool do_more_prompt(int typed_char)
|
static bool do_more_prompt(int typed_char)
|
||||||
{
|
{
|
||||||
static bool entered = false;
|
static bool entered = false;
|
||||||
@ -3511,10 +3511,10 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get a typed character directly from the user.
|
// Get a typed character directly from the user.
|
||||||
int c = get_keystroke(NULL);
|
int c = prompt_for_input(confirm_buttons, HLF_M, true, NULL);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case CAR: // User accepts default option
|
case CAR: // User accepts default option
|
||||||
case NL:
|
case NUL:
|
||||||
retval = dfltbutton;
|
retval = dfltbutton;
|
||||||
break;
|
break;
|
||||||
case Ctrl_C: // User aborts/cancels
|
case Ctrl_C: // User aborts/cancels
|
||||||
@ -3523,6 +3523,7 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
|
|||||||
break;
|
break;
|
||||||
default: // Could be a hotkey?
|
default: // Could be a hotkey?
|
||||||
if (c < 0) { // special keys are ignored here
|
if (c < 0) { // special keys are ignored here
|
||||||
|
msg_didout = msg_didany = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == ':' && ex_cmd) {
|
if (c == ':' && ex_cmd) {
|
||||||
@ -3545,6 +3546,7 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// No hotkey match, so keep waiting
|
// No hotkey match, so keep waiting
|
||||||
|
msg_didout = msg_didany = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3598,19 +3600,20 @@ static char *console_dialog_alloc(const char *message, const char *buttons, bool
|
|||||||
has_hotkey[0] = false;
|
has_hotkey[0] = false;
|
||||||
|
|
||||||
// Compute the size of memory to allocate.
|
// Compute the size of memory to allocate.
|
||||||
int len = 0;
|
int msg_len = 0;
|
||||||
|
int button_len = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
const char *r = buttons;
|
const char *r = buttons;
|
||||||
while (*r) {
|
while (*r) {
|
||||||
if (*r == DLG_BUTTON_SEP) {
|
if (*r == DLG_BUTTON_SEP) {
|
||||||
len += 3; // '\n' -> ', '; 'x' -> '(x)'
|
button_len += 3; // '\n' -> ', '; 'x' -> '(x)'
|
||||||
lenhotkey += HOTK_LEN; // each button needs a hotkey
|
lenhotkey += HOTK_LEN; // each button needs a hotkey
|
||||||
if (idx < HAS_HOTKEY_LEN - 1) {
|
if (idx < HAS_HOTKEY_LEN - 1) {
|
||||||
has_hotkey[++idx] = false;
|
has_hotkey[++idx] = false;
|
||||||
}
|
}
|
||||||
} else if (*r == DLG_HOTKEY_CHAR) {
|
} else if (*r == DLG_HOTKEY_CHAR) {
|
||||||
r++;
|
r++;
|
||||||
len++; // '&a' -> '[a]'
|
button_len++; // '&a' -> '[a]'
|
||||||
if (idx < HAS_HOTKEY_LEN - 1) {
|
if (idx < HAS_HOTKEY_LEN - 1) {
|
||||||
has_hotkey[idx] = true;
|
has_hotkey[idx] = true;
|
||||||
}
|
}
|
||||||
@ -3620,21 +3623,22 @@ static char *console_dialog_alloc(const char *message, const char *buttons, bool
|
|||||||
MB_PTR_ADV(r);
|
MB_PTR_ADV(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
len += (int)(strlen(message)
|
msg_len += (int)strlen(message) + 3; // for the NL's and NUL
|
||||||
+ 2 // for the NL's
|
button_len += (int)strlen(buttons) + 3; // for the ": " and NUL
|
||||||
+ strlen(buttons)
|
lenhotkey++; // for the NUL
|
||||||
+ 3); // for the ": " and NUL
|
|
||||||
lenhotkey++; // for the NUL
|
|
||||||
|
|
||||||
// If no hotkey is specified, first char is used.
|
// If no hotkey is specified, first char is used.
|
||||||
if (!has_hotkey[0]) {
|
if (!has_hotkey[0]) {
|
||||||
len += 2; // "x" -> "[x]"
|
button_len += 2; // "x" -> "[x]"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now allocate space for the strings
|
// Now allocate space for the strings
|
||||||
xfree(confirm_msg);
|
xfree(confirm_msg);
|
||||||
confirm_msg = xmalloc((size_t)len);
|
confirm_msg = xmalloc((size_t)msg_len);
|
||||||
*confirm_msg = NUL;
|
snprintf(confirm_msg, (size_t)msg_len, "\n%s\n", message);
|
||||||
|
|
||||||
|
xfree(confirm_buttons);
|
||||||
|
confirm_buttons = xmalloc((size_t)button_len);
|
||||||
|
|
||||||
return xmalloc((size_t)lenhotkey);
|
return xmalloc((size_t)lenhotkey);
|
||||||
}
|
}
|
||||||
@ -3652,42 +3656,34 @@ static char *msg_show_console_dialog(const char *message, const char *buttons, i
|
|||||||
bool has_hotkey[HAS_HOTKEY_LEN] = { false };
|
bool has_hotkey[HAS_HOTKEY_LEN] = { false };
|
||||||
char *hotk = console_dialog_alloc(message, buttons, has_hotkey);
|
char *hotk = console_dialog_alloc(message, buttons, has_hotkey);
|
||||||
|
|
||||||
copy_hotkeys_and_msg(message, buttons, dfltbutton, has_hotkey, hotk);
|
copy_confirm_hotkeys(buttons, dfltbutton, has_hotkey, hotk);
|
||||||
|
|
||||||
display_confirm_msg();
|
display_confirm_msg();
|
||||||
return hotk;
|
return hotk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies hotkeys & dialog message into the memory allocated for it
|
/// Copies hotkeys into the memory allocated for it
|
||||||
///
|
///
|
||||||
/// @param message Message which will be part of the confirm_msg
|
|
||||||
/// @param buttons String containing button names
|
/// @param buttons String containing button names
|
||||||
/// @param default_button_idx Number of default button
|
/// @param default_button_idx Number of default button
|
||||||
/// @param has_hotkey An element in this array is true if corresponding button
|
/// @param has_hotkey An element in this array is true if corresponding button
|
||||||
/// has a hotkey
|
/// has a hotkey
|
||||||
/// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied
|
/// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied
|
||||||
static void copy_hotkeys_and_msg(const char *message, const char *buttons, int default_button_idx,
|
static void copy_confirm_hotkeys(const char *buttons, int default_button_idx,
|
||||||
const bool has_hotkey[], char *hotkeys_ptr)
|
const bool has_hotkey[], char *hotkeys_ptr)
|
||||||
{
|
{
|
||||||
*confirm_msg = '\n';
|
|
||||||
STRCPY(confirm_msg + 1, message);
|
|
||||||
|
|
||||||
char *msgp = confirm_msg + 1 + strlen(message);
|
|
||||||
|
|
||||||
// Define first default hotkey. Keep the hotkey string NUL
|
// Define first default hotkey. Keep the hotkey string NUL
|
||||||
// terminated to avoid reading past the end.
|
// terminated to avoid reading past the end.
|
||||||
hotkeys_ptr[copy_char(buttons, hotkeys_ptr, true)] = NUL;
|
hotkeys_ptr[copy_char(buttons, hotkeys_ptr, true)] = NUL;
|
||||||
|
|
||||||
// Remember where the choices start, displaying starts here when
|
|
||||||
// "hotkeys_ptr" typed at the more prompt.
|
|
||||||
confirm_msg_tail = msgp;
|
|
||||||
*msgp++ = '\n';
|
|
||||||
|
|
||||||
bool first_hotkey = false; // Is the first char of button a hotkey
|
bool first_hotkey = false; // Is the first char of button a hotkey
|
||||||
if (!has_hotkey[0]) {
|
if (!has_hotkey[0]) {
|
||||||
first_hotkey = true; // If no hotkey is specified, first char is used
|
first_hotkey = true; // If no hotkey is specified, first char is used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remember where the choices start, sent as prompt to cmdline.
|
||||||
|
char *msgp = confirm_buttons;
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
const char *r = buttons;
|
const char *r = buttons;
|
||||||
while (*r) {
|
while (*r) {
|
||||||
|
@ -444,7 +444,7 @@ void spell_suggest(int count)
|
|||||||
char wcopy[MAXWLEN + 2];
|
char wcopy[MAXWLEN + 2];
|
||||||
suginfo_T sug;
|
suginfo_T sug;
|
||||||
suggest_T *stp;
|
suggest_T *stp;
|
||||||
bool mouse_used;
|
bool mouse_used = false;
|
||||||
int selected = count;
|
int selected = count;
|
||||||
int badlen = 0;
|
int badlen = 0;
|
||||||
int msg_scroll_save = msg_scroll;
|
int msg_scroll_save = msg_scroll;
|
||||||
@ -594,15 +594,11 @@ void spell_suggest(int count)
|
|||||||
cmdmsg_rl = false;
|
cmdmsg_rl = false;
|
||||||
msg_col = 0;
|
msg_col = 0;
|
||||||
// Ask for choice.
|
// Ask for choice.
|
||||||
selected = prompt_for_number(&mouse_used);
|
selected = prompt_for_input(NULL, 0, false, &mouse_used);
|
||||||
|
|
||||||
if (ui_has(kUIMessages)) {
|
|
||||||
ui_call_msg_clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouse_used) {
|
if (mouse_used) {
|
||||||
selected -= lines_left;
|
selected = sug.su_ga.ga_len + 1 - (cmdline_row - mouse_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
lines_left = Rows; // avoid more prompt
|
lines_left = Rows; // avoid more prompt
|
||||||
// don't delay for 'smd' in normal_cmd()
|
// don't delay for 'smd' in normal_cmd()
|
||||||
msg_scroll = msg_scroll_save;
|
msg_scroll = msg_scroll_save;
|
||||||
|
@ -669,7 +669,7 @@ void do_tag(char *tag, int type, int count, int forceit, bool verbose)
|
|||||||
|
|
||||||
if (ask_for_selection) {
|
if (ask_for_selection) {
|
||||||
// Ask to select a tag from the list.
|
// Ask to select a tag from the list.
|
||||||
int i = prompt_for_number(NULL);
|
int i = prompt_for_input(NULL, 0, false, NULL);
|
||||||
if (i <= 0 || i > num_matches || got_int) {
|
if (i <= 0 || i > num_matches || got_int) {
|
||||||
// no valid choice: don't change anything
|
// no valid choice: don't change anything
|
||||||
if (use_tagstack) {
|
if (use_tagstack) {
|
||||||
|
@ -718,10 +718,10 @@ void ui_call_event(char *name, bool fast, Array args)
|
|||||||
bool handled = false;
|
bool handled = false;
|
||||||
UIEventCallback *event_cb;
|
UIEventCallback *event_cb;
|
||||||
|
|
||||||
// Prompt messages should be shown immediately so must be safe
|
// Return prompt is still a non-fast event, other prompt messages are
|
||||||
|
// followed by a "cmdline_show" event.
|
||||||
if (strcmp(name, "msg_show") == 0) {
|
if (strcmp(name, "msg_show") == 0) {
|
||||||
char *kind = args.items[0].data.string.data;
|
fast = !strequal(args.items[0].data.string.data, "return_prompt");
|
||||||
fast = !kind || ((strncmp(kind, "confirm", 7) != 0 && strstr(kind, "_prompt") == NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map_foreach(&ui_event_cbs, ui_event_ns_id, event_cb, {
|
map_foreach(&ui_event_cbs, ui_event_ns_id, event_cb, {
|
||||||
|
@ -219,6 +219,7 @@ describe('swapfile detection', function()
|
|||||||
.. [[%.swp"]],
|
.. [[%.swp"]],
|
||||||
}
|
}
|
||||||
feed('e') -- Chose "Edit" at the swap dialog.
|
feed('e') -- Chose "Edit" at the swap dialog.
|
||||||
|
screen2:expect({ any = pesc('E5555: API call: Vim(edit):E325: ATTENTION') })
|
||||||
feed('<c-c>')
|
feed('<c-c>')
|
||||||
screen2:expect(expected_no_dialog)
|
screen2:expect(expected_no_dialog)
|
||||||
|
|
||||||
@ -531,10 +532,6 @@ describe('quitting swapfile dialog on startup stops TUI properly', function()
|
|||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
api.nvim_chan_send(chan, 'q')
|
api.nvim_chan_send(chan, 'q')
|
||||||
retry(nil, nil, function()
|
|
||||||
eq('Press ENTER or type command to continue', eval("getline('$')->trim(' ', 2)"))
|
|
||||||
end)
|
|
||||||
api.nvim_chan_send(chan, '\r')
|
|
||||||
retry(nil, nil, function()
|
retry(nil, nil, function()
|
||||||
eq(
|
eq(
|
||||||
{ '', '[Process exited 1]', '' },
|
{ '', '[Process exited 1]', '' },
|
||||||
|
@ -268,43 +268,6 @@ describe('vim.ui_attach', function()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
-- No fast context for prompt message kinds
|
|
||||||
feed(':%s/Function/Replacement/c<cr>')
|
|
||||||
screen:expect({
|
|
||||||
grid = [[
|
|
||||||
^E122: {10:Function} Foo already exists, add !|
|
|
||||||
to replace it |
|
|
||||||
replace with Replacement (y/n/a/q/l/^E/^|
|
|
||||||
Y)? |
|
|
||||||
{1:~ }|
|
|
||||||
]],
|
|
||||||
messages = {
|
|
||||||
{
|
|
||||||
content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 18 } },
|
|
||||||
kind = 'confirm_sub',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
feed('<esc>:call inputlist(["Select:", "One", "Two"])<cr>')
|
|
||||||
screen:expect({
|
|
||||||
grid = [[
|
|
||||||
E122: {10:Function} Foo already exists, add !|
|
|
||||||
to replace it |
|
|
||||||
Type number and <Enter> or click with th|
|
|
||||||
e mouse (q or empty cancels): |
|
|
||||||
{1:^~ }|
|
|
||||||
]],
|
|
||||||
messages = {
|
|
||||||
{
|
|
||||||
content = { { 'Select:\nOne\nTwo\n' } },
|
|
||||||
kind = 'list_cmd',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
content = { { 'Type number and <Enter> or click with the mouse (q or empty cancels): ' } },
|
|
||||||
kind = 'number_prompt',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -1456,13 +1456,12 @@ describe('cmdheight=0', function()
|
|||||||
}
|
}
|
||||||
|
|
||||||
feed(':%s/foo/bar/gc<CR>')
|
feed(':%s/foo/bar/gc<CR>')
|
||||||
screen:expect {
|
screen:expect([[
|
||||||
grid = [[
|
{3: }|
|
||||||
{2:foo} |
|
|*2
|
||||||
{1:~ }|*3
|
{6:replace with bar (y/n/a/q}|
|
||||||
{6:replace wi...q/l/^E/^Y)?}^ |
|
{6:/l/^E/^Y)?}^ |
|
||||||
]],
|
]])
|
||||||
}
|
|
||||||
|
|
||||||
feed('y')
|
feed('y')
|
||||||
screen:expect {
|
screen:expect {
|
||||||
|
@ -368,7 +368,7 @@ describe('input non-printable chars', function()
|
|||||||
"Xtest-overwrite" |
|
"Xtest-overwrite" |
|
||||||
{9:WARNING: The file has been changed since reading it!!!} |
|
{9:WARNING: The file has been changed since reading it!!!} |
|
||||||
{6:Do you really want to write to it (y/n)?}u |
|
{6:Do you really want to write to it (y/n)?}u |
|
||||||
{6:Do you really want to write to it (y/n)?} |
|
{6:Do you really want to write to it (y/n)?}{18:^E} |
|
||||||
{6:Do you really want to write to it (y/n)?}^ |
|
{6:Do you really want to write to it (y/n)?}^ |
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ describe('input non-printable chars', function()
|
|||||||
"Xtest-overwrite" |
|
"Xtest-overwrite" |
|
||||||
{9:WARNING: The file has been changed since reading it!!!} |
|
{9:WARNING: The file has been changed since reading it!!!} |
|
||||||
{6:Do you really want to write to it (y/n)?}u |
|
{6:Do you really want to write to it (y/n)?}u |
|
||||||
{6:Do you really want to write to it (y/n)?} |
|
{6:Do you really want to write to it (y/n)?}{18:^E} |
|
||||||
{6:Do you really want to write to it (y/n)?}n |
|
{6:Do you really want to write to it (y/n)?}n |
|
||||||
{6:Press ENTER or type command to continue}^ |
|
{6:Press ENTER or type command to continue}^ |
|
||||||
]])
|
]])
|
||||||
|
@ -42,18 +42,25 @@ describe('ui/ext_messages', function()
|
|||||||
it('msg_clear follows msg_show kind of confirm', function()
|
it('msg_clear follows msg_show kind of confirm', function()
|
||||||
feed('iline 1<esc>')
|
feed('iline 1<esc>')
|
||||||
feed(':call confirm("test")<cr>')
|
feed(':call confirm("test")<cr>')
|
||||||
screen:expect {
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
line ^1 |
|
line ^1 |
|
||||||
{1:~ }|*4
|
{1:~ }|*4
|
||||||
]],
|
]],
|
||||||
|
cmdline = {
|
||||||
|
{
|
||||||
|
content = { { '' } },
|
||||||
|
pos = 0,
|
||||||
|
prompt = '[O]k: ',
|
||||||
|
},
|
||||||
|
},
|
||||||
messages = {
|
messages = {
|
||||||
{
|
{
|
||||||
content = { { '\ntest\n[O]k: ', 6, 10 } },
|
content = { { '\ntest\n', 6, 10 } },
|
||||||
kind = 'confirm',
|
kind = 'confirm',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
feed('<cr>')
|
feed('<cr>')
|
||||||
screen:expect {
|
screen:expect {
|
||||||
@ -67,22 +74,29 @@ describe('ui/ext_messages', function()
|
|||||||
it('msg_show kinds', function()
|
it('msg_show kinds', function()
|
||||||
feed('iline 1\nline 2<esc>')
|
feed('iline 1\nline 2<esc>')
|
||||||
|
|
||||||
-- kind=confirm
|
-- confirm is now cmdline prompt
|
||||||
feed(':echo confirm("test")<cr>')
|
feed(':echo confirm("test")<cr>')
|
||||||
screen:expect {
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
line 1 |
|
line 1 |
|
||||||
line ^2 |
|
line ^2 |
|
||||||
{1:~ }|*3
|
{1:~ }|*3
|
||||||
]],
|
]],
|
||||||
|
cmdline = {
|
||||||
|
{
|
||||||
|
content = { { '' } },
|
||||||
|
pos = 0,
|
||||||
|
prompt = '[O]k: ',
|
||||||
|
},
|
||||||
|
},
|
||||||
messages = {
|
messages = {
|
||||||
{
|
{
|
||||||
content = { { '\ntest\n[O]k: ', 6, 10 } },
|
content = { { '\ntest\n', 6, 10 } },
|
||||||
kind = 'confirm',
|
kind = 'confirm',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
feed('<cr><cr>')
|
feed('<cr>')
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
line 1 |
|
line 1 |
|
||||||
@ -91,7 +105,7 @@ describe('ui/ext_messages', function()
|
|||||||
]],
|
]],
|
||||||
messages = {
|
messages = {
|
||||||
{
|
{
|
||||||
content = { { '\ntest\n[O]k: ', 6, 10 } },
|
content = { { '\ntest\n', 6, 10 } },
|
||||||
kind = 'confirm',
|
kind = 'confirm',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -104,23 +118,24 @@ describe('ui/ext_messages', function()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
feed('<cr><cr>')
|
feed('<cr>')
|
||||||
|
|
||||||
-- kind=confirm_sub
|
-- :substitute confirm is now cmdline prompt
|
||||||
feed(':%s/i/X/gc<cr>')
|
feed(':%s/i/X/gc<cr>')
|
||||||
screen:expect {
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
l{2:i}ne 1 |
|
l{2:^i}ne 1 |
|
||||||
l{10:i}ne ^2 |
|
l{10:i}ne 2 |
|
||||||
{1:~ }|*3
|
{1:~ }|*3
|
||||||
]],
|
]],
|
||||||
messages = {
|
cmdline = {
|
||||||
{
|
{
|
||||||
content = { { 'replace with X (y/n/a/q/l/^E/^Y)?', 6, 18 } },
|
content = { { '' } },
|
||||||
kind = 'confirm_sub',
|
pos = 0,
|
||||||
|
prompt = 'replace with X (y/n/a/q/l/^E/^Y)?',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
feed('nq')
|
feed('nq')
|
||||||
|
|
||||||
-- kind=wmsg (editing readonly file)
|
-- kind=wmsg (editing readonly file)
|
||||||
@ -1031,42 +1046,42 @@ stack traceback:
|
|||||||
feed('z=')
|
feed('z=')
|
||||||
screen:expect({
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
{100:helllo} |
|
{100:^helllo} |
|
||||||
{1:~ }|*3
|
{1:~ }|*4
|
||||||
{1:^~ }|
|
|
||||||
]],
|
]],
|
||||||
|
cmdline = {
|
||||||
|
{
|
||||||
|
content = { { '' } },
|
||||||
|
pos = 0,
|
||||||
|
prompt = 'Type number and <Enter> or click with the mouse (q or empty cancels):',
|
||||||
|
},
|
||||||
|
},
|
||||||
messages = {
|
messages = {
|
||||||
{
|
{
|
||||||
content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\n' } },
|
content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\n' } },
|
||||||
kind = 'list_cmd',
|
kind = 'list_cmd',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
content = { { 'Type number and <Enter> or click with the mouse (q or empty cancels): ' } },
|
|
||||||
kind = 'number_prompt',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
feed('1')
|
feed('1')
|
||||||
screen:expect({
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
{100:helllo} |
|
{100:^helllo} |
|
||||||
{1:~ }|*3
|
{1:~ }|*4
|
||||||
{1:^~ }|
|
|
||||||
]],
|
]],
|
||||||
|
cmdline = {
|
||||||
|
{
|
||||||
|
content = { { '1' } },
|
||||||
|
pos = 1,
|
||||||
|
prompt = 'Type number and <Enter> or click with the mouse (q or empty cancels):',
|
||||||
|
},
|
||||||
|
},
|
||||||
messages = {
|
messages = {
|
||||||
{
|
{
|
||||||
content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\n' } },
|
content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\n' } },
|
||||||
kind = 'list_cmd',
|
kind = 'list_cmd',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
content = { { 'Type number and <Enter> or click with the mouse (q or empty cancels): ' } },
|
|
||||||
kind = 'number_prompt',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
content = { { '1' } },
|
|
||||||
kind = '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ describe('NULL', function()
|
|||||||
null_expr_test(
|
null_expr_test(
|
||||||
'is accepted as an empty list by inputlist()',
|
'is accepted as an empty list by inputlist()',
|
||||||
'[feedkeys("\\n"), inputlist(L)]',
|
'[feedkeys("\\n"), inputlist(L)]',
|
||||||
'Type number and <Enter> or click with the mouse (q or empty cancels): ',
|
'',
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
)
|
)
|
||||||
null_expr_test(
|
null_expr_test(
|
||||||
|
@ -471,7 +471,9 @@ func Test_spellsuggest_option_number()
|
|||||||
\ .. "Change \"baord\" to:\n"
|
\ .. "Change \"baord\" to:\n"
|
||||||
\ .. " 1 \"board\"\n"
|
\ .. " 1 \"board\"\n"
|
||||||
\ .. " 2 \"bard\"\n"
|
\ .. " 2 \"bard\"\n"
|
||||||
\ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
|
"\ Nvim: Prompt message is sent to cmdline prompt.
|
||||||
|
"\ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
|
||||||
|
\ , a)
|
||||||
|
|
||||||
set spell spellsuggest=0
|
set spell spellsuggest=0
|
||||||
call assert_equal("\nSorry, no suggestions", execute('norm $z='))
|
call assert_equal("\nSorry, no suggestions", execute('norm $z='))
|
||||||
@ -509,7 +511,9 @@ func Test_spellsuggest_option_expr()
|
|||||||
\ .. " 1 \"BARD\"\n"
|
\ .. " 1 \"BARD\"\n"
|
||||||
\ .. " 2 \"BOARD\"\n"
|
\ .. " 2 \"BOARD\"\n"
|
||||||
\ .. " 3 \"BROAD\"\n"
|
\ .. " 3 \"BROAD\"\n"
|
||||||
\ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
|
"\ Nvim: Prompt message is sent to cmdline prompt.
|
||||||
|
"\ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
|
||||||
|
\ , a)
|
||||||
|
|
||||||
" With verbose, z= should show the score i.e. word length with
|
" With verbose, z= should show the score i.e. word length with
|
||||||
" our SpellSuggest() function.
|
" our SpellSuggest() function.
|
||||||
@ -521,7 +525,9 @@ func Test_spellsuggest_option_expr()
|
|||||||
\ .. " 1 \"BARD\" (4 - 0)\n"
|
\ .. " 1 \"BARD\" (4 - 0)\n"
|
||||||
\ .. " 2 \"BOARD\" (5 - 0)\n"
|
\ .. " 2 \"BOARD\" (5 - 0)\n"
|
||||||
\ .. " 3 \"BROAD\" (5 - 0)\n"
|
\ .. " 3 \"BROAD\" (5 - 0)\n"
|
||||||
\ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
|
"\ Nvim: Prompt message is sent to cmdline prompt.
|
||||||
|
"\ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
|
||||||
|
\ , a)
|
||||||
|
|
||||||
set spell& spellsuggest& verbose&
|
set spell& spellsuggest& verbose&
|
||||||
bwipe!
|
bwipe!
|
||||||
|
@ -1231,8 +1231,10 @@ func Test_tselect_listing()
|
|||||||
2 FS v first Xfoo
|
2 FS v first Xfoo
|
||||||
typeref:typename:char
|
typeref:typename:char
|
||||||
2
|
2
|
||||||
Type number and <Enter> (q or empty cancels):
|
|
||||||
[DATA]
|
[DATA]
|
||||||
|
" Type number and <Enter> (q or empty cancels):
|
||||||
|
" Nvim: Prompt message is sent to cmdline prompt.
|
||||||
|
|
||||||
call assert_equal(expected, l)
|
call assert_equal(expected, l)
|
||||||
|
|
||||||
call delete('Xtags')
|
call delete('Xtags')
|
||||||
|
Loading…
Reference in New Issue
Block a user