aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_getln.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:23:01 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:23:01 +0000
commit142d9041391780ac15b89886a54015fdc5c73995 (patch)
tree0f6b5cac1a60810a03f52826c9e67c9e2780b033 /src/nvim/ex_getln.c
parentad86b5db74922285699ab2a1dbb2ff20e6268a33 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-142d9041391780ac15b89886a54015fdc5c73995.tar.gz
rneovim-142d9041391780ac15b89886a54015fdc5c73995.tar.bz2
rneovim-142d9041391780ac15b89886a54015fdc5c73995.zip
Merge remote-tracking branch 'upstream/master' into userreg
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r--src/nvim/ex_getln.c1361
1 files changed, 758 insertions, 603 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 031226c5a1..76c3680742 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -5,44 +5,45 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "klib/kvec.h"
#include "nvim/api/extmark.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
#include "nvim/arabic.h"
#include "nvim/ascii.h"
-#include "nvim/assert.h"
+#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
#include "nvim/cmdhist.h"
#include "nvim/cursor.h"
-#include "nvim/cursor_shape.h"
#include "nvim/digraph.h"
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
-#include "nvim/event/loop.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
-#include "nvim/func_attr.h"
+#include "nvim/extmark.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/gettext.h"
#include "nvim/globals.h"
#include "nvim/grid.h"
-#include "nvim/highlight.h"
#include "nvim/highlight_defs.h"
#include "nvim/highlight_group.h"
-#include "nvim/indent.h"
#include "nvim/keycodes.h"
-#include "nvim/log.h"
-#include "nvim/main.h"
+#include "nvim/macros.h"
#include "nvim/mapping.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
@@ -51,15 +52,18 @@
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
+#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
#include "nvim/optionstr.h"
#include "nvim/os/input.h"
-#include "nvim/os/time.h"
+#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/popupmenu.h"
+#include "nvim/pos.h"
#include "nvim/profile.h"
#include "nvim/regexp.h"
+#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
#include "nvim/strings.h"
@@ -94,7 +98,7 @@ typedef struct {
pos_T match_end;
bool did_incsearch;
bool incsearch_postponed;
- int magic_save;
+ optmagic_T magic_overruled_save;
} incsearch_state_T;
typedef struct command_line_state {
@@ -113,7 +117,6 @@ typedef struct command_line_state {
incsearch_state_T is_state;
int did_wild_list; // did wild_list() recently
int wim_index; // index in wim_flags[]
- int res;
int save_msg_scroll;
int save_State; // remember State when called
char *save_p_icm;
@@ -153,6 +156,14 @@ typedef struct cmdpreview_info {
garray_T save_view;
} CpInfo;
+/// Return value when handling keys in command-line mode.
+enum {
+ CMDLINE_NOT_CHANGED = 1,
+ CMDLINE_CHANGED = 2,
+ GOTO_NORMAL_MODE = 3,
+ PROCESS_NEXT_KEY = 4,
+};
+
/// The current cmdline_info. It is initialized in getcmdline() and after that
/// used by other functions. When invoking getcmdline() recursively it needs
/// to be saved with save_cmdline() and restored with restore_cmdline().
@@ -207,7 +218,7 @@ static void init_incsearch_state(incsearch_state_T *s)
s->match_start = curwin->w_cursor;
s->did_incsearch = false;
s->incsearch_postponed = false;
- s->magic_save = p_magic;
+ s->magic_overruled_save = magic_overruled;
clearpos(&s->match_end);
s->save_cursor = curwin->w_cursor; // may be restored later
s->search_start = curwin->w_cursor;
@@ -230,6 +241,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
pos_T save_cursor;
bool use_last_pat;
bool retval = false;
+ magic_T magic = 0;
*skiplen = 0;
*patlen = ccline.cmdlen;
@@ -262,7 +274,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
parse_command_modifiers(&ea, &dummy, &dummy_cmdmod, true);
cmd = skip_range(ea.cmd, NULL);
- if (vim_strchr("sgvl", *cmd) == NULL) {
+ if (vim_strchr("sgvl", (uint8_t)(*cmd)) == NULL) {
goto theend;
}
@@ -272,16 +284,16 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
goto theend;
}
- if (STRNCMP(cmd, "substitute", p - cmd) == 0
- || STRNCMP(cmd, "smagic", p - cmd) == 0
- || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0
- || STRNCMP(cmd, "vglobal", p - cmd) == 0) {
+ if (strncmp(cmd, "substitute", (size_t)(p - cmd)) == 0
+ || strncmp(cmd, "smagic", (size_t)(p - cmd)) == 0
+ || strncmp(cmd, "snomagic", (size_t)MAX(p - cmd, 3)) == 0
+ || strncmp(cmd, "vglobal", (size_t)(p - cmd)) == 0) {
if (*cmd == 's' && cmd[1] == 'm') {
- p_magic = true;
+ magic_overruled = OPTION_MAGIC_ON;
} else if (*cmd == 's' && cmd[1] == 'n') {
- p_magic = false;
+ magic_overruled = OPTION_MAGIC_OFF;
}
- } else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0) {
+ } else if (strncmp(cmd, "sort", (size_t)MAX(p - cmd, 3)) == 0) {
// skip over ! and flags
if (*p == '!') {
p = skipwhite(p + 1);
@@ -292,11 +304,11 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
if (*p == NUL) {
goto theend;
}
- } else if (STRNCMP(cmd, "vimgrep", MAX(p - cmd, 3)) == 0
- || STRNCMP(cmd, "vimgrepadd", MAX(p - cmd, 8)) == 0
- || STRNCMP(cmd, "lvimgrep", MAX(p - cmd, 2)) == 0
- || STRNCMP(cmd, "lvimgrepadd", MAX(p - cmd, 9)) == 0
- || STRNCMP(cmd, "global", p - cmd) == 0) {
+ } else if (strncmp(cmd, "vimgrep", (size_t)MAX(p - cmd, 3)) == 0
+ || strncmp(cmd, "vimgrepadd", (size_t)MAX(p - cmd, 8)) == 0
+ || strncmp(cmd, "lvimgrep", (size_t)MAX(p - cmd, 2)) == 0
+ || strncmp(cmd, "lvimgrepadd", (size_t)MAX(p - cmd, 9)) == 0
+ || strncmp(cmd, "global", (size_t)(p - cmd)) == 0) {
// skip over "!/".
if (*p == '!') {
p++;
@@ -312,9 +324,9 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
}
p = skipwhite(p);
- delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
+ delim = (delim_optional && vim_isIDc((uint8_t)(*p))) ? ' ' : *p++;
*search_delim = delim;
- end = skip_regexp(p, delim, p_magic, NULL);
+ end = skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic);
use_last_pat = end == p && *end == delim;
if (end == p && !use_last_pat) {
@@ -324,10 +336,8 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
// Don't do 'hlsearch' highlighting if the pattern matches everything.
if (!use_last_pat) {
char c = *end;
- int empty;
-
*end = NUL;
- empty = empty_pattern(p);
+ bool empty = empty_pattern_magic(p, strlen(p), magic);
*end = c;
if (empty) {
goto theend;
@@ -370,8 +380,8 @@ static void may_do_incsearch_highlighting(int firstc, long count, incsearch_stat
pos_T end_pos;
proftime_T tm;
int skiplen, patlen;
- char_u next_char;
- char_u use_last_pat;
+ char next_char;
+ bool use_last_pat;
int search_delim;
// Parsing range may already set the last search pattern.
@@ -408,7 +418,7 @@ static void may_do_incsearch_highlighting(int firstc, long count, incsearch_stat
int found; // do_search() result
// Use the previous pattern for ":s//".
- next_char = (char_u)ccline.cmdbuff[skiplen + patlen];
+ next_char = ccline.cmdbuff[skiplen + patlen];
use_last_pat = patlen == 0 && skiplen > 0
&& ccline.cmdbuff[skiplen - 1] == next_char;
@@ -435,9 +445,9 @@ static void may_do_incsearch_highlighting(int firstc, long count, incsearch_stat
.sa_tm = &tm,
};
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
- (char_u *)ccline.cmdbuff + skiplen, count,
+ ccline.cmdbuff + skiplen, count,
search_flags, &sia);
- ccline.cmdbuff[skiplen + patlen] = (char)next_char;
+ ccline.cmdbuff[skiplen + patlen] = next_char;
emsg_off--;
if (curwin->w_cursor.lnum < search_first_line
|| curwin->w_cursor.lnum > search_last_line) {
@@ -482,17 +492,17 @@ static void may_do_incsearch_highlighting(int firstc, long count, incsearch_stat
} else {
end_pos = curwin->w_cursor; // shutup gcc 4
}
- //
+
// Disable 'hlsearch' highlighting if the pattern matches
// everything. Avoids a flash when typing "foo\|".
if (!use_last_pat) {
- next_char = (char_u)ccline.cmdbuff[skiplen + patlen];
+ next_char = ccline.cmdbuff[skiplen + patlen];
ccline.cmdbuff[skiplen + patlen] = NUL;
- if (empty_pattern(ccline.cmdbuff) && !no_hlsearch) {
+ if (empty_pattern(ccline.cmdbuff + skiplen, search_delim) && !no_hlsearch) {
redraw_all_later(UPD_SOME_VALID);
set_no_hlsearch(true);
}
- ccline.cmdbuff[skiplen + patlen] = (char)next_char;
+ ccline.cmdbuff[skiplen + patlen] = next_char;
}
validate_cursor();
@@ -548,11 +558,11 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
// command line has no uppercase characters, convert
// the character to lowercase
if (p_ic && p_scs
- && !pat_has_uppercase((char_u *)ccline.cmdbuff + skiplen)) {
+ && !pat_has_uppercase(ccline.cmdbuff + skiplen)) {
*c = mb_tolower(*c);
}
if (*c == search_delim
- || vim_strchr((p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL) {
+ || vim_strchr((magic_isset() ? "\\~^$.*[" : "\\^$"), *c) != NULL) {
// put a backslash before special characters
stuffcharReadbuff(*c);
*c = '\\';
@@ -565,32 +575,64 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool call_update_screen)
{
- if (s->did_incsearch) {
- s->did_incsearch = false;
- if (gotesc) {
+ if (!s->did_incsearch) {
+ return;
+ }
+
+ s->did_incsearch = false;
+ if (gotesc) {
+ curwin->w_cursor = s->save_cursor;
+ } else {
+ if (!equalpos(s->save_cursor, s->search_start)) {
+ // put the '" mark at the original position
curwin->w_cursor = s->save_cursor;
- } else {
- if (!equalpos(s->save_cursor, s->search_start)) {
- // put the '" mark at the original position
- curwin->w_cursor = s->save_cursor;
- setpcmark();
- }
- curwin->w_cursor = s->search_start; // -V519
+ setpcmark();
}
- restore_viewstate(curwin, &s->old_viewstate);
- highlight_match = false;
+ curwin->w_cursor = s->search_start; // -V519
+ }
+ restore_viewstate(curwin, &s->old_viewstate);
+ highlight_match = false;
- // by default search all lines
- search_first_line = 0;
- search_last_line = MAXLNUM;
+ // by default search all lines
+ search_first_line = 0;
+ search_last_line = MAXLNUM;
- p_magic = s->magic_save;
+ magic_overruled = s->magic_overruled_save;
- validate_cursor(); // needed for TAB
- redraw_all_later(UPD_SOME_VALID);
- if (call_update_screen) {
- update_screen();
- }
+ validate_cursor(); // needed for TAB
+ redraw_all_later(UPD_SOME_VALID);
+ if (call_update_screen) {
+ update_screen();
+ }
+}
+
+/// Initialize the current command-line info.
+static void init_ccline(int firstc, int indent)
+{
+ ccline.overstrike = false; // always start in insert mode
+
+ assert(indent >= 0);
+
+ // set some variables for redrawcmd()
+ ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
+ ccline.cmdindent = (firstc > 0 ? indent : 0);
+
+ // alloc initial ccline.cmdbuff
+ alloc_cmdbuff(indent + 50);
+ ccline.cmdlen = ccline.cmdpos = 0;
+ ccline.cmdbuff[0] = NUL;
+
+ ccline.last_colors = (ColoredCmdline){ .cmdbuff = NULL,
+ .colors = KV_INITIAL_VALUE };
+ sb_text_start_cmdline();
+
+ // autoindent for :insert and :append
+ if (firstc <= 0) {
+ memset(ccline.cmdbuff, ' ', (size_t)indent);
+ ccline.cmdbuff[indent] = NUL;
+ ccline.cmdpos = indent;
+ ccline.cmdspos = indent;
+ ccline.cmdlen = indent;
}
}
@@ -598,8 +640,8 @@ static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool
///
/// @param count only used for incremental search
/// @param indent indent for inside conditionals
-/// @param init_ccline clear ccline first
-static uint8_t *command_line_enter(int firstc, long count, int indent, bool init_ccline)
+/// @param clear_ccline clear ccline first
+static uint8_t *command_line_enter(int firstc, long count, int indent, bool clear_ccline)
{
// can be invoked recursively, identify each level
static int cmdline_level = 0;
@@ -622,14 +664,14 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
bool did_save_ccline = false;
if (ccline.cmdbuff != NULL) {
- // Currently ccline can never be in use if init_ccline is false.
+ // Currently ccline can never be in use if clear_ccline is false.
// Some changes will be needed if this is no longer the case.
- assert(init_ccline);
+ assert(clear_ccline);
// Being called recursively. Since ccline is global, we need to save
// the current buffer and restore it when returning.
save_cmdline(&save_ccline);
did_save_ccline = true;
- } else if (init_ccline) {
+ } else if (clear_ccline) {
CLEAR_FIELD(ccline);
}
@@ -643,33 +685,9 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
cmd_hkmap = 0;
}
+ init_ccline(s->firstc, s->indent);
ccline.prompt_id = last_prompt_id++;
ccline.level = cmdline_level;
- ccline.overstrike = false; // always start in insert mode
-
- assert(indent >= 0);
-
- // set some variables for redrawcmd()
- ccline.cmdfirstc = (s->firstc == '@' ? 0 : s->firstc);
- ccline.cmdindent = (s->firstc > 0 ? s->indent : 0);
-
- // alloc initial ccline.cmdbuff
- alloc_cmdbuff(indent + 50);
- ccline.cmdlen = ccline.cmdpos = 0;
- ccline.cmdbuff[0] = NUL;
-
- ccline.last_colors = (ColoredCmdline){ .cmdbuff = NULL,
- .colors = KV_INITIAL_VALUE };
- sb_text_start_cmdline();
-
- // autoindent for :insert and :append
- if (s->firstc <= 0) {
- memset(ccline.cmdbuff, ' ', (size_t)s->indent);
- ccline.cmdbuff[s->indent] = NUL;
- ccline.cmdpos = s->indent;
- ccline.cmdspos = s->indent;
- ccline.cmdlen = s->indent;
- }
if (cmdline_level == 50) {
// Somehow got into a loop recursively calling getcmdline(), bail out.
@@ -707,7 +725,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
if (ccline.input_fn) {
s->xpc.xp_context = ccline.xp_context;
s->xpc.xp_pattern = ccline.cmdbuff;
- s->xpc.xp_arg = (char *)ccline.xp_arg;
+ s->xpc.xp_arg = ccline.xp_arg;
}
// Avoid scrolling when called by a recursive do_cmdline(), e.g. when
@@ -735,13 +753,14 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
TryState tstate;
Error err = ERROR_INIT;
bool tl_ret = true;
- save_v_event_T save_v_event;
- dict_T *dict = get_v_event(&save_v_event);
char firstcbuf[2];
firstcbuf[0] = (char)(firstc > 0 ? firstc : '-');
firstcbuf[1] = 0;
if (has_event(EVENT_CMDLINEENTER)) {
+ save_v_event_T save_v_event;
+ dict_T *dict = get_v_event(&save_v_event);
+
// set v:event to a dictionary with information about the commandline
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
@@ -754,7 +773,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
tl_ret = try_leave(&tstate, &err);
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
- msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ msg_scroll = true;
+ msg_puts_attr(err.msg, HL_ATTR(HLF_E)|MSG_HIST);
api_clear_error(&err);
redrawcmd();
}
@@ -803,6 +823,9 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
state_enter(&s->state);
if (has_event(EVENT_CMDLINELEAVE)) {
+ save_v_event_T save_v_event;
+ dict_T *dict = get_v_event(&save_v_event);
+
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
tv_dict_set_keys_readonly(dict);
@@ -859,7 +882,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
- semsg(e_autocmd_err, err.msg);
+ emsg(err.msg);
did_emsg = false;
api_clear_error(&err);
}
@@ -885,7 +908,7 @@ theend:
xfree(ccline.last_colors.cmdbuff);
kv_destroy(ccline.last_colors.colors);
- char_u *p = (char_u *)ccline.cmdbuff;
+ char *p = ccline.cmdbuff;
if (ui_has(kUICmdline)) {
ui_call_cmdline_hide(ccline.level);
@@ -900,7 +923,7 @@ theend:
ccline.cmdbuff = NULL;
}
- return p;
+ return (uint8_t *)p;
}
static int command_line_check(VimState *state)
@@ -919,6 +942,191 @@ static int command_line_check(VimState *state)
return 1;
}
+/// Handle CTRL-\ pressed in Command-line mode:
+/// - CTRL-\ CTRL-N or CTRL-\ CTRL-G goes to Normal mode.
+/// - CTRL-\ e prompts for an expression.
+static int command_line_handle_ctrl_bsl(CommandLineState *s)
+{
+ no_mapping++;
+ allow_keys++;
+ s->c = plain_vgetc();
+ no_mapping--;
+ allow_keys--;
+
+ // CTRL-\ e doesn't work when obtaining an expression, unless it
+ // is in a mapping.
+ if (s->c != Ctrl_N
+ && s->c != Ctrl_G
+ && (s->c != 'e'
+ || (ccline.cmdfirstc == '=' && KeyTyped)
+ || cmdline_star > 0)) {
+ vungetc(s->c);
+ return PROCESS_NEXT_KEY;
+ }
+
+ if (s->c == 'e') {
+ // Replace the command line with the result of an expression.
+ // This will call getcmdline() recursively in get_expr_register().
+ if (ccline.cmdpos == ccline.cmdlen) {
+ new_cmdpos = 99999; // keep it at the end
+ } else {
+ new_cmdpos = ccline.cmdpos;
+ }
+
+ s->c = get_expr_register();
+ if (s->c == '=') {
+ // Evaluate the expression. Set "textlock" to avoid nasty things
+ // like going to another buffer.
+ textlock++;
+ char *p = get_expr_line();
+ textlock--;
+
+ if (p != NULL) {
+ int len = (int)strlen(p);
+ realloc_cmdbuff(len + 1);
+ ccline.cmdlen = len;
+ STRCPY(ccline.cmdbuff, p);
+ xfree(p);
+
+ // Restore the cursor or use the position set with
+ // set_cmdline_pos().
+ if (new_cmdpos > ccline.cmdlen) {
+ ccline.cmdpos = ccline.cmdlen;
+ } else {
+ ccline.cmdpos = new_cmdpos;
+ }
+
+ KeyTyped = false; // Don't do p_wc completion.
+ redrawcmd();
+ return CMDLINE_CHANGED;
+ }
+ }
+ beep_flush();
+ got_int = false; // don't abandon the command line
+ did_emsg = false;
+ emsg_on_display = false;
+ redrawcmd();
+ return CMDLINE_NOT_CHANGED;
+ }
+
+ s->gotesc = true; // will free ccline.cmdbuff after putting it in history
+ return GOTO_NORMAL_MODE;
+}
+
+/// Completion for 'wildchar' or 'wildcharm' key.
+/// - hitting <ESC> twice means: abandon command line.
+/// - wildcard expansion is only done when the 'wildchar' key is really
+/// typed, not when it comes from a macro
+/// @return CMDLINE_CHANGED if command line is changed or CMDLINE_NOT_CHANGED.
+static int command_line_wildchar_complete(CommandLineState *s)
+{
+ int res;
+ int options = WILD_NO_BEEP;
+ if (wim_flags[s->wim_index] & WIM_BUFLASTUSED) {
+ options |= WILD_BUFLASTUSED;
+ }
+ if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice
+ // if 'wildmode' contains "list" may still need to list
+ if (s->xpc.xp_numfiles > 1
+ && !s->did_wild_list
+ && ((wim_flags[s->wim_index] & WIM_LIST)
+ || (p_wmnu && (wim_flags[s->wim_index] & WIM_FULL) != 0))) {
+ (void)showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
+ redrawcmd();
+ s->did_wild_list = true;
+ }
+
+ if (wim_flags[s->wim_index] & WIM_LONGEST) {
+ res = nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@');
+ } else if (wim_flags[s->wim_index] & WIM_FULL) {
+ res = nextwild(&s->xpc, WILD_NEXT, options, s->firstc != '@');
+ } else {
+ res = OK; // don't insert 'wildchar' now
+ }
+ } else { // typed p_wc first time
+ s->wim_index = 0;
+ int j = ccline.cmdpos;
+
+ // if 'wildmode' first contains "longest", get longest
+ // common part
+ if (wim_flags[0] & WIM_LONGEST) {
+ res = nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@');
+ } else {
+ res = nextwild(&s->xpc, WILD_EXPAND_KEEP, options, s->firstc != '@');
+ }
+
+ // if interrupted while completing, behave like it failed
+ if (got_int) {
+ (void)vpeekc(); // remove <C-C> from input stream
+ got_int = false; // don't abandon the command line
+ (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
+ s->xpc.xp_context = EXPAND_NOTHING;
+ return CMDLINE_CHANGED;
+ }
+
+ // when more than one match, and 'wildmode' first contains
+ // "list", or no change and 'wildmode' contains "longest,list",
+ // list all matches
+ if (res == OK && s->xpc.xp_numfiles > 1) {
+ // a "longest" that didn't do anything is skipped (but not
+ // "list:longest")
+ if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j) {
+ s->wim_index = 1;
+ }
+ if ((wim_flags[s->wim_index] & WIM_LIST)
+ || (p_wmnu && (wim_flags[s->wim_index] & WIM_FULL) != 0)) {
+ if (!(wim_flags[0] & WIM_LONGEST)) {
+ int p_wmnu_save = p_wmnu;
+ p_wmnu = 0;
+ // remove match
+ nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@');
+ p_wmnu = p_wmnu_save;
+ }
+
+ (void)showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
+ redrawcmd();
+ s->did_wild_list = true;
+
+ if (wim_flags[s->wim_index] & WIM_LONGEST) {
+ nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@');
+ } else if (wim_flags[s->wim_index] & WIM_FULL) {
+ nextwild(&s->xpc, WILD_NEXT, options, s->firstc != '@');
+ }
+ } else {
+ vim_beep(BO_WILD);
+ }
+ } else if (s->xpc.xp_numfiles == -1) {
+ s->xpc.xp_context = EXPAND_NOTHING;
+ }
+ }
+
+ if (s->wim_index < 3) {
+ s->wim_index++;
+ }
+
+ if (s->c == ESC) {
+ s->gotesc = true;
+ }
+
+ return (res == OK) ? CMDLINE_CHANGED : CMDLINE_NOT_CHANGED;
+}
+
+static void command_line_end_wildmenu(CommandLineState *s)
+{
+ if (cmdline_pum_active()) {
+ cmdline_pum_remove();
+ }
+ if (s->xpc.xp_numfiles != -1) {
+ (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
+ }
+ s->did_wild_list = false;
+ if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) {
+ s->xpc.xp_context = EXPAND_NOTHING;
+ }
+ s->wim_index = 0;
+ wildmenu_cleanup(&ccline);
+}
+
static int command_line_execute(VimState *state, int key)
{
if (key == K_IGNORE || key == K_NOP) {
@@ -937,6 +1145,19 @@ static int command_line_execute(VimState *state, int key)
map_execute_lua();
}
+ // nvim_select_popupmenu_item() can be called from the handling of
+ // K_EVENT, K_COMMAND, or K_LUA.
+ if (pum_want.active) {
+ if (cmdline_pum_active()) {
+ nextwild(&s->xpc, WILD_PUM_WANT, 0, s->firstc != '@');
+ if (pum_want.finish) {
+ nextwild(&s->xpc, WILD_APPLY, WILD_NO_BEEP, s->firstc != '@');
+ command_line_end_wildmenu(s);
+ }
+ }
+ pum_want.active = false;
+ }
+
if (!cmdline_was_last_drawn) {
redrawcmdline();
}
@@ -1005,100 +1226,49 @@ static int command_line_execute(VimState *state, int key)
}
if (cmdline_pum_active() || s->did_wild_list) {
+ // Ctrl-Y: Accept the current selection and close the popup menu.
+ // Ctrl-E: cancel the cmdline popup menu and return the original text.
if (s->c == Ctrl_E || s->c == Ctrl_Y) {
const int wild_type = (s->c == Ctrl_E) ? WILD_CANCEL : WILD_APPLY;
- s->res = nextwild(&s->xpc, wild_type, WILD_NO_BEEP, s->firstc != '@');
+ (void)nextwild(&s->xpc, wild_type, WILD_NO_BEEP, s->firstc != '@');
s->c = Ctrl_E;
}
}
+ // The wildmenu is cleared if the pressed key is not used for
+ // navigating the wild menu (i.e. the key is not 'wildchar' or
+ // 'wildcharm' or Ctrl-N or Ctrl-P or Ctrl-A or Ctrl-L).
+ // If the popup menu is displayed, then PageDown and PageUp keys are
+ // also used to navigate the menu.
+ bool end_wildmenu = (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_Z
+ && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
+ && s->c != Ctrl_L);
+ end_wildmenu = end_wildmenu && (!cmdline_pum_active()
+ || (s->c != K_PAGEDOWN && s->c != K_PAGEUP
+ && s->c != K_KPAGEDOWN && s->c != K_KPAGEUP));
+
// free expanded names when finished walking through matches
- if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_Z
- && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
- && s->c != Ctrl_L) {
- if (cmdline_pum_active()) {
- cmdline_pum_remove();
- }
- if (s->xpc.xp_numfiles != -1) {
- (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
- }
- s->did_wild_list = false;
- if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) {
- s->xpc.xp_context = EXPAND_NOTHING;
- }
- s->wim_index = 0;
- wildmenu_cleanup(&ccline);
+ if (end_wildmenu) {
+ command_line_end_wildmenu(s);
}
if (p_wmnu) {
s->c = wildmenu_process_key(&ccline, s->c, &s->xpc);
}
- // CTRL-\ CTRL-N goes to Normal mode, CTRL-\ e prompts for an expression.
+ // CTRL-\ CTRL-N or CTRL-\ CTRL-G goes to Normal mode,
+ // CTRL-\ e prompts for an expression.
if (s->c == Ctrl_BSL) {
- no_mapping++;
- allow_keys++;
- s->c = plain_vgetc();
- no_mapping--;
- allow_keys--;
- // CTRL-\ e doesn't work when obtaining an expression, unless it
- // is in a mapping.
- if (s->c != Ctrl_N
- && s->c != Ctrl_G
- && (s->c != 'e'
- || (ccline.cmdfirstc == '=' && KeyTyped)
- || cmdline_star > 0)) {
- vungetc(s->c);
- s->c = Ctrl_BSL;
- } else if (s->c == 'e') {
- char_u *p = NULL;
- int len;
-
- // Replace the command line with the result of an expression.
- // Need to save and restore the current command line, to be
- // able to enter a new one...
- if (ccline.cmdpos == ccline.cmdlen) {
- new_cmdpos = 99999; // keep it at the end
- } else {
- new_cmdpos = ccline.cmdpos;
- }
-
- s->c = get_expr_register();
- if (s->c == '=') {
- textlock++;
- p = (char_u *)get_expr_line();
- textlock--;
-
- if (p != NULL) {
- len = (int)STRLEN(p);
- realloc_cmdbuff(len + 1);
- ccline.cmdlen = len;
- STRCPY(ccline.cmdbuff, p);
- xfree(p);
-
- // Restore the cursor or use the position set with
- // set_cmdline_pos().
- if (new_cmdpos > ccline.cmdlen) {
- ccline.cmdpos = ccline.cmdlen;
- } else {
- ccline.cmdpos = new_cmdpos;
- }
-
- KeyTyped = false; // Don't do p_wc completion.
- redrawcmd();
- return command_line_changed(s);
- }
- }
- beep_flush();
- got_int = false; // don't abandon the command line
- did_emsg = false;
- emsg_on_display = false;
- redrawcmd();
+ switch (command_line_handle_ctrl_bsl(s)) {
+ case CMDLINE_CHANGED:
+ return command_line_changed(s);
+ case CMDLINE_NOT_CHANGED:
return command_line_not_changed(s);
- } else {
- s->gotesc = true; // will free ccline.cmdbuff after putting it
- // in history
- return 0; // back to Normal mode
+ case GOTO_NORMAL_MODE:
+ return 0; // back to cmd mode
+ default:
+ s->c = Ctrl_BSL; // backslash key not processed by
+ // command_line_handle_ctrl_bsl()
}
}
@@ -1146,107 +1316,8 @@ static int command_line_execute(VimState *state, int key)
}
// Completion for 'wildchar' or 'wildcharm' key.
- // - hitting <ESC> twice means: abandon command line.
- // - wildcard expansion is only done when the 'wildchar' key is really
- // typed, not when it comes from a macro
- if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm
- || s->c == Ctrl_Z) {
- int options = WILD_NO_BEEP;
- if (wim_flags[s->wim_index] & WIM_BUFLASTUSED) {
- options |= WILD_BUFLASTUSED;
- }
- if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice
- // if 'wildmode' contains "list" may still need to list
- if (s->xpc.xp_numfiles > 1
- && !s->did_wild_list
- && ((wim_flags[s->wim_index] & WIM_LIST)
- || (p_wmnu && (wim_flags[s->wim_index] & WIM_FULL) != 0))) {
- (void)showmatches(&s->xpc, p_wmnu
- && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
- redrawcmd();
- s->did_wild_list = true;
- }
-
- if (wim_flags[s->wim_index] & WIM_LONGEST) {
- s->res = nextwild(&s->xpc, WILD_LONGEST, options,
- s->firstc != '@');
- } else if (wim_flags[s->wim_index] & WIM_FULL) {
- s->res = nextwild(&s->xpc, WILD_NEXT, options,
- s->firstc != '@');
- } else {
- s->res = OK; // don't insert 'wildchar' now
- }
- } else { // typed p_wc first time
- s->wim_index = 0;
- int j = ccline.cmdpos;
-
- // if 'wildmode' first contains "longest", get longest
- // common part
- if (wim_flags[0] & WIM_LONGEST) {
- s->res = nextwild(&s->xpc, WILD_LONGEST, options,
- s->firstc != '@');
- } else {
- s->res = nextwild(&s->xpc, WILD_EXPAND_KEEP, options,
- s->firstc != '@');
- }
-
- // if interrupted while completing, behave like it failed
- if (got_int) {
- (void)vpeekc(); // remove <C-C> from input stream
- got_int = false; // don't abandon the command line
- (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
- s->xpc.xp_context = EXPAND_NOTHING;
- return command_line_changed(s);
- }
-
- // when more than one match, and 'wildmode' first contains
- // "list", or no change and 'wildmode' contains "longest,list",
- // list all matches
- if (s->res == OK && s->xpc.xp_numfiles > 1) {
- // a "longest" that didn't do anything is skipped (but not
- // "list:longest")
- if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j) {
- s->wim_index = 1;
- }
- if ((wim_flags[s->wim_index] & WIM_LIST)
- || (p_wmnu && (wim_flags[s->wim_index] & WIM_FULL) != 0)) {
- if (!(wim_flags[0] & WIM_LONGEST)) {
- int p_wmnu_save = p_wmnu;
- p_wmnu = 0;
- // remove match
- nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@');
- p_wmnu = p_wmnu_save;
- }
-
- (void)showmatches(&s->xpc, p_wmnu
- && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
- redrawcmd();
- s->did_wild_list = true;
-
- if (wim_flags[s->wim_index] & WIM_LONGEST) {
- nextwild(&s->xpc, WILD_LONGEST, options,
- s->firstc != '@');
- } else if (wim_flags[s->wim_index] & WIM_FULL) {
- nextwild(&s->xpc, WILD_NEXT, options,
- s->firstc != '@');
- }
- } else {
- vim_beep(BO_WILD);
- }
- } else if (s->xpc.xp_numfiles == -1) {
- s->xpc.xp_context = EXPAND_NOTHING;
- }
- }
-
- if (s->wim_index < 3) {
- s->wim_index++;
- }
-
- if (s->c == ESC) {
- s->gotesc = true;
- }
-
- if (s->res == OK) {
+ if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm || s->c == Ctrl_Z) {
+ if (command_line_wildchar_complete(s) == CMDLINE_CHANGED) {
return command_line_changed(s);
}
}
@@ -1303,9 +1374,9 @@ static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_
ui_flush();
pos_T t;
- char_u *pat;
+ char *pat;
int search_flags = SEARCH_NOOF;
- char_u save;
+ char save;
if (search_delim == ccline.cmdbuff[skiplen]) {
pat = last_search_pattern();
@@ -1314,9 +1385,9 @@ static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_
return FAIL;
}
skiplen = 0;
- patlen = (int)STRLEN(pat);
+ patlen = (int)strlen(pat);
} else {
- pat = (char_u *)ccline.cmdbuff + skiplen;
+ pat = ccline.cmdbuff + skiplen;
}
if (next_match) {
@@ -1389,6 +1460,199 @@ static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_
return FAIL;
}
+/// Handle backspace, delete and CTRL-W keys in the command-line mode.
+static int command_line_erase_chars(CommandLineState *s)
+{
+ if (s->c == K_KDEL) {
+ s->c = K_DEL;
+ }
+
+ // Delete current character is the same as backspace on next
+ // character, except at end of line
+ if (s->c == K_DEL && ccline.cmdpos != ccline.cmdlen) {
+ ccline.cmdpos++;
+ }
+
+ if (s->c == K_DEL) {
+ ccline.cmdpos += mb_off_next(ccline.cmdbuff,
+ ccline.cmdbuff + ccline.cmdpos);
+ }
+
+ if (ccline.cmdpos > 0) {
+ char *p;
+
+ int j = ccline.cmdpos;
+ p = mb_prevptr(ccline.cmdbuff, ccline.cmdbuff + j);
+
+ if (s->c == Ctrl_W) {
+ while (p > ccline.cmdbuff && ascii_isspace(*p)) {
+ p = mb_prevptr(ccline.cmdbuff, p);
+ }
+
+ int i = mb_get_class(p);
+ while (p > ccline.cmdbuff && mb_get_class(p) == i) {
+ p = mb_prevptr(ccline.cmdbuff, p);
+ }
+
+ if (mb_get_class(p) != i) {
+ p += utfc_ptr2len(p);
+ }
+ }
+
+ ccline.cmdpos = (int)(p - ccline.cmdbuff);
+ ccline.cmdlen -= j - ccline.cmdpos;
+ int i = ccline.cmdpos;
+
+ while (i < ccline.cmdlen) {
+ ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
+ }
+
+ // Truncate at the end, required for multi-byte chars.
+ ccline.cmdbuff[ccline.cmdlen] = NUL;
+ if (ccline.cmdlen == 0) {
+ s->is_state.search_start = s->is_state.save_cursor;
+ // save view settings, so that the screen won't be restored at the
+ // wrong position
+ s->is_state.old_viewstate = s->is_state.init_viewstate;
+ }
+ redrawcmd();
+ } else if (ccline.cmdlen == 0 && s->c != Ctrl_W
+ && ccline.cmdprompt == NULL && s->indent == 0) {
+ // In ex and debug mode it doesn't make sense to return.
+ if (exmode_active || ccline.cmdfirstc == '>') {
+ return CMDLINE_NOT_CHANGED;
+ }
+
+ XFREE_CLEAR(ccline.cmdbuff); // no commandline to return
+ if (!cmd_silent && !ui_has(kUICmdline)) {
+ if (cmdmsg_rl) {
+ msg_col = Columns;
+ } else {
+ msg_col = 0;
+ }
+ msg_putchar(' '); // delete ':'
+ }
+ s->is_state.search_start = s->is_state.save_cursor;
+ redraw_cmdline = true;
+ return GOTO_NORMAL_MODE;
+ }
+ return CMDLINE_CHANGED;
+}
+
+/// Handle the CTRL-^ key in the command-line mode and toggle the use of the
+/// language :lmap mappings and/or Input Method.
+static void command_line_toggle_langmap(CommandLineState *s)
+{
+ if (map_to_exists_mode("", MODE_LANGMAP, false)) {
+ // ":lmap" mappings exists, toggle use of mappings.
+ State ^= MODE_LANGMAP;
+ if (s->b_im_ptr != NULL) {
+ if (State & MODE_LANGMAP) {
+ *s->b_im_ptr = B_IMODE_LMAP;
+ } else {
+ *s->b_im_ptr = B_IMODE_NONE;
+ }
+ }
+ }
+
+ if (s->b_im_ptr != NULL) {
+ if (s->b_im_ptr == &curbuf->b_p_iminsert) {
+ set_iminsert_global(curbuf);
+ } else {
+ set_imsearch_global(curbuf);
+ }
+ }
+ ui_cursor_shape(); // may show different cursor shape
+ // Show/unshow value of 'keymap' in status lines later.
+ status_redraw_curbuf();
+}
+
+/// Handle the CTRL-R key in the command-line mode and insert the contents of a
+/// numbered or named register.
+static int command_line_insert_reg(CommandLineState *s)
+{
+ const int save_new_cmdpos = new_cmdpos;
+
+ putcmdline('"', true);
+ no_mapping++;
+ allow_keys++;
+ int i = s->c = plain_vgetc(); // CTRL-R <char>
+ if (i == Ctrl_O) {
+ i = Ctrl_R; // CTRL-R CTRL-O == CTRL-R CTRL-R
+ }
+
+ if (i == Ctrl_R) {
+ s->c = plain_vgetc(); // CTRL-R CTRL-R <char>
+ }
+ no_mapping--;
+ allow_keys--;
+ // Insert the result of an expression.
+ new_cmdpos = -1;
+ if (s->c == '=') {
+ if (ccline.cmdfirstc == '=' // can't do this recursively
+ || cmdline_star > 0) { // or when typing a password
+ beep_flush();
+ s->c = ESC;
+ } else {
+ s->c = get_expr_register();
+ }
+ }
+
+ if (s->c != ESC) { // use ESC to cancel inserting register
+ cmdline_paste(s->c, i == Ctrl_R, false);
+
+ // When there was a serious error abort getting the
+ // command line.
+ if (aborting()) {
+ s->gotesc = true; // will free ccline.cmdbuff after
+ // putting it in history
+ return GOTO_NORMAL_MODE;
+ }
+ KeyTyped = false; // Don't do p_wc completion.
+ if (new_cmdpos >= 0) {
+ // set_cmdline_pos() was used
+ if (new_cmdpos > ccline.cmdlen) {
+ ccline.cmdpos = ccline.cmdlen;
+ } else {
+ ccline.cmdpos = new_cmdpos;
+ }
+ }
+ }
+ new_cmdpos = save_new_cmdpos;
+
+ // remove the double quote
+ ccline.special_char = NUL;
+ redrawcmd();
+
+ // The text has been stuffed, the command line didn't change yet.
+ return CMDLINE_NOT_CHANGED;
+}
+
+/// Handle the Left and Right mouse clicks in the command-line mode.
+static void command_line_left_right_mouse(CommandLineState *s)
+{
+ if (s->c == K_LEFTRELEASE || s->c == K_RIGHTRELEASE) {
+ s->ignore_drag_release = true;
+ } else {
+ s->ignore_drag_release = false;
+ }
+
+ ccline.cmdspos = cmd_startcol();
+ for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
+ ccline.cmdpos++) {
+ int cells = cmdline_charsize(ccline.cmdpos);
+ if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
+ && mouse_col < ccline.cmdspos % Columns + cells) {
+ break;
+ }
+
+ // Count ">" for double-wide char that doesn't fit.
+ correct_screencol(ccline.cmdpos, cells, &ccline.cmdspos);
+ ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos) - 1;
+ ccline.cmdspos += cells;
+ }
+}
+
static void command_line_next_histidx(CommandLineState *s, bool next_match)
{
int j = (int)strlen(s->lookfor);
@@ -1434,96 +1698,118 @@ static void command_line_next_histidx(CommandLineState *s, bool next_match)
if ((s->c != K_UP && s->c != K_DOWN)
|| s->hiscnt == s->save_hiscnt
- || STRNCMP(get_histentry(s->histype)[s->hiscnt].hisstr,
+ || strncmp(get_histentry(s->histype)[s->hiscnt].hisstr,
s->lookfor, (size_t)j) == 0) {
break;
}
}
}
-static int command_line_handle_key(CommandLineState *s)
+/// Handle the Up, Down, Page Up, Page down, CTRL-N and CTRL-P key in the
+/// command-line mode.
+static int command_line_browse_history(CommandLineState *s)
{
- // Big switch for a typed command line character.
- switch (s->c) {
- case K_BS:
- case Ctrl_H:
- case K_DEL:
- case K_KDEL:
- case Ctrl_W:
- if (s->c == K_KDEL) {
- s->c = K_DEL;
- }
+ if (s->histype == HIST_INVALID || get_hislen() == 0 || s->firstc == NUL) {
+ // no history
+ return CMDLINE_NOT_CHANGED;
+ }
- // delete current character is the same as backspace on next
- // character, except at end of line
- if (s->c == K_DEL && ccline.cmdpos != ccline.cmdlen) {
- ccline.cmdpos++;
- }
+ s->save_hiscnt = s->hiscnt;
- if (s->c == K_DEL) {
- ccline.cmdpos += mb_off_next((char_u *)ccline.cmdbuff,
- (char_u *)ccline.cmdbuff + ccline.cmdpos);
- }
+ // save current command string so it can be restored later
+ if (s->lookfor == NULL) {
+ s->lookfor = xstrdup(ccline.cmdbuff);
+ s->lookfor[ccline.cmdpos] = NUL;
+ }
- if (ccline.cmdpos > 0) {
- char_u *p;
+ bool next_match = (s->c == K_DOWN || s->c == K_S_DOWN || s->c == Ctrl_N
+ || s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN);
+ command_line_next_histidx(s, next_match);
- int j = ccline.cmdpos;
- p = mb_prevptr((char_u *)ccline.cmdbuff, (char_u *)ccline.cmdbuff + j);
+ if (s->hiscnt != s->save_hiscnt) {
+ // jumped to other entry
+ char *p;
+ int len = 0;
+ int old_firstc;
- if (s->c == Ctrl_W) {
- while (p > (char_u *)ccline.cmdbuff && ascii_isspace(*p)) {
- p = mb_prevptr((char_u *)ccline.cmdbuff, p);
- }
+ XFREE_CLEAR(ccline.cmdbuff);
+ s->xpc.xp_context = EXPAND_NOTHING;
+ if (s->hiscnt == get_hislen()) {
+ p = s->lookfor; // back to the old one
+ } else {
+ p = get_histentry(s->histype)[s->hiscnt].hisstr;
+ }
+
+ if (s->histype == HIST_SEARCH
+ && p != s->lookfor
+ && (old_firstc = (uint8_t)p[strlen(p) + 1]) != s->firstc) {
+ // Correct for the separator character used when
+ // adding the history entry vs the one used now.
+ // First loop: count length.
+ // Second loop: copy the characters.
+ for (int i = 0; i <= 1; i++) {
+ len = 0;
+ for (int j = 0; p[j] != NUL; j++) {
+ // Replace old sep with new sep, unless it is
+ // escaped.
+ if (p[j] == old_firstc
+ && (j == 0 || p[j - 1] != '\\')) {
+ if (i > 0) {
+ ccline.cmdbuff[len] = (char)s->firstc;
+ }
+ } else {
+ // Escape new sep, unless it is already
+ // escaped.
+ if (p[j] == s->firstc
+ && (j == 0 || p[j - 1] != '\\')) {
+ if (i > 0) {
+ ccline.cmdbuff[len] = '\\';
+ }
+ len++;
+ }
- int i = mb_get_class(p);
- while (p > (char_u *)ccline.cmdbuff && mb_get_class(p) == i) {
- p = mb_prevptr((char_u *)ccline.cmdbuff, p);
+ if (i > 0) {
+ ccline.cmdbuff[len] = p[j];
+ }
+ }
+ len++;
}
- if (mb_get_class(p) != i) {
- p += utfc_ptr2len((char *)p);
+ if (i == 0) {
+ alloc_cmdbuff(len);
}
}
+ ccline.cmdbuff[len] = NUL;
+ } else {
+ alloc_cmdbuff((int)strlen(p));
+ STRCPY(ccline.cmdbuff, p);
+ }
- ccline.cmdpos = (int)(p - (char_u *)ccline.cmdbuff);
- ccline.cmdlen -= j - ccline.cmdpos;
- int i = ccline.cmdpos;
-
- while (i < ccline.cmdlen) {
- ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
- }
-
- // Truncate at the end, required for multi-byte chars.
- ccline.cmdbuff[ccline.cmdlen] = NUL;
- if (ccline.cmdlen == 0) {
- s->is_state.search_start = s->is_state.save_cursor;
- // save view settings, so that the screen won't be restored at the
- // wrong position
- s->is_state.old_viewstate = s->is_state.init_viewstate;
- }
- redrawcmd();
- } else if (ccline.cmdlen == 0 && s->c != Ctrl_W
- && ccline.cmdprompt == NULL && s->indent == 0) {
- // In ex and debug mode it doesn't make sense to return.
- if (exmode_active || ccline.cmdfirstc == '>') {
- return command_line_not_changed(s);
- }
+ ccline.cmdpos = ccline.cmdlen = (int)strlen(ccline.cmdbuff);
+ redrawcmd();
+ return CMDLINE_CHANGED;
+ }
+ beep_flush();
+ return CMDLINE_NOT_CHANGED;
+}
- XFREE_CLEAR(ccline.cmdbuff); // no commandline to return
- if (!cmd_silent && !ui_has(kUICmdline)) {
- if (cmdmsg_rl) {
- msg_col = Columns;
- } else {
- msg_col = 0;
- }
- msg_putchar(' '); // delete ':'
- }
- s->is_state.search_start = s->is_state.save_cursor;
- redraw_cmdline = true;
- return 0; // back to cmd mode
+static int command_line_handle_key(CommandLineState *s)
+{
+ // Big switch for a typed command line character.
+ switch (s->c) {
+ case K_BS:
+ case Ctrl_H:
+ case K_DEL:
+ case K_KDEL:
+ case Ctrl_W:
+ switch (command_line_erase_chars(s)) {
+ case CMDLINE_NOT_CHANGED:
+ return command_line_not_changed(s);
+ case GOTO_NORMAL_MODE:
+ return 0; // back to cmd mode
+ default:
+ return command_line_changed(s);
}
- return command_line_changed(s);
case K_INS:
case K_KINS:
@@ -1533,28 +1819,7 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s);
case Ctrl_HAT:
- if (map_to_exists_mode("", MODE_LANGMAP, false)) {
- // ":lmap" mappings exists, toggle use of mappings.
- State ^= MODE_LANGMAP;
- if (s->b_im_ptr != NULL) {
- if (State & MODE_LANGMAP) {
- *s->b_im_ptr = B_IMODE_LMAP;
- } else {
- *s->b_im_ptr = B_IMODE_NONE;
- }
- }
- }
-
- if (s->b_im_ptr != NULL) {
- if (s->b_im_ptr == &curbuf->b_p_iminsert) {
- set_iminsert_global();
- } else {
- set_imsearch_global();
- }
- }
- ui_cursor_shape(); // may show different cursor shape
- // Show/unshow value of 'keymap' in status lines later.
- status_redraw_curbuf();
+ command_line_toggle_langmap(s);
return command_line_not_changed(s);
case Ctrl_U: {
@@ -1590,58 +1855,15 @@ static int command_line_handle_key(CommandLineState *s)
// putting it in history
return 0; // back to cmd mode
- case Ctrl_R: { // insert register
- putcmdline('"', true);
- no_mapping++;
- allow_keys++;
- int i = s->c = plain_vgetc(); // CTRL-R <char>
- if (i == Ctrl_O) {
- i = Ctrl_R; // CTRL-R CTRL-O == CTRL-R CTRL-R
- }
-
- if (i == Ctrl_R) {
- s->c = plain_vgetc(); // CTRL-R CTRL-R <char>
- }
- no_mapping--;
- allow_keys--;
- // Insert the result of an expression.
- // Need to save the current command line, to be able to enter
- // a new one...
- new_cmdpos = -1;
- if (s->c == '=') {
- if (ccline.cmdfirstc == '=' // can't do this recursively
- || cmdline_star > 0) { // or when typing a password
- beep_flush();
- s->c = ESC;
- } else {
- s->c = get_expr_register();
- }
- }
-
- if (s->c != ESC) { // use ESC to cancel inserting register
- cmdline_paste(s->c, i == Ctrl_R, false);
-
- // When there was a serious error abort getting the
- // command line.
- if (aborting()) {
- s->gotesc = true; // will free ccline.cmdbuff after
- // putting it in history
- return 0; // back to cmd mode
- }
- KeyTyped = false; // Don't do p_wc completion.
- if (new_cmdpos >= 0) {
- // set_cmdline_pos() was used
- if (new_cmdpos > ccline.cmdlen) {
- ccline.cmdpos = ccline.cmdlen;
- } else {
- ccline.cmdpos = new_cmdpos;
- }
- }
+ case Ctrl_R: // insert register
+ switch (command_line_insert_reg(s)) {
+ case CMDLINE_NOT_CHANGED:
+ return command_line_not_changed(s);
+ case GOTO_NORMAL_MODE:
+ return 0; // back to cmd mode
+ default:
+ return command_line_changed(s);
}
- ccline.special_char = NUL;
- redrawcmd();
- return command_line_changed(s);
- }
case Ctrl_D:
if (showmatches(&s->xpc, false) == EXPAND_NOTHING) {
@@ -1722,26 +1944,7 @@ static int command_line_handle_key(CommandLineState *s)
FALLTHROUGH;
case K_LEFTMOUSE:
case K_RIGHTMOUSE:
- if (s->c == K_LEFTRELEASE || s->c == K_RIGHTRELEASE) {
- s->ignore_drag_release = true;
- } else {
- s->ignore_drag_release = false;
- }
-
- ccline.cmdspos = cmd_startcol();
- for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
- ccline.cmdpos++) {
- int cells = cmdline_charsize(ccline.cmdpos);
- if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
- && mouse_col < ccline.cmdspos % Columns + cells) {
- break;
- }
-
- // Count ">" for double-wide char that doesn't fit.
- correct_screencol(ccline.cmdpos, cells, &ccline.cmdspos);
- ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos) - 1;
- ccline.cmdspos += cells;
- }
+ command_line_left_right_mouse(s);
return command_line_not_changed(s);
// Mouse scroll wheel: ignored here
@@ -1808,8 +2011,8 @@ static int command_line_handle_key(CommandLineState *s)
case Ctrl_N: // next match
case Ctrl_P: // previous match
if (s->xpc.xp_numfiles > 0) {
- if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
- 0, s->firstc != '@') == FAIL) {
+ const int wild_type = (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT;
+ if (nextwild(&s->xpc, wild_type, 0, s->firstc != '@') == FAIL) {
break;
}
return command_line_not_changed(s);
@@ -1824,88 +2027,27 @@ static int command_line_handle_key(CommandLineState *s)
case K_KPAGEUP:
case K_PAGEDOWN:
case K_KPAGEDOWN:
- if (s->histype == HIST_INVALID || get_hislen() == 0 || s->firstc == NUL) {
- // no history
- return command_line_not_changed(s);
- }
-
- s->save_hiscnt = s->hiscnt;
-
- // save current command string so it can be restored later
- if (s->lookfor == NULL) {
- s->lookfor = xstrdup(ccline.cmdbuff);
- s->lookfor[ccline.cmdpos] = NUL;
- }
-
- bool next_match = (s->c == K_DOWN || s->c == K_S_DOWN || s->c == Ctrl_N
- || s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN);
- command_line_next_histidx(s, next_match);
-
- if (s->hiscnt != s->save_hiscnt) {
- // jumped to other entry
- char_u *p;
- int len = 0;
- int old_firstc;
-
- XFREE_CLEAR(ccline.cmdbuff);
- s->xpc.xp_context = EXPAND_NOTHING;
- if (s->hiscnt == get_hislen()) {
- p = (char_u *)s->lookfor; // back to the old one
- } else {
- p = (char_u *)get_histentry(s->histype)[s->hiscnt].hisstr;
+ if (cmdline_pum_active()
+ && (s->c == K_PAGEUP || s->c == K_PAGEDOWN
+ || s->c == K_KPAGEUP || s->c == K_KPAGEDOWN)) {
+ // If the popup menu is displayed, then PageUp and PageDown
+ // are used to scroll the menu.
+ const int wild_type =
+ (s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN) ? WILD_PAGEDOWN : WILD_PAGEUP;
+ if (nextwild(&s->xpc, wild_type, 0, s->firstc != '@') == FAIL) {
+ break;
}
-
- if (s->histype == HIST_SEARCH
- && p != (char_u *)s->lookfor
- && (old_firstc = p[STRLEN(p) + 1]) != s->firstc) {
- // Correct for the separator character used when
- // adding the history entry vs the one used now.
- // First loop: count length.
- // Second loop: copy the characters.
- for (int i = 0; i <= 1; i++) {
- len = 0;
- for (int j = 0; p[j] != NUL; j++) {
- // Replace old sep with new sep, unless it is
- // escaped.
- if (p[j] == old_firstc
- && (j == 0 || p[j - 1] != '\\')) {
- if (i > 0) {
- ccline.cmdbuff[len] = (char)s->firstc;
- }
- } else {
- // Escape new sep, unless it is already
- // escaped.
- if (p[j] == s->firstc
- && (j == 0 || p[j - 1] != '\\')) {
- if (i > 0) {
- ccline.cmdbuff[len] = '\\';
- }
- len++;
- }
-
- if (i > 0) {
- ccline.cmdbuff[len] = (char)p[j];
- }
- }
- len++;
- }
-
- if (i == 0) {
- alloc_cmdbuff(len);
- }
- }
- ccline.cmdbuff[len] = NUL;
- } else {
- alloc_cmdbuff((int)STRLEN(p));
- STRCPY(ccline.cmdbuff, p);
+ return command_line_not_changed(s);
+ } else {
+ switch (command_line_browse_history(s)) {
+ case CMDLINE_CHANGED:
+ return command_line_changed(s);
+ case GOTO_NORMAL_MODE:
+ return 0;
+ default:
+ return command_line_not_changed(s);
}
-
- ccline.cmdpos = ccline.cmdlen = (int)strlen(ccline.cmdbuff);
- redrawcmd();
- return command_line_changed(s);
}
- beep_flush();
- return command_line_not_changed(s);
case Ctrl_G: // next match
case Ctrl_T: // previous match
@@ -1981,11 +2123,11 @@ static int command_line_handle_key(CommandLineState *s)
// put the character in the command line
if (IS_SPECIAL(s->c) || mod_mask != 0) {
- put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true);
+ put_on_cmdline((char *)get_special_key_name(s->c, mod_mask), -1, true);
} else {
- int j = utf_char2bytes(s->c, (char *)IObuff);
+ int j = utf_char2bytes(s->c, IObuff);
IObuff[j] = NUL; // exclude composing chars
- put_on_cmdline((char_u *)IObuff, j, true);
+ put_on_cmdline(IObuff, j, true);
}
return command_line_changed(s);
}
@@ -2005,16 +2147,35 @@ static int command_line_not_changed(CommandLineState *s)
/// Guess that the pattern matches everything. Only finds specific cases, such
/// as a trailing \|, which can happen while typing a pattern.
-static int empty_pattern(char *p)
+static bool empty_pattern(char *p, int delim)
{
size_t n = strlen(p);
+ magic_T magic_val = MAGIC_ON;
- // remove trailing \v and the like
- while (n >= 2 && p[n - 2] == '\\'
- && vim_strchr("mMvVcCZ", p[n - 1]) != NULL) {
- n -= 2;
+ if (n > 0) {
+ (void)skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic_val);
+ } else {
+ return true;
}
- return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
+
+ return empty_pattern_magic(p, n, magic_val);
+}
+
+static bool empty_pattern_magic(char *p, size_t len, magic_T magic_val)
+{
+ // remove trailing \v and the like
+ while (len >= 2 && p[len - 2] == '\\'
+ && vim_strchr("mMvVcCZ", (uint8_t)p[len - 1]) != NULL) {
+ len -= 2;
+ }
+
+ // true, if the pattern is empty, or the pattern ends with \| and magic is
+ // set (or it ends with '|' and very magic is set)
+ return len == 0 || (len > 1
+ && ((p[len - 2] == '\\'
+ && p[len - 1] == '|' && magic_val == MAGIC_ON)
+ || (p[len - 2] != '\\'
+ && p[len - 1] == '|' && magic_val == MAGIC_ALL)));
}
handle_T cmdpreview_get_bufnr(void)
@@ -2384,7 +2545,8 @@ static void do_autocmd_cmdlinechanged(int firstc)
bool tl_ret = try_leave(&tstate, &err);
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
- msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ msg_scroll = true;
+ msg_puts_attr(err.msg, HL_ATTR(HLF_E)|MSG_HIST);
api_clear_error(&err);
redrawcmd();
}
@@ -2463,9 +2625,9 @@ static void abandon_cmdline(void)
///
/// @param count only used for incremental search
/// @param indent indent for inside conditionals
-char_u *getcmdline(int firstc, long count, int indent, bool do_concat FUNC_ATTR_UNUSED)
+char *getcmdline(int firstc, long count, int indent, bool do_concat FUNC_ATTR_UNUSED)
{
- return command_line_enter(firstc, count, indent, true);
+ return (char *)command_line_enter(firstc, count, indent, true);
}
/// Get a command line with a prompt
@@ -2498,10 +2660,10 @@ char *getcmdline_prompt(const int firstc, const char *const prompt, const int at
CLEAR_FIELD(ccline);
}
ccline.prompt_id = last_prompt_id++;
- ccline.cmdprompt = (char_u *)prompt;
+ ccline.cmdprompt = (char *)prompt;
ccline.cmdattr = attr;
ccline.xp_context = xp_context;
- ccline.xp_arg = (char_u *)xp_arg;
+ ccline.xp_arg = (char *)xp_arg;
ccline.input_fn = (firstc == '@');
ccline.highlight_callback = highlight_callback;
@@ -2525,12 +2687,6 @@ char *getcmdline_prompt(const int firstc, const char *const prompt, const int at
return ret;
}
-// Return current cmdline prompt
-char_u *get_cmdprompt(void)
-{
- return ccline.cmdprompt;
-}
-
/// Read the 'wildmode' option, fill wim_flags[].
int check_opt_wim(void)
{
@@ -2547,13 +2703,13 @@ int check_opt_wim(void)
if (p[i] != NUL && p[i] != ',' && p[i] != ':') {
return FAIL;
}
- if (i == 7 && STRNCMP(p, "longest", 7) == 0) {
+ if (i == 7 && strncmp(p, "longest", 7) == 0) {
new_wim_flags[idx] |= WIM_LONGEST;
- } else if (i == 4 && STRNCMP(p, "full", 4) == 0) {
+ } else if (i == 4 && strncmp(p, "full", 4) == 0) {
new_wim_flags[idx] |= WIM_FULL;
- } else if (i == 4 && STRNCMP(p, "list", 4) == 0) {
+ } else if (i == 4 && strncmp(p, "list", 4) == 0) {
new_wim_flags[idx] |= WIM_LIST;
- } else if (i == 8 && STRNCMP(p, "lastused", 8) == 0) {
+ } else if (i == 8 && strncmp(p, "lastused", 8) == 0) {
new_wim_flags[idx] |= WIM_BUFLASTUSED;
} else {
return FAIL;
@@ -2710,7 +2866,7 @@ char *getexline(int c, void *cookie, int indent, bool do_concat)
(void)vgetc();
}
- return (char *)getcmdline(c, 1L, indent, do_concat);
+ return getcmdline(c, 1L, indent, do_concat);
}
bool cmdline_overstrike(void)
@@ -2748,7 +2904,7 @@ void realloc_cmdbuff(int len)
return; // no need to resize
}
- char_u *p = (char_u *)ccline.cmdbuff;
+ char *p = ccline.cmdbuff;
alloc_cmdbuff(len); // will get some more
// There isn't always a NUL after the command, but it may need to be
// there, thus copy up to the NUL and add a NUL.
@@ -2760,7 +2916,7 @@ void realloc_cmdbuff(int len)
&& ccline.xpc->xp_pattern != NULL
&& ccline.xpc->xp_context != EXPAND_NOTHING
&& ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) {
- int i = (int)((char_u *)ccline.xpc->xp_pattern - p);
+ int i = (int)(ccline.xpc->xp_pattern - p);
// If xp_pattern points inside the old cmdbuff it needs to be adjusted
// to point into the newly allocated memory.
@@ -3095,10 +3251,10 @@ static void draw_cmdline(int start, int len)
bool do_arabicshape = false;
int mb_l;
for (int i = start; i < start + len; i += mb_l) {
- char_u *p = (char_u *)ccline.cmdbuff + i;
+ char *p = ccline.cmdbuff + i;
int u8cc[MAX_MCO];
int u8c = utfc_ptr2char_len(p, u8cc, start + len - i);
- mb_l = utfc_ptr2len_len((char *)p, start + len - i);
+ mb_l = utfc_ptr2len_len(p, start + len - i);
if (ARABIC_CHAR(u8c)) {
do_arabicshape = true;
break;
@@ -3131,10 +3287,10 @@ static void draw_cmdline(int start, int len)
int prev_c = 0;
int prev_c1 = 0;
for (int i = start; i < start + len; i += mb_l) {
- char_u *p = (char_u *)ccline.cmdbuff + i;
+ char *p = ccline.cmdbuff + i;
int u8cc[MAX_MCO];
int u8c = utfc_ptr2char_len(p, u8cc, start + len - i);
- mb_l = utfc_ptr2len_len((char *)p, start + len - i);
+ mb_l = utfc_ptr2len_len(p, start + len - i);
if (ARABIC_CHAR(u8c)) {
int pc;
int pc1 = 0;
@@ -3148,7 +3304,7 @@ static void draw_cmdline(int start, int len)
if (i + mb_l >= start + len) {
nc = NUL;
} else {
- nc = utf_ptr2char((char *)p + mb_l);
+ nc = utf_ptr2char(p + mb_l);
}
} else {
// Displaying from left to right.
@@ -3207,7 +3363,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
if (cmdline_star) {
content = arena_array(&arena, 1);
size_t len = 0;
- for (char_u *p = (char_u *)ccline.cmdbuff; *p; MB_PTR_ADV(p)) {
+ for (char *p = ccline.cmdbuff; *p; MB_PTR_ADV(p)) {
len++;
}
char *buf = arena_alloc(&arena, len, false);
@@ -3238,7 +3394,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
char charbuf[2] = { (char)line->cmdfirstc, 0 };
ui_call_cmdline_show(content, line->cmdpos,
cstr_as_string(charbuf),
- cstr_as_string((char *)(line->cmdprompt)),
+ cstr_as_string((line->cmdprompt)),
line->cmdindent,
line->level);
if (line->special_char) {
@@ -3374,14 +3530,14 @@ void unputcmdline(void)
// part will be redrawn, otherwise it will not. If this function is called
// twice in a row, then 'redraw' should be false and redrawcmd() should be
// called afterwards.
-void put_on_cmdline(char_u *str, int len, int redraw)
+void put_on_cmdline(char *str, int len, int redraw)
{
int i;
int m;
int c;
if (len < 0) {
- len = (int)STRLEN(str);
+ len = (int)strlen(str);
}
realloc_cmdbuff(ccline.cmdlen + len + 1);
@@ -3394,7 +3550,7 @@ void put_on_cmdline(char_u *str, int len, int redraw)
} else {
// Count nr of characters in the new string.
m = 0;
- for (i = 0; i < len; i += utfc_ptr2len((char *)str + i)) {
+ for (i = 0; i < len; i += utfc_ptr2len(str + i)) {
m++;
}
// Count nr of bytes in cmdline that are overwritten by these
@@ -3520,7 +3676,7 @@ static void restore_cmdline(CmdlineInfo *ccp)
static bool cmdline_paste(int regname, bool literally, bool remcr)
{
char *arg;
- char_u *p;
+ char *p;
bool allocated;
// check for valid regname; also accept special characters for CTRL-R in
@@ -3552,21 +3708,21 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
// When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
// part of the word.
- p = (char_u *)arg;
+ p = arg;
if (p_is && regname == Ctrl_W) {
- char_u *w;
+ char *w;
int len;
// Locate start of last word in the cmd buffer.
- for (w = (char_u *)ccline.cmdbuff + ccline.cmdpos; w > (char_u *)ccline.cmdbuff;) {
- len = utf_head_off(ccline.cmdbuff, (char *)w - 1) + 1;
- if (!vim_iswordc(utf_ptr2char((char *)w - len))) {
+ for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff;) {
+ len = utf_head_off(ccline.cmdbuff, w - 1) + 1;
+ if (!vim_iswordc(utf_ptr2char(w - len))) {
break;
}
w -= len;
}
- len = (int)(((char_u *)ccline.cmdbuff + ccline.cmdpos) - w);
- if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) {
+ len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
+ if (p_ic ? STRNICMP(w, arg, len) == 0 : strncmp(w, arg, (size_t)len) == 0) {
p += len;
}
}
@@ -3585,7 +3741,7 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
// When "literally" is true, insert literally.
// When "literally" is false, insert as typed, but don't leave the command
// line.
-void cmdline_paste_str(char_u *s, int literally)
+void cmdline_paste_str(char *s, int literally)
{
int c, cv;
@@ -3593,11 +3749,11 @@ void cmdline_paste_str(char_u *s, int literally)
put_on_cmdline(s, -1, true);
} else {
while (*s != NUL) {
- cv = *s;
+ cv = (uint8_t)(*s);
if (cv == Ctrl_V && s[1]) {
s++;
}
- c = mb_cptr2char_adv((const char_u **)&s);
+ c = mb_cptr2char_adv((const char **)&s);
if (cv == Ctrl_V || c == ESC || c == Ctrl_C
|| c == CAR || c == NL || c == Ctrl_L
|| (c == Ctrl_BSL && *s == Ctrl_N)) {
@@ -3638,7 +3794,7 @@ static void redrawcmdprompt(void)
msg_putchar(ccline.cmdfirstc);
}
if (ccline.cmdprompt != NULL) {
- msg_puts_attr((const char *)ccline.cmdprompt, ccline.cmdattr);
+ msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
// do the reverse of cmd_startcol()
if (ccline.cmdfirstc != NUL) {
@@ -3708,7 +3864,7 @@ void compute_cmdrow(void)
cmdline_row = wp->w_winrow + wp->w_height
+ wp->w_hsep_height + wp->w_status_height + global_stl_height();
}
- if (cmdline_row == Rows) {
+ if (cmdline_row == Rows && p_ch > 0) {
cmdline_row--;
}
lines_left = cmdline_row;
@@ -3796,7 +3952,7 @@ static int ccheck_abbr(int c)
spos = 0;
}
- return check_abbr(c, (char_u *)ccline.cmdbuff, ccline.cmdpos, spos);
+ return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, spos);
}
/// Escape special characters in "fname", depending on "what":
@@ -3813,34 +3969,31 @@ char *vim_strsave_fnameescape(const char *const fname, const int what)
{
#ifdef BACKSLASH_IN_FILENAME
# define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
-# define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`%#'\"|!<")
- char_u buf[sizeof(PATH_ESC_CHARS)];
+# define BUFFER_ESC_CHARS (" \t\n*?[`%#'\"|!<")
+ char buf[sizeof(PATH_ESC_CHARS)];
int j = 0;
// Don't escape '[', '{' and '!' if they are in 'isfname' and for the
// ":buffer" command.
for (const char *p = what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS;
*p != NUL; p++) {
- if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p)) {
+ if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec((uint8_t)(*p))) {
buf[j++] = *p;
}
}
buf[j] = NUL;
- char *p = (char *)vim_strsave_escaped((const char_u *)fname,
- (const char_u *)buf);
+ char *p = vim_strsave_escaped(fname, buf);
#else
-# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
-# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
-# define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`$\\%#'\"|!<")
- char *p =
- (char *)vim_strsave_escaped((const char_u *)fname,
- what == VSE_SHELL ? SHELL_ESC_CHARS
- : what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS);
+# define PATH_ESC_CHARS " \t\n*?[{`$\\%#'\"|!<"
+# define SHELL_ESC_CHARS " \t\n*?[{`$\\%#'\"|!<>();&"
+# define BUFFER_ESC_CHARS " \t\n*?[`$\\%#'\"|!<"
+ char *p = vim_strsave_escaped(fname,
+ what == VSE_SHELL ? SHELL_ESC_CHARS : what ==
+ VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS);
if (what == VSE_SHELL && csh_like_shell()) {
// For csh and similar shells need to put two backslashes before '!'.
// One is taken by Vim, one by the shell.
- char *s = (char *)vim_strsave_escaped((const char_u *)p,
- (const char_u *)"!");
+ char *s = vim_strsave_escaped(p, "!");
xfree(p);
p = s;
}
@@ -3858,16 +4011,16 @@ char *vim_strsave_fnameescape(const char *const fname, const int what)
/// Put a backslash before the file name in "pp", which is in allocated memory.
void escape_fname(char **pp)
{
- char_u *p = xmalloc(strlen(*pp) + 2);
+ char *p = xmalloc(strlen(*pp) + 2);
p[0] = '\\';
STRCPY(p + 1, *pp);
xfree(*pp);
- *pp = (char *)p;
+ *pp = p;
}
/// For each file name in files[num_files]:
/// If 'orig_pat' starts with "~/", replace the home directory with "~".
-void tilde_replace(char_u *orig_pat, int num_files, char **files)
+void tilde_replace(char *orig_pat, int num_files, char **files)
{
char *p;
@@ -3948,12 +4101,14 @@ static char *get_cmdline_completion(void)
}
CmdlineInfo *p = get_ccline_ptr();
- if (p != NULL && p->xpc != NULL) {
- set_expand_context(p->xpc);
- char *cmd_compl = get_user_cmd_complete(p->xpc, p->xpc->xp_context);
- if (cmd_compl != NULL) {
- return xstrdup(cmd_compl);
- }
+ if (p == NULL || p->xpc == NULL) {
+ return NULL;
+ }
+
+ set_expand_context(p->xpc);
+ char *cmd_compl = get_user_cmd_complete(p->xpc, p->xpc->xp_context);
+ if (cmd_compl != NULL) {
+ return xstrdup(cmd_compl);
}
return NULL;
@@ -4134,7 +4289,7 @@ char *check_cedit(void)
if (*p_cedit == NUL) {
cedit_key = -1;
} else {
- n = string_to_key((char_u *)p_cedit);
+ n = string_to_key(p_cedit);
if (vim_isprintc(n)) {
return e_invarg;
}