vim-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 vim/vim#2634)
07ad816525
This commit is contained in:
Jan Edmund Lazo
2019-05-20 12:49:42 -04:00
parent b9ba1295b4
commit 783aa6b507
5 changed files with 98 additions and 0 deletions

View File

@@ -2081,6 +2081,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
@@ -4013,6 +4014,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

@@ -806,6 +806,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

@@ -9547,6 +9547,37 @@ f_getbufvar_end:
} }
} }
// "getchangelist()" function
static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
const buf_T *const buf = find_buffer(&argvars[0]);
if (buf == NULL) {
return;
}
list_T *const l = tv_list_alloc(buf->b_changelistlen);
tv_list_append_list(rettv->vval.v_list, l);
// 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.
tv_list_append_number(rettv->vval.v_list,
(buf == curwin->w_buffer)
? curwin->w_changelistidx
: buf->b_changelistlen);
for (int i = 0; i < buf->b_changelistlen; i++) {
if (buf->b_changelist[i].mark.lnum == 0) {
continue;
}
dict_T *const d = tv_dict_alloc();
tv_list_append_dict(l, d);
tv_dict_add_nr(d, S_LEN("lnum"), buf->b_changelist[i].mark.lnum);
tv_dict_add_nr(d, S_LEN("col"), buf->b_changelist[i].mark.col);
tv_dict_add_nr(d, S_LEN("coladd"), buf->b_changelist[i].mark.coladd);
}
}
/* /*
* "getchar()" function * "getchar()" function
*/ */

View File

@@ -116,6 +116,7 @@ return {
getbufinfo={args={0, 1}}, getbufinfo={args={0, 1}},
getbufline={args={2, 3}}, getbufline={args={2, 3}},
getbufvar={args={2, 3}}, getbufvar={args={2, 3}},
getchangelist={args={1, 1}},
getchar={args={0, 1}}, getchar={args={0, 1}},
getcharmod={}, getcharmod={},
getcharsearch={}, getcharsearch={},

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