forked from aniani/vim
patch 8.0.1497: getting the jump list requires parsing the output of :jumps
Problem: Getting the jump list requires parsing the output of :jumps. Solution: Add getjumplist(). (Yegappan Lakshmanan, closes #2609)
This commit is contained in:
@@ -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
|
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}
|
getfsize({fname}) Number size in bytes of file {fname}
|
||||||
getftime({fname}) Number last modification time of file
|
getftime({fname}) Number last modification time of file
|
||||||
getftype({fname}) String description of type of file {fname}
|
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}) String line {lnum} of current buffer
|
||||||
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
|
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
|
||||||
getloclist({nr} [, {what}]) List list of location list items
|
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
|
"file" are returned. On MS-Windows a symbolic link to a
|
||||||
directory returns "dir" instead of "link".
|
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()*
|
||||||
getline({lnum} [, {end}])
|
getline({lnum} [, {end}])
|
||||||
Without {end} the result is a String, which is line {lnum}
|
Without {end} the result is a String, which is line {lnum}
|
||||||
|
@@ -807,6 +807,7 @@ Buffers, windows and the argument list:
|
|||||||
getbufinfo() get a list with buffer information
|
getbufinfo() get a list with buffer information
|
||||||
gettabinfo() get a list with tab page information
|
gettabinfo() get a list with tab page information
|
||||||
getwininfo() get a list with window information
|
getwininfo() get a list with window information
|
||||||
|
getjumplist() get a list of jump list entries
|
||||||
|
|
||||||
Command line: *command-line-functions*
|
Command line: *command-line-functions*
|
||||||
getcmdline() get the current command line
|
getcmdline() get the current command line
|
||||||
|
@@ -2198,6 +2198,7 @@ test_arglist \
|
|||||||
test_job_fails \
|
test_job_fails \
|
||||||
test_join \
|
test_join \
|
||||||
test_json \
|
test_json \
|
||||||
|
test_jumplist \
|
||||||
test_jumps \
|
test_jumps \
|
||||||
test_lambda \
|
test_lambda \
|
||||||
test_langmap \
|
test_langmap \
|
||||||
|
@@ -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_getfsize(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_getftime(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_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_getline(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED);
|
static void f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED);
|
||||||
static void f_getmatches(typval_T *argvars, typval_T *rettv);
|
static void f_getmatches(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -621,6 +622,7 @@ static struct fst
|
|||||||
{"getfsize", 1, 1, f_getfsize},
|
{"getfsize", 1, 1, f_getfsize},
|
||||||
{"getftime", 1, 1, f_getftime},
|
{"getftime", 1, 1, f_getftime},
|
||||||
{"getftype", 1, 1, f_getftype},
|
{"getftype", 1, 1, f_getftype},
|
||||||
|
{"getjumplist", 0, 2, f_getjumplist},
|
||||||
{"getline", 1, 2, f_getline},
|
{"getline", 1, 2, f_getline},
|
||||||
{"getloclist", 1, 2, f_getloclist},
|
{"getloclist", 1, 2, f_getloclist},
|
||||||
{"getmatches", 0, 0, f_getmatches},
|
{"getmatches", 0, 0, f_getmatches},
|
||||||
@@ -4840,6 +4842,56 @@ f_getftype(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_string = type;
|
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
|
* "getline(lnum, [end])" function
|
||||||
*/
|
*/
|
||||||
|
21
src/list.c
21
src/list.c
@@ -474,6 +474,27 @@ list_append_dict(list_T *list, dict_T *dict)
|
|||||||
return OK;
|
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".
|
* Make a copy of "str" and append it as an item to list "l".
|
||||||
* When "len" >= 0 use "str[len]".
|
* When "len" >= 0 use "str[len]".
|
||||||
|
@@ -21,6 +21,7 @@ long list_idx_of_item(list_T *l, listitem_T *item);
|
|||||||
void list_append(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_tv(list_T *l, typval_T *tv);
|
||||||
int list_append_dict(list_T *list, dict_T *dict);
|
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_string(list_T *l, char_u *str, int len);
|
||||||
int list_append_number(list_T *l, varnumber_T n);
|
int list_append_number(list_T *l, varnumber_T n);
|
||||||
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
|
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
|
||||||
|
@@ -120,6 +120,7 @@ NEW_TESTS = test_arabic.res \
|
|||||||
test_ins_complete.res \
|
test_ins_complete.res \
|
||||||
test_job_fails.res \
|
test_job_fails.res \
|
||||||
test_json.res \
|
test_json.res \
|
||||||
|
test_jumplist.res \
|
||||||
test_langmap.res \
|
test_langmap.res \
|
||||||
test_let.res \
|
test_let.res \
|
||||||
test_lineending.res \
|
test_lineending.res \
|
||||||
|
64
src/testdir/test_jumplist.vim
Normal file
64
src/testdir/test_jumplist.vim
Normal file
@@ -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
|
@@ -771,6 +771,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1497,
|
||||||
/**/
|
/**/
|
||||||
1496,
|
1496,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user