diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-08-23 19:39:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-23 19:39:04 +0200 |
commit | 82aaac5baafb4101022604c5e720e37987279184 (patch) | |
tree | a755fb4e7644d7c85604e9e1f7c8e22be0d68b24 | |
parent | 79ea7709b7cab13b89d98088f4733a354a7f2a54 (diff) | |
parent | 2a1887c2df27c5f91f0f2f6ad6c70da60239cfce (diff) | |
download | rneovim-82aaac5baafb4101022604c5e720e37987279184.tar.gz rneovim-82aaac5baafb4101022604c5e720e37987279184.tar.bz2 rneovim-82aaac5baafb4101022604c5e720e37987279184.zip |
Merge #10833 from janlazo/vim-8.1.0037
vim-patch:8.0.1386,8.1.{37,39,187}
-rw-r--r-- | runtime/doc/eval.txt | 56 | ||||
-rw-r--r-- | src/nvim/eval.c | 150 | ||||
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_bufline.vim | 49 | ||||
-rw-r--r-- | src/nvim/testdir/test_bufwintabinfo.vim | 26 | ||||
-rw-r--r-- | src/nvim/testdir/test_edit.vim | 2 |
6 files changed, 163 insertions, 121 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 5e8c5151f2..de2650baa4 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2495,6 +2495,21 @@ append({lnum}, {text}) *append()* 0 for success. Example: > :let failed = append(line('$'), "# THE END") :let failed = append(0, ["Chapter 1", "the beginning"]) + +appendbufline({expr}, {lnum}, {text}) *appendbufline()* + Like |append()| but append the text in buffer {expr}. + + For the use of {expr}, see |bufname()|. + + {lnum} is used like with |append()|. Note that using |line()| + would use the current buffer, not the one appending to. + Use "$" to append at the end of the buffer. + + On success 0 is returned, on failure 1 is returned. + + If {expr} is not a valid buffer or {lnum} is not valid, an + error message is given. Example: > + :let failed = appendbufline(13, 0, "# THE START") < *argc()* argc([{winid}]) @@ -4026,6 +4041,7 @@ getbufinfo([{dict}]) be specified in {dict}: buflisted include only listed buffers. bufloaded include only loaded buffers. + bufmodified include only modified buffers. Otherwise, {expr} specifies a particular buffer to return information for. For the use of {expr}, see |bufname()| @@ -4725,25 +4741,6 @@ gettagstack([{nr}]) *gettagstack()* See |tagstack| for more information about the tag stack. -getwinpos([{timeout}]) *getwinpos()* - The result is a list with two numbers, the result of - getwinposx() and getwinposy() combined: - [x-pos, y-pos] - {timeout} can be used to specify how long to wait in msec for - a response from the terminal. When omitted 100 msec is used. - - *getwinposx()* -getwinposx() The result is a Number, which is the X coordinate in pixels of - the left hand side of the GUI Vim window. The result will be - -1 if the information is not available. - The value can be used with `:winpos`. - - *getwinposy()* -getwinposy() The result is a Number, which is the Y coordinate in pixels of - the top of the GUI Vim window. The result will be -1 if the - information is not available. - The value can be used with `:winpos`. - getwininfo([{winid}]) *getwininfo()* Returns information about windows as a List with Dictionaries. @@ -4773,6 +4770,25 @@ getwininfo([{winid}]) *getwininfo()* winnr window number winrow topmost screen column of the window +getwinpos([{timeout}]) *getwinpos()* + The result is a list with two numbers, the result of + getwinposx() and getwinposy() combined: + [x-pos, y-pos] + {timeout} can be used to specify how long to wait in msec for + a response from the terminal. When omitted 100 msec is used. + + *getwinposx()* +getwinposx() The result is a Number, which is the X coordinate in pixels of + the left hand side of the GUI Vim window. The result will be + -1 if the information is not available. + The value can be used with `:winpos`. + + *getwinposy()* +getwinposy() The result is a Number, which is the Y coordinate in pixels of + the top of the GUI Vim window. The result will be -1 if the + information is not available. + The value can be used with `:winpos`. + getwinvar({winnr}, {varname} [, {def}]) *getwinvar()* Like |gettabwinvar()| for the current tabpage. Examples: > @@ -8872,7 +8888,7 @@ win_id2win({expr}) *win_id2win()* win_screenpos({nr}) *win_screenpos()* Return the screen position of window {nr} as a list with two numbers: [row, col]. The first window always has position - [1, 1]. + [1, 1], unless there is a tabline, then it is [2, 1]. {nr} can be the window number or the |window-ID|. Return [0, 0] if the window cannot be found in the current tabpage. diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8f6d6cd55e..3d56522f79 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1224,9 +1224,7 @@ static void restore_vimvar(int idx, typval_T *save_tv) /// If there is a window for "curbuf", make it the current window. static void find_win_for_curbuf(void) { - wininfo_T *wip; - - for (wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next) { + for (wininfo_T *wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next) { if (wip->wi_win != NULL) { curwin = wip->wi_win; break; @@ -6741,61 +6739,24 @@ static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) api_free_dictionary(metadata); } -/* - * "append(lnum, string/list)" function - */ +// "append(lnum, string/list)" function static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - long lnum; - list_T *l = NULL; - listitem_T *li = NULL; - typval_T *tv; - long added = 0; + const linenr_T lnum = tv_get_lnum(&argvars[0]); - /* When coming here from Insert mode, sync undo, so that this can be - * undone separately from what was previously inserted. */ - if (u_sync_once == 2) { - u_sync_once = 1; /* notify that u_sync() was called */ - u_sync(TRUE); - } - - lnum = tv_get_lnum(argvars); - if (lnum >= 0 - && lnum <= curbuf->b_ml.ml_line_count - && u_save(lnum, lnum + 1) == OK) { - if (argvars[1].v_type == VAR_LIST) { - l = argvars[1].vval.v_list; - if (l == NULL) { - return; - } - li = tv_list_first(l); - } - for (;; ) { - if (l == NULL) { - tv = &argvars[1]; // Append a string. - } else if (li == NULL) { - break; // End of list. - } else { - tv = TV_LIST_ITEM_TV(li); // Append item from list. - } - const char *const line = tv_get_string_chk(tv); - if (line == NULL) { // Type error. - rettv->vval.v_number = 1; // Failed. - break; - } - ml_append(lnum + added, (char_u *)line, (colnr_T)0, false); - added++; - if (l == NULL) { - break; - } - li = TV_LIST_ITEM_NEXT(l, li); - } + set_buffer_lines(curbuf, lnum, true, &argvars[1], rettv); +} - appended_lines_mark(lnum, added); - if (curwin->w_cursor.lnum > lnum) - curwin->w_cursor.lnum += added; - } else - rettv->vval.v_number = 1; /* Failed */ +// "appendbufline(buf, lnum, string/list)" function +static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + buf_T *const buf = tv_get_buf(&argvars[0], false); + if (buf == NULL) { + rettv->vval.v_number = 1; // FAIL + } else { + const linenr_T lnum = tv_get_lnum_buf(&argvars[1], buf); + set_buffer_lines(buf, lnum, true, &argvars[2], rettv); + } } static void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr) @@ -8297,22 +8258,18 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "deletebufline()" function static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; - linenr_T first, last; - linenr_T lnum; - long count; - int is_curbuf; + linenr_T last; buf_T *curbuf_save = NULL; win_T *curwin_save = NULL; - buf = tv_get_buf(&argvars[0], false); + buf_T *const buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { rettv->vval.v_number = 1; // FAIL return; } - is_curbuf = buf == curbuf; + const bool is_curbuf = buf == curbuf; - first = tv_get_lnum_buf(&argvars[1], buf); + const linenr_T first = tv_get_lnum_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { last = tv_get_lnum_buf(&argvars[2], buf); } else { @@ -8334,7 +8291,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (last > curbuf->b_ml.ml_line_count) { last = curbuf->b_ml.ml_line_count; } - count = last - first + 1; + const long count = last - first + 1; // When coming here from Insert mode, sync undo, so that this can be // undone separately from what was previously inserted. @@ -8348,7 +8305,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - for (lnum = first; lnum <= last; lnum++) { + for (linenr_T lnum = first; lnum <= last; lnum++) { ml_delete(first, true); } @@ -9735,6 +9692,7 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool filtered = false; bool sel_buflisted = false; bool sel_bufloaded = false; + bool sel_bufmodified = false; tv_list_alloc_ret(rettv, kListLenMayKnow); @@ -9756,6 +9714,10 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (di != NULL && tv_get_number(&di->di_tv)) { sel_bufloaded = true; } + di = tv_dict_find(sel_d, S_LEN("bufmodified")); + if (di != NULL && tv_get_number(&di->di_tv)) { + sel_bufmodified = true; + } } } else if (argvars[0].v_type != VAR_UNKNOWN) { // Information about one buffer. Argument specifies the buffer @@ -9775,7 +9737,8 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) continue; } if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL) - || (sel_buflisted && !buf->b_p_bl))) { + || (sel_buflisted && !buf->b_p_bl) + || (sel_bufmodified && !buf->b_changed))) { continue; } @@ -10876,12 +10839,12 @@ static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) tv_dict_add_nr(dict, S_LEN("winnr"), winnr); tv_dict_add_nr(dict, S_LEN("winid"), wp->handle); tv_dict_add_nr(dict, S_LEN("height"), wp->w_height); - tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow); + tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow + 1); tv_dict_add_nr(dict, S_LEN("topline"), wp->w_topline); tv_dict_add_nr(dict, S_LEN("botline"), wp->w_botline - 1); tv_dict_add_nr(dict, S_LEN("width"), wp->w_width); tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum); - tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol); + tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol + 1); tv_dict_add_nr(dict, S_LEN("terminal"), bt_terminal(wp->w_buffer)); tv_dict_add_nr(dict, S_LEN("quickfix"), bt_quickfix(wp->w_buffer)); @@ -15130,16 +15093,19 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// Set line or list of lines in buffer "buf". -static void set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines, - typval_T *rettv) +static void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, + const typval_T *lines, typval_T *rettv) + FUNC_ATTR_NONNULL_ARG(4, 5) { + linenr_T lnum = lnum_arg + (append ? 1 : 0); + const char *line = NULL; list_T *l = NULL; listitem_T *li = NULL; long added = 0; - linenr_T lcount; + linenr_T append_lnum; buf_T *curbuf_save = NULL; win_T *curwin_save = NULL; - int is_curbuf = buf == curbuf; + const bool is_curbuf = buf == curbuf; // When using the current buffer ml_mfp will be set if needed. Useful when // setline() is used on startup. For other buffers the buffer must be @@ -15150,22 +15116,20 @@ static void set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines, } if (!is_curbuf) { - wininfo_T *wip; - curbuf_save = curbuf; curwin_save = curwin; curbuf = buf; - for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) { - if (wip->wi_win != NULL) { - curwin = wip->wi_win; - break; - } - } + find_win_for_curbuf(); } - lcount = curbuf->b_ml.ml_line_count; - - const char *line = NULL; + if (append) { + // appendbufline() uses the line number below which we insert + append_lnum = lnum - 1; + } else { + // setbufline() uses the line number above which we insert, we only + // append if it's below the last line + append_lnum = curbuf->b_ml.ml_line_count; + } if (lines->v_type == VAR_LIST) { l = lines->vval.v_list; @@ -15197,7 +15161,7 @@ static void set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines, u_sync(true); } - if (lnum <= curbuf->b_ml.ml_line_count) { + if (!append && lnum <= curbuf->b_ml.ml_line_count) { // Existing line, replace it. if (u_savesub(lnum) == OK && ml_replace(lnum, (char_u *)line, true) == OK) { @@ -15208,20 +15172,27 @@ static void set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines, rettv->vval.v_number = 0; // OK } } else if (added > 0 || u_save(lnum - 1, lnum) == OK) { - // lnum is one past the last line, append the line. + // append the line. added++; if (ml_append(lnum - 1, (char_u *)line, 0, false) == OK) { rettv->vval.v_number = 0; // OK } } - if (l == NULL) /* only one string argument */ + if (l == NULL) { // only one string argument break; - ++lnum; + } + lnum++; } if (added > 0) { - appended_lines_mark(lcount, added); + appended_lines_mark(append_lnum, added); + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (wp->w_buffer == buf && wp->w_cursor.lnum > append_lnum) { + wp->w_cursor.lnum += added; + } + } + check_cursor_col(); } if (!is_curbuf) { @@ -15241,8 +15212,7 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = 1; // FAIL } else { lnum = tv_get_lnum_buf(&argvars[1], buf); - - set_buffer_lines(buf, lnum, &argvars[2], rettv); + set_buffer_lines(buf, lnum, false, &argvars[2], rettv); } } @@ -15393,7 +15363,7 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr) { linenr_T lnum = tv_get_lnum(&argvars[0]); - set_buffer_lines(curbuf, lnum, &argvars[1], rettv); + set_buffer_lines(curbuf, lnum, false, &argvars[1], rettv); } /// Create quickfix/location list from VimL values diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index db45409e77..6b63003e69 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -20,6 +20,7 @@ return { ['and']={args=2}, api_info={}, append={args=2}, + appendbufline={args=3}, argc={args={0, 1}}, argidx={}, arglistid={args={0, 2}}, diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim index b886e99506..1f83e8b776 100644 --- a/src/nvim/testdir/test_bufline.vim +++ b/src/nvim/testdir/test_bufline.vim @@ -1,4 +1,4 @@ -" Tests for setbufline() and getbufline() +" Tests for setbufline(), getbufline(), appendbufline(), deletebufline() source shared.vim @@ -65,3 +65,50 @@ func Test_setline_startup() call delete('Xscript') call delete('Xtest') endfunc + +func Test_appendbufline() + new + let b = bufnr('%') + hide + call assert_equal(0, appendbufline(b, 0, ['foo', 'bar'])) + call assert_equal(['foo'], getbufline(b, 1)) + call assert_equal(['bar'], getbufline(b, 2)) + call assert_equal(['foo', 'bar'], getbufline(b, 1, 2)) + exe "bd!" b + call assert_equal([], getbufline(b, 1, 2)) + + split Xtest + call setline(1, ['a', 'b', 'c']) + let b = bufnr('%') + wincmd w + call assert_equal(1, appendbufline(b, 4, ['x'])) + call assert_equal(1, appendbufline(1234, 1, ['x'])) + call assert_equal(0, appendbufline(b, 3, ['d', 'e'])) + call assert_equal(['c'], getbufline(b, 3)) + call assert_equal(['d'], getbufline(b, 4)) + call assert_equal(['e'], getbufline(b, 5)) + call assert_equal([], getbufline(b, 6)) + exe "bwipe! " . b +endfunc + +func Test_deletebufline() + new + let b = bufnr('%') + call setline(1, ['aaa', 'bbb', 'ccc']) + hide + call assert_equal(0, deletebufline(b, 2)) + call assert_equal(['aaa', 'ccc'], getbufline(b, 1, 2)) + call assert_equal(0, deletebufline(b, 2, 8)) + call assert_equal(['aaa'], getbufline(b, 1, 2)) + exe "bd!" b + call assert_equal(1, deletebufline(b, 1)) + + split Xtest + call setline(1, ['a', 'b', 'c']) + let b = bufnr('%') + wincmd w + call assert_equal(1, deletebufline(b, 4)) + call assert_equal(0, deletebufline(b, 1)) + call assert_equal(['b', 'c'], getbufline(b, 1, 2)) + exe "bwipe! " . b +endfunc diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim index a6b4524cc0..0e8c7d1dc1 100644 --- a/src/nvim/testdir/test_bufwintabinfo.vim +++ b/src/nvim/testdir/test_bufwintabinfo.vim @@ -20,6 +20,13 @@ function Test_getbufwintabinfo() call assert_equal('vim', l[0].variables.editor) call assert_notequal(-1, index(l[0].windows, bufwinid('%'))) + " Test for getbufinfo() with 'bufmodified' + call assert_equal(0, len(getbufinfo({'bufmodified' : 1}))) + call setbufline('Xtestfile1', 1, ["Line1"]) + let l = getbufinfo({'bufmodified' : 1}) + call assert_equal(1, len(l)) + call assert_equal(bufnr('Xtestfile1'), l[0].bufnr) + if has('signs') call append(0, ['Linux', 'Windows', 'Mac']) sign define Mark text=>> texthl=Search @@ -45,21 +52,22 @@ function Test_getbufwintabinfo() let winlist = getwininfo() call assert_equal(5, len(winlist)) call assert_equal(winwidth(1), winlist[0].width) - call assert_equal(0, winlist[0].wincol) - let tablineheight = winlist[0].winrow == 1 ? 1 : 0 - call assert_equal(tablineheight, winlist[0].winrow) " tabline adds one + call assert_equal(1, winlist[0].wincol) + " tabline adds one row in terminal, not in GUI + let tablineheight = winlist[0].winrow == 2 ? 1 : 0 + call assert_equal(tablineheight + 1, winlist[0].winrow) call assert_equal(winbufnr(2), winlist[1].bufnr) call assert_equal(winheight(2), winlist[1].height) - call assert_equal(0, winlist[1].wincol) - call assert_equal(tablineheight + winheight(1) + 1, winlist[1].winrow) + call assert_equal(1, winlist[1].wincol) + call assert_equal(tablineheight + winheight(1) + 2, winlist[1].winrow) call assert_equal(1, winlist[2].winnr) - call assert_equal(tablineheight, winlist[2].winrow) - call assert_equal(0, winlist[2].wincol) + call assert_equal(tablineheight + 1, winlist[2].winrow) + call assert_equal(1, winlist[2].wincol) - call assert_equal(winlist[2].width + 1, winlist[3].wincol) - call assert_equal(0, winlist[4].wincol) + call assert_equal(winlist[2].width + 2, winlist[3].wincol) + call assert_equal(1, winlist[4].wincol) call assert_equal(1, winlist[0].tabnr) call assert_equal(1, winlist[1].tabnr) diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim index 827c54e704..1010ae4e09 100644 --- a/src/nvim/testdir/test_edit.vim +++ b/src/nvim/testdir/test_edit.vim @@ -537,7 +537,7 @@ func! Test_edit_CTRL_I() " Tab in completion mode let path=expand("%:p:h") new - call setline(1, [path."/", '']) + call setline(1, [path. "/", '']) call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix') call assert_match('runtest\.vim', getline(1)) %d |