diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
commit | 1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch) | |
tree | cd08258054db80bb9a11b1061bb091c70b76926a /src/nvim/mark.c | |
parent | eaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.gz rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.bz2 rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.zip |
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r-- | src/nvim/mark.c | 318 |
1 files changed, 157 insertions, 161 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c index f1a1f25e6c..5839cf7a2e 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - // mark.c: functions for setting marks and jumping to them #include <assert.h> @@ -9,7 +6,7 @@ #include <stdio.h> #include <string.h> -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/charset.h" @@ -17,14 +14,13 @@ #include "nvim/diff.h" #include "nvim/edit.h" #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/extmark.h" #include "nvim/extmark_defs.h" #include "nvim/fold.h" #include "nvim/gettext.h" #include "nvim/globals.h" -#include "nvim/highlight_defs.h" +#include "nvim/highlight.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -32,16 +28,15 @@ #include "nvim/message.h" #include "nvim/move.h" #include "nvim/normal.h" -#include "nvim/option_defs.h" +#include "nvim/option_vars.h" +#include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/quickfix.h" -#include "nvim/sign.h" #include "nvim/strings.h" #include "nvim/textobject.h" -#include "nvim/undo_defs.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" // This file contains routines to maintain and manipulate marks. @@ -51,9 +46,6 @@ // There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing // shada). -/// Global marks (marks with file number or name) -static xfmark_T namedfm[NGLOBALMARKS]; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mark.c.generated.h" #endif @@ -80,11 +72,12 @@ void free_xfmark(xfmark_T fm) } /// Free and clear fmark_T item -void clear_fmark(fmark_T *fm) +void clear_fmark(fmark_T *const fm, const Timestamp timestamp) FUNC_ATTR_NONNULL_ALL { free_fmark(*fm); - CLEAR_POINTER(fm); + *fm = (fmark_T)INIT_FMARK; + fm->timestamp = timestamp; } // Set named mark "c" to position "pos". @@ -239,7 +232,7 @@ fmark_T *get_jumplist(win_T *win, int count) return NULL; } - for (;;) { + while (true) { if (win->w_jumplistidx + count < 0 || win->w_jumplistidx + count >= win->w_jumplistlen) { return NULL; @@ -445,11 +438,11 @@ fmark_T *mark_get_motion(buf_T *buf, win_T *win, int name) listcmd_busy = true; // avoid that '' is changed if (name == '{' || name == '}') { // to previous/next paragraph oparg_T oa; - if (findpar(&oa.inclusive, name == '}' ? FORWARD : BACKWARD, 1L, NUL, false)) { + if (findpar(&oa.inclusive, name == '}' ? FORWARD : BACKWARD, 1, NUL, false)) { mark = pos_to_mark(buf, NULL, win->w_cursor); } } else if (name == '(' || name == ')') { // to previous/next sentence - if (findsent(name == ')' ? FORWARD : BACKWARD, 1L)) { + if (findsent(name == ')' ? FORWARD : BACKWARD, 1)) { mark = pos_to_mark(buf, NULL, win->w_cursor); } } @@ -521,11 +514,10 @@ fmark_T *pos_to_mark(buf_T *buf, fmark_T *fmp, pos_T pos) /// @return whether the buffer was switched or not. static MarkMoveRes switch_to_mark_buf(fmark_T *fm, bool pcmark_on_switch) { - bool res; if (fm->fnum != curbuf->b_fnum) { // Switch to another file. int getfile_flag = pcmark_on_switch ? GETF_SETMARK : 0; - res = buflist_getfile(fm->fnum, (linenr_T)1, getfile_flag, false) == OK; + bool res = buflist_getfile(fm->fnum, fm->mark.lnum, getfile_flag, false) == OK; return res == true ? kMarkSwitchedBuf : kMarkMoveFailed; } return 0; @@ -542,7 +534,11 @@ MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags) { static fmark_T fm_copy = INIT_FMARK; MarkMoveRes res = kMarkMoveSuccess; - if (!mark_check(fm)) { + const char *errormsg = NULL; + if (!mark_check(fm, &errormsg)) { + if (errormsg != NULL) { + emsg(errormsg); + } res = kMarkMoveFailed; goto end; } @@ -558,7 +554,10 @@ MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags) goto end; } // Check line count now that the **destination buffer is loaded**. - if (!mark_check_line_bounds(curbuf, fm)) { + if (!mark_check_line_bounds(curbuf, fm, &errormsg)) { + if (errormsg != NULL) { + emsg(errormsg); + } res |= kMarkMoveFailed; goto end; } @@ -617,11 +616,8 @@ fmarkv_T mark_view_make(linenr_T topline, pos_T pos) /// @return next mark or NULL if no mark is found. fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line) { - int i; fmark_T *result = NULL; - pos_T pos; - - pos = *startpos; + pos_T pos = *startpos; if (dir == BACKWARD && begin_line) { pos.col = 0; @@ -629,7 +625,7 @@ fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line) pos.col = MAXCOL; } - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { if (curbuf->b_namedm[i].mark.lnum > 0) { if (dir == FORWARD) { if ((result == NULL || lt(curbuf->b_namedm[i].mark, result->mark)) @@ -677,7 +673,7 @@ static void fname2fnum(xfmark_T *fm) char *p = path_shorten_fname(NameBuff, IObuff); // buflist_new() will call fmarks_check_names() - (void)buflist_new(NameBuff, p, (linenr_T)1, 0); + (void)buflist_new(NameBuff, p, 1, 0); } // Check all file marks for a name that matches the file name in buf. @@ -686,18 +682,17 @@ static void fname2fnum(xfmark_T *fm) void fmarks_check_names(buf_T *buf) { char *name = buf->b_ffname; - int i; if (buf->b_ffname == NULL) { return; } - for (i = 0; i < NGLOBALMARKS; i++) { + for (int i = 0; i < NGLOBALMARKS; i++) { fmarks_check_one(&namedfm[i], name, buf); } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - for (i = 0; i < wp->w_jumplistlen; i++) { + for (int i = 0; i < wp->w_jumplistlen; i++) { fmarks_check_one(&wp->w_jumplist[i], name, buf); } } @@ -715,43 +710,45 @@ static void fmarks_check_one(xfmark_T *fm, char *name, buf_T *buf) /// Check the position in @a fm is valid. /// -/// Emit error message and return accordingly. -/// /// Checks for: /// - NULL raising unknown mark error. /// - Line number <= 0 raising mark not set. /// - Line number > buffer line count, raising invalid mark. +/// /// @param fm[in] File mark to check. +/// @param errormsg[out] Error message, if any. /// /// @return true if the mark passes all the above checks, else false. -bool mark_check(fmark_T *fm) +bool mark_check(fmark_T *fm, const char **errormsg) { if (fm == NULL) { - emsg(_(e_umark)); + *errormsg = _(e_umark); return false; } else if (fm->mark.lnum <= 0) { // In both cases it's an error but only raise when equals to 0 if (fm->mark.lnum == 0) { - emsg(_(e_marknotset)); + *errormsg = _(e_marknotset); } return false; } // Only check for valid line number if the buffer is loaded. - if (fm->fnum == curbuf->handle && !mark_check_line_bounds(curbuf, fm)) { + if (fm->fnum == curbuf->handle && !mark_check_line_bounds(curbuf, fm, errormsg)) { return false; } return true; } /// Check if a mark line number is greater than the buffer line count, and set e_markinval. +/// /// @note Should be done after the buffer is loaded into memory. /// @param buf Buffer where the mark is set. /// @param fm Mark to check. +/// @param errormsg[out] Error message, if any. /// @return true if below line count else false. -bool mark_check_line_bounds(buf_T *buf, fmark_T *fm) +bool mark_check_line_bounds(buf_T *buf, fmark_T *fm, const char **errormsg) { if (buf != NULL && fm->mark.lnum > buf->b_ml.ml_line_count) { - emsg(_(e_markinval)); + *errormsg = _(e_markinval); return false; } return true; @@ -762,20 +759,20 @@ bool mark_check_line_bounds(buf_T *buf, fmark_T *fm) /// Used mainly when trashing the entire buffer during ":e" type commands. /// /// @param[out] buf Buffer to clear marks in. -void clrallmarks(buf_T *const buf) +void clrallmarks(buf_T *const buf, const Timestamp timestamp) FUNC_ATTR_NONNULL_ALL { for (size_t i = 0; i < NMARKS; i++) { - clear_fmark(&buf->b_namedm[i]); + clear_fmark(&buf->b_namedm[i], timestamp); } - clear_fmark(&buf->b_last_cursor); + clear_fmark(&buf->b_last_cursor, timestamp); buf->b_last_cursor.mark.lnum = 1; - clear_fmark(&buf->b_last_insert); - clear_fmark(&buf->b_last_change); + clear_fmark(&buf->b_last_insert, timestamp); + clear_fmark(&buf->b_last_change, timestamp); buf->b_op_start.lnum = 0; // start/end op mark cleared buf->b_op_end.lnum = 0; for (int i = 0; i < buf->b_changelistlen; i++) { - clear_fmark(&buf->b_changelist[i]); + clear_fmark(&buf->b_changelist[i], timestamp); } buf->b_changelistlen = 0; } @@ -795,18 +792,17 @@ char *fm_getname(fmark_T *fmark, int lead_len) /// The returned string has been allocated. static char *mark_line(pos_T *mp, int lead_len) { - char *s, *p; - int len; + char *p; if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) { return xstrdup("-invalid-"); } assert(Columns >= 0); // Allow for up to 5 bytes per character. - s = xstrnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5); + char *s = xstrnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5); // Truncate the line to fit it in the window - len = 0; + int len = 0; for (p = s; *p != NUL; MB_PTR_ADV(p)) { len += ptr2cells(p); if (len >= Columns - lead_len) { @@ -821,19 +817,18 @@ static char *mark_line(pos_T *mp, int lead_len) void ex_marks(exarg_T *eap) { char *arg = eap->arg; - int i; char *name; - pos_T *posp, *startp, *endp; + pos_T *posp; if (arg != NULL && *arg == NUL) { arg = NULL; } show_one_mark('\'', arg, &curwin->w_pcmark, NULL, true); - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { show_one_mark(i + 'a', arg, &curbuf->b_namedm[i].mark, NULL, true); } - for (i = 0; i < NGLOBALMARKS; i++) { + for (int i = 0; i < NGLOBALMARKS; i++) { if (namedfm[i].fmark.fnum != 0) { name = fm_getname(&namedfm[i].fmark, 15); } else { @@ -855,8 +850,8 @@ void ex_marks(exarg_T *eap) show_one_mark('.', arg, &curbuf->b_last_change.mark, NULL, true); // Show the marks as where they will jump to. - startp = &curbuf->b_visual.vi_start; - endp = &curbuf->b_visual.vi_end; + pos_T *startp = &curbuf->b_visual.vi_start; + pos_T *endp = &curbuf->b_visual.vi_end; if ((lt(*startp, *endp) || endp->lnum == 0) && startp->lnum != 0) { posp = startp; } else { @@ -880,7 +875,7 @@ static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int curren did_title = false; } else { if (arg == NULL) { - msg(_("No marks set")); + msg(_("No marks set"), 0); } else { semsg(_("E283: No marks matching \"%s\""), arg); } @@ -902,9 +897,9 @@ static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int curren msg_putchar('\n'); if (!got_int) { snprintf(IObuff, IOSIZE, " %c %6" PRIdLINENR " %4d ", c, p->lnum, p->col); - msg_outtrans(IObuff); + msg_outtrans(IObuff, 0); if (name != NULL) { - msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0); + msg_outtrans(name, current ? HL_ATTR(HLF_D) : 0); } } } @@ -917,33 +912,30 @@ static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int curren // ":delmarks[!] [marks]" void ex_delmarks(exarg_T *eap) { - char *p; int from, to; - int i; - int lower; - int digit; int n; if (*eap->arg == NUL && eap->forceit) { // clear all marks - clrallmarks(curbuf); + clrallmarks(curbuf, os_time()); } else if (eap->forceit) { emsg(_(e_invarg)); } else if (*eap->arg == NUL) { emsg(_(e_argreq)); } else { // clear specified marks only - for (p = eap->arg; *p != NUL; p++) { - lower = ASCII_ISLOWER(*p); - digit = ascii_isdigit(*p); + const Timestamp timestamp = os_time(); + for (char *p = eap->arg; *p != NUL; p++) { + int lower = ASCII_ISLOWER(*p); + int digit = ascii_isdigit(*p); if (lower || digit || ASCII_ISUPPER(*p)) { if (p[1] == '-') { // clear range of marks from = (uint8_t)(*p); to = (uint8_t)p[2]; if (!(lower ? ASCII_ISLOWER(p[2]) - : (digit ? ascii_isdigit(p[2]) - : ASCII_ISUPPER(p[2]))) + : (digit ? ascii_isdigit(p[2]) + : ASCII_ISUPPER(p[2]))) || to < from) { semsg(_(e_invarg2), p); return; @@ -954,9 +946,10 @@ void ex_delmarks(exarg_T *eap) from = to = (uint8_t)(*p); } - for (i = from; i <= to; i++) { + for (int i = from; i <= to; i++) { if (lower) { curbuf->b_namedm[i - 'a'].mark.lnum = 0; + curbuf->b_namedm[i - 'a'].timestamp = timestamp; } else { if (digit) { n = i - '0' + NMARKS; @@ -965,25 +958,29 @@ void ex_delmarks(exarg_T *eap) } namedfm[n].fmark.mark.lnum = 0; namedfm[n].fmark.fnum = 0; + namedfm[n].fmark.timestamp = timestamp; XFREE_CLEAR(namedfm[n].fname); } } } else { switch (*p) { case '"': - CLEAR_FMARK(&curbuf->b_last_cursor); break; + clear_fmark(&curbuf->b_last_cursor, timestamp); + break; case '^': - CLEAR_FMARK(&curbuf->b_last_insert); break; + clear_fmark(&curbuf->b_last_insert, timestamp); + break; case '.': - CLEAR_FMARK(&curbuf->b_last_change); break; + clear_fmark(&curbuf->b_last_change, timestamp); + break; case '[': - curbuf->b_op_start.lnum = 0; break; + curbuf->b_op_start.lnum = 0; break; case ']': - curbuf->b_op_end.lnum = 0; break; + curbuf->b_op_end.lnum = 0; break; case '<': curbuf->b_visual.vi_start.lnum = 0; break; case '>': - curbuf->b_visual.vi_end.lnum = 0; break; + curbuf->b_visual.vi_end.lnum = 0; break; case ' ': break; default: @@ -998,15 +995,12 @@ void ex_delmarks(exarg_T *eap) // print the jumplist void ex_jumps(exarg_T *eap) { - int i; - char *name; - cleanup_jumplist(curwin, true); // Highlight title msg_puts_title(_("\n jump line col file/text")); - for (i = 0; i < curwin->w_jumplistlen && !got_int; i++) { + for (int i = 0; i < curwin->w_jumplistlen && !got_int; i++) { if (curwin->w_jumplist[i].fmark.mark.lnum != 0) { - name = fm_getname(&curwin->w_jumplist[i].fmark, 16); + char *name = fm_getname(&curwin->w_jumplist[i].fmark, 16); // Make sure to output the current indicator, even when on an wiped // out buffer. ":filter" may still skip it. @@ -1028,10 +1022,9 @@ void ex_jumps(exarg_T *eap) i == curwin->w_jumplistidx ? '>' : ' ', i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx : curwin->w_jumplistidx - i, curwin->w_jumplist[i].fmark.mark.lnum, curwin->w_jumplist[i].fmark.mark.col); - msg_outtrans(IObuff); - msg_outtrans_attr(name, - curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum - ? HL_ATTR(HLF_D) : 0); + msg_outtrans(IObuff, 0); + msg_outtrans(name, + curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum ? HL_ATTR(HLF_D) : 0); xfree(name); os_breakcheck(); } @@ -1051,26 +1044,24 @@ void ex_clearjumps(exarg_T *eap) // print the changelist void ex_changes(exarg_T *eap) { - int i; - char *name; - // Highlight title msg_puts_title(_("\nchange line col text")); - for (i = 0; i < curbuf->b_changelistlen && !got_int; i++) { + for (int i = 0; i < curbuf->b_changelistlen && !got_int; i++) { if (curbuf->b_changelist[i].mark.lnum != 0) { msg_putchar('\n'); if (got_int) { break; } - snprintf(IObuff, IOSIZE, "%c %3d %5ld %4d ", + snprintf(IObuff, IOSIZE, "%c %3d %5" PRIdLINENR " %4d ", i == curwin->w_changelistidx ? '>' : ' ', - i > curwin->w_changelistidx ? i - curwin->w_changelistidx : curwin->w_changelistidx - i, - (long)curbuf->b_changelist[i].mark.lnum, + i > + curwin->w_changelistidx ? i - curwin->w_changelistidx : curwin->w_changelistidx - i, + curbuf->b_changelist[i].mark.lnum, curbuf->b_changelist[i].mark.col); - msg_outtrans(IObuff); - name = mark_line(&curbuf->b_changelist[i].mark, 17); - msg_outtrans_attr(name, HL_ATTR(HLF_D)); + msg_outtrans(IObuff, 0); + char *name = mark_line(&curbuf->b_changelist[i].mark, 17); + msg_outtrans(name, HL_ATTR(HLF_D)); xfree(name); os_breakcheck(); } @@ -1109,19 +1100,19 @@ void ex_changes(exarg_T *eap) } \ } -// Adjust marks between line1 and line2 (inclusive) to move 'amount' lines. +// Adjust marks between "line1" and "line2" (inclusive) to move "amount" lines. // Must be called before changed_*(), appended_lines() or deleted_lines(). // May be called before or after changing the text. -// When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks -// within this range are made invalid. -// If 'amount_after' is non-zero adjust marks after line2. +// When deleting lines "line1" to "line2", use an "amount" of MAXLNUM: The +// marks within this range are made invalid. +// If "amount_after" is non-zero adjust marks after "line2". // Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2); // Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0); // or: mark_adjust(56, 55, MAXLNUM, 2); void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after, ExtmarkOp op) { - mark_adjust_internal(line1, line2, amount, amount_after, true, op); + mark_adjust_buf(curbuf, line1, line2, amount, amount_after, true, false, op); } // mark_adjust_nofold() does the same as mark_adjust() but without adjusting @@ -1132,84 +1123,83 @@ void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amoun void mark_adjust_nofold(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after, ExtmarkOp op) { - mark_adjust_internal(line1, line2, amount, amount_after, false, op); + mark_adjust_buf(curbuf, line1, line2, amount, amount_after, false, false, op); } -static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount, - linenr_T amount_after, bool adjust_folds, ExtmarkOp op) +void mark_adjust_buf(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount, + linenr_T amount_after, bool adjust_folds, bool by_api, ExtmarkOp op) { - int i; - int fnum = curbuf->b_fnum; + int fnum = buf->b_fnum; linenr_T *lp; static pos_T initpos = { 1, 0, 0 }; - if (line2 < line1 && amount_after == 0L) { // nothing to do + if (line2 < line1 && amount_after == 0) { // nothing to do return; } if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // named marks, lower case and upper case - for (i = 0; i < NMARKS; i++) { - ONE_ADJUST(&(curbuf->b_namedm[i].mark.lnum)); + for (int i = 0; i < NMARKS; i++) { + ONE_ADJUST(&(buf->b_namedm[i].mark.lnum)); if (namedfm[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum)); } } - for (i = NMARKS; i < NGLOBALMARKS; i++) { + for (int i = NMARKS; i < NGLOBALMARKS; i++) { if (namedfm[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum)); } } // last Insert position - ONE_ADJUST(&(curbuf->b_last_insert.mark.lnum)); + ONE_ADJUST(&(buf->b_last_insert.mark.lnum)); // last change position - ONE_ADJUST(&(curbuf->b_last_change.mark.lnum)); + ONE_ADJUST(&(buf->b_last_change.mark.lnum)); // last cursor position, if it was set - if (!equalpos(curbuf->b_last_cursor.mark, initpos)) { - ONE_ADJUST(&(curbuf->b_last_cursor.mark.lnum)); + if (!equalpos(buf->b_last_cursor.mark, initpos)) { + ONE_ADJUST(&(buf->b_last_cursor.mark.lnum)); } // list of change positions - for (i = 0; i < curbuf->b_changelistlen; i++) { - ONE_ADJUST_NODEL(&(curbuf->b_changelist[i].mark.lnum)); + for (int i = 0; i < buf->b_changelistlen; i++) { + ONE_ADJUST_NODEL(&(buf->b_changelist[i].mark.lnum)); } // Visual area - ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_start.lnum)); - ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_end.lnum)); + ONE_ADJUST_NODEL(&(buf->b_visual.vi_start.lnum)); + ONE_ADJUST_NODEL(&(buf->b_visual.vi_end.lnum)); // quickfix marks - if (!qf_mark_adjust(NULL, line1, line2, amount, amount_after)) { - curbuf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY; + if (!qf_mark_adjust(buf, NULL, line1, line2, amount, amount_after)) { + buf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY; } // location lists bool found_one = false; FOR_ALL_TAB_WINDOWS(tab, win) { - found_one |= qf_mark_adjust(win, line1, line2, amount, amount_after); + found_one |= qf_mark_adjust(buf, win, line1, line2, amount, amount_after); } if (!found_one) { - curbuf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY; + buf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY; } - - sign_mark_adjust(line1, line2, amount, amount_after); } if (op != kExtmarkNOOP) { - extmark_adjust(curbuf, line1, line2, amount, amount_after, op); + extmark_adjust(buf, line1, line2, amount, amount_after, op); } - // previous context mark - ONE_ADJUST(&(curwin->w_pcmark.lnum)); + if (curwin->w_buffer == buf) { + // previous context mark + ONE_ADJUST(&(curwin->w_pcmark.lnum)); - // previous pcmark - ONE_ADJUST(&(curwin->w_prev_pcmark.lnum)); + // previous pcpmark + ONE_ADJUST(&(curwin->w_prev_pcmark.lnum)); - // saved cursor for formatting - if (saved_cursor.lnum != 0) { - ONE_ADJUST_NODEL(&(saved_cursor.lnum)); + // saved cursor for formatting + if (saved_cursor.lnum != 0) { + ONE_ADJUST_NODEL(&(saved_cursor.lnum)); + } } // Adjust items in all windows related to the current buffer. @@ -1217,17 +1207,17 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // Marks in the jumplist. When deleting lines, this may create // duplicate marks in the jumplist, they will be removed later. - for (i = 0; i < win->w_jumplistlen; i++) { + for (int i = 0; i < win->w_jumplistlen; i++) { if (win->w_jumplist[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(win->w_jumplist[i].fmark.mark.lnum)); } } } - if (win->w_buffer == curbuf) { + if (win->w_buffer == buf) { if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // marks in the tag stack - for (i = 0; i < win->w_tagstacklen; i++) { + for (int i = 0; i < win->w_tagstacklen; i++) { if (win->w_tagstack[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(win->w_tagstack[i].fmark.mark.lnum)); } @@ -1242,22 +1232,29 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount // topline and cursor position for windows with the same buffer // other than the current window - if (win != curwin) { + if (win != curwin || by_api) { if (win->w_topline >= line1 && win->w_topline <= line2) { if (amount == MAXLNUM) { // topline is deleted if (line1 <= 1) { win->w_topline = 1; } else { - win->w_topline = line1 - 1; + // api: if the deleted region was replaced with new contents, display that + win->w_topline = (by_api && amount_after > line1 - line2 - 1) ? line1 : line1 - 1; } - } else { // keep topline on the same line + } else if (win->w_topline > line1) { + // keep topline on the same line, unless inserting just + // above it (we probably want to see that line then) win->w_topline += amount; } win->w_topfill = 0; - } else if (amount_after && win->w_topline > line2) { + // api: display new line if inserted right at topline + // TODO(bfredl): maybe always? + } else if (amount_after && win->w_topline > line2 + (by_api ? 1 : 0)) { win->w_topline += amount_after; win->w_topfill = 0; } + } + if (win != curwin && !by_api) { if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) { if (amount == MAXLNUM) { // line with cursor is deleted if (line1 <= 1) { @@ -1281,7 +1278,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount } // adjust diffs - diff_mark_adjust(line1, line2, amount, amount_after); + diff_mark_adjust(buf, line1, line2, amount, amount_after); } // This code is used often, needs to be fast. @@ -1306,24 +1303,23 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount // position. // "spaces_removed" is the number of spaces that were removed, matters when the // cursor is inside them. -void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long col_amount, +void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, colnr_T col_amount, int spaces_removed) { - int i; int fnum = curbuf->b_fnum; pos_T *posp; - if ((col_amount == 0L && lnum_amount == 0L) || (cmdmod.cmod_flags & CMOD_LOCKMARKS)) { + if ((col_amount == 0 && lnum_amount == 0) || (cmdmod.cmod_flags & CMOD_LOCKMARKS)) { return; // nothing to do } // named marks, lower case and upper case - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { COL_ADJUST(&(curbuf->b_namedm[i].mark)); if (namedfm[i].fmark.fnum == fnum) { COL_ADJUST(&(namedfm[i].fmark.mark)); } } - for (i = NMARKS; i < NGLOBALMARKS; i++) { + for (int i = NMARKS; i < NGLOBALMARKS; i++) { if (namedfm[i].fmark.fnum == fnum) { COL_ADJUST(&(namedfm[i].fmark.mark)); } @@ -1336,7 +1332,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c COL_ADJUST(&(curbuf->b_last_change.mark)); // list of change positions - for (i = 0; i < curbuf->b_changelistlen; i++) { + for (int i = 0; i < curbuf->b_changelistlen; i++) { COL_ADJUST(&(curbuf->b_changelist[i].mark)); } @@ -1356,7 +1352,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c // Adjust items in all windows related to the current buffer. FOR_ALL_WINDOWS_IN_TAB(win, curtab) { // marks in the jumplist - for (i = 0; i < win->w_jumplistlen; i++) { + for (int i = 0; i < win->w_jumplistlen; i++) { if (win->w_jumplist[i].fmark.fnum == fnum) { COL_ADJUST(&(win->w_jumplist[i].fmark.mark)); } @@ -1364,7 +1360,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c if (win->w_buffer == curbuf) { // marks in the tag stack - for (i = 0; i < win->w_tagstacklen; i++) { + for (int i = 0; i < win->w_tagstacklen; i++) { if (win->w_tagstack[i].fmark.fnum == fnum) { COL_ADJUST(&(win->w_tagstack[i].fmark.mark)); } @@ -1457,9 +1453,7 @@ void cleanup_jumplist(win_T *wp, bool loadfiles) // Copy the jumplist from window "from" to window "to". void copy_jumplist(win_T *from, win_T *to) { - int i; - - for (i = 0; i < from->w_jumplistlen; i++) { + for (int i = 0; i < from->w_jumplistlen; i++) { to->w_jumplist[i] = from->w_jumplist[i]; if (from->w_jumplist[i].fname != NULL) { to->w_jumplist[i].fname = xstrdup(from->w_jumplist[i].fname); @@ -1523,9 +1517,9 @@ const void *mark_global_iter(const void *const iter, char *const name, xfmark_T return NULL; } size_t iter_off = (size_t)(iter_mark - &(namedfm[0])); - *name = (char)(iter_off < NMARKS ? - 'A' + (char)iter_off : - '0' + (char)(iter_off - NMARKS)); + *name = (char)(iter_off < NMARKS + ? 'A' + (char)iter_off + : '0' + (char)(iter_off - NMARKS)); *fm = *iter_mark; while ((size_t)(++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) { if (iter_mark->fmark.mark.lnum) { @@ -1587,11 +1581,15 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, cha FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT { *name = NUL; - char mark_name = (char)(iter == NULL ? NUL : - iter == &(buf->b_last_cursor) ? '"' : - iter == &(buf->b_last_insert) ? '^' : - iter == &(buf->b_last_change) ? '.' : - 'a' + (char)((const fmark_T *)iter - &(buf->b_namedm[0]))); + char mark_name = (char)(iter == NULL + ? NUL + : (iter == &(buf->b_last_cursor) + ? '"' + : (iter == &(buf->b_last_insert) + ? '^' + : (iter == &(buf->b_last_change) + ? '.' + : 'a' + (const fmark_T *)iter - &(buf->b_namedm[0]))))); const fmark_T *iter_mark = next_buffer_mark(buf, &mark_name); while (iter_mark != NULL && iter_mark->mark.lnum == 0) { iter_mark = next_buffer_mark(buf, &mark_name); @@ -1671,9 +1669,7 @@ bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const b // Free items in the jumplist of window "wp". void free_jumplist(win_T *wp) { - int i; - - for (i = 0; i < wp->w_jumplistlen; i++) { + for (int i = 0; i < wp->w_jumplistlen; i++) { free_xfmark(wp->w_jumplist[i]); } wp->w_jumplistlen = 0; @@ -1710,7 +1706,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp) FUNC_ATTR_NONNULL_ALL { if (lp->col > 0 || lp->coladd > 1) { - const char *const p = ml_get_buf(buf, lp->lnum, false); + const char *const p = ml_get_buf(buf, lp->lnum); if (*p == NUL || (int)strlen(p) < lp->col) { lp->col = 0; } else { |