From 8ce092941862a18a6591f62f398ed9e8bd9202be Mon Sep 17 00:00:00 2001 From: matveyt Date: Fri, 23 Jul 2021 18:06:01 +0200 Subject: [PATCH] Remove EXMODE_NORMAL --- runtime/doc/eval.txt | 3 +- runtime/doc/options.txt | 5 - runtime/doc/quickref.txt | 1 - runtime/doc/vim_diff.txt | 1 + src/nvim/ex_cmds.c | 19 ++- src/nvim/ex_docmd.c | 17 +-- src/nvim/ex_docmd.h | 4 - src/nvim/ex_getln.c | 264 +-------------------------------------- src/nvim/getchar.c | 24 ++-- src/nvim/globals.h | 3 +- src/nvim/main.c | 10 +- src/nvim/main.h | 1 + src/nvim/message.c | 5 +- src/nvim/normal.c | 11 +- src/nvim/option_defs.h | 1 - src/nvim/options.lua | 2 +- src/nvim/state.c | 6 +- 17 files changed, 50 insertions(+), 327 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 8c360b1778..e32691dfb4 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -6358,8 +6358,7 @@ mode([expr]) Return a string that indicates the current mode. Rv Virtual Replace |gR| Rx Replace mode |i_CTRL-X| completion c Command-line editing - cv Vim Ex mode |gQ| - ce Normal Ex mode |Q| + cv Vim Ex mode |Q| or |gQ| r Hit-enter prompt rm The -- more -- prompt r? |:confirm| query of some sort diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 6aa508956b..ab2230641d 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4539,11 +4539,6 @@ A jump table for the options with a short description can be found at |Q_op|. List of items that control the format of the output of |:hardcopy|. See |popt-option|. - *'prompt'* *'noprompt'* -'prompt' boolean (default on) - global - When on a ":" prompt is used in Ex mode. - *'pumblend'* *'pb'* 'pumblend' 'pb' number (default 0) global diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index fb20a583c9..c19b05f6c7 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -809,7 +809,6 @@ Short explanation of each option: *option-list* 'printmbcharset' 'pmbcs' CJK character set to be used for :hardcopy 'printmbfont' 'pmbfn' font names to be used for CJK output of :hardcopy 'printoptions' 'popt' controls the format of :hardcopy output -'prompt' 'prompt' enable prompt in Ex mode 'pumheight' 'ph' maximum height of the popup menu 'pumwidth' 'pw' minimum width of the popup menu 'pythondll' name of the Python 2 dynamic library diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 27c4b82aca..a259afded0 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -473,6 +473,7 @@ Options: 'maxmem' Nvim delegates memory-management to the OS. 'maxmemtot' Nvim delegates memory-management to the OS. 'maxcombine' (6 is always used) + *'prompt'* *'noprompt'* *'restorescreen'* *'rs'* *'norestorescreen'* *'nors'* 'shelltype' *'shortname'* *'sn'* *'noshortname'* *'nosn'* diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0e7d7c2dc2..dc096bdb93 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2887,7 +2887,6 @@ void ex_append(exarg_T *eap) } else if (lnum > 0) indent = get_indent_lnum(lnum); } - ex_keep_indent = FALSE; if (eap->getline == NULL) { /* No getline() function, use the lines that follow. This ends * when there is no more. */ @@ -2915,10 +2914,6 @@ void ex_append(exarg_T *eap) if (theline == NULL) break; - /* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */ - if (ex_keep_indent) - append_indent = indent; - /* Look for the "." after automatic indent. */ vcol = 0; for (p = theline; indent > vcol; ++p) { @@ -3751,6 +3746,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, */ while (subflags.do_ask) { if (exmode_active) { + char *prompt; char_u *resp; colnr_T sc, ec; @@ -3767,13 +3763,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, sc += numw; ec += numw; } - msg_start(); - for (i = 0; i < (long)sc; ++i) - msg_putchar(' '); - for (; i <= (long)ec; ++i) - msg_putchar('^'); - resp = getexmodeline('?', NULL, 0, true); + prompt = xmallocz(ec + 1); + memset(prompt, ' ', sc); + memset(prompt + sc, '^', ec - sc + 1); + resp = (char_u *)getcmdline_prompt(NUL, prompt, 0, EXPAND_NOTHING, + NULL, CALLBACK_NONE); + msg_putchar('\n'); + xfree(prompt); if (resp != NULL) { typed = *resp; xfree(resp); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 83472fe146..cf604c2015 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -186,17 +186,14 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp) } /// Repeatedly get commands for Ex mode, until the ":vi" command is given. -void do_exmode(int improved) +void do_exmode(void) { int save_msg_scroll; int prev_msg_row; linenr_T prev_line; int changedtick; - if (improved) - exmode_active = EXMODE_VIM; - else - exmode_active = EXMODE_NORMAL; + exmode_active = true; State = NORMAL; /* When using ":global /pat/ visual" and then "Q" we return to continue @@ -212,7 +209,7 @@ void do_exmode(int improved) while (exmode_active) { /* Check for a ":normal" command and no more characters left. */ if (ex_normal_busy > 0 && typebuf.tb_len == 0) { - exmode_active = 0; + exmode_active = false; break; } msg_scroll = true; @@ -750,8 +747,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, * the :endtry to be missed. */ && (cstack.cs_trylevel == 0 || did_emsg_syntax) && used_getline - && (getline_equal(fgetline, cookie, getexmodeline) - || getline_equal(fgetline, cookie, getexline))) + && getline_equal(fgetline, cookie, getexline)) && (next_cmdline != NULL || cstack.cs_idx >= 0 || (flags & DOCMD_REPEAT))); @@ -2056,8 +2052,7 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only) // in ex mode, an empty line works like :+ if (*eap->cmd == NUL && exmode_active - && (getline_equal(eap->getline, eap->cookie, getexmodeline) - || getline_equal(eap->getline, eap->cookie, getexline)) + && getline_equal(eap->getline, eap->cookie, getexline) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { eap->cmd = (char_u *)"+"; if (!skip_only) { @@ -7303,7 +7298,7 @@ do_exedit( */ if (exmode_active && (eap->cmdidx == CMD_visual || eap->cmdidx == CMD_view)) { - exmode_active = 0; + exmode_active = false; ex_pressedreturn = false; if (*eap->arg == NUL) { /* Special case: ":global/pat/visual\NLvi-commands" */ diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index f6bd2adcd5..c8c5a0a3e2 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -16,10 +16,6 @@ #define VALID_PATH 1 #define VALID_HEAD 2 -/* Values for exmode_active (0 is no exmode) */ -#define EXMODE_NORMAL 1 -#define EXMODE_VIM 2 - // Structure used to save the current state. Used when executing Normal mode // commands while in any other mode. typedef struct { diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 4ebd384ae0..855f71ca28 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2510,266 +2510,6 @@ getexline( return getcmdline(c, 1L, indent, do_concat); } -/* - * Get an Ex command line for Ex mode. - * In Ex mode we only use the OS supplied line editing features and no - * mappings or abbreviations. - * Returns a string in allocated memory or NULL. - */ -char_u * -getexmodeline( - int promptc, // normally ':', NUL for ":append" and '?' - // for :s prompt - void *cookie, - int indent, // indent for inside conditionals - bool do_concat -) -{ - garray_T line_ga; - char_u *pend; - int startcol = 0; - int c1 = 0; - int escaped = FALSE; /* CTRL-V typed */ - int vcol = 0; - char_u *p; - int prev_char; - int len; - - /* always start in column 0; write a newline if necessary */ - compute_cmdrow(); - if ((msg_col || msg_didout) && promptc != '?') - msg_putchar('\n'); - if (promptc == ':') { - /* indent that is only displayed, not in the line itself */ - if (p_prompt) - msg_putchar(':'); - while (indent-- > 0) - msg_putchar(' '); - startcol = msg_col; - } - - ga_init(&line_ga, 1, 30); - - /* autoindent for :insert and :append is in the line itself */ - if (promptc <= 0) { - vcol = indent; - while (indent >= 8) { - ga_append(&line_ga, TAB); - msg_puts(" "); - indent -= 8; - } - while (indent-- > 0) { - ga_append(&line_ga, ' '); - msg_putchar(' '); - } - } - no_mapping++; - - /* - * Get the line, one character at a time. - */ - got_int = FALSE; - while (!got_int) { - ga_grow(&line_ga, 40); - - /* Get one character at a time. Don't use inchar(), it can't handle - * special characters. */ - prev_char = c1; - - // Check for a ":normal" command and no more characters left. - if (ex_normal_busy > 0 && typebuf.tb_len == 0) { - c1 = '\n'; - } else { - c1 = vgetc(); - } - - /* - * Handle line editing. - * Previously this was left to the system, putting the terminal in - * cooked mode, but then CTRL-D and CTRL-T can't be used properly. - */ - if (got_int) { - msg_putchar('\n'); - break; - } - - if (!escaped) { - /* CR typed means "enter", which is NL */ - if (c1 == '\r') - c1 = '\n'; - - if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) { - if (!GA_EMPTY(&line_ga)) { - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - len = utf_head_off(p, p + line_ga.ga_len - 1) + 1; - line_ga.ga_len -= len; - goto redraw; - } - continue; - } - - if (c1 == Ctrl_U) { - msg_col = startcol; - msg_clr_eos(); - line_ga.ga_len = 0; - goto redraw; - } - - int num_spaces; - if (c1 == Ctrl_T) { - int sw = get_sw_value(curbuf); - - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - indent = get_indent_str(p, 8, FALSE); - num_spaces = sw - indent % sw; -add_indent: - if (num_spaces > 0) { - ga_grow(&line_ga, num_spaces + 1); - p = (char_u *)line_ga.ga_data; - char_u *s = skipwhite(p); - - // Insert spaces after leading whitespaces. - long move_len = line_ga.ga_len - (s - p) + 1; - assert(move_len >= 0); - memmove(s + num_spaces, s, (size_t)move_len); - memset(s, ' ', (size_t)num_spaces); - - line_ga.ga_len += num_spaces; - } -redraw: - /* redraw the line */ - msg_col = startcol; - vcol = 0; - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - while (p < (char_u *)line_ga.ga_data + line_ga.ga_len) { - if (*p == TAB) { - do { - msg_putchar(' '); - } while (++vcol % 8); - p++; - } else { - len = utfc_ptr2len(p); - msg_outtrans_len(p, len); - vcol += ptr2cells(p); - p += len; - } - } - msg_clr_eos(); - cmd_cursor_goto(msg_row, msg_col); - continue; - } - - if (c1 == Ctrl_D) { - /* Delete one shiftwidth. */ - p = (char_u *)line_ga.ga_data; - if (prev_char == '0' || prev_char == '^') { - if (prev_char == '^') - ex_keep_indent = TRUE; - indent = 0; - p[--line_ga.ga_len] = NUL; - } else { - p[line_ga.ga_len] = NUL; - indent = get_indent_str(p, 8, FALSE); - if (indent == 0) { - continue; - } - --indent; - indent -= indent % get_sw_value(curbuf); - } - - // reduce the line's indentation - char_u *from = skipwhite(p); - char_u *to = from; - int old_indent; - while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) { - *--to = NUL; - } - long move_len = line_ga.ga_len - (from - p) + 1; - assert(move_len > 0); - memmove(to, from, (size_t)move_len); - line_ga.ga_len -= (int)(from - to); - - // Removed to much indentation, fix it before redrawing. - num_spaces = indent - old_indent; - goto add_indent; - } - - if (c1 == Ctrl_V || c1 == Ctrl_Q) { - escaped = TRUE; - continue; - } - - if (IS_SPECIAL(c1)) { - // Ignore other special key codes - continue; - } - } - - if (IS_SPECIAL(c1)) { - c1 = '?'; - } - len = utf_char2bytes(c1, (char_u *)line_ga.ga_data + line_ga.ga_len); - if (c1 == '\n') { - msg_putchar('\n'); - } else if (c1 == TAB) { - // Don't use chartabsize(), 'ts' can be different. - do { - msg_putchar(' '); - } while (++vcol % 8); - } else { - msg_outtrans_len(((char_u *)line_ga.ga_data) + line_ga.ga_len, len); - vcol += char2cells(c1); - } - line_ga.ga_len += len; - escaped = FALSE; - - cmd_cursor_goto(msg_row, msg_col); - pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len; - - /* We are done when a NL is entered, but not when it comes after an - * odd number of backslashes, that results in a NUL. */ - if (!GA_EMPTY(&line_ga) && pend[-1] == '\n') { - int bcount = 0; - - while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\') - ++bcount; - - if (bcount > 0) { - /* Halve the number of backslashes: "\NL" -> "NUL", "\\NL" -> - * "\NL", etc. */ - line_ga.ga_len -= (bcount + 1) / 2; - pend -= (bcount + 1) / 2; - pend[-1] = '\n'; - } - - if ((bcount & 1) == 0) { - --line_ga.ga_len; - --pend; - *pend = NUL; - break; - } - } - } - - no_mapping--; - - /* make following messages go to the next line */ - msg_didout = FALSE; - msg_col = 0; - if (msg_row < Rows - 1) { - msg_row++; - } - emsg_on_display = false; // don't want os_delay() - - if (got_int) - ga_clear(&line_ga); - - return (char_u *)line_ga.ga_data; -} - bool cmdline_overstrike(void) { return ccline.overstrike; @@ -6469,7 +6209,7 @@ static int open_cmdwin(void) char_u typestr[2]; int save_restart_edit = restart_edit; int save_State = State; - int save_exmode = exmode_active; + bool save_exmode = exmode_active; int save_cmdmsg_rl = cmdmsg_rl; /* Can't do this recursively. Can't do it when typing a password. */ @@ -6563,7 +6303,7 @@ static int open_cmdwin(void) save_cmdline(&save_ccline); // No Ex mode here! - exmode_active = 0; + exmode_active = false; State = NORMAL; setmouse(); diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 538ebf7978..b0d06b7a30 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2230,20 +2230,22 @@ static int vgetorpeek(bool advance) timedout = true; continue; } - /* When 'insertmode' is set, ESC just beeps in Insert - * mode. Use CTRL-L to make edit() return. - * For the command line only CTRL-C always breaks it. - * For the cmdline window: Alternate between ESC and - * CTRL-C: ESC for most situations and CTRL-C to close the - * cmdline window. */ - if (p_im && (State & INSERT)) + // When 'insertmode' is set, ESC just beeps in Insert + // mode. Use CTRL-L to make edit() return. + // In Ex-mode \n is compatible with original Vim behaviour. + // For the command line only CTRL-C always breaks it. + // For the cmdline window: Alternate between ESC and + // CTRL-C: ESC for most situations and CTRL-C to close the + // cmdline window. + if (p_im && (State & INSERT)) { c = Ctrl_L; - else if ((State & CMDLINE) - || (cmdwin_type > 0 && tc == ESC) - ) + } else if (exmode_active) { + c = '\n'; + } else if ((State & CMDLINE) || (cmdwin_type > 0 && tc == ESC)) { c = Ctrl_C; - else + } else { c = ESC; + } tc = c; break; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 9fd5ccf324..bbc936cf16 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -239,7 +239,6 @@ EXTERN int did_wait_return INIT(= false); // wait_return() was used and EXTERN int need_maketitle INIT(= true); // call maketitle() soon EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg -EXTERN int ex_keep_indent INIT(= false); // getexmodeline(): keep indent EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0 EXTERN int didset_vim INIT(= false); // did set $VIM ourselves @@ -621,7 +620,7 @@ EXTERN long opcount INIT(= 0); // count for pending operator EXTERN int motion_force INIT(=0); // motion force for pending operator // Ex Mode (Q) state -EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM. +EXTERN bool exmode_active INIT(= false); // true if Ex mode is active EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p. EXTERN int reg_recording INIT(= 0); // register for recording or zero diff --git a/src/nvim/main.c b/src/nvim/main.c index 909defe6d0..d6eedf7010 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -318,7 +318,8 @@ int main(int argc, char **argv) debug_break_level = params.use_debug_break_level; // Read ex-commands if invoked with "-es". - if (!params.input_isatty && silent_mode && exmode_active == EXMODE_NORMAL) { + if (!params.input_isatty && !params.input_neverscript + && silent_mode && exmode_active) { input_start(STDIN_FILENO); } @@ -764,7 +765,7 @@ static bool edit_stdin(bool explicit, mparm_T *parmp) { bool implicit = !headless_mode && !embedded_mode - && exmode_active != EXMODE_NORMAL // -E/-Es but not -e/-es. + && (!exmode_active || parmp->input_neverscript) && !parmp->input_isatty && scriptin[0] == NULL; // `-s -` was not given. return explicit || implicit; @@ -907,11 +908,12 @@ static void command_line_scan(mparm_T *parmp) break; } case 'e': { // "-e" Ex mode - exmode_active = EXMODE_NORMAL; + exmode_active = true; break; } case 'E': { // "-E" Ex mode - exmode_active = EXMODE_VIM; + exmode_active = true; + parmp->input_neverscript = true; break; } case 'f': { // "-f" GUI: run in foreground. diff --git a/src/nvim/main.h b/src/nvim/main.h index 61252f2bce..d387e6d668 100644 --- a/src/nvim/main.h +++ b/src/nvim/main.h @@ -30,6 +30,7 @@ typedef struct { bool input_isatty; // stdin is a terminal bool output_isatty; // stdout is a terminal bool err_isatty; // stderr is a terminal + bool input_neverscript; // never treat stdin as script (-E/-Es) int no_swap_file; // "-n" argument used int use_debug_break_level; int window_count; // number of windows to use diff --git a/src/nvim/message.c b/src/nvim/message.c index ec5dabbbc0..3ab4ad5287 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1324,9 +1324,8 @@ void msg_start(void) 0; } else if (msg_didout) { // start message on next line msg_putchar('\n'); - did_return = TRUE; - if (exmode_active != EXMODE_NORMAL) - cmdline_row = msg_row; + did_return = true; + cmdline_row = msg_row; } if (!msg_didany || lines_left < 0) msg_starthere(); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 74a3d74860..cba7b7a10b 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1188,7 +1188,7 @@ static void normal_check_interrupt(NormalState *s) && s->previous_got_int) { // Typed two CTRL-C in a row: go back to ex mode as if "Q" was // used and keep "got_int" set, so that it aborts ":g". - exmode_active = EXMODE_NORMAL; + exmode_active = true; State = NORMAL; } else if (!global_busy || !exmode_active) { if (!quit_more) { @@ -1398,7 +1398,7 @@ static int normal_check(VimState *state) if (s->noexmode) { return 0; } - do_exmode(exmode_active == EXMODE_VIM); + do_exmode(); return -1; } @@ -4652,7 +4652,7 @@ static void nv_exmode(cmdarg_T *cap) if (VIsual_active) { vim_beep(BO_EX); } else if (!checkclearop(cap->oap)) { - do_exmode(false); + do_exmode(); } } @@ -7101,8 +7101,9 @@ static void nv_g_cmd(cmdarg_T *cap) break; } - if (!checkclearopq(oap)) - do_exmode(true); + if (!checkclearopq(oap)) { + do_exmode(); + } break; case ',': diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 0a556390e7..5e40bdd6ef 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -459,7 +459,6 @@ EXTERN char_u *p_pmcs; // 'printmbcharset' EXTERN char_u *p_pfn; // 'printfont' EXTERN char_u *p_popt; // 'printoptions' EXTERN char_u *p_header; // 'printheader' -EXTERN int p_prompt; // 'prompt' EXTERN char_u *p_guicursor; // 'guicursor' EXTERN char_u *p_guifont; // 'guifont' EXTERN char_u *p_guifontwide; // 'guifontwide' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 48e53c68f3..0830fb4638 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1800,7 +1800,7 @@ return { full_name='prompt', short_desc=N_("enable prompt in Ex mode"), type='bool', scope={'global'}, - varname='p_prompt', + varname='p_force_on', defaults={if_true={vi=true}} }, { diff --git a/src/nvim/state.c b/src/nvim/state.c index a3c74789d1..437cb0db47 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -171,12 +171,10 @@ char *get_mode(void) buf[1] = 'x'; } } - } else if ((State & CMDLINE) || exmode_active) { + } else if (State & CMDLINE) { buf[0] = 'c'; - if (exmode_active == EXMODE_VIM) { + if (exmode_active) { buf[1] = 'v'; - } else if (exmode_active == EXMODE_NORMAL) { - buf[1] = 'e'; } } else if (State & TERM_FOCUS) { buf[0] = 't';