diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/ex_cmds.c | 27 | ||||
| -rw-r--r-- | src/nvim/ex_getln.c | 46 | ||||
| -rw-r--r-- | src/nvim/getchar.c | 44 | ||||
| -rw-r--r-- | src/nvim/option.h | 12 | 
4 files changed, 73 insertions, 56 deletions
| diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 66b6aa2f46..a747ead6b9 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3100,8 +3100,6 @@ static char_u *sub_parse_flags(char_u *cmd, subflags_T *subflags,    return cmd;  } -/// do_sub() -///  /// Perform a substitution from line eap->line1 to line eap->line2 using the  /// command pointed to by eap->arg which should be of the form:  /// @@ -3110,7 +3108,7 @@ static char_u *sub_parse_flags(char_u *cmd, subflags_T *subflags,  /// The usual escapes are supported as described in the regexp docs.  ///  /// @return buffer used for 'inccommand' preview -buf_T *do_sub(exarg_T *eap) +static buf_T *do_sub(exarg_T *eap)  {    long i = 0;    regmmatch_T regmatch; @@ -3139,6 +3137,7 @@ buf_T *do_sub(exarg_T *eap)    bool endcolumn = false;   // cursor in last column when done    MatchedLineVec matched_lines = KV_INITIAL_VALUE;    pos_T old_cursor = curwin->w_cursor; +  proftime_T timeout = eap->is_live ? profile_setlimit(p_rdt) : profile_zero();    int start_nsubs;    int save_ma = 0;    int save_b_changed = curbuf->b_changed; @@ -3581,7 +3580,7 @@ buf_T *do_sub(exarg_T *eap)                  || typed == intr_char  #endif                  ) { -              got_quit = TRUE; +              got_quit = true;                break;              }              if (typed == 'n') @@ -3882,6 +3881,10 @@ skip:      }      line_breakcheck(); + +    if (profile_passed_limit(timeout)) { +      got_quit = true; +    }    }    if (first_line != 0) { @@ -3949,9 +3952,14 @@ skip:    // Show 'inccommand' preview if there are matched lines.    buf_T *preview_buf = NULL; -  if (eap->is_live && *p_icm != NUL && matched_lines.size != 0 && pat != NULL) { -    curbuf->b_changed = save_b_changed;  // preserve 'modified' during preview -    preview_buf = show_sub(eap, old_cursor, pat, sub, &matched_lines); +  if (eap->is_live && !aborting()) { +    if (got_quit) {  // Substitution is too slow, disable 'inccommand'. +      set_string_option_direct((char_u *)"icm", -1, (char_u *)"", OPT_FREE, +                               SID_NONE); +    } else if (*p_icm != NUL && matched_lines.size != 0 && pat != NULL) { +      curbuf->b_changed = save_b_changed;  // preserve 'modified' during preview +      preview_buf = show_sub(eap, old_cursor, pat, sub, &matched_lines); +    }    }    for (MatchedLine m; kv_size(matched_lines);) { @@ -6017,7 +6025,8 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr, char_u *pat, char_u *sub,    cmdmod.tab = 0;                 // disable :tab modifier    cmdmod.noswapfile = true;       // disable swap for preview buffer    // disable file info message -  set_option_value((char_u *)"shm", 0L, (char_u *)"F", 0); +  set_string_option_direct((char_u *)"shm", -1, (char_u *)"F", OPT_FREE, +                           SID_NONE);    bool outside_curline = (eap->line1 != old_cusr.lnum                            || eap->line2 != old_cusr.lnum); @@ -6096,7 +6105,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr, char_u *pat, char_u *sub,    win_size_restore(&save_winsizes);    ga_clear(&save_winsizes); -  set_option_value((char_u *)"shm", 0L, save_shm_p, 0); +  set_string_option_direct((char_u *)"shm", -1, save_shm_p, OPT_FREE, SID_NONE);    xfree(save_shm_p);    // Update screen now. Must do this _before_ close_windows(). diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index c4169f03f0..3093caebaf 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -95,19 +95,21 @@ typedef struct command_line_state {    char_u *lookfor;                      // string to match    int hiscnt;                           // current history line in use    int histype;                          // history type to be used -  pos_T old_cursor; -  colnr_T old_curswant; -  colnr_T old_leftcol; -  linenr_T old_topline; -  int old_topfill; -  linenr_T old_botline; +  pos_T     old_cursor; +  colnr_T   old_curswant; +  colnr_T   old_leftcol; +  linenr_T  old_topline; +  int       old_topfill; +  linenr_T  old_botline;    int did_incsearch;    int incsearch_postponed; +  bool live;                            // performing 'inccommand' preview    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 +  int       save_msg_scroll; +  int       save_State;                 // remember State when called +  char_u   *save_p_icm;    int some_key_typed;                   // one of the keys was typed    // mouse drag and release events are ignored, unless they are    // preceded with a mouse down event @@ -159,6 +161,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)    s->indent = indent;    s->save_msg_scroll = msg_scroll;    s->save_State = State; +  s->save_p_icm = vim_strsave(p_icm);    s->ignore_drag_release = true;    if (s->firstc == -1) { @@ -323,9 +326,12 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)      need_wait_return = false;    } +  set_string_option_direct((char_u *)"icm", -1, s->save_p_icm, OPT_FREE, +                           SID_NONE);    State = s->save_State;    setmouse();    ui_cursor_shape();            // may show different cursor shape +  xfree(s->save_p_icm);    {      char_u *p = ccline.cmdbuff; @@ -394,7 +400,8 @@ static int command_line_execute(VimState *state, int key)    if ((s->c == Ctrl_C)        && s->firstc != '@'        && !s->break_ctrl_c -      && !global_busy) { +      && !global_busy +      && !cmd_is_live(ccline.cmdbuff)) {      got_int = false;    } @@ -981,7 +988,6 @@ static int command_line_handle_key(CommandLineState *s)      status_redraw_curbuf();      return command_line_not_changed(s); -  // case '@':   only in very old vi    case Ctrl_U:      // delete all characters left of the cursor      s->j = ccline.cmdpos; @@ -996,7 +1002,6 @@ static int command_line_handle_key(CommandLineState *s)      redrawcmd();      return command_line_changed(s); -    case ESC:           // get here if p_wc != ESC or when ESC typed twice    case Ctrl_C:      // In exmode it doesn't make sense to return.  Except when @@ -1489,11 +1494,11 @@ static int command_line_handle_key(CommandLineState *s)  static int command_line_not_changed(CommandLineState *s)  { -  // This part implements incremental searches for "/" and "?" Jump to -  // cmdline_not_changed when a character has been read but the command line -  // did not change. Then we only search and redraw if something changed in -  // the past.  Jump to cmdline_changed when the command line did change. -  // (Sorry for the goto's, I know it is ugly). +  // Incremental searches for "/" and "?": +  // Enter command_line_not_changed() when a character has been read but the +  // command line did not change. Then we only search and redraw if something +  // changed in the past. +  // Enter command_line_changed() when the command line did change.    if (!s->incsearch_postponed) {      return 1;    } @@ -1592,11 +1597,13 @@ static int command_line_changed(CommandLineState *s)      redrawcmdline();      s->did_incsearch = true;    } else if (s->firstc == ':' -             && KeyTyped            // only if interactive +             && current_SID == 0    // only if interactive               && *p_icm != NUL       // 'inccommand' is set               && curbuf->b_p_ma      // buffer is modifiable               && cmdline_star == 0   // not typing a password -             && cmd_is_live(ccline.cmdbuff)) { +             && cmd_is_live(ccline.cmdbuff) +             && !vpeekc_any()) { +    s->live = true;      // process a "live" command ('inccommand')      do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_LIVE); @@ -1610,6 +1617,9 @@ static int command_line_changed(CommandLineState *s)      update_topline();      redrawcmdline(); +  } else if (s->live) { +    s->live = false; +    update_screen(SOME_VALID);  // Clear 'inccommand' preview.    }    if (cmdmsg_rl || (p_arshape && !p_tbidi && enc_utf8)) { diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index dad0ac33cd..ab52ee0372 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1583,29 +1583,27 @@ vungetc ( /* unget one character (can only be done once!) */    old_mouse_col = mouse_col;  } -/* - * get a character: - * 1. from the stuffbuffer - *	This is used for abbreviated commands like "D" -> "d$". - *	Also used to redo a command for ".". - * 2. from the typeahead buffer - *	Stores text obtained previously but not used yet. - *	Also stores the result of mappings. - *	Also used for the ":normal" command. - * 3. from the user - *	This may do a blocking wait if "advance" is TRUE. - * - * if "advance" is TRUE (vgetc()): - *	really get the character. - *	KeyTyped is set to TRUE in the case the user typed the key. - *	KeyStuffed is TRUE if the character comes from the stuff buffer. - * if "advance" is FALSE (vpeekc()): - *	just look whether there is a character available. - * - * When "no_mapping" is zero, checks for mappings in the current mode. - * Only returns one byte (of a multi-byte character). - * K_SPECIAL and CSI may be escaped, need to get two more bytes then. - */ +/// get a character: +/// 1. from the stuffbuffer +///    This is used for abbreviated commands like "D" -> "d$". +///    Also used to redo a command for ".". +/// 2. from the typeahead buffer +///    Stores text obtained previously but not used yet. +///    Also stores the result of mappings. +///    Also used for the ":normal" command. +/// 3. from the user +///    This may do a blocking wait if "advance" is TRUE. +/// +/// if "advance" is TRUE (vgetc()): +///    really get the character. +///    KeyTyped is set to TRUE in the case the user typed the key. +///    KeyStuffed is TRUE if the character comes from the stuff buffer. +/// if "advance" is FALSE (vpeekc()): +///    just look whether there is a character available. +/// +/// When "no_mapping" is zero, checks for mappings in the current mode. +/// Only returns one byte (of a multi-byte character). +/// K_SPECIAL and CSI may be escaped, need to get two more bytes then.  static int vgetorpeek(int advance)  {    int c, c1; diff --git a/src/nvim/option.h b/src/nvim/option.h index cf167cdd2c..60f14dea44 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -13,12 +13,12 @@  /// When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global  /// values, get local value.  typedef enum { -  OPT_FREE = 1,  ///< Free old value if it was allocated. -  OPT_GLOBAL = 2,  ///< Use global value. -  OPT_LOCAL = 4,  ///< Use local value. -  OPT_MODELINE = 8,  ///< Option in modeline. -  OPT_WINONLY = 16,  ///< Only set window-local options. -  OPT_NOWIN = 32,  ///< Don’t set window-local options. +  OPT_FREE     = 1,   ///< Free old value if it was allocated. +  OPT_GLOBAL   = 2,   ///< Use global value. +  OPT_LOCAL    = 4,   ///< Use local value. +  OPT_MODELINE = 8,   ///< Option in modeline. +  OPT_WINONLY  = 16,  ///< Only set window-local options. +  OPT_NOWIN    = 32,  ///< Don’t set window-local options.  } OptionFlags;  #ifdef INCLUDE_GENERATED_DECLARATIONS | 
