diff options
Diffstat (limited to 'src/nvim/mark.c')
| -rw-r--r-- | src/nvim/mark.c | 103 |
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; } /* |