mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.0.1498: getjumplist() returns duplicate entries
Problem: Getjumplist() returns duplicate entries. (lacygoill)
Solution: Call cleanup_jumplist(). (Yegappan Lakshmanan)
a7e18d237f
This commit is contained in:
parent
41828a7302
commit
d6d9596b38
@ -10055,7 +10055,7 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
{
|
{
|
||||||
tv_list_alloc_ret(rettv, kListLenMayKnow);
|
tv_list_alloc_ret(rettv, kListLenMayKnow);
|
||||||
const win_T *const wp = find_tabwin(&argvars[0], &argvars[1]);
|
win_T *const wp = find_tabwin(&argvars[0], &argvars[1]);
|
||||||
if (wp == NULL) {
|
if (wp == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -10064,14 +10064,21 @@ static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
tv_list_append_list(rettv->vval.v_list, l);
|
tv_list_append_list(rettv->vval.v_list, l);
|
||||||
tv_list_append_number(rettv->vval.v_list, wp->w_jumplistidx);
|
tv_list_append_number(rettv->vval.v_list, wp->w_jumplistidx);
|
||||||
|
|
||||||
|
cleanup_jumplist(wp);
|
||||||
for (int i = 0; i < wp->w_jumplistlen; i++) {
|
for (int i = 0; i < wp->w_jumplistlen; i++) {
|
||||||
|
if (wp->w_jumplist[i].fmark.mark.lnum == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (wp->w_jumplist[i].fmark.fnum == 0) {
|
||||||
|
fname2fnum(&wp->w_jumplist[i]);
|
||||||
|
}
|
||||||
dict_T *const d = tv_dict_alloc();
|
dict_T *const d = tv_dict_alloc();
|
||||||
tv_list_append_dict(l, d);
|
tv_list_append_dict(l, d);
|
||||||
tv_dict_add_nr(d, S_LEN("lnum"), wp->w_jumplist[i].fmark.mark.lnum);
|
tv_dict_add_nr(d, S_LEN("lnum"), wp->w_jumplist[i].fmark.mark.lnum);
|
||||||
tv_dict_add_nr(d, S_LEN("col"), wp->w_jumplist[i].fmark.mark.col);
|
tv_dict_add_nr(d, S_LEN("col"), wp->w_jumplist[i].fmark.mark.col);
|
||||||
tv_dict_add_nr(d, S_LEN("coladd"), wp->w_jumplist[i].fmark.mark.coladd);
|
tv_dict_add_nr(d, S_LEN("coladd"), wp->w_jumplist[i].fmark.mark.coladd);
|
||||||
tv_dict_add_nr(d, S_LEN("bufnr"), wp->w_jumplist[i].fmark.fnum);
|
tv_dict_add_nr(d, S_LEN("bufnr"), wp->w_jumplist[i].fmark.fnum);
|
||||||
if (wp->w_jumplist[i].fmark.fnum == 0) {
|
if (wp->w_jumplist[i].fname != NULL) {
|
||||||
tv_dict_add_str(d, S_LEN("filename"), (char *)wp->w_jumplist[i].fname);
|
tv_dict_add_str(d, S_LEN("filename"), (char *)wp->w_jumplist[i].fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ pos_T *movemark(int count)
|
|||||||
pos_T *pos;
|
pos_T *pos;
|
||||||
xfmark_T *jmp;
|
xfmark_T *jmp;
|
||||||
|
|
||||||
cleanup_jumplist();
|
cleanup_jumplist(curwin);
|
||||||
|
|
||||||
if (curwin->w_jumplistlen == 0) /* nothing to jump to */
|
if (curwin->w_jumplistlen == 0) /* nothing to jump to */
|
||||||
return (pos_T *)NULL;
|
return (pos_T *)NULL;
|
||||||
@ -463,7 +463,7 @@ getnextmark (
|
|||||||
* This is used for marks obtained from the .shada file. It's postponed
|
* This is used for marks obtained from the .shada file. It's postponed
|
||||||
* until the mark is used to avoid a long startup delay.
|
* until the mark is used to avoid a long startup delay.
|
||||||
*/
|
*/
|
||||||
static void fname2fnum(xfmark_T *fm)
|
void fname2fnum(xfmark_T *fm)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
|
||||||
@ -781,7 +781,7 @@ void ex_jumps(exarg_T *eap)
|
|||||||
int i;
|
int i;
|
||||||
char_u *name;
|
char_u *name;
|
||||||
|
|
||||||
cleanup_jumplist();
|
cleanup_jumplist(curwin);
|
||||||
/* Highlight title */
|
/* Highlight title */
|
||||||
MSG_PUTS_TITLE(_("\n jump line col file/text"));
|
MSG_PUTS_TITLE(_("\n jump line col file/text"));
|
||||||
for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i) {
|
for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i) {
|
||||||
@ -1156,53 +1156,51 @@ void mark_col_adjust(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When deleting lines, this may create duplicate marks in the
|
||||||
* When deleting lines, this may create duplicate marks in the
|
// jumplist. They will be removed here for the specified window.
|
||||||
* jumplist. They will be removed here for the current window.
|
void cleanup_jumplist(win_T *wp)
|
||||||
*/
|
|
||||||
void cleanup_jumplist(void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int from, to;
|
int from, to;
|
||||||
|
|
||||||
to = 0;
|
to = 0;
|
||||||
for (from = 0; from < curwin->w_jumplistlen; ++from) {
|
for (from = 0; from < wp->w_jumplistlen; ++from) {
|
||||||
if (curwin->w_jumplistidx == from)
|
if (wp->w_jumplistidx == from)
|
||||||
curwin->w_jumplistidx = to;
|
wp->w_jumplistidx = to;
|
||||||
for (i = from + 1; i < curwin->w_jumplistlen; ++i)
|
for (i = from + 1; i < wp->w_jumplistlen; ++i)
|
||||||
if (curwin->w_jumplist[i].fmark.fnum
|
if (wp->w_jumplist[i].fmark.fnum
|
||||||
== curwin->w_jumplist[from].fmark.fnum
|
== wp->w_jumplist[from].fmark.fnum
|
||||||
&& curwin->w_jumplist[from].fmark.fnum != 0
|
&& wp->w_jumplist[from].fmark.fnum != 0
|
||||||
&& curwin->w_jumplist[i].fmark.mark.lnum
|
&& wp->w_jumplist[i].fmark.mark.lnum
|
||||||
== curwin->w_jumplist[from].fmark.mark.lnum)
|
== wp->w_jumplist[from].fmark.mark.lnum)
|
||||||
break;
|
break;
|
||||||
if (i >= curwin->w_jumplistlen) { // no duplicate
|
if (i >= wp->w_jumplistlen) { // no duplicate
|
||||||
if (to != from) {
|
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
|
// this way valgrind complains about overlapping source and destination
|
||||||
// in memcpy() call. (clang-3.6.0, debug build with -DEXITFREE).
|
// 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++;
|
to++;
|
||||||
} else {
|
} else {
|
||||||
xfree(curwin->w_jumplist[from].fname);
|
xfree(wp->w_jumplist[from].fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
|
if (wp->w_jumplistidx == wp->w_jumplistlen) {
|
||||||
curwin->w_jumplistidx = to;
|
wp->w_jumplistidx = to;
|
||||||
}
|
}
|
||||||
curwin->w_jumplistlen = to;
|
wp->w_jumplistlen = to;
|
||||||
|
|
||||||
// When pointer is below last jump, remove the jump if it matches the current
|
// When pointer is below last jump, remove the jump if it matches the current
|
||||||
// line. This avoids useless/phantom jumps. #9805
|
// line. This avoids useless/phantom jumps. #9805
|
||||||
if (curwin->w_jumplistlen
|
if (wp->w_jumplistlen
|
||||||
&& curwin->w_jumplistidx == curwin->w_jumplistlen) {
|
&& wp->w_jumplistidx == wp->w_jumplistlen) {
|
||||||
const xfmark_T *fm_last = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
|
const xfmark_T *fm_last = &wp->w_jumplist[wp->w_jumplistlen - 1];
|
||||||
if (fm_last->fmark.fnum == curbuf->b_fnum
|
if (fm_last->fmark.fnum == curbuf->b_fnum
|
||||||
&& fm_last->fmark.mark.lnum == curwin->w_cursor.lnum) {
|
&& fm_last->fmark.mark.lnum == wp->w_cursor.lnum) {
|
||||||
xfree(fm_last->fname);
|
xfree(fm_last->fname);
|
||||||
curwin->w_jumplistlen--;
|
wp->w_jumplistlen--;
|
||||||
curwin->w_jumplistidx--;
|
wp->w_jumplistidx--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2739,7 +2739,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||||||
|
|
||||||
// Initialize jump list
|
// Initialize jump list
|
||||||
const void *jump_iter = NULL;
|
const void *jump_iter = NULL;
|
||||||
cleanup_jumplist();
|
cleanup_jumplist(curwin);
|
||||||
setpcmark();
|
setpcmark();
|
||||||
do {
|
do {
|
||||||
xfmark_T fm;
|
xfmark_T fm;
|
||||||
|
@ -29,7 +29,6 @@ func Test_getjumplist()
|
|||||||
normal gg
|
normal gg
|
||||||
|
|
||||||
call assert_equal([[
|
call assert_equal([[
|
||||||
\ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
|
||||||
\ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
\ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
||||||
\ {'lnum': 50, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
\ {'lnum': 50, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
||||||
\ {'lnum': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 4],
|
\ {'lnum': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 4],
|
||||||
@ -48,17 +47,16 @@ func Test_getjumplist()
|
|||||||
call assert_equal([[
|
call assert_equal([[
|
||||||
\ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
\ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
||||||
\ {'lnum': 50, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
\ {'lnum': 50, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
||||||
\ {'lnum': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
|
||||||
\ {'lnum': 5, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
\ {'lnum': 5, 'bufnr': bnr, 'col': 0, 'coladd': 0},
|
||||||
\ {'lnum': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 5],
|
\ {'lnum': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 5],
|
||||||
\ getjumplist())
|
\ getjumplist())
|
||||||
|
|
||||||
let l = getjumplist()
|
let l = getjumplist()
|
||||||
call test_garbagecollect_now()
|
call test_garbagecollect_now()
|
||||||
call assert_equal(5, l[1])
|
call assert_equal(4, l[1])
|
||||||
clearjumps
|
clearjumps
|
||||||
call test_garbagecollect_now()
|
call test_garbagecollect_now()
|
||||||
call assert_equal(5, l[1])
|
call assert_equal(4, l[1])
|
||||||
|
|
||||||
call delete("Xtest")
|
call delete("Xtest")
|
||||||
endfunc
|
endfunc
|
||||||
|
Loading…
Reference in New Issue
Block a user