diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index ae389a6727..a2487336f1 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -629,6 +629,8 @@ void ex_sort(exarg_T *eap) if (sort_abort) goto sortend; + bcount_t old_count = 0, new_count = 0; + // Insert the lines in the sorted order below the last one. lnum = eap->line2; for (i = 0; i < count; i++) { @@ -641,6 +643,8 @@ void ex_sort(exarg_T *eap) } s = ml_get(get_lnum); + size_t bytelen = STRLEN(s) + 1; // include EOL in bytelen + old_count += bytelen; if (!unique || i == 0 || (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0) { // Copy the line into a buffer, it may become invalid in @@ -649,6 +653,7 @@ void ex_sort(exarg_T *eap) if (ml_append(lnum++, sortbuf1, (colnr_T)0, false) == FAIL) { break; } + new_count += bytelen; } fast_breakcheck(); if (got_int) @@ -668,11 +673,16 @@ void ex_sort(exarg_T *eap) deleted = (long)(count - (lnum - eap->line2)); if (deleted > 0) { mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted, - kExtmarkUndo); + kExtmarkNOOP); msgmore(-deleted); } else if (deleted < 0) { - mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkUndo); + mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP); } + + extmark_splice(curbuf, eap->line1-1, 0, + count, 0, old_count, + lnum - eap->line2, 0, new_count, kExtmarkUndo); + if (change_occurred || deleted != 0) { changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); } @@ -1032,14 +1042,15 @@ void free_prev_shellcmd(void) * Bangs in the argument are replaced with the previously entered command. * Remember the argument. */ -void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out) +void do_bang(int addr_count, exarg_T *eap, bool forceit, + bool do_in, bool do_out) + FUNC_ATTR_NONNULL_ALL { - char_u *arg = eap->arg; /* command */ - linenr_T line1 = eap->line1; /* start of range */ - linenr_T line2 = eap->line2; /* end of range */ - char_u *newcmd = NULL; /* the new command */ - int free_newcmd = FALSE; /* need to free() newcmd */ - int ins_prevcmd; + char_u *arg = eap->arg; // command + linenr_T line1 = eap->line1; // start of range + linenr_T line2 = eap->line2; // end of range + char_u *newcmd = NULL; // the new command + bool free_newcmd = false; // need to free() newcmd char_u *t; char_u *p; char_u *trailarg; @@ -1064,7 +1075,7 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out) * Try to find an embedded bang, like in :!<cmd> ! [args] * (:!! is indicated by the 'forceit' variable) */ - ins_prevcmd = forceit; + bool ins_prevcmd = forceit; trailarg = arg; do { len = (int)STRLEN(trailarg) + 1; @@ -1101,7 +1112,7 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out) else { trailarg = p; *trailarg++ = NUL; - ins_prevcmd = TRUE; + ins_prevcmd = true; break; } } @@ -1131,7 +1142,7 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out) STRCPY(newcmd, p_shq); STRCAT(newcmd, prevcmd); STRCAT(newcmd, p_shq); - free_newcmd = TRUE; + free_newcmd = true; } if (addr_count == 0) { /* :! */ /* echo the command */ @@ -1164,15 +1175,15 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out) // do this. // Alternatively, if on Unix and redirecting input or output, but not both, // and the 'shelltemp' option isn't set, use pipes. -// We use input redirection if do_in is TRUE. -// We use output redirection if do_out is TRUE. +// We use input redirection if do_in is true. +// We use output redirection if do_out is true. static void do_filter( linenr_T line1, linenr_T line2, exarg_T *eap, /* for forced 'ff' and 'fenc' */ char_u *cmd, - int do_in, - int do_out) + bool do_in, + bool do_out) { char_u *itmp = NULL; char_u *otmp = NULL; @@ -1669,10 +1680,17 @@ void ex_update(exarg_T *eap) */ void ex_write(exarg_T *eap) { - if (eap->usefilter) /* input lines to shell command */ - do_bang(1, eap, FALSE, TRUE, FALSE); - else + if (eap->cmdidx == CMD_saveas) { + // :saveas does not take a range, uses all lines. + eap->line1 = 1; + eap->line2 = curbuf->b_ml.ml_line_count; + } + + if (eap->usefilter) { // input lines to shell command + do_bang(1, eap, false, true, false); + } else { (void)do_write(eap); + } } /* @@ -3675,6 +3693,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, } else { char_u *orig_line = NULL; int len_change = 0; + const bool save_p_lz = p_lz; int save_p_fen = curwin->w_p_fen; curwin->w_p_fen = FALSE; @@ -3683,6 +3702,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, int temp = RedrawingDisabled; RedrawingDisabled = 0; + // avoid calling update_screen() in vgetorpeek() + p_lz = false; + if (new_start != NULL) { /* There already was a substitution, we would * like to show this to the user. We cannot @@ -3736,7 +3758,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, /* clear the question */ msg_didout = FALSE; /* don't scroll up */ msg_col = 0; - gotocmdline(TRUE); + gotocmdline(true); + p_lz = save_p_lz; // restore the line if (orig_line != NULL) { |