diff options
-rw-r--r-- | runtime/doc/builtin.txt | 39 | ||||
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 18 | ||||
-rw-r--r-- | test/old/testdir/test_functions.vim | 11 |
4 files changed, 53 insertions, 17 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index bf8d64ec02..d5607afdf5 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -546,7 +546,8 @@ undotree() List undo file tree uniq({list} [, {func} [, {dict}]]) List remove adjacent duplicates from a list values({dict}) List values in {dict} -virtcol({expr}) Number screen column of cursor or mark +virtcol({expr} [, {list}]) Number or List + screen column of cursor or mark virtcol2col({winid}, {lnum}, {col}) Number byte index of a character on screen visualmode([expr]) String last visual mode used @@ -637,6 +638,7 @@ add({object}, {expr}) *add()* and({expr}, {expr}) *and()* Bitwise AND on the two arguments. The arguments are converted to a number. A List, Dict or Float argument causes an error. + Also see `or()` and `xor()`. Example: > :let flag = and(bits, 0x80) < Can also be used as a |method|: > @@ -9070,7 +9072,7 @@ values({dict}) *values()* Can also be used as a |method|: > mydict->values() -virtcol({expr}) *virtcol()* +virtcol({expr} [, {list}]) *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 @@ -9079,13 +9081,17 @@ virtcol({expr}) *virtcol()* the <Tab>. For example, for a <Tab> in column 1, with 'ts' set to 8, it returns 8. |conceal| is ignored. For the byte position use |col()|. + For the use of {expr} see |col()|. - When 'virtualedit' is used {expr} can be [lnum, col, off], where - "off" is the offset in screen columns from the start of the - character. E.g., a position within a <Tab> or after the last - character. When "off" is omitted zero is used. - When Virtual editing is active in the current mode, a position - beyond the end of the line can be returned. |'virtualedit'| + + When 'virtualedit' is used {expr} can be [lnum, col, off], + where "off" is the offset in screen columns from the start of + the character. E.g., a position within a <Tab> or after the + last character. When "off" is omitted zero is used. When + Virtual editing is active in the current mode, a position + beyond the end of the line can be returned. Also see + |'virtualedit'| + The accepted positions are: . the cursor position $ the end of the cursor line (the result is the @@ -9097,11 +9103,22 @@ virtcol({expr}) *virtcol()* cursor is the end). When not in Visual mode 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 + character. + Note that only marks in the current file can be used. Examples: > - virtcol(".") with text "foo^Lbar", with cursor on the "^L", returns 5 - virtcol("$") with text "foo^Lbar", returns 9 - virtcol("'t") with text " there", with 't at 'h', returns 6 + " With text "foo^Lbar" and cursor on the "^L": + + virtcol(".") " returns 5 + virtcol(".", 1) " returns [4, 5] + virtcol("$") " returns 9 + + " With text " there", with 't at 'h': + + virtcol("'t") " returns 6 < The first column is 1. 0 is returned for an error. A more advanced example that echoes the maximum length of all lines: > diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 5babfa4809..357ecd5575 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -436,7 +436,7 @@ return { undotree={}, uniq={args={1, 3}, base=1}, values={args=1, base=1}, - virtcol={args=1, base=1}, + virtcol={args={1, 2}, base=1}, virtcol2col={args=3, base=1}, visualmode={args={0, 1}}, wait={args={2,3}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 2a5f1cb720..72e25411ff 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -9275,10 +9275,11 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tv_dict_add_list(dict, S_LEN("entries"), u_eval_tree(curbuf->b_u_oldhead)); } -/// "virtcol(string)" function +/// "virtcol(string, bool)" function static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - colnr_T vcol = 0; + colnr_T vcol_start = 0; + colnr_T vcol_end = 0; int fnum = curbuf->b_fnum; pos_T *fp = var2fpos(&argvars[0], false, &fnum, false); @@ -9293,11 +9294,18 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) fp->col = (colnr_T)len; } } - getvvcol(curwin, fp, NULL, NULL, &vcol); - vcol++; + getvvcol(curwin, fp, &vcol_start, NULL, &vcol_end); + vcol_start++; + vcol_end++; } - rettv->vval.v_number = vcol; + 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); + tv_list_append_number(rettv->vval.v_list, vcol_end); + } else { + rettv->vval.v_number = vcol_end; + } } /// "visualmode()" function diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index 78eab3aaa5..a1f34ea8b6 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -2607,4 +2607,15 @@ func Test_builtin_check() endfunc +" Test for virtcol() +func Test_virtcol() + enew! + 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)) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab |