Hi,

On Sat, Feb 10, 2018 at 3:38 PM, lacygoill <[email protected]> wrote:
>
> Consider this snippet whose purpose is to populate the location list of the
> current window with the locations in the jumplist:
>
> nno  <silent>  g:j  :<c-u>call <sid>qf_jumplist()<cr>
> fu! s:qf_jumplist() abort
>     let jumplist = get(getjumplist(), 0, [])
>     call setloclist(0, jumplist)
>     lopen
> endfu
>
> If I press the keys g:j of the mapping, it raises the following error:
>
> Error detected while processing function <SNR>173_qf_jumplist:
> line    2:
> E92: Buffer 1 not found
>
> I need to filter the output getjumplist() to remove any location matching a
> buffer which doesn't exist:
>
> nno  <silent>  g:j  :<c-u>call <sid>qf_jumplist()<cr>
> fu! s:qf_jumplist() abort
>     let jumplist = get(getjumplist(), 0, [])
>     call filter(jumplist, {i,v -> bufexists(v.bufnr)})
>     call setloclist(0, jumplist)
>     lopen
> endfu
>
> But even then, the length of the location list is much bigger than the one
> of the jumplist displayed by :jumps. So, I need to silently execute :jumps
> before invoking getjumplist() to get the same result:
>
> nno  <silent>  g:j  :<c-u>call <sid>qf_jumplist()<cr>
> fu! s:qf_jumplist() abort
>     sil jumps
>     let jumplist = get(getjumplist(), 0, [])
>     call filter(jumplist, {i,v -> bufexists(v.bufnr)})
>     call setloclist(0, jumplist)
>     call setloclist(0, [], 'a', { 'title': ':jumps'})
>     lopen
> endfu
>
> It seems that initially, without you having executed a :jumps command to
> display the jumplist nor pressing C-o and C-i, getjumplist() includes in the
> list one or several identical locations matching (bufnr, lnum, col) = (1, 0,
> 0); as many as needed to get a list whose size is 100, no matter the current
> size of the jumplist.
> Usually this location doesn't exist on my machine, because when I start Vim,
> it automatically restores a saved session from an unnamed buffer 1, and the
> latter is probably wiped in the process.
> Which is why I need to invoke filter() in the previous snippet to check
> whether every buffer currently exists.
>
> I don't think this location should be present, because I can't find it in
> the output of :jumps.
> If it was there, I think I should find something like this:
>
> jump line  col file/text
> x     1    0
> ^              ^
> some number    no filename/no text, because buffer 1 was an unnamed/empty
> buffer
>
> Besides, initially some (all?) entries are present several times in the
> output of getjumplist(), which explains why the location list is bigger than
> the jumplist, even after removing locations matching non-existing buffers.
>
> Shouldn't getjumplist() return the same locations as :jumps, regardless of
> whether the latter has been invoked, or whether we've already moved in the
> jumplist?
>

Thanks for reporting the problem. Can you try the attached patch?

Thanks,
Yegappan

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index da870c67b..1940cac99 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -4871,8 +4871,11 @@ f_getjumplist(typval_T *argvars, typval_T *rettv)
        return;
     list_append_number(rettv->vval.v_list, (varnumber_T)wp->w_jumplistidx);
 
+    cleanup_jumplist(wp);
     for (i = 0; i < wp->w_jumplistlen; ++i)
     {
+       if (curwin->w_jumplist[i].fmark.mark.lnum == 0)
+           continue;
        if ((d = dict_alloc()) == NULL)
            return;
        if (list_append_dict(l, d) == FAIL)
diff --git a/src/mark.c b/src/mark.c
index 1acdd12d6..c97ec7f30 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -31,9 +31,6 @@ static void fname2fnum(xfmark_T *fm);
 static void fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf);
 static char_u *mark_line(pos_T *mp, int lead_len);
 static void show_one_mark(int, char_u *, pos_T *, char_u *, int current);
-#ifdef FEAT_JUMPLIST
-static void cleanup_jumplist(void);
-#endif
 #ifdef FEAT_VIMINFO
 static void write_one_filemark(FILE *fp, xfmark_T *fm, int c1, int c2);
 #endif
@@ -225,7 +222,7 @@ movemark(int count)
     pos_T      *pos;
     xfmark_T   *jmp;
 
-    cleanup_jumplist();
+    cleanup_jumplist(curwin);
 
     if (curwin->w_jumplistlen == 0)        /* nothing to jump to */
        return (pos_T *)NULL;
@@ -895,7 +892,7 @@ ex_jumps(exarg_T *eap UNUSED)
     int                i;
     char_u     *name;
 
-    cleanup_jumplist();
+    cleanup_jumplist(curwin);
     /* Highlight title */
     MSG_PUTS_TITLE(_("\n jump line  col file/text"));
     for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i)
@@ -1305,34 +1302,34 @@ mark_col_adjust(
 #ifdef FEAT_JUMPLIST
 /*
  * When deleting lines, this may create duplicate marks in the
- * jumplist. They will be removed here for the current window.
+ * jumplist. They will be removed here for the specified window.
  */
-    static void
-cleanup_jumplist(void)
+    void
+cleanup_jumplist(win_T *wp)
 {
     int            i;
     int            from, to;
 
     to = 0;
-    for (from = 0; from < curwin->w_jumplistlen; ++from)
+    for (from = 0; from < wp->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 (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 */
-           curwin->w_jumplist[to++] = curwin->w_jumplist[from];
+       if (i >= wp->w_jumplistlen)         /* no duplicate */
+           wp->w_jumplist[to++] = wp->w_jumplist[from];
        else
-           vim_free(curwin->w_jumplist[from].fname);
+           vim_free(wp->w_jumplist[from].fname);
     }
-    if (curwin->w_jumplistidx == curwin->w_jumplistlen)
-       curwin->w_jumplistidx = to;
-    curwin->w_jumplistlen = to;
+    if (wp->w_jumplistidx == wp->w_jumplistlen)
+       wp->w_jumplistidx = to;
+    wp->w_jumplistlen = to;
 }
 
 /*
@@ -1741,7 +1738,7 @@ write_viminfo_filemarks(FILE *fp)
     /* Write the jumplist with -' */
     fputs(_("\n# Jumplist (newest first):\n"), fp);
     setpcmark();       /* add current cursor position */
-    cleanup_jumplist();
+    cleanup_jumplist(curwin);
     vi_idx = 0;
     idx = curwin->w_jumplistlen - 1;
     for (i = 0; i < JUMPLISTSIZE; ++i)
diff --git a/src/proto/mark.pro b/src/proto/mark.pro
index ff1f441e8..c13daca2e 100644
--- a/src/proto/mark.pro
+++ b/src/proto/mark.pro
@@ -23,6 +23,7 @@ void mark_adjust_nofold(linenr_T line1, linenr_T line2, long 
amount, long amount
 void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long 
col_amount);
 void copy_jumplist(win_T *from, win_T *to);
 void free_jumplist(win_T *wp);
+void cleanup_jumplist(win_T *wp);
 void set_last_cursor(win_T *win);
 void free_all_marks(void);
 int read_viminfo_filemark(vir_T *virp, int force);
diff --git a/src/testdir/test_jumplist.vim b/src/testdir/test_jumplist.vim
index 7079d21aa..02dbd7619 100644
--- a/src/testdir/test_jumplist.vim
+++ b/src/testdir/test_jumplist.vim
@@ -29,7 +29,6 @@ func Test_getjumplist()
   normal gg
 
   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': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 4],
@@ -48,17 +47,16 @@ func Test_getjumplist()
   call assert_equal([[
              \ {'lnum': 1, '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': 100, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 5],
              \ getjumplist())
 
   let l = getjumplist()
   call test_garbagecollect_now()
-  call assert_equal(5, l[1])
+  call assert_equal(4, l[1])
   clearjumps
   call test_garbagecollect_now()
-  call assert_equal(5, l[1])
+  call assert_equal(4, l[1])
 
   call delete("Xtest")
 endfunc

Raspunde prin e-mail lui