0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 8.0.1514: getting the list of changes is not easy

Problem:    Getting the list of changes is not easy.
Solution:   Add the getchangelist() function. (Yegappan Lakshmanan,
            closes #2634)
This commit is contained in:
Bram Moolenaar
2018-02-13 13:59:59 +01:00
parent 4867974137
commit 07ad816525
7 changed files with 124 additions and 0 deletions

View File

@@ -2152,6 +2152,7 @@ getbufline({expr}, {lnum} [, {end}])
List lines {lnum} to {end} of buffer {expr} List lines {lnum} to {end} of buffer {expr}
getbufvar({expr}, {varname} [, {def}]) getbufvar({expr}, {varname} [, {def}])
any variable {varname} in buffer {expr} any variable {varname} in buffer {expr}
getchangelist({expr}) List list of change list items
getchar([expr]) Number get one character from the user getchar([expr]) Number get one character from the user
getcharmod() Number modifiers for the last typed character getcharmod() Number modifiers for the last typed character
getcharsearch() Dict last character search getcharsearch() Dict last character search
@@ -4278,6 +4279,22 @@ getbufvar({expr}, {varname} [, {def}]) *getbufvar()*
:let bufmodified = getbufvar(1, "&mod") :let bufmodified = getbufvar(1, "&mod")
:echo "todo myvar = " . getbufvar("todo", "myvar") :echo "todo myvar = " . getbufvar("todo", "myvar")
< <
getchangelist({expr}) *getchangelist()*
Returns the |changelist| for the buffer {expr}. For the use
of {expr}, see |bufname()| above. If buffer {expr} doesn't
exist, an empty list is returned.
The returned list contains two entries: a list with the change
locations and the current position in the list. Each
entry in the change list is a dictionary with the following
entries:
col column number
coladd column offset for 'virtualedit'
lnum line number
If buffer {expr} is the current buffer, then the current
position refers to the position in the list. For other
buffers, it is set to the length of the list.
getchar([expr]) *getchar()* getchar([expr]) *getchar()*
Get a single character from the user or input stream. Get a single character from the user or input stream.
If [expr] is omitted, wait until a character is available. If [expr] is omitted, wait until a character is available.

View File

@@ -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
getchangelist() get a list of change list entries
getjumplist() get a list of jump list entries getjumplist() get a list of jump list entries
Command line: *command-line-functions* Command line: *command-line-functions*

View File

@@ -2127,6 +2127,7 @@ test_arglist \
test_cd \ test_cd \
test_cdo \ test_cdo \
test_changedtick \ test_changedtick \
test_changelist \
test_channel \ test_channel \
test_charsearch \ test_charsearch \
test_charsearch_utf8 \ test_charsearch_utf8 \

View File

@@ -165,6 +165,7 @@ static void f_get(typval_T *argvars, typval_T *rettv);
static void f_getbufinfo(typval_T *argvars, typval_T *rettv); static void f_getbufinfo(typval_T *argvars, typval_T *rettv);
static void f_getbufline(typval_T *argvars, typval_T *rettv); static void f_getbufline(typval_T *argvars, typval_T *rettv);
static void f_getbufvar(typval_T *argvars, typval_T *rettv); static void f_getbufvar(typval_T *argvars, typval_T *rettv);
static void f_getchangelist(typval_T *argvars, typval_T *rettv);
static void f_getchar(typval_T *argvars, typval_T *rettv); static void f_getchar(typval_T *argvars, typval_T *rettv);
static void f_getcharmod(typval_T *argvars, typval_T *rettv); static void f_getcharmod(typval_T *argvars, typval_T *rettv);
static void f_getcharsearch(typval_T *argvars, typval_T *rettv); static void f_getcharsearch(typval_T *argvars, typval_T *rettv);
@@ -607,6 +608,7 @@ static struct fst
{"getbufinfo", 0, 1, f_getbufinfo}, {"getbufinfo", 0, 1, f_getbufinfo},
{"getbufline", 2, 3, f_getbufline}, {"getbufline", 2, 3, f_getbufline},
{"getbufvar", 2, 3, f_getbufvar}, {"getbufvar", 2, 3, f_getbufvar},
{"getchangelist", 1, 1, f_getchangelist},
{"getchar", 0, 1, f_getchar}, {"getchar", 0, 1, f_getchar},
{"getcharmod", 0, 0, f_getcharmod}, {"getcharmod", 0, 0, f_getcharmod},
{"getcharsearch", 0, 0, f_getcharsearch}, {"getcharsearch", 0, 0, f_getcharsearch},
@@ -4346,6 +4348,58 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
--emsg_off; --emsg_off;
} }
/*
* "getchangelist()" function
*/
static void
f_getchangelist(typval_T *argvars, typval_T *rettv)
{
#ifdef FEAT_JUMPLIST
buf_T *buf;
int i;
list_T *l;
dict_T *d;
#endif
if (rettv_list_alloc(rettv) != OK)
return;
#ifdef FEAT_JUMPLIST
buf = find_buffer(&argvars[0]);
if (buf == NULL)
return;
l = list_alloc();
if (l == NULL)
return;
if (list_append_list(rettv->vval.v_list, l) == FAIL)
return;
/*
* The current window change list index tracks only the position in the
* current buffer change list. For other buffers, use the change list
* length as the current index.
*/
list_append_number(rettv->vval.v_list,
(varnumber_T)((buf == curwin->w_buffer)
? curwin->w_changelistidx : buf->b_changelistlen));
for (i = 0; i < buf->b_changelistlen; ++i)
{
if (buf->b_changelist[i].lnum == 0)
continue;
if ((d = dict_alloc()) == NULL)
return;
if (list_append_dict(l, d) == FAIL)
return;
dict_add_nr_str(d, "lnum", (long)buf->b_changelist[i].lnum, NULL);
dict_add_nr_str(d, "col", (long)buf->b_changelist[i].col, NULL);
# ifdef FEAT_VIRTUALEDIT
dict_add_nr_str(d, "coladd", (long)buf->b_changelist[i].coladd, NULL);
# endif
}
#endif
}
/* /*
* "getchar()" function * "getchar()" function
*/ */

View File

@@ -75,6 +75,7 @@ NEW_TESTS = test_arabic.res \
test_breakindent.res \ test_breakindent.res \
test_bufwintabinfo.res \ test_bufwintabinfo.res \
test_cdo.res \ test_cdo.res \
test_changelist.res \
test_channel.res \ test_channel.res \
test_charsearch.res \ test_charsearch.res \
test_cindent.res \ test_cindent.res \

View File

@@ -0,0 +1,48 @@
" Tests for the changelist functionality
" Tests for the getchangelist() function
func Test_getchangelist()
if !has("jumplist")
return
endif
bwipe!
enew
call assert_equal([], getchangelist(10))
call assert_equal([[], 0], getchangelist(bufnr('%')))
call writefile(['line1', 'line2', 'line3'], 'Xfile1.txt')
call writefile(['line1', 'line2', 'line3'], 'Xfile2.txt')
edit Xfile1.txt
exe "normal 1Goline\<C-G>u1.1"
exe "normal 3Goline\<C-G>u2.1"
exe "normal 5Goline\<C-G>u3.1"
normal g;
call assert_equal([[
\ {'lnum' : 2, 'col' : 4, 'coladd' : 0},
\ {'lnum' : 4, 'col' : 4, 'coladd' : 0},
\ {'lnum' : 6, 'col' : 4, 'coladd' : 0}], 2],
\ getchangelist(bufnr('%')))
hide edit Xfile2.txt
exe "normal 1GOline\<C-G>u1.0"
exe "normal 2Goline\<C-G>u2.0"
call assert_equal([[
\ {'lnum' : 1, 'col' : 6, 'coladd' : 0},
\ {'lnum' : 3, 'col' : 6, 'coladd' : 0}], 2],
\ getchangelist(bufnr('%')))
hide enew
call assert_equal([[
\ {'lnum' : 2, 'col' : 4, 'coladd' : 0},
\ {'lnum' : 4, 'col' : 4, 'coladd' : 0},
\ {'lnum' : 6, 'col' : 4, 'coladd' : 0}], 3], getchangelist(2))
call assert_equal([[
\ {'lnum' : 1, 'col' : 6, 'coladd' : 0},
\ {'lnum' : 3, 'col' : 6, 'coladd' : 0}], 2], getchangelist(3))
bwipe!
call delete('Xfile1.txt')
call delete('Xfile2.txt')
endfunc

View File

@@ -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 */
/**/
1514,
/**/ /**/
1513, 1513,
/**/ /**/