aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mark.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r--src/nvim/mark.c103
1 files changed, 67 insertions, 36 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 602648c27c..5c9367ab01 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -214,7 +214,7 @@ pos_T *movemark(int count)
pos_T *pos;
xfmark_T *jmp;
- cleanup_jumplist();
+ cleanup_jumplist(curwin, true);
if (curwin->w_jumplistlen == 0) /* nothing to jump to */
return (pos_T *)NULL;
@@ -781,13 +781,11 @@ void ex_jumps(exarg_T *eap)
int i;
char_u *name;
- cleanup_jumplist();
- /* Highlight title */
+ 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) {
if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
- if (curwin->w_jumplist[i].fmark.fnum == 0)
- fname2fnum(&curwin->w_jumplist[i]);
name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
if (name == NULL) /* file name not available */
continue;
@@ -1069,19 +1067,24 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
{ \
posp->lnum += lnum_amount; \
assert(col_amount > INT_MIN && col_amount <= INT_MAX); \
- if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) \
+ if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) { \
posp->col = 0; \
- else \
+ } else if (posp->col < spaces_removed) { \
+ posp->col = (int)col_amount + spaces_removed; \
+ } else { \
posp->col += (colnr_T)col_amount; \
+ } \
} \
}
-/*
- * Adjust marks in line "lnum" at column "mincol" and further: add
- * "lnum_amount" to the line number and add "col_amount" to the column
- * position.
- */
-void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount)
+// Adjust marks in line "lnum" at column "mincol" and further: add
+// "lnum_amount" to the line number and add "col_amount" to the column
+// 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, long lnum_amount, long col_amount,
+ int spaces_removed)
{
int i;
int fnum = curbuf->b_fnum;
@@ -1151,41 +1154,69 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_a
}
}
-/*
- * When deleting lines, this may create duplicate marks in the
- * jumplist. They will be removed here for the current window.
- */
-void cleanup_jumplist(void)
+// When deleting lines, this may create duplicate marks in the
+// jumplist. They will be removed here for the specified window.
+// When "loadfiles" is true first ensure entries have the "fnum" field set
+// (this may be a bit slow).
+void cleanup_jumplist(win_T *wp, bool loadfiles)
{
int i;
- int from, to;
- to = 0;
- for (from = 0; from < curwin->w_jumplistlen; ++from) {
- if (curwin->w_jumplistidx == from)
- curwin->w_jumplistidx = to;
- for (i = from + 1; i < curwin->w_jumplistlen; ++i)
- if (curwin->w_jumplist[i].fmark.fnum
- == curwin->w_jumplist[from].fmark.fnum
- && curwin->w_jumplist[from].fmark.fnum != 0
- && curwin->w_jumplist[i].fmark.mark.lnum
- == curwin->w_jumplist[from].fmark.mark.lnum)
+ if (loadfiles) {
+ // If specified, load all the files from the jump list. This is
+ // needed to properly clean up duplicate entries, but will take some
+ // time.
+ for (i = 0; i < wp->w_jumplistlen; i++) {
+ if ((wp->w_jumplist[i].fmark.fnum == 0)
+ && (wp->w_jumplist[i].fmark.mark.lnum != 0)) {
+ fname2fnum(&wp->w_jumplist[i]);
+ }
+ }
+ }
+
+ int to = 0;
+ for (int from = 0; from < wp->w_jumplistlen; from++) {
+ if (wp->w_jumplistidx == from) {
+ wp->w_jumplistidx = to;
+ }
+ for (i = from + 1; i < wp->w_jumplistlen; i++) {
+ if (wp->w_jumplist[i].fmark.fnum
+ == wp->w_jumplist[from].fmark.fnum
+ && wp->w_jumplist[from].fmark.fnum != 0
+ && wp->w_jumplist[i].fmark.mark.lnum
+ == wp->w_jumplist[from].fmark.mark.lnum) {
break;
- if (i >= curwin->w_jumplistlen) { // no duplicate
+ }
+ }
+ if (i >= wp->w_jumplistlen) { // no duplicate
if (to != from) {
- // Not using curwin->w_jumplist[to++] = curwin->w_jumplist[from] because
+ // Not using wp->w_jumplist[to++] = wp->w_jumplist[from] because
// this way valgrind complains about overlapping source and destination
// in memcpy() call. (clang-3.6.0, debug build with -DEXITFREE).
- curwin->w_jumplist[to] = curwin->w_jumplist[from];
+ wp->w_jumplist[to] = wp->w_jumplist[from];
}
to++;
} else {
- xfree(curwin->w_jumplist[from].fname);
+ xfree(wp->w_jumplist[from].fname);
+ }
+ }
+ if (wp->w_jumplistidx == wp->w_jumplistlen) {
+ wp->w_jumplistidx = to;
+ }
+ wp->w_jumplistlen = to;
+
+ // When pointer is below last jump, remove the jump if it matches the current
+ // line. This avoids useless/phantom jumps. #9805
+ if (wp->w_jumplistlen
+ && wp->w_jumplistidx == wp->w_jumplistlen) {
+ const xfmark_T *fm_last = &wp->w_jumplist[wp->w_jumplistlen - 1];
+ if (fm_last->fmark.fnum == curbuf->b_fnum
+ && fm_last->fmark.mark.lnum == wp->w_cursor.lnum) {
+ xfree(fm_last->fname);
+ wp->w_jumplistlen--;
+ wp->w_jumplistidx--;
}
}
- if (curwin->w_jumplistidx == curwin->w_jumplistlen)
- curwin->w_jumplistidx = to;
- curwin->w_jumplistlen = to;
}
/*