diff options
-rw-r--r-- | runtime/doc/eval.txt | 17 | ||||
-rw-r--r-- | runtime/doc/usr_41.txt | 1 | ||||
-rw-r--r-- | src/nvim/eval.c | 31 | ||||
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_changelist.vim | 48 |
5 files changed, 98 insertions, 0 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 22157206a4..b88138aea3 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2081,6 +2081,7 @@ getbufline({expr}, {lnum} [, {end}]) List lines {lnum} to {end} of buffer {expr} getbufvar({expr}, {varname} [, {def}]) any variable {varname} in buffer {expr} +getchangelist({expr}) List list of change list items getchar([expr]) Number get one character from the user getcharmod() Number modifiers for the last typed character getcharsearch() Dict last character search @@ -4013,6 +4014,22 @@ getbufvar({expr}, {varname} [, {def}]) *getbufvar()* :let bufmodified = getbufvar(1, "&mod") :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()* Get a single character from the user or input stream. If [expr] is omitted, wait until a character is available. diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 87164c8d90..234aba1932 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -806,6 +806,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 + getchangelist() get a list of change list entries getjumplist() get a list of jump list entries Command line: *command-line-functions* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6479163028..7229b2f977 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -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 */ diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index d4bb69613e..aad2de5d30 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -116,6 +116,7 @@ return { getbufinfo={args={0, 1}}, getbufline={args={2, 3}}, getbufvar={args={2, 3}}, + getchangelist={args={1, 1}}, getchar={args={0, 1}}, getcharmod={}, getcharsearch={}, diff --git a/src/nvim/testdir/test_changelist.vim b/src/nvim/testdir/test_changelist.vim new file mode 100644 index 0000000000..0880fce840 --- /dev/null +++ b/src/nvim/testdir/test_changelist.vim @@ -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 |