mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	vim-patch:8.2.5019: cannot get the first screen column of a character (#23312)
Problem:    Cannot get the first screen column of a character.
Solution:   Let virtcol() optionally return a list. (closes vim/vim#10482,
            closes vim/vim#7964)
0f7a3e1de6
Co-authored-by: LemonBoy <thatlemon@gmail.com>
			
			
This commit is contained in:
		@@ -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: >
 | 
			
		||||
 
 | 
			
		||||
@@ -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}},
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user