diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-08-18 08:42:45 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-18 08:42:45 +0800 |
commit | f8afa8023ee032dfb2aa9a6489f51484fb276732 (patch) | |
tree | f1520e2fc6d990bd9cf9876bdf1bf126f5881431 | |
parent | 46163ddf5d718c4e749df78ef8e54d0715de6cb9 (diff) | |
download | rneovim-f8afa8023ee032dfb2aa9a6489f51484fb276732.tar.gz rneovim-f8afa8023ee032dfb2aa9a6489f51484fb276732.tar.bz2 rneovim-f8afa8023ee032dfb2aa9a6489f51484fb276732.zip |
vim-patch:9.0.1728: missing winid argument for virtcol() (#24770)
Problem: missing winid argument for virtcol()
Solution: Add a {winid} argument to virtcol()
Other functions col(), charcol() and virtcol2col() support a {winid}
argument, so it makes sense for virtcol() to also support than.
Also add test for virtcol2col() with 'showbreak' and {winid}.
closes: vim/vim#12633
https://github.com/vim/vim/commit/825cf813fa0fddf085fcbd3194781e875320ff63
-rw-r--r-- | runtime/doc/builtin.txt | 13 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/vimfn.lua | 14 | ||||
-rw-r--r-- | src/nvim/eval.lua | 17 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 27 | ||||
-rw-r--r-- | test/old/testdir/test_cursor_func.vim | 19 | ||||
-rw-r--r-- | test/old/testdir/test_functions.vim | 22 |
6 files changed, 92 insertions, 20 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 94e9223ee9..9a662761c4 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -8399,7 +8399,7 @@ values({dict}) *values()* in arbitrary order. Also see |items()| and |keys()|. Returns zero if {dict} is not a |Dict|. -virtcol({expr} [, {list}]) *virtcol()* +virtcol({expr} [, {list} [, {winid}]]) *virtcol()* The result is a Number, which is the screen column of the file position given with {expr}. That is, the last screen position occupied by the character at that position, when the screen @@ -8431,10 +8431,13 @@ virtcol({expr} [, {list}]) *virtcol()* returns the cursor position. Differs from |'<| in that it's updated right away. - If {list} is present and non-zero then virtcol() returns a List - with the first and last screen position occupied by the + If {list} is present and non-zero then virtcol() returns a + List with the first and last screen position occupied by the character. + With the optional {winid} argument the values are obtained for + that window instead of the current window. + Note that only marks in the current file can be used. Examples: >vim " With text "foo^Lbar" and cursor on the "^L": @@ -8446,8 +8449,8 @@ virtcol({expr} [, {list}]) *virtcol()* " With text " there", with 't at 'h': echo virtcol("'t") " returns 6 -< Techo he first column is 1. 0 is returned for an error. - A echo more advanced example that echoes the maximum length of +< The first column is 1. 0 or [0, 0] is returned for an error. + A more advanced example that echoes the maximum length of all lines: >vim echo max(map(range(1, line('$')), "virtcol([v:val, '$'])")) diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index ce325ce1f8..8ae6dd5f10 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -10013,10 +10013,13 @@ function vim.fn.values(dict) end --- returns the cursor position. Differs from |'<| in --- that it's updated right away. --- ---- If {list} is present and non-zero then virtcol() returns a List ---- with the first and last screen position occupied by the +--- If {list} is present and non-zero then virtcol() returns a +--- List with the first and last screen position occupied by the --- character. --- +--- With the optional {winid} argument the values are obtained for +--- that window instead of the current window. +--- --- Note that only marks in the current file can be used. --- Examples: >vim --- " With text "foo^Lbar" and cursor on the "^L": @@ -10028,15 +10031,16 @@ function vim.fn.values(dict) end --- " With text " there", with 't at 'h': --- --- echo virtcol("'t") " returns 6 ---- <Techo he first column is 1. 0 is returned for an error. ---- A echo more advanced example that echoes the maximum length of +--- <The first column is 1. 0 or [0, 0] is returned for an error. +--- A more advanced example that echoes the maximum length of --- all lines: >vim --- echo max(map(range(1, line('$')), "virtcol([v:val, '$'])")) --- --- @param expr any --- @param list? any +--- @param winid? integer --- @return any -function vim.fn.virtcol(expr, list) end +function vim.fn.virtcol(expr, list, winid) end --- The result is a Number, which is the byte index of the --- character in window {winid} at buffer line {lnum} and virtual diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e019e8fcab..2b89d34a6d 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -11893,7 +11893,7 @@ M.funcs = { signature = 'values({dict})', }, virtcol = { - args = { 1, 2 }, + args = { 1, 3 }, base = 1, desc = [=[ The result is a Number, which is the screen column of the file @@ -11927,10 +11927,13 @@ M.funcs = { returns the cursor position. Differs from |'<| in that it's updated right away. - If {list} is present and non-zero then virtcol() returns a List - with the first and last screen position occupied by the + If {list} is present and non-zero then virtcol() returns a + List with the first and last screen position occupied by the character. + With the optional {winid} argument the values are obtained for + that window instead of the current window. + Note that only marks in the current file can be used. Examples: >vim " With text "foo^Lbar" and cursor on the "^L": @@ -11942,15 +11945,15 @@ M.funcs = { " With text " there", with 't at 'h': echo virtcol("'t") " returns 6 - <Techo he first column is 1. 0 is returned for an error. - A echo more advanced example that echoes the maximum length of + <The first column is 1. 0 or [0, 0] is returned for an error. + A more advanced example that echoes the maximum length of all lines: >vim echo max(map(range(1, line('$')), "virtcol([v:val, '$'])")) ]=], name = 'virtcol', - params = { { 'expr', 'any' }, { 'list', 'any' } }, - signature = 'virtcol({expr} [, {list}])', + params = { { 'expr', 'any' }, { 'list', 'any' }, { 'winid', 'integer' } }, + signature = 'virtcol({expr} [, {list} [, {winid}]])', }, virtcol2col = { args = 3, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index e8224671dc..9926530d58 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -8748,13 +8748,31 @@ static void f_type(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_number = n; } -/// "virtcol(string, bool)" function +/// "virtcol({expr}, [, {list} [, {winid}]])" function static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { colnr_T vcol_start = 0; colnr_T vcol_end = 0; - int fnum = curbuf->b_fnum; + switchwin_T switchwin; + bool winchanged = false; + + if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { + // use the window specified in the third argument + tabpage_T *tp; + win_T *wp = win_id2wp_tp((int)tv_get_number(&argvars[2]), &tp); + if (wp == NULL || tp == NULL) { + goto theend; + } + if (switch_win_noblock(&switchwin, wp, tp, true) != OK) { + goto theend; + } + + check_cursor(); + winchanged = true; + } + + int fnum = curbuf->b_fnum; pos_T *fp = var2fpos(&argvars[0], false, &fnum, false); if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count && fnum == curbuf->b_fnum) { @@ -8772,6 +8790,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) vcol_end++; } +theend: if (argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1])) { tv_list_alloc_ret(rettv, 2); tv_list_append_number(rettv->vval.v_list, vcol_start); @@ -8779,6 +8798,10 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } else { rettv->vval.v_number = vcol_end; } + + if (winchanged) { + restore_win_noblock(&switchwin, true); + } } /// "visualmode()" function diff --git a/test/old/testdir/test_cursor_func.vim b/test/old/testdir/test_cursor_func.vim index 3d6ad8405c..e8b30226de 100644 --- a/test/old/testdir/test_cursor_func.vim +++ b/test/old/testdir/test_cursor_func.vim @@ -540,9 +540,28 @@ func Test_virtcol2col() call assert_equal(8, virtcol2col(0, 1, 7)) call assert_equal(8, virtcol2col(0, 1, 8)) + let w = winwidth(0) + call setline(2, repeat('a', w + 2)) + let win_nosbr = win_getid() + split + setlocal showbreak=!! + let win_sbr = win_getid() + call assert_equal(w, virtcol2col(win_nosbr, 2, w)) + call assert_equal(w + 1, virtcol2col(win_nosbr, 2, w + 1)) + call assert_equal(w + 2, virtcol2col(win_nosbr, 2, w + 2)) + call assert_equal(w + 2, virtcol2col(win_nosbr, 2, w + 3)) + call assert_equal(w, virtcol2col(win_sbr, 2, w)) + call assert_equal(w + 1, virtcol2col(win_sbr, 2, w + 1)) + call assert_equal(w + 1, virtcol2col(win_sbr, 2, w + 2)) + call assert_equal(w + 1, virtcol2col(win_sbr, 2, w + 3)) + call assert_equal(w + 2, virtcol2col(win_sbr, 2, w + 4)) + call assert_equal(w + 2, virtcol2col(win_sbr, 2, w + 5)) + close + call assert_fails('echo virtcol2col("0", 1, 20)', 'E1210:') call assert_fails('echo virtcol2col(0, "1", 20)', 'E1210:') call assert_fails('echo virtcol2col(0, 1, "1")', 'E1210:') + bw! endfunc diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index e286090018..c91e989233 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -3093,12 +3093,32 @@ endfunc " Test for virtcol() func Test_virtcol() - enew! + new call setline(1, "the\tquick\tbrown\tfox") norm! 4| call assert_equal(8, virtcol('.')) call assert_equal(8, virtcol('.', v:false)) call assert_equal([4, 8], virtcol('.', v:true)) + + let w = winwidth(0) + call setline(2, repeat('a', w + 2)) + let win_nosbr = win_getid() + split + setlocal showbreak=!! + let win_sbr = win_getid() + call assert_equal([w, w], virtcol([2, w], v:true, win_nosbr)) + call assert_equal([w + 1, w + 1], virtcol([2, w + 1], v:true, win_nosbr)) + call assert_equal([w + 2, w + 2], virtcol([2, w + 2], v:true, win_nosbr)) + call assert_equal([w, w], virtcol([2, w], v:true, win_sbr)) + call assert_equal([w + 3, w + 3], virtcol([2, w + 1], v:true, win_sbr)) + call assert_equal([w + 4, w + 4], virtcol([2, w + 2], v:true, win_sbr)) + close + + call assert_equal(0, virtcol('')) + call assert_equal([0, 0], virtcol('', v:true)) + call assert_equal(0, virtcol('.', v:false, 5001)) + call assert_equal([0, 0], virtcol('.', v:true, 5001)) + bwipe! endfunc |