mirror of
https://github.com/vim/vim.git
synced 2025-07-25 10:54:51 -04:00
patch 8.2.2324: not easy to get mark en cursor posotion by character count
Problem: Not easy to get mark en cursor posotion by character count. Solution: Add functions that use character index. (Yegappan Lakshmanan, closes #7648)
This commit is contained in:
parent
31a11b942a
commit
6f02b00bb0
@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.2. Last change: 2020 Dec 29
|
||||
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 10
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -49,7 +49,7 @@ There are ten types of variables:
|
||||
*Number* *Integer*
|
||||
Number A 32 or 64 bit signed number. |expr-number|
|
||||
The number of bits is available in |v:numbersize|.
|
||||
Examples: -123 0x10 0177 0b1011
|
||||
Examples: -123 0x10 0177 0o177 0b1011
|
||||
|
||||
Float A floating point number. |floating-point-format| *Float*
|
||||
{only when compiled with the |+float| feature}
|
||||
@ -97,9 +97,10 @@ the Number. Examples:
|
||||
Conversion from a String to a Number only happens in legacy Vim script, not in
|
||||
Vim9 script. It is done by converting the first digits to a number.
|
||||
Hexadecimal "0xf9", Octal "017" or "0o17", and Binary "0b10"
|
||||
numbers are recognized (NOTE: when using |scriptversion-4| octal with a
|
||||
leading "0" is not recognized). If the String doesn't start with digits, the
|
||||
result is zero.
|
||||
numbers are recognized
|
||||
NOTE: when using |scriptversion-4| octal with a leading "0" is not recognized.
|
||||
The 0o notation requires patch 8.2.0886.
|
||||
If the String doesn't start with digits, the result is zero.
|
||||
Examples:
|
||||
String "456" --> Number 456 ~
|
||||
String "6bar" --> Number 6 ~
|
||||
@ -1150,7 +1151,7 @@ expr7 *expr7*
|
||||
|
||||
For '!' |TRUE| becomes |FALSE|, |FALSE| becomes |TRUE| (one).
|
||||
For '-' the sign of the number is changed.
|
||||
For '+' the number is unchanged.
|
||||
For '+' the number is unchanged. Note: "++" has no effect.
|
||||
|
||||
A String will be converted to a Number first.
|
||||
|
||||
@ -1191,6 +1192,7 @@ start with one!
|
||||
If the length of the String is less than the index, the result is an empty
|
||||
String. A negative index always results in an empty string (reason: backward
|
||||
compatibility). Use [-1:] to get the last byte or character.
|
||||
In Vim9 script a negative index is used like with a list: count from the end.
|
||||
|
||||
If expr8 is a |List| then it results the item at index expr1. See |list-index|
|
||||
for possible index values. If the index is out of range this results in an
|
||||
@ -1318,8 +1320,8 @@ When using the lambda form there must be no white space between the } and the
|
||||
number
|
||||
------
|
||||
number number constant *expr-number*
|
||||
*hex-number* *octal-number* *binary-number*
|
||||
|
||||
*0x* *hex-number* *0o* *octal-number* *binary-number*
|
||||
Decimal, Hexadecimal (starting with 0x or 0X), Binary (starting with 0b or 0B)
|
||||
and Octal (starting with 0, 0o or 0O).
|
||||
|
||||
@ -1572,7 +1574,7 @@ Note how execute() is used to execute an Ex command. That's ugly though.
|
||||
|
||||
Lambda expressions have internal names like '<lambda>42'. If you get an error
|
||||
for a lambda expression, you can find what it is with the following command: >
|
||||
:function {'<lambda>42'}
|
||||
:function <lambda>42
|
||||
See also: |numbered-function|
|
||||
|
||||
==============================================================================
|
||||
@ -2475,12 +2477,13 @@ ch_status({handle} [, {options}])
|
||||
changenr() Number current change number
|
||||
char2nr({expr} [, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
|
||||
charclass({string}) Number character class of {string}
|
||||
charcol({expr}) Number column number of cursor or mark
|
||||
charidx({string}, {idx} [, {countcc}])
|
||||
Number char index of byte {idx} in {string}
|
||||
chdir({dir}) String change current working directory
|
||||
cindent({lnum}) Number C indent for line {lnum}
|
||||
clearmatches([{win}]) none clear all matches
|
||||
col({expr}) Number column nr of cursor or mark
|
||||
col({expr}) Number column byte index of cursor or mark
|
||||
complete({startcol}, {matches}) none set Insert mode completion
|
||||
complete_add({expr}) Number add completion match
|
||||
complete_check() Number check for key typed during completion
|
||||
@ -2558,6 +2561,7 @@ getbufvar({expr}, {varname} [, {def}])
|
||||
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
|
||||
getcharpos({expr}) List position of cursor, mark, etc.
|
||||
getcharsearch() Dict last character search
|
||||
getcmdline() String return the current command-line
|
||||
getcmdpos() Number return cursor position in command-line
|
||||
@ -2566,6 +2570,7 @@ getcmdwintype() String return current command-line window type
|
||||
getcompletion({pat}, {type} [, {filtered}])
|
||||
List list of cmdline completion matches
|
||||
getcurpos([{winnr}]) List position of the cursor
|
||||
getcursorcharpos([{winnr}]) List character position of the cursor
|
||||
getcwd([{winnr} [, {tabnr}]]) String get the current working directory
|
||||
getenv({name}) String return environment variable
|
||||
getfontname([{name}]) String name of font being used
|
||||
@ -2828,8 +2833,10 @@ setbufline({expr}, {lnum}, {text})
|
||||
setbufvar({expr}, {varname}, {val})
|
||||
none set {varname} in buffer {expr} to {val}
|
||||
setcellwidths({list}) none set character cell width overrides
|
||||
setcharpos({expr}, {list}) Number set the {expr} position to {list}
|
||||
setcharsearch({dict}) Dict set character search from {dict}
|
||||
setcmdpos({pos}) Number set cursor position in command-line
|
||||
setcursorcharpos({list}) Number move cursor to position in {list}
|
||||
setenv({name}, {val}) none set environment variable
|
||||
setfperm({fname}, {mode}) Number set {fname} file permissions to {mode}
|
||||
setline({lnum}, {line}) Number set line {lnum} to {line}
|
||||
@ -3513,8 +3520,8 @@ byteidxcomp({expr}, {nr}) *byteidxcomp()*
|
||||
< The first and third echo result in 3 ('e' plus composing
|
||||
character is 3 bytes), the second echo results in 1 ('e' is
|
||||
one byte).
|
||||
Only works differently from byteidx() when 'encoding' is set to
|
||||
a Unicode encoding.
|
||||
Only works differently from byteidx() when 'encoding' is set
|
||||
to a Unicode encoding.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetName()->byteidxcomp(idx)
|
||||
@ -3590,6 +3597,18 @@ charclass({string}) *charclass()*
|
||||
other specific Unicode class
|
||||
The class is used in patterns and word motions.
|
||||
|
||||
*charcol()*
|
||||
charcol({expr}) Same as |col()| but returns the character index of the column
|
||||
position given with {expr} instead of the byte position.
|
||||
|
||||
Example:
|
||||
With the cursor on '세' in line 5 with text "여보세요": >
|
||||
charcol('.') returns 3
|
||||
col('.') returns 7
|
||||
|
||||
< Can also be used as a |method|: >
|
||||
GetPos()->col()
|
||||
<
|
||||
*charidx()*
|
||||
charidx({string}, {idx} [, {countcc}])
|
||||
Return the character index of the byte at {idx} in {string}.
|
||||
@ -3680,7 +3699,8 @@ col({expr}) The result is a Number, which is the byte index of the column
|
||||
out of range then col() returns zero.
|
||||
To get the line number use |line()|. To get both use
|
||||
|getpos()|.
|
||||
For the screen column position use |virtcol()|.
|
||||
For the screen column position use |virtcol()|. For the
|
||||
character position use |charcol()|.
|
||||
Note that only marks in the current file can be used.
|
||||
Examples: >
|
||||
col(".") column of cursor
|
||||
@ -3981,6 +4001,9 @@ cursor({list})
|
||||
This is like the return value of |getpos()| or |getcurpos()|,
|
||||
but without the first item.
|
||||
|
||||
To position the cursor using the character count, use
|
||||
|setcursorcharpos()|.
|
||||
|
||||
Does not change the jumplist.
|
||||
If {lnum} is greater than the number of lines in the buffer,
|
||||
the cursor will be positioned at the last line in the buffer.
|
||||
@ -5220,6 +5243,20 @@ getcharmod() *getcharmod()*
|
||||
character itself are obtained. Thus Shift-a results in "A"
|
||||
without a modifier.
|
||||
|
||||
*getcharpos()*
|
||||
getcharpos({expr})
|
||||
Get the position for {expr}. Same as |getpos()| but the column
|
||||
number in the returned List is a character index instead of
|
||||
a byte index.
|
||||
|
||||
Example:
|
||||
With the cursor on '세' in line 5 with text "여보세요": >
|
||||
getcharpos('.') returns [0, 5, 3, 0]
|
||||
getpos('.') returns [0, 5, 7, 0]
|
||||
<
|
||||
Can also be used as a |method|: >
|
||||
GetMark()->getcharpos()
|
||||
|
||||
getcharsearch() *getcharsearch()*
|
||||
Return the current character search information as a {dict}
|
||||
with the following entries:
|
||||
@ -5345,8 +5382,11 @@ getcurpos([{winid}])
|
||||
includes an extra "curswant" item in the list:
|
||||
[0, lnum, col, off, curswant] ~
|
||||
The "curswant" number is the preferred column when moving the
|
||||
cursor vertically. Also see |getpos()|.
|
||||
The first "bufnum" item is always zero.
|
||||
cursor vertically. Also see |getcursorcharpos()| and
|
||||
|getpos()|.
|
||||
The first "bufnum" item is always zero. The byte position of
|
||||
the cursor is returned in 'col'. To get the character
|
||||
position, use |getcursorcharpos()|.
|
||||
|
||||
The optional {winid} argument can specify the window. It can
|
||||
be the window number or the |window-ID|. The last known
|
||||
@ -5360,7 +5400,24 @@ getcurpos([{winid}])
|
||||
call setpos('.', save_cursor)
|
||||
< Note that this only works within the window. See
|
||||
|winrestview()| for restoring more state.
|
||||
*getcwd()*
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetWinid()->getcurpos()
|
||||
|
||||
< *getcursorcharpos()*
|
||||
getcursorcharpos([{winid}])
|
||||
Same as |getcurpos()| but the column number in the returned
|
||||
List is a character index instead of a byte index.
|
||||
|
||||
Example:
|
||||
With the cursor on '보' in line 3 with text "여보세요": >
|
||||
getcursorcharpos() returns [0, 3, 2, 0, 3]
|
||||
getcurpos() returns [0, 3, 4, 0, 3]
|
||||
|
||||
< Can also be used as a |method|: >
|
||||
GetWinid()->getcursorcharpos()
|
||||
|
||||
< *getcwd()*
|
||||
getcwd([{winnr} [, {tabnr}]])
|
||||
The result is a String, which is the name of the current
|
||||
working directory.
|
||||
@ -5667,16 +5724,18 @@ getpos({expr}) Get the position for {expr}. For possible values of {expr}
|
||||
Note that for '< and '> Visual mode matters: when it is "V"
|
||||
(visual line mode) the column of '< is zero and the column of
|
||||
'> is a large number.
|
||||
The column number in the returned List is the byte position
|
||||
within the line. To get the character position in the line,
|
||||
use |getcharpos()|
|
||||
This can be used to save and restore the position of a mark: >
|
||||
let save_a_mark = getpos("'a")
|
||||
...
|
||||
call setpos("'a", save_a_mark)
|
||||
< Also see |getcurpos()| and |setpos()|.
|
||||
< Also see |getcharpos()|, |getcurpos()| and |setpos()|.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetMark()->getpos()
|
||||
|
||||
|
||||
getqflist([{what}]) *getqflist()*
|
||||
Returns a |List| with all the current quickfix errors. Each
|
||||
list item is a dictionary with these entries:
|
||||
@ -7542,8 +7601,10 @@ matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()*
|
||||
<
|
||||
|
||||
*max()*
|
||||
max({expr}) Return the maximum value of all items in {expr}.
|
||||
{expr} can be a |List| or a |Dictionary|. For a Dictionary,
|
||||
max({expr}) Return the maximum value of all items in {expr}. Example: >
|
||||
echo max([apples, pears, oranges])
|
||||
|
||||
< {expr} can be a |List| or a |Dictionary|. For a Dictionary,
|
||||
it returns the maximum of all values in the Dictionary.
|
||||
If {expr} is neither a List nor a Dictionary, or one of the
|
||||
items in {expr} cannot be used as a Number this results in
|
||||
@ -7613,8 +7674,10 @@ menu_info({name} [, {mode}]) *menu_info()*
|
||||
|
||||
|
||||
< *min()*
|
||||
min({expr}) Return the minimum value of all items in {expr}.
|
||||
{expr} can be a |List| or a |Dictionary|. For a Dictionary,
|
||||
min({expr}) Return the minimum value of all items in {expr}. Example: >
|
||||
echo min([apples, pears, oranges])
|
||||
|
||||
< {expr} can be a |List| or a |Dictionary|. For a Dictionary,
|
||||
it returns the minimum of all values in the Dictionary.
|
||||
If {expr} is neither a List nor a Dictionary, or one of the
|
||||
items in {expr} cannot be used as a Number this results in
|
||||
@ -7631,13 +7694,13 @@ mkdir({name} [, {path} [, {prot}]])
|
||||
necessary. Otherwise it must be "".
|
||||
|
||||
If {prot} is given it is used to set the protection bits of
|
||||
the new directory. The default is 0755 (rwxr-xr-x: r/w for
|
||||
the user readable for others). Use 0700 to make it unreadable
|
||||
for others. This is only used for the last part of {name}.
|
||||
Thus if you create /tmp/foo/bar then /tmp/foo will be created
|
||||
with 0755.
|
||||
the new directory. The default is 0o755 (rwxr-xr-x: r/w for
|
||||
the user, readable for others). Use 0o700 to make it
|
||||
unreadable for others. This is only used for the last part of
|
||||
{name}. Thus if you create /tmp/foo/bar then /tmp/foo will be
|
||||
created with 0o755.
|
||||
Example: >
|
||||
:call mkdir($HOME . "/tmp/foo/bar", "p", 0700)
|
||||
:call mkdir($HOME . "/tmp/foo/bar", "p", 0o700)
|
||||
|
||||
< This function is not available in the |sandbox|.
|
||||
|
||||
@ -9200,6 +9263,19 @@ setcellwidths({list}) *setcellwidths()*
|
||||
< You can use the script $VIMRUNTIME/tools/emoji_list.vim to see
|
||||
the effect for known emoji characters.
|
||||
|
||||
setcharpos({expr}, {list}) *setcharpos()*
|
||||
Same as |setpos()| but uses the specified column number as the
|
||||
character index instead of the byte index in the line.
|
||||
|
||||
Example:
|
||||
With the text "여보세요" in line 8: >
|
||||
call setcharpos('.', [0, 8, 4, 0])
|
||||
< positions the cursor on the fourth character '요'. >
|
||||
call setpos('.', [0, 8, 4, 0])
|
||||
< positions the cursor on the second character '보'.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetPosition()->setcharpos('.')
|
||||
|
||||
setcharsearch({dict}) *setcharsearch()*
|
||||
Set the current character search information to {dict},
|
||||
@ -9242,6 +9318,21 @@ setcmdpos({pos}) *setcmdpos()*
|
||||
Can also be used as a |method|: >
|
||||
GetPos()->setcmdpos()
|
||||
|
||||
setcursorcharpos({lnum}, {col} [, {off}]) *setcursorcharpos()*
|
||||
setcursorcharpos({list})
|
||||
Same as |cursor()| but uses the specified column number as the
|
||||
character index instead of the byte index in the line.
|
||||
|
||||
Example:
|
||||
With the text "여보세요" in line 4: >
|
||||
call setcursorcharpos(4, 3)
|
||||
< positions the cursor on the third character '세'. >
|
||||
call cursor(4, 3)
|
||||
< positions the cursor on the first character '여'.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetCursorPos()->setcursorcharpos()
|
||||
|
||||
setenv({name}, {val}) *setenv()*
|
||||
Set environment variable {name} to {val}.
|
||||
When {val} is |v:null| the environment variable is deleted.
|
||||
@ -9353,7 +9444,8 @@ setpos({expr}, {list})
|
||||
|
||||
"lnum" and "col" are the position in the buffer. The first
|
||||
column is 1. Use a zero "lnum" to delete a mark. If "col" is
|
||||
smaller than 1 then 1 is used.
|
||||
smaller than 1 then 1 is used. To use the character count
|
||||
instead of the byte count, use |setcharpos()|.
|
||||
|
||||
The "off" number is only used when 'virtualedit' is set. Then
|
||||
it is the offset in screen columns from the start of the
|
||||
@ -9373,7 +9465,7 @@ setpos({expr}, {list})
|
||||
Returns 0 when the position could be set, -1 otherwise.
|
||||
An error message is given if {expr} is invalid.
|
||||
|
||||
Also see |getpos()| and |getcurpos()|.
|
||||
Also see |setcharpos()|, |getpos()| and |getcurpos()|.
|
||||
|
||||
This does not restore the preferred column for moving
|
||||
vertically; if you set the cursor position with this, |j| and
|
||||
|
@ -753,6 +753,11 @@ Cursor and mark position: *cursor-functions* *mark-functions*
|
||||
screenchar() get character code at a screen line/row
|
||||
screenchars() get character codes at a screen line/row
|
||||
screenstring() get string of characters at a screen line/row
|
||||
charcol() character number of the cursor or a mark
|
||||
getcharpos() get character position of cursor, mark, etc.
|
||||
setcharpos() set character position of cursor, mark, etc.
|
||||
getcursorcharpos() get character position of the cursor
|
||||
setcursorcharpos() set character position of the cursor
|
||||
|
||||
Working with text in the current buffer: *text-functions*
|
||||
getline() get a line or list of lines from the buffer
|
||||
|
100
src/eval.c
100
src/eval.c
@ -5053,6 +5053,61 @@ string2float(
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert the specified byte index of line 'lnum' in buffer 'buf' to a
|
||||
* character index. Works only for loaded buffers. Returns -1 on failure.
|
||||
* The index of the first character is one.
|
||||
*/
|
||||
int
|
||||
buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx)
|
||||
{
|
||||
char_u *str;
|
||||
|
||||
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
|
||||
return -1;
|
||||
|
||||
if (lnum > buf->b_ml.ml_line_count)
|
||||
lnum = buf->b_ml.ml_line_count;
|
||||
|
||||
str = ml_get_buf(buf, lnum, FALSE);
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
if (*str == NUL)
|
||||
return 1;
|
||||
|
||||
return mb_charlen_len(str, byteidx + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the specified character index of line 'lnum' in buffer 'buf' to a
|
||||
* byte index. Works only for loaded buffers. Returns -1 on failure. The index
|
||||
* of the first byte and the first character is one.
|
||||
*/
|
||||
int
|
||||
buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx)
|
||||
{
|
||||
char_u *str;
|
||||
char_u *t;
|
||||
|
||||
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
|
||||
return -1;
|
||||
|
||||
if (lnum > buf->b_ml.ml_line_count)
|
||||
lnum = buf->b_ml.ml_line_count;
|
||||
|
||||
str = ml_get_buf(buf, lnum, FALSE);
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
// Convert the character offset to a byte offset
|
||||
t = str;
|
||||
while (*t != NUL && --charidx > 0)
|
||||
t += mb_ptr2len(t);
|
||||
|
||||
return t - str + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a String variable into a position.
|
||||
* Returns NULL when there is an error.
|
||||
@ -5061,7 +5116,8 @@ string2float(
|
||||
var2fpos(
|
||||
typval_T *varp,
|
||||
int dollar_lnum, // TRUE when $ is last line
|
||||
int *fnum) // set to fnum for '0, 'A, etc.
|
||||
int *fnum, // set to fnum for '0, 'A, etc.
|
||||
int charcol) // return character column
|
||||
{
|
||||
char_u *name;
|
||||
static pos_T pos;
|
||||
@ -5083,7 +5139,10 @@ var2fpos(
|
||||
pos.lnum = list_find_nr(l, 0L, &error);
|
||||
if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
|
||||
return NULL; // invalid line number
|
||||
len = (long)STRLEN(ml_get(pos.lnum));
|
||||
if (charcol)
|
||||
len = (long)mb_charlen(ml_get(pos.lnum));
|
||||
else
|
||||
len = (long)STRLEN(ml_get(pos.lnum));
|
||||
|
||||
// Get the column number
|
||||
// We accept "$" for the column number: last column.
|
||||
@ -5118,18 +5177,29 @@ var2fpos(
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
if (name[0] == '.') // cursor
|
||||
return &curwin->w_cursor;
|
||||
{
|
||||
pos = curwin->w_cursor;
|
||||
if (charcol)
|
||||
pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1;
|
||||
return &pos;
|
||||
}
|
||||
if (name[0] == 'v' && name[1] == NUL) // Visual start
|
||||
{
|
||||
if (VIsual_active)
|
||||
return &VIsual;
|
||||
return &curwin->w_cursor;
|
||||
pos = VIsual;
|
||||
else
|
||||
pos = curwin->w_cursor;
|
||||
if (charcol)
|
||||
pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1;
|
||||
return &pos;
|
||||
}
|
||||
if (name[0] == '\'') // mark
|
||||
{
|
||||
pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
|
||||
if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
|
||||
return NULL;
|
||||
if (charcol)
|
||||
pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col) - 1;
|
||||
return pp;
|
||||
}
|
||||
|
||||
@ -5164,7 +5234,10 @@ var2fpos(
|
||||
else
|
||||
{
|
||||
pos.lnum = curwin->w_cursor.lnum;
|
||||
pos.col = (colnr_T)STRLEN(ml_get_curline());
|
||||
if (charcol)
|
||||
pos.col = (colnr_T)mb_charlen(ml_get_curline());
|
||||
else
|
||||
pos.col = (colnr_T)STRLEN(ml_get_curline());
|
||||
}
|
||||
return &pos;
|
||||
}
|
||||
@ -5184,7 +5257,8 @@ list2fpos(
|
||||
typval_T *arg,
|
||||
pos_T *posp,
|
||||
int *fnump,
|
||||
colnr_T *curswantp)
|
||||
colnr_T *curswantp,
|
||||
int charcol)
|
||||
{
|
||||
list_T *l = arg->vval.v_list;
|
||||
long i = 0;
|
||||
@ -5216,6 +5290,18 @@ list2fpos(
|
||||
n = list_find_nr(l, i++, NULL); // col
|
||||
if (n < 0)
|
||||
return FAIL;
|
||||
// If character position is specified, then convert to byte position
|
||||
if (charcol)
|
||||
{
|
||||
buf_T *buf;
|
||||
|
||||
// Get the text for the specified line in a loaded buffer
|
||||
buf = buflist_findnr(fnump == NULL ? curbuf->b_fnum : *fnump);
|
||||
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
|
||||
return FAIL;
|
||||
|
||||
n = buf_charidx_to_byteidx(buf, posp->lnum, n);
|
||||
}
|
||||
posp->col = n;
|
||||
|
||||
n = list_find_nr(l, i, NULL); // off
|
||||
|
406
src/evalfunc.c
406
src/evalfunc.c
@ -47,6 +47,7 @@ static void f_ceil(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_changenr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_char2nr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_charcol(typval_T *argvars, typval_T *rettv);
|
||||
static void f_charidx(typval_T *argvars, typval_T *rettv);
|
||||
static void f_col(typval_T *argvars, typval_T *rettv);
|
||||
static void f_confirm(typval_T *argvars, typval_T *rettv);
|
||||
@ -87,12 +88,14 @@ static void f_function(typval_T *argvars, typval_T *rettv);
|
||||
static void f_garbagecollect(typval_T *argvars, typval_T *rettv);
|
||||
static void f_get(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getchangelist(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getcharpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getcharsearch(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getenv(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getfontname(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getjumplist(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getpid(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getcurpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getreg(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getreginfo(typval_T *argvars, typval_T *rettv);
|
||||
@ -190,7 +193,9 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv);
|
||||
static void f_searchpair(typval_T *argvars, typval_T *rettv);
|
||||
static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_searchpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setcharpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setcursorcharpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setenv(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setfperm(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setpos(typval_T *argvars, typval_T *rettv);
|
||||
@ -790,6 +795,8 @@ static funcentry_T global_functions[] =
|
||||
ret_number, f_char2nr},
|
||||
{"charclass", 1, 1, FEARG_1, NULL,
|
||||
ret_number, f_charclass},
|
||||
{"charcol", 1, 1, FEARG_1, NULL,
|
||||
ret_number, f_charcol},
|
||||
{"charidx", 2, 3, FEARG_1, NULL,
|
||||
ret_number, f_charidx},
|
||||
{"chdir", 1, 1, FEARG_1, NULL,
|
||||
@ -928,6 +935,8 @@ static funcentry_T global_functions[] =
|
||||
ret_number, f_getchar},
|
||||
{"getcharmod", 0, 0, 0, NULL,
|
||||
ret_number, f_getcharmod},
|
||||
{"getcharpos", 1, 1, FEARG_1, NULL,
|
||||
ret_list_number, f_getcharpos},
|
||||
{"getcharsearch", 0, 0, 0, NULL,
|
||||
ret_dict_any, f_getcharsearch},
|
||||
{"getcmdline", 0, 0, 0, NULL,
|
||||
@ -942,6 +951,8 @@ static funcentry_T global_functions[] =
|
||||
ret_list_string, f_getcompletion},
|
||||
{"getcurpos", 0, 1, FEARG_1, NULL,
|
||||
ret_list_number, f_getcurpos},
|
||||
{"getcursorcharpos", 0, 1, FEARG_1, NULL,
|
||||
ret_list_number, f_getcursorcharpos},
|
||||
{"getcwd", 0, 2, FEARG_1, NULL,
|
||||
ret_string, f_getcwd},
|
||||
{"getenv", 1, 1, FEARG_1, NULL,
|
||||
@ -1394,10 +1405,14 @@ static funcentry_T global_functions[] =
|
||||
ret_void, f_setbufvar},
|
||||
{"setcellwidths", 1, 1, FEARG_1, NULL,
|
||||
ret_void, f_setcellwidths},
|
||||
{"setcharpos", 2, 2, FEARG_2, NULL,
|
||||
ret_number, f_setcharpos},
|
||||
{"setcharsearch", 1, 1, FEARG_1, NULL,
|
||||
ret_void, f_setcharsearch},
|
||||
{"setcmdpos", 1, 1, FEARG_1, NULL,
|
||||
ret_number, f_setcmdpos},
|
||||
{"setcursorcharpos", 1, 3, FEARG_1, NULL,
|
||||
ret_number, f_setcursorcharpos},
|
||||
{"setenv", 2, 2, FEARG_2, NULL,
|
||||
ret_void, f_setenv},
|
||||
{"setfperm", 2, 2, FEARG_1, NULL,
|
||||
@ -2423,6 +2438,61 @@ f_char2nr(typval_T *argvars, typval_T *rettv)
|
||||
rettv->vval.v_number = tv_get_string(&argvars[0])[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current cursor column and store it in 'rettv'. If 'charcol' is TRUE,
|
||||
* returns the character index of the column. Otherwise, returns the byte index
|
||||
* of the column.
|
||||
*/
|
||||
static void
|
||||
get_col(typval_T *argvars, typval_T *rettv, int charcol)
|
||||
{
|
||||
colnr_T col = 0;
|
||||
pos_T *fp;
|
||||
int fnum = curbuf->b_fnum;
|
||||
|
||||
fp = var2fpos(&argvars[0], FALSE, &fnum, charcol);
|
||||
if (fp != NULL && fnum == curbuf->b_fnum)
|
||||
{
|
||||
if (fp->col == MAXCOL)
|
||||
{
|
||||
// '> can be MAXCOL, get the length of the line then
|
||||
if (fp->lnum <= curbuf->b_ml.ml_line_count)
|
||||
col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
|
||||
else
|
||||
col = MAXCOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
col = fp->col + 1;
|
||||
// col(".") when the cursor is on the NUL at the end of the line
|
||||
// because of "coladd" can be seen as an extra column.
|
||||
if (virtual_active() && fp == &curwin->w_cursor)
|
||||
{
|
||||
char_u *p = ml_get_cursor();
|
||||
|
||||
if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
|
||||
curwin->w_virtcol - curwin->w_cursor.coladd))
|
||||
{
|
||||
int l;
|
||||
|
||||
if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
|
||||
col += l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rettv->vval.v_number = col;
|
||||
}
|
||||
|
||||
/*
|
||||
* "charcol()" function
|
||||
*/
|
||||
static void
|
||||
f_charcol(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
get_col(argvars, rettv, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "charidx()" function
|
||||
*/
|
||||
@ -2497,42 +2567,7 @@ get_optional_window(typval_T *argvars, int idx)
|
||||
static void
|
||||
f_col(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
colnr_T col = 0;
|
||||
pos_T *fp;
|
||||
int fnum = curbuf->b_fnum;
|
||||
|
||||
fp = var2fpos(&argvars[0], FALSE, &fnum);
|
||||
if (fp != NULL && fnum == curbuf->b_fnum)
|
||||
{
|
||||
if (fp->col == MAXCOL)
|
||||
{
|
||||
// '> can be MAXCOL, get the length of the line then
|
||||
if (fp->lnum <= curbuf->b_ml.ml_line_count)
|
||||
col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
|
||||
else
|
||||
col = MAXCOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
col = fp->col + 1;
|
||||
// col(".") when the cursor is on the NUL at the end of the line
|
||||
// because of "coladd" can be seen as an extra column.
|
||||
if (virtual_active() && fp == &curwin->w_cursor)
|
||||
{
|
||||
char_u *p = ml_get_cursor();
|
||||
|
||||
if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
|
||||
curwin->w_virtcol - curwin->w_cursor.coladd))
|
||||
{
|
||||
int l;
|
||||
|
||||
if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
|
||||
col += l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rettv->vval.v_number = col;
|
||||
get_col(argvars, rettv, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2633,26 +2668,24 @@ f_cosh(typval_T *argvars, typval_T *rettv)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "cursor(lnum, col)" function, or
|
||||
* "cursor(list)"
|
||||
*
|
||||
* Moves the cursor to the specified line and column.
|
||||
* Returns 0 when the position could be set, -1 otherwise.
|
||||
* Set the cursor position.
|
||||
* If 'charcol' is TRUE, then use the column number as a character offet.
|
||||
* Otherwise use the column number as a byte offset.
|
||||
*/
|
||||
static void
|
||||
f_cursor(typval_T *argvars, typval_T *rettv)
|
||||
set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol)
|
||||
{
|
||||
long line, col;
|
||||
long coladd = 0;
|
||||
int set_curswant = TRUE;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
if (argvars[1].v_type == VAR_UNKNOWN)
|
||||
if (argvars[0].v_type == VAR_LIST)
|
||||
{
|
||||
pos_T pos;
|
||||
colnr_T curswant = -1;
|
||||
|
||||
if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL)
|
||||
if (list2fpos(argvars, &pos, NULL, &curswant, charcol) == FAIL)
|
||||
{
|
||||
emsg(_(e_invarg));
|
||||
return;
|
||||
@ -2666,15 +2699,24 @@ f_cursor(typval_T *argvars, typval_T *rettv)
|
||||
set_curswant = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if ((argvars[0].v_type == VAR_NUMBER ||
|
||||
argvars[0].v_type == VAR_STRING)
|
||||
&& argvars[1].v_type == VAR_NUMBER)
|
||||
{
|
||||
line = tv_get_lnum(argvars);
|
||||
if (line < 0)
|
||||
semsg(_(e_invarg2), tv_get_string(&argvars[0]));
|
||||
col = (long)tv_get_number_chk(&argvars[1], NULL);
|
||||
if (charcol)
|
||||
col = buf_charidx_to_byteidx(curbuf, line, col);
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
emsg(_(e_invarg));
|
||||
return;
|
||||
}
|
||||
if (line < 0 || col < 0 || coladd < 0)
|
||||
return; // type error; errmsg already given
|
||||
if (line > 0)
|
||||
@ -2693,6 +2735,19 @@ f_cursor(typval_T *argvars, typval_T *rettv)
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* "cursor(lnum, col)" function, or
|
||||
* "cursor(list)"
|
||||
*
|
||||
* Moves the cursor to the specified line and column.
|
||||
* Returns 0 when the position could be set, -1 otherwise.
|
||||
*/
|
||||
static void
|
||||
f_cursor(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
set_cursorpos(argvars, rettv, FALSE);
|
||||
}
|
||||
|
||||
#ifdef MSWIN
|
||||
/*
|
||||
* "debugbreak()" function
|
||||
@ -3887,6 +3942,88 @@ f_getchangelist(typval_T *argvars, typval_T *rettv)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
getpos_both(
|
||||
typval_T *argvars,
|
||||
typval_T *rettv,
|
||||
int getcurpos,
|
||||
int charcol)
|
||||
{
|
||||
pos_T *fp = NULL;
|
||||
pos_T pos;
|
||||
win_T *wp = curwin;
|
||||
list_T *l;
|
||||
int fnum = -1;
|
||||
|
||||
if (rettv_list_alloc(rettv) == OK)
|
||||
{
|
||||
l = rettv->vval.v_list;
|
||||
if (getcurpos)
|
||||
{
|
||||
if (argvars[0].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
wp = find_win_by_nr_or_id(&argvars[0]);
|
||||
if (wp != NULL)
|
||||
fp = &wp->w_cursor;
|
||||
}
|
||||
else
|
||||
fp = &curwin->w_cursor;
|
||||
if (fp != NULL && charcol)
|
||||
{
|
||||
pos = *fp;
|
||||
pos.col = buf_byteidx_to_charidx(wp->w_buffer, pos.lnum,
|
||||
pos.col) - 1;
|
||||
fp = &pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
fp = var2fpos(&argvars[0], TRUE, &fnum, charcol);
|
||||
if (fnum != -1)
|
||||
list_append_number(l, (varnumber_T)fnum);
|
||||
else
|
||||
list_append_number(l, (varnumber_T)0);
|
||||
list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
|
||||
: (varnumber_T)0);
|
||||
list_append_number(l, (fp != NULL)
|
||||
? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
|
||||
: (varnumber_T)0);
|
||||
list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd :
|
||||
(varnumber_T)0);
|
||||
if (getcurpos)
|
||||
{
|
||||
int save_set_curswant = curwin->w_set_curswant;
|
||||
colnr_T save_curswant = curwin->w_curswant;
|
||||
colnr_T save_virtcol = curwin->w_virtcol;
|
||||
|
||||
if (wp == curwin)
|
||||
update_curswant();
|
||||
list_append_number(l, wp == NULL ? 0 : wp->w_curswant == MAXCOL
|
||||
? (varnumber_T)MAXCOL : (varnumber_T)wp->w_curswant + 1);
|
||||
|
||||
// Do not change "curswant", as it is unexpected that a get
|
||||
// function has a side effect.
|
||||
if (wp == curwin && save_set_curswant)
|
||||
{
|
||||
curwin->w_set_curswant = save_set_curswant;
|
||||
curwin->w_curswant = save_curswant;
|
||||
curwin->w_virtcol = save_virtcol;
|
||||
curwin->w_valid &= ~VALID_VIRTCOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rettv->vval.v_number = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* "getcharpos()" function
|
||||
*/
|
||||
static void
|
||||
f_getcharpos(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
{
|
||||
getpos_both(argvars, rettv, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "getcharsearch()" function
|
||||
*/
|
||||
@ -4019,77 +4156,19 @@ f_getpid(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
rettv->vval.v_number = mch_get_pid();
|
||||
}
|
||||
|
||||
static void
|
||||
getpos_both(
|
||||
typval_T *argvars,
|
||||
typval_T *rettv,
|
||||
int getcurpos)
|
||||
{
|
||||
pos_T *fp = NULL;
|
||||
win_T *wp = curwin;
|
||||
list_T *l;
|
||||
int fnum = -1;
|
||||
|
||||
if (rettv_list_alloc(rettv) == OK)
|
||||
{
|
||||
l = rettv->vval.v_list;
|
||||
if (getcurpos)
|
||||
{
|
||||
if (argvars[0].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
wp = find_win_by_nr_or_id(&argvars[0]);
|
||||
if (wp != NULL)
|
||||
fp = &wp->w_cursor;
|
||||
}
|
||||
else
|
||||
fp = &curwin->w_cursor;
|
||||
}
|
||||
else
|
||||
fp = var2fpos(&argvars[0], TRUE, &fnum);
|
||||
if (fnum != -1)
|
||||
list_append_number(l, (varnumber_T)fnum);
|
||||
else
|
||||
list_append_number(l, (varnumber_T)0);
|
||||
list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
|
||||
: (varnumber_T)0);
|
||||
list_append_number(l, (fp != NULL)
|
||||
? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
|
||||
: (varnumber_T)0);
|
||||
list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd :
|
||||
(varnumber_T)0);
|
||||
if (getcurpos)
|
||||
{
|
||||
int save_set_curswant = curwin->w_set_curswant;
|
||||
colnr_T save_curswant = curwin->w_curswant;
|
||||
colnr_T save_virtcol = curwin->w_virtcol;
|
||||
|
||||
if (wp == curwin)
|
||||
update_curswant();
|
||||
list_append_number(l, wp == NULL ? 0 : wp->w_curswant == MAXCOL
|
||||
? (varnumber_T)MAXCOL : (varnumber_T)wp->w_curswant + 1);
|
||||
|
||||
// Do not change "curswant", as it is unexpected that a get
|
||||
// function has a side effect.
|
||||
if (wp == curwin && save_set_curswant)
|
||||
{
|
||||
curwin->w_set_curswant = save_set_curswant;
|
||||
curwin->w_curswant = save_curswant;
|
||||
curwin->w_virtcol = save_virtcol;
|
||||
curwin->w_valid &= ~VALID_VIRTCOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rettv->vval.v_number = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* "getcurpos()" function
|
||||
*/
|
||||
static void
|
||||
f_getcurpos(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
getpos_both(argvars, rettv, TRUE);
|
||||
getpos_both(argvars, rettv, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
f_getcursorcharpos(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
getpos_both(argvars, rettv, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4098,7 +4177,7 @@ f_getcurpos(typval_T *argvars, typval_T *rettv)
|
||||
static void
|
||||
f_getpos(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
getpos_both(argvars, rettv, FALSE);
|
||||
getpos_both(argvars, rettv, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6183,14 +6262,14 @@ f_line(typval_T *argvars, typval_T *rettv)
|
||||
== OK)
|
||||
{
|
||||
check_cursor();
|
||||
fp = var2fpos(&argvars[0], TRUE, &fnum);
|
||||
fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
|
||||
}
|
||||
restore_win_noblock(save_curwin, save_curtab, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
// use current window
|
||||
fp = var2fpos(&argvars[0], TRUE, &fnum);
|
||||
fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
|
||||
|
||||
if (fp != NULL)
|
||||
lnum = fp->lnum;
|
||||
@ -8065,6 +8144,60 @@ f_searchpos(typval_T *argvars, typval_T *rettv)
|
||||
list_append_number(rettv->vval.v_list, (varnumber_T)n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the cursor or mark position.
|
||||
* If 'charpos' is TRUE, then use the column number as a character offet.
|
||||
* Otherwise use the column number as a byte offset.
|
||||
*/
|
||||
static void
|
||||
set_position(typval_T *argvars, typval_T *rettv, int charpos)
|
||||
{
|
||||
pos_T pos;
|
||||
int fnum;
|
||||
char_u *name;
|
||||
colnr_T curswant = -1;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
|
||||
name = tv_get_string_chk(argvars);
|
||||
if (name != NULL)
|
||||
{
|
||||
if (list2fpos(&argvars[1], &pos, &fnum, &curswant, charpos) == OK)
|
||||
{
|
||||
if (pos.col != MAXCOL && --pos.col < 0)
|
||||
pos.col = 0;
|
||||
if ((name[0] == '.' && name[1] == NUL))
|
||||
{
|
||||
// set cursor; "fnum" is ignored
|
||||
curwin->w_cursor = pos;
|
||||
if (curswant >= 0)
|
||||
{
|
||||
curwin->w_curswant = curswant - 1;
|
||||
curwin->w_set_curswant = FALSE;
|
||||
}
|
||||
check_cursor();
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
|
||||
{
|
||||
// set mark
|
||||
if (setmark_pos(name[1], &pos, fnum) == OK)
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
emsg(_(e_invarg));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* "setcharpos()" function
|
||||
*/
|
||||
static void
|
||||
f_setcharpos(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
set_position(argvars, rettv, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
@ -8106,6 +8239,15 @@ f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "setcursorcharpos" function
|
||||
*/
|
||||
static void
|
||||
f_setcursorcharpos(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
set_cursorpos(argvars, rettv, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "setenv()" function
|
||||
*/
|
||||
@ -8165,41 +8307,7 @@ f_setfperm(typval_T *argvars, typval_T *rettv)
|
||||
static void
|
||||
f_setpos(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
pos_T pos;
|
||||
int fnum;
|
||||
char_u *name;
|
||||
colnr_T curswant = -1;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
name = tv_get_string_chk(argvars);
|
||||
if (name != NULL)
|
||||
{
|
||||
if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK)
|
||||
{
|
||||
if (pos.col != MAXCOL && --pos.col < 0)
|
||||
pos.col = 0;
|
||||
if (name[0] == '.' && name[1] == NUL)
|
||||
{
|
||||
// set cursor; "fnum" is ignored
|
||||
curwin->w_cursor = pos;
|
||||
if (curswant >= 0)
|
||||
{
|
||||
curwin->w_curswant = curswant - 1;
|
||||
curwin->w_set_curswant = FALSE;
|
||||
}
|
||||
check_cursor();
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
|
||||
{
|
||||
// set mark
|
||||
if (setmark_pos(name[1], &pos, fnum) == OK)
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
emsg(_(e_invarg));
|
||||
}
|
||||
}
|
||||
set_position(argvars, rettv, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -9947,7 +10055,7 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
|
||||
int fnum = curbuf->b_fnum;
|
||||
int len;
|
||||
|
||||
fp = var2fpos(&argvars[0], FALSE, &fnum);
|
||||
fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE);
|
||||
if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
|
||||
&& fnum == curbuf->b_fnum)
|
||||
{
|
||||
|
@ -55,8 +55,10 @@ char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copy
|
||||
char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
|
||||
char_u *string_quote(char_u *str, int function);
|
||||
int string2float(char_u *text, float_T *value);
|
||||
pos_T *var2fpos(typval_T *varp, int dollar_lnum, int *fnum);
|
||||
int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp);
|
||||
int buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx);
|
||||
int buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx);
|
||||
pos_T *var2fpos(typval_T *varp, int dollar_lnum, int *fnum, int charcol);
|
||||
int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp, int char_col);
|
||||
int get_env_len(char_u **arg);
|
||||
int get_id_len(char_u **arg);
|
||||
int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose);
|
||||
|
@ -4201,7 +4201,7 @@ tagstack_push_items(win_T *wp, list_T *l)
|
||||
// parse 'from' for the cursor position before the tag jump
|
||||
if ((di = dict_find(itemdict, (char_u *)"from", -1)) == NULL)
|
||||
continue;
|
||||
if (list2fpos(&di->di_tv, &mark, &fnum, NULL) != OK)
|
||||
if (list2fpos(&di->di_tv, &mark, &fnum, NULL, FALSE) != OK)
|
||||
continue;
|
||||
if ((tagname =
|
||||
dict_get_string(itemdict, (char_u *)"tagname", TRUE)) == NULL)
|
||||
|
@ -1,4 +1,4 @@
|
||||
" Tests for cursor().
|
||||
" Tests for cursor() and other functions that get/set the cursor position
|
||||
|
||||
func Test_wrong_arguments()
|
||||
call assert_fails('call cursor(1. 3)', 'E474:')
|
||||
@ -123,4 +123,187 @@ func Test_screenpos_number()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func SaveVisualStartCharPos()
|
||||
call add(g:VisualStartPos, getcharpos('v'))
|
||||
return ''
|
||||
endfunc
|
||||
|
||||
" Test for the getcharpos() function
|
||||
func Test_getcharpos()
|
||||
call assert_fails('call getcharpos({})', 'E731:')
|
||||
call assert_equal([0, 0, 0, 0], getcharpos(0))
|
||||
new
|
||||
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
|
||||
|
||||
" Test for '.' and '$'
|
||||
normal 1G
|
||||
call assert_equal([0, 1, 1, 0], getcharpos('.'))
|
||||
call assert_equal([0, 4, 1, 0], getcharpos('$'))
|
||||
normal 2G6l
|
||||
call assert_equal([0, 2, 7, 0], getcharpos('.'))
|
||||
normal 3G$
|
||||
call assert_equal([0, 3, 1, 0], getcharpos('.'))
|
||||
normal 4G$
|
||||
call assert_equal([0, 4, 9, 0], getcharpos('.'))
|
||||
|
||||
" Test for a mark
|
||||
normal 2G7lmmgg
|
||||
call assert_equal([0, 2, 8, 0], getcharpos("'m"))
|
||||
delmarks m
|
||||
call assert_equal([0, 0, 0, 0], getcharpos("'m"))
|
||||
|
||||
" Test for the visual start column
|
||||
vnoremap <expr> <F3> SaveVisualStartCharPos()
|
||||
let g:VisualStartPos = []
|
||||
exe "normal 2G6lv$\<F3>ohh\<F3>o\<F3>"
|
||||
call assert_equal([[0, 2, 7, 0], [0, 2, 9, 0], [0, 2, 5, 0]], g:VisualStartPos)
|
||||
call assert_equal([0, 2, 9, 0], getcharpos('v'))
|
||||
let g:VisualStartPos = []
|
||||
exe "normal 3Gv$\<F3>o\<F3>"
|
||||
call assert_equal([[0, 3, 1, 0], [0, 3, 1, 0]], g:VisualStartPos)
|
||||
let g:VisualStartPos = []
|
||||
exe "normal 1Gv$\<F3>o\<F3>"
|
||||
call assert_equal([[0, 1, 1, 0], [0, 1, 1, 0]], g:VisualStartPos)
|
||||
vunmap <F3>
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for the setcharpos() function
|
||||
func Test_setcharpos()
|
||||
call assert_equal(-1, setcharpos('.', test_null_list()))
|
||||
new
|
||||
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
|
||||
call setcharpos('.', [0, 1, 1, 0])
|
||||
call assert_equal([1, 1], [line('.'), col('.')])
|
||||
call setcharpos('.', [0, 2, 7, 0])
|
||||
call assert_equal([2, 9], [line('.'), col('.')])
|
||||
call setcharpos('.', [0, 3, 4, 0])
|
||||
call assert_equal([3, 1], [line('.'), col('.')])
|
||||
call setcharpos('.', [0, 3, 1, 0])
|
||||
call assert_equal([3, 1], [line('.'), col('.')])
|
||||
call setcharpos('.', [0, 4, 0, 0])
|
||||
call assert_equal([4, 1], [line('.'), col('.')])
|
||||
call setcharpos('.', [0, 4, 20, 0])
|
||||
call assert_equal([4, 9], [line('.'), col('.')])
|
||||
|
||||
" Test for mark
|
||||
delmarks m
|
||||
call setcharpos("'m", [0, 2, 9, 0])
|
||||
normal `m
|
||||
call assert_equal([2, 11], [line('.'), col('.')])
|
||||
|
||||
%bw!
|
||||
call assert_equal(-1, setcharpos('.', [10, 3, 1, 0]))
|
||||
endfunc
|
||||
|
||||
func SaveVisualStartCharCol()
|
||||
call add(g:VisualStartCol, charcol('v'))
|
||||
return ''
|
||||
endfunc
|
||||
|
||||
" Test for the charcol() function
|
||||
func Test_charcol()
|
||||
call assert_fails('call charcol({})', 'E731:')
|
||||
call assert_equal(0, charcol(0))
|
||||
new
|
||||
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
|
||||
|
||||
" Test for '.' and '$'
|
||||
normal 1G
|
||||
call assert_equal(1, charcol('.'))
|
||||
call assert_equal(1, charcol('$'))
|
||||
normal 2G6l
|
||||
call assert_equal(7, charcol('.'))
|
||||
call assert_equal(10, charcol('$'))
|
||||
normal 3G$
|
||||
call assert_equal(1, charcol('.'))
|
||||
call assert_equal(2, charcol('$'))
|
||||
normal 4G$
|
||||
call assert_equal(9, charcol('.'))
|
||||
call assert_equal(10, charcol('$'))
|
||||
|
||||
" Test for [lnum, '$']
|
||||
call assert_equal(1, charcol([1, '$']))
|
||||
call assert_equal(10, charcol([2, '$']))
|
||||
call assert_equal(2, charcol([3, '$']))
|
||||
call assert_equal(0, charcol([5, '$']))
|
||||
|
||||
" Test for a mark
|
||||
normal 2G7lmmgg
|
||||
call assert_equal(8, charcol("'m"))
|
||||
delmarks m
|
||||
call assert_equal(0, charcol("'m"))
|
||||
|
||||
" Test for the visual start column
|
||||
vnoremap <expr> <F3> SaveVisualStartCharCol()
|
||||
let g:VisualStartCol = []
|
||||
exe "normal 2G6lv$\<F3>ohh\<F3>o\<F3>"
|
||||
call assert_equal([7, 9, 5], g:VisualStartCol)
|
||||
call assert_equal(9, charcol('v'))
|
||||
let g:VisualStartCol = []
|
||||
exe "normal 3Gv$\<F3>o\<F3>"
|
||||
call assert_equal([1, 1], g:VisualStartCol)
|
||||
let g:VisualStartCol = []
|
||||
exe "normal 1Gv$\<F3>o\<F3>"
|
||||
call assert_equal([1, 1], g:VisualStartCol)
|
||||
vunmap <F3>
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for getcursorcharpos()
|
||||
func Test_getcursorcharpos()
|
||||
call assert_equal(getcursorcharpos(), getcursorcharpos(0))
|
||||
call assert_equal([0, 0, 0, 0, 0], getcursorcharpos(-1))
|
||||
call assert_equal([0, 0, 0, 0, 0], getcursorcharpos(1999))
|
||||
|
||||
new
|
||||
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
|
||||
normal 1G9l
|
||||
call assert_equal([0, 1, 1, 0, 1], getcursorcharpos())
|
||||
normal 2G9l
|
||||
call assert_equal([0, 2, 9, 0, 14], getcursorcharpos())
|
||||
normal 3G9l
|
||||
call assert_equal([0, 3, 1, 0, 1], getcursorcharpos())
|
||||
normal 4G9l
|
||||
call assert_equal([0, 4, 9, 0, 9], getcursorcharpos())
|
||||
|
||||
let winid = win_getid()
|
||||
normal 2G5l
|
||||
wincmd w
|
||||
call assert_equal([0, 2, 6, 0, 11], getcursorcharpos(winid))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for setcursorcharpos()
|
||||
func Test_setcursorcharpos()
|
||||
call assert_fails('call setcursorcharpos(test_null_list())', 'E474:')
|
||||
call assert_fails('call setcursorcharpos([1])', 'E474:')
|
||||
call assert_fails('call setcursorcharpos([1, 1, 1, 1, 1])', 'E474:')
|
||||
new
|
||||
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
|
||||
normal G
|
||||
call setcursorcharpos([1, 1])
|
||||
call assert_equal([1, 1], [line('.'), col('.')])
|
||||
call setcursorcharpos([2, 7, 0])
|
||||
call assert_equal([2, 9], [line('.'), col('.')])
|
||||
call setcursorcharpos(3, 4)
|
||||
call assert_equal([3, 1], [line('.'), col('.')])
|
||||
call setcursorcharpos([3, 1])
|
||||
call assert_equal([3, 1], [line('.'), col('.')])
|
||||
call setcursorcharpos([4, 0, 0, 0])
|
||||
call assert_equal([4, 1], [line('.'), col('.')])
|
||||
call setcursorcharpos([4, 20])
|
||||
call assert_equal([4, 9], [line('.'), col('.')])
|
||||
normal 1G
|
||||
call setcursorcharpos([100, 100, 100, 100])
|
||||
call assert_equal([4, 9], [line('.'), col('.')])
|
||||
normal 1G
|
||||
call setcursorcharpos('$', 1)
|
||||
call assert_equal([4, 1], [line('.'), col('.')])
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -1579,7 +1579,7 @@ tv_get_lnum(typval_T *argvars)
|
||||
if (lnum <= 0) // no valid number, try using arg like line()
|
||||
{
|
||||
int fnum;
|
||||
pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum);
|
||||
pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
|
||||
|
||||
if (fp != NULL)
|
||||
lnum = fp->lnum;
|
||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2324,
|
||||
/**/
|
||||
2323,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user