]> granicus.if.org Git - vim/commitdiff
patch 8.0.1497: getting the jump list requires parsing the output of :jumps v8.0.1497
authorBram Moolenaar <Bram@vim.org>
Sat, 10 Feb 2018 20:06:32 +0000 (21:06 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 10 Feb 2018 20:06:32 +0000 (21:06 +0100)
Problem:    Getting the jump list requires parsing the output of :jumps.
Solution:   Add getjumplist(). (Yegappan Lakshmanan, closes #2609)

runtime/doc/eval.txt
runtime/doc/usr_41.txt
src/Makefile
src/evalfunc.c
src/list.c
src/proto/list.pro
src/testdir/Make_all.mak
src/testdir/test_jumplist.vim [new file with mode: 0644]
src/version.c

index 1235edfa6e87171c737b0316a17e926f8ba526d3..9158f3850a640acc80ccab123f4f0fabd8752335 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 8.0.  Last change: 2018 Feb 09
+*eval.txt*     For Vim version 8.0.  Last change: 2018 Feb 10
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -2167,6 +2167,8 @@ getfperm({fname})         String  file permissions of file {fname}
 getfsize({fname})              Number  size in bytes of file {fname}
 getftime({fname})              Number  last modification time of file
 getftype({fname})              String  description of type of file {fname}
+getjumplist([{winnr} [, {tabnr}]])
+                               List    list of jump list items
 getline({lnum})                        String  line {lnum} of current buffer
 getline({lnum}, {end})         List    lines {lnum} to {end} of current buffer
 getloclist({nr} [, {what}])    List    list of location list items
@@ -4560,6 +4562,26 @@ getftype({fname})                                        *getftype()*
                "file" are returned.  On MS-Windows a symbolic link to a
                directory returns "dir" instead of "link".
 
+                                                       *getjumplist()*
+getjumplist([{winnr} [, {tabnr}]])
+               Returns the |jumplist| for the specified window.
+
+               Without arguments use the current window.
+               With {winnr} only use this window in the current tab page.
+               {winnr} can also be a |window-ID|.
+               With {winnr} and {tabnr} use the window in the specified tab
+               page.
+
+               The returned list contains two entries: a list with the jump
+               locations and the last used jump position number in the list.
+               Each entry in the jump location list is a dictionary with
+               the following entries:
+                       bufnr           buffer number
+                       col             column number
+                       coladd          column offset for 'virtualedit'
+                       filename        filename if available
+                       lnum            line number
+
                                                        *getline()*
 getline({lnum} [, {end}])
                Without {end} the result is a String, which is line {lnum}
index 837418bf165c6ff9f431b27055db149142ca4884..590fde4827d30dd4f7315def43b9e281e78c2f26 100644 (file)
@@ -807,6 +807,7 @@ Buffers, windows and the argument list:
        getbufinfo()            get a list with buffer information
        gettabinfo()            get a list with tab page information
        getwininfo()            get a list with window information
+       getjumplist()           get a list of jump list entries
 
 Command line:                                  *command-line-functions*
        getcmdline()            get the current command line
index e0d601cc8e58558b662804b5cb1c8f036e21189e..7cd501e9b84f598f1a088bce7efc070ecfd0ded7 100644 (file)
@@ -2198,6 +2198,7 @@ test_arglist \
        test_job_fails \
        test_join \
        test_json \
+       test_jumplist \
        test_jumps \
        test_lambda \
        test_langmap \
index f09be92af4dfcbdce7e3bec34533198b146a538f..da870c67bb49067960335cd8951cedd898cdb1b5 100644 (file)
@@ -180,6 +180,7 @@ static void f_getfperm(typval_T *argvars, typval_T *rettv);
 static void f_getfsize(typval_T *argvars, typval_T *rettv);
 static void f_getftime(typval_T *argvars, typval_T *rettv);
 static void f_getftype(typval_T *argvars, typval_T *rettv);
+static void f_getjumplist(typval_T *argvars, typval_T *rettv);
 static void f_getline(typval_T *argvars, typval_T *rettv);
 static void f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED);
 static void f_getmatches(typval_T *argvars, typval_T *rettv);
@@ -621,6 +622,7 @@ static struct fst
     {"getfsize",       1, 1, f_getfsize},
     {"getftime",       1, 1, f_getftime},
     {"getftype",       1, 1, f_getftype},
+    {"getjumplist",    0, 2, f_getjumplist},
     {"getline",                1, 2, f_getline},
     {"getloclist",     1, 2, f_getloclist},
     {"getmatches",     0, 0, f_getmatches},
@@ -4840,6 +4842,56 @@ f_getftype(typval_T *argvars, typval_T *rettv)
     rettv->vval.v_string = type;
 }
 
+/*
+ * "getjumplist()" function
+ */
+    static void
+f_getjumplist(typval_T *argvars, typval_T *rettv)
+{
+#ifdef FEAT_JUMPLIST
+    win_T      *wp;
+    int                i;
+    list_T     *l;
+    dict_T     *d;
+#endif
+
+    if (rettv_list_alloc(rettv) != OK)
+       return;
+
+#ifdef FEAT_JUMPLIST
+    wp = find_tabwin(&argvars[0], &argvars[1]);
+    if (wp == NULL)
+       return;
+
+    l = list_alloc();
+    if (l == NULL)
+       return;
+
+    if (list_append_list(rettv->vval.v_list, l) == FAIL)
+       return;
+    list_append_number(rettv->vval.v_list, (varnumber_T)wp->w_jumplistidx);
+
+    for (i = 0; i < wp->w_jumplistlen; ++i)
+    {
+       if ((d = dict_alloc()) == NULL)
+           return;
+       if (list_append_dict(l, d) == FAIL)
+           return;
+       dict_add_nr_str(d, "lnum", (long)wp->w_jumplist[i].fmark.mark.lnum,
+               NULL);
+       dict_add_nr_str(d, "col", (long)wp->w_jumplist[i].fmark.mark.col,
+               NULL);
+# ifdef FEAT_VIRTUALEDIT
+       dict_add_nr_str(d, "coladd", (long)wp->w_jumplist[i].fmark.mark.coladd,
+               NULL);
+# endif
+       dict_add_nr_str(d, "bufnr", (long)wp->w_jumplist[i].fmark.fnum, NULL);
+       if (wp->w_jumplist[i].fmark.fnum == 0)
+           dict_add_nr_str(d, "filename", 0L, wp->w_jumplist[i].fname);
+    }
+#endif
+}
+
 /*
  * "getline(lnum, [end])" function
  */
@@ -5612,11 +5664,11 @@ f_has(typval_T *argvars, typval_T *rettv)
        "beos",
 #endif
 #ifdef MACOS_X
-       "mac",          /* Mac OS X (and, once, Mac OS Classic) */
-       "osx",          /* Mac OS X */
+       "mac",          /* Mac OS X (and, once, Mac OS Classic) */
+       "osx",          /* Mac OS X */
 # ifdef MACOS_X_DARWIN
-       "macunix",      /* Mac OS X, with the darwin feature */
-       "osxdarwin",    /* synonym for macunix */
+       "macunix",      /* Mac OS X, with the darwin feature */
+       "osxdarwin",    /* synonym for macunix */
 # endif
 #endif
 #ifdef __QNX__
index b593f7171926140d29a21ac25c8669b8dd1be03f..1dfaa210e6acd8dad9e872ad0efe9fb065ac5204 100644 (file)
@@ -474,6 +474,27 @@ list_append_dict(list_T *list, dict_T *dict)
     return OK;
 }
 
+/*
+ * Append list2 to list1.
+ * Return FAIL when out of memory.
+ */
+    int
+list_append_list(list1, list2)
+    list_T     *list1;
+    list_T     *list2;
+{
+    listitem_T *li = listitem_alloc();
+
+    if (li == NULL)
+       return FAIL;
+    li->li_tv.v_type = VAR_LIST;
+    li->li_tv.v_lock = 0;
+    li->li_tv.vval.v_list = list2;
+    list_append(list1, li);
+    ++list2->lv_refcount;
+    return OK;
+}
+
 /*
  * Make a copy of "str" and append it as an item to list "l".
  * When "len" >= 0 use "str[len]".
index fe54bab2b41492987eebf63ca751e9e4e41bc161..c4fd195f1f3fc4c7b1382dd03101529e209d43bf 100644 (file)
@@ -21,6 +21,7 @@ long list_idx_of_item(list_T *l, listitem_T *item);
 void list_append(list_T *l, listitem_T *item);
 int list_append_tv(list_T *l, typval_T *tv);
 int list_append_dict(list_T *list, dict_T *dict);
+int list_append_list(list_T *list1, list_T *list2);
 int list_append_string(list_T *l, char_u *str, int len);
 int list_append_number(list_T *l, varnumber_T n);
 int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
index 4626d80c2f14ca15084cb51c85704903754f563f..2d98fa6a11c472742e5e170fbce4ec851f38c60e 100644 (file)
@@ -120,6 +120,7 @@ NEW_TESTS = test_arabic.res \
            test_ins_complete.res \
            test_job_fails.res \
            test_json.res \
+           test_jumplist.res \
            test_langmap.res \
            test_let.res \
            test_lineending.res \
diff --git a/src/testdir/test_jumplist.vim b/src/testdir/test_jumplist.vim
new file mode 100644 (file)
index 0000000..7079d21
--- /dev/null
@@ -0,0 +1,64 @@
+" Tests for the jumplist functionality
+
+" Tests for the getjumplist() function
+func Test_getjumplist()
+  if !has("jumplist")
+    return
+  endif
+
+  %bwipe
+  clearjumps
+  call assert_equal([[], 0], getjumplist())
+  call assert_equal([[], 0], getjumplist(1))
+  call assert_equal([[], 0], getjumplist(1, 1))
+
+  call assert_equal([], getjumplist(100))
+  call assert_equal([], getjumplist(1, 100))
+
+  let lines = []
+  for i in range(1, 100)
+    call add(lines, "Line " . i)
+  endfor
+  call writefile(lines, "Xtest")
+
+  " Jump around and create a jump list
+  edit Xtest
+  let bnr = bufnr('%')
+  normal 50%
+  normal G
+  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],
+             \ getjumplist())
+
+  " Traverse the jump list and verify the results
+  5
+  exe "normal \<C-O>"
+  call assert_equal(2, getjumplist(1)[1])
+  exe "normal 2\<C-O>"
+  call assert_equal(0, getjumplist(1, 1)[1])
+  exe "normal 3\<C-I>"
+  call assert_equal(3, getjumplist()[1])
+  exe "normal \<C-O>"
+  normal 20%
+  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])
+  clearjumps
+  call test_garbagecollect_now()
+  call assert_equal(5, l[1])
+
+  call delete("Xtest")
+endfunc
index dbd272109b68d97f8c28f818c45ee205ca6fb93f..87ae3f5ece84fec529ba6b14c037eb88fe1274ae 100644 (file)
@@ -771,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1497,
 /**/
     1496,
 /**/