aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/input.c')
-rw-r--r--src/nvim/input.c147
1 files changed, 38 insertions, 109 deletions
diff --git a/src/nvim/input.c b/src/nvim/input.c
index 3d3240c59f..fb89d86a75 100644
--- a/src/nvim/input.c
+++ b/src/nvim/input.c
@@ -1,16 +1,15 @@
// input.c: high level functions for prompting the user or input
// like yes/no or number prompts.
-#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nvim/ascii_defs.h"
+#include "nvim/ex_getln.h"
#include "nvim/getchar.h"
#include "nvim/gettext_defs.h"
#include "nvim/globals.h"
-#include "nvim/highlight.h"
#include "nvim/highlight_defs.h"
#include "nvim/input.h"
#include "nvim/keycodes.h"
@@ -34,44 +33,36 @@
/// No other characters are accepted, the message is repeated until a valid
/// reply is entered or <C-c> is hit.
///
-/// @param[in] str Prompt: question to ask user. Is always followed by
-/// " (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.
+/// @param[in] str Prompt: question to ask user. Is always followed by " (y/n)?".
///
/// @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;
no_wait_return++;
State = MODE_CONFIRM; // Mouse behaves like with :confirm.
setmouse(); // Disable mouse in xterm.
- no_mapping++;
- allow_keys++; // no mapping here, but recognize keys
+ snprintf(IObuff, IOSIZE, _("%s (y/n)?"), str);
+ char *prompt = xstrdup(IObuff);
int r = ' ';
while (r != 'y' && r != 'n') {
// same highlighting as for wait_return()
- smsg(HLF_R, "%s (y/n)?", str);
- if (direct) {
- r = get_keystroke(NULL);
- } else {
- r = plain_vgetc();
- }
+ r = prompt_for_input(prompt, HLF_R, true, NULL);
if (r == Ctrl_C || r == ESC) {
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--;
State = save_State;
setmouse();
- no_mapping--;
- allow_keys--;
+ xfree(prompt);
return r;
}
@@ -157,104 +148,42 @@ int get_keystroke(MultiQueue *events)
return n;
}
-/// Get a number from the user.
-/// When "mouse_used" is not NULL allow using the mouse.
+/// Ask the user for input through a cmdline prompt.
///
-/// @param colon allow colon to abort
-int get_number(int colon, bool *mouse_used)
+/// @param one_key Return from cmdline after one key press.
+/// @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 typed = 0;
+ int ret = one_key ? ESC : 0;
+ char *kmsg = keep_msg ? xstrdup(keep_msg) : NULL;
- if (mouse_used != NULL) {
- *mouse_used = false;
+ if (prompt == NULL) {
+ if (mouse_used != NULL) {
+ prompt = _("Type number and <Enter> or click with the mouse (q or empty cancels): ");
+ } else {
+ prompt = _("Type number and <Enter> (q or empty cancels): ");
+ }
}
- // When not printing messages, the user won't know what to type, return a
- // zero (as if CR was hit).
- if (msg_silent != 0) {
- return 0;
- }
+ cmdline_row = msg_row;
+ ui_flush();
- 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--;
+ 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--;
- return n;
-}
+ no_mapping--;
-/// Ask the user to enter a number.
-///
-/// When "mouse_used" is not NULL allow using the mouse and in that case return
-/// the line number.
-int prompt_for_number(bool *mouse_used)
-{
- // 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): "));
+ if (resp) {
+ ret = one_key ? (int)(*resp) : atoi(resp);
+ xfree(resp);
}
- // Set the state such that text can be selected/copied/pasted and we still
- // get mouse events.
- int save_cmdline_row = cmdline_row;
- 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;
+ if (kmsg != NULL) {
+ set_keep_msg(kmsg, keep_msg_hl_id);
+ xfree(kmsg);
}
- State = save_State;
- // May need to restore mouse shape.
- setmouse();
- return i;
+ return ret;
}