diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 2da8c205c1..b220b034dd 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -790,7 +790,10 @@ void ex_retab(exarg_T *eap) for (col = 0; col < len; col++) { ptr[col] = (col < num_tabs) ? '\t' : ' '; } - ml_replace(lnum, new_line, false); + if (ml_replace(lnum, new_line, false) == OK) { + // "new_line" may have been copied + new_line = curbuf->b_ml.ml_line_ptr; + } if (first_line == 0) { first_line = lnum; } @@ -2178,6 +2181,8 @@ theend: /// ECMD_OLDBUF: use existing buffer if it exists /// ECMD_FORCEIT: ! used for Ex command /// ECMD_ADDBUF: don't edit, just add to buffer list +/// ECMD_ALTBUF: like ECMD_ADDBUF and also set the alternate +/// file /// @param oldwin Should be "curwin" when editing a new buffer in the current /// window, NULL when splitting the window first. When not NULL /// info of the previous buffer for "oldwin" is stored. @@ -2234,8 +2239,10 @@ int do_ecmd( path_fix_case(sfname); // set correct case for sfname #endif - if ((flags & ECMD_ADDBUF) && (ffname == NULL || *ffname == NUL)) + if ((flags & (ECMD_ADDBUF | ECMD_ALTBUF)) + && (ffname == NULL || *ffname == NUL)) { goto theend; + } if (ffname == NULL) other_file = TRUE; @@ -2265,15 +2272,16 @@ int do_ecmd( // If the file was changed we may not be allowed to abandon it: // - if we are going to re-edit the same file // - or if we are the only window on this file and if ECMD_HIDE is FALSE - if ( ((!other_file && !(flags & ECMD_OLDBUF)) - || (curbuf->b_nwindows == 1 - && !(flags & (ECMD_HIDE | ECMD_ADDBUF)))) - && check_changed(curbuf, (p_awa ? CCGD_AW : 0) - | (other_file ? 0 : CCGD_MULTWIN) - | ((flags & ECMD_FORCEIT) ? CCGD_FORCEIT : 0) - | (eap == NULL ? 0 : CCGD_EXCMD))) { - if (fnum == 0 && other_file && ffname != NULL) + if (((!other_file && !(flags & ECMD_OLDBUF)) + || (curbuf->b_nwindows == 1 + && !(flags & (ECMD_HIDE | ECMD_ADDBUF | ECMD_ALTBUF)))) + && check_changed(curbuf, (p_awa ? CCGD_AW : 0) + | (other_file ? 0 : CCGD_MULTWIN) + | ((flags & ECMD_FORCEIT) ? CCGD_FORCEIT : 0) + | (eap == NULL ? 0 : CCGD_EXCMD))) { + if (fnum == 0 && other_file && ffname != NULL) { (void)setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum); + } goto theend; } @@ -2303,25 +2311,35 @@ int do_ecmd( * Otherwise we re-use the current buffer. */ if (other_file) { - if (!(flags & ECMD_ADDBUF)) { - if (!cmdmod.keepalt) + if (!(flags & (ECMD_ADDBUF | ECMD_ALTBUF))) { + if (!cmdmod.keepalt) { curwin->w_alt_fnum = curbuf->b_fnum; - if (oldwin != NULL) + } + if (oldwin != NULL) { buflist_altfpos(oldwin); + } } if (fnum) { buf = buflist_findnr(fnum); } else { - if (flags & ECMD_ADDBUF) { - linenr_T tlnum = 1L; + if (flags & (ECMD_ADDBUF | ECMD_ALTBUF)) { + // Default the line number to zero to avoid that a wininfo item + // is added for the current window. + linenr_T tlnum = 0; if (command != NULL) { tlnum = atol((char *)command); if (tlnum <= 0) tlnum = 1L; } - (void)buflist_new(ffname, sfname, tlnum, BLN_LISTED); + // Add BLN_NOCURWIN to avoid a new wininfo items are associated + // with the current window. + const buf_T *const newbuf + = buflist_new(ffname, sfname, tlnum, BLN_LISTED | BLN_NOCURWIN); + if (newbuf != NULL && (flags & ECMD_ALTBUF)) { + curwin->w_alt_fnum = newbuf->b_fnum; + } goto theend; } buf = buflist_new(ffname, sfname, 0L, @@ -2413,7 +2431,10 @@ int do_ecmd( (flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD, false); - the_curwin->w_closing = false; + // Autocommands may have closed the window. + if (win_valid(the_curwin)) { + the_curwin->w_closing = false; + } buf->b_locked--; // autocmds may abort script processing @@ -2464,8 +2485,7 @@ int do_ecmd( curwin->w_pcmark.lnum = 1; curwin->w_pcmark.col = 0; } else { // !other_file - if ((flags & ECMD_ADDBUF) - || check_fname() == FAIL) { + if ((flags & (ECMD_ADDBUF | ECMD_ALTBUF)) || check_fname() == FAIL) { goto theend; } oldbuf = (flags & ECMD_OLDBUF); @@ -2531,13 +2551,13 @@ int do_ecmd( goto theend; } u_unchanged(curbuf); - buf_updates_unregister_all(curbuf); + buf_updates_unload(curbuf, false); buf_freeall(curbuf, BFA_KEEP_UNDO); // Tell readfile() not to clear or reload undo info. readfile_flags = READ_KEEP_UNDO; } else { - buf_updates_unregister_all(curbuf); + buf_updates_unload(curbuf, false); buf_freeall(curbuf, 0); // Free all things for buffer. } // If autocommands deleted the buffer we were going to re-edit, give @@ -3310,11 +3330,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, int save_b_changed = curbuf->b_changed; bool preview = (State & CMDPREVIEW); - // inccommand tests fail without this check - if (!preview) { - // Required for Undo to work for extmarks. - u_save_cursor(); - } + bool did_save = false; if (!global_busy) { sub_nsubs = 0; @@ -3991,6 +4007,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, int matchcols = end.col - ((end.lnum == start.lnum) ? start.col : 0); int subcols = new_endcol - ((lnum == lnum_start) ? start_col : 0); + if (!did_save) { + // Required for Undo to work for extmarks. + u_save_cursor(); + did_save = true; + } extmark_splice(curbuf, lnum_start-1, start_col, end.lnum-start.lnum, matchcols, replaced_bytes, lnum-lnum_start, subcols, sublen-1, kExtmarkUndo); @@ -4220,7 +4241,7 @@ skip: size_t subsize = preview_lines.subresults.size; if (preview && !aborting()) { if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable. - set_string_option_direct((char_u *)"icm", -1, (char_u *)"", OPT_FREE, + set_string_option_direct("icm", -1, (char_u *)"", OPT_FREE, SID_NONE); } else if (*p_icm != NUL && pat != NULL) { if (pre_src_id == 0) { @@ -4521,7 +4542,7 @@ prepare_tagpreview ( RESET_BINDING(curwin); /* don't take over 'scrollbind' and 'cursorbind' */ curwin->w_p_diff = false; // no 'diff' - set_string_option_direct((char_u *)"fdc", -1, // no 'foldcolumn' + set_string_option_direct("fdc", -1, // no 'foldcolumn' (char_u *)"0", OPT_FREE, SID_NONE); return true; } @@ -5016,7 +5037,7 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, static void prepare_help_buffer(void) { curbuf->b_help = true; - set_string_option_direct((char_u *)"buftype", -1, (char_u *)"help", + set_string_option_direct("buftype", -1, (char_u *)"help", OPT_FREE|OPT_LOCAL, 0); // Always set these options after jumping to a help tag, because the @@ -5026,13 +5047,13 @@ static void prepare_help_buffer(void) // Only set it when needed, buf_init_chartab() is some work. char_u *p = (char_u *)"!-~,^*,^|,^\",192-255"; if (STRCMP(curbuf->b_p_isk, p) != 0) { - set_string_option_direct((char_u *)"isk", -1, p, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct("isk", -1, p, OPT_FREE|OPT_LOCAL, 0); check_buf_options(curbuf); (void)buf_init_chartab(curbuf, FALSE); } // Don't use the global foldmethod. - set_string_option_direct((char_u *)"fdm", -1, (char_u *)"manual", + set_string_option_direct("fdm", -1, (char_u *)"manual", OPT_FREE|OPT_LOCAL, 0); curbuf->b_p_ts = 8; // 'tabstop' is 8. @@ -5652,7 +5673,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr, cmdmod.tab = 0; // disable :tab modifier cmdmod.noswapfile = true; // disable swap for preview buffer // disable file info message - set_string_option_direct((char_u *)"shm", -1, (char_u *)"F", OPT_FREE, + set_string_option_direct("shm", -1, (char_u *)"F", OPT_FREE, SID_NONE); bool outside_curline = (eap->line1 != old_cusr.lnum @@ -5775,7 +5796,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr, update_screen(SOME_VALID); RedrawingDisabled = save_rd; - set_string_option_direct((char_u *)"shm", -1, save_shm_p, OPT_FREE, SID_NONE); + set_string_option_direct("shm", -1, save_shm_p, OPT_FREE, SID_NONE); xfree(save_shm_p); cmdmod = save_cmdmod; |