mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:7.4.1730
Problem: It is not easy to get a character out of a string.
Solution: Add strgetchar() and strcharpart().
58de0e2dcc
This commit is contained in:
parent
500c485e36
commit
d6e27f90b9
@ -15612,6 +15612,39 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
}
|
||||
}
|
||||
|
||||
// "strgetchar()" function
|
||||
static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
char_u *str;
|
||||
int len;
|
||||
int error = false;
|
||||
int charidx;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
str = get_tv_string_chk(&argvars[0]);
|
||||
if (str == NULL) {
|
||||
return;
|
||||
}
|
||||
len = (int)STRLEN(str);
|
||||
charidx = get_tv_number_chk(&argvars[1], &error);
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
int byteidx = 0;
|
||||
|
||||
while (charidx >= 0 && byteidx < len) {
|
||||
if (charidx == 0) {
|
||||
rettv->vval.v_number = mb_ptr2char(str + byteidx);
|
||||
break;
|
||||
}
|
||||
charidx--;
|
||||
byteidx += mb_char2len(str[byteidx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "stridx()" function
|
||||
*/
|
||||
@ -15712,6 +15745,58 @@ static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->vval.v_number = (varnumber_T) mb_string2cells(s);
|
||||
}
|
||||
|
||||
// "strcharpart()" function
|
||||
static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
|
||||
char_u *p;
|
||||
int nchar;
|
||||
int nbyte = 0;
|
||||
int charlen;
|
||||
int len = 0;
|
||||
int slen;
|
||||
int error = false;
|
||||
|
||||
p = get_tv_string(&argvars[0]);
|
||||
slen = (int)STRLEN(p);
|
||||
|
||||
nchar = get_tv_number_chk(&argvars[1], &error);
|
||||
if (!error) {
|
||||
if (nchar > 0) {
|
||||
while (nchar > 0 && nbyte < slen) {
|
||||
nbyte += mb_char2len(p[nbyte]);
|
||||
nchar--;
|
||||
}
|
||||
} else {
|
||||
nbyte = nchar;
|
||||
}
|
||||
}
|
||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||
charlen = get_tv_number(&argvars[2]);
|
||||
while (charlen > 0 && nbyte + len < slen) {
|
||||
len += mb_char2len(p[nbyte + len]);
|
||||
charlen--;
|
||||
}
|
||||
} else {
|
||||
len = slen - nbyte; // default: all bytes that are available.
|
||||
}
|
||||
|
||||
// Only return the overlap between the specified part and the actual
|
||||
// string.
|
||||
if (nbyte < 0) {
|
||||
len += nbyte;
|
||||
nbyte = 0;
|
||||
} else if (nbyte > slen) {
|
||||
nbyte = slen;
|
||||
}
|
||||
if (len < 0) {
|
||||
len = 0;
|
||||
} else if (nbyte + len > slen) {
|
||||
len = slen - nbyte;
|
||||
}
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = vim_strnsave(p + nbyte, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* "strpart()" function
|
||||
*/
|
||||
|
@ -268,9 +268,11 @@ return {
|
||||
sqrt={args=1, func="float_op_wrapper", data="&sqrt"},
|
||||
str2float={args=1},
|
||||
str2nr={args={1, 2}},
|
||||
strcharpart={args={2, 3}},
|
||||
strchars={args={1,2}},
|
||||
strdisplaywidth={args={1, 2}},
|
||||
strftime={args={1, 2}},
|
||||
strgetchar={args={2,2}},
|
||||
stridx={args={2, 3}},
|
||||
string={args=1},
|
||||
strlen={args=1},
|
||||
|
@ -4,6 +4,7 @@
|
||||
source test_assign.vim
|
||||
source test_cursor_func.vim
|
||||
source test_ex_undo.vim
|
||||
source test_expr.vim
|
||||
source test_feedkeys.vim
|
||||
source test_cmdline.vim
|
||||
source test_menu.vim
|
||||
|
48
src/nvim/testdir/test_expr.vim
Normal file
48
src/nvim/testdir/test_expr.vim
Normal file
@ -0,0 +1,48 @@
|
||||
" Tests for expressions.
|
||||
|
||||
func Test_strgetchar()
|
||||
call assert_equal(char2nr('a'), strgetchar('axb', 0))
|
||||
call assert_equal(char2nr('x'), strgetchar('axb', 1))
|
||||
call assert_equal(char2nr('b'), strgetchar('axb', 2))
|
||||
|
||||
call assert_equal(-1, strgetchar('axb', -1))
|
||||
call assert_equal(-1, strgetchar('axb', 3))
|
||||
call assert_equal(-1, strgetchar('', 0))
|
||||
|
||||
if !has('multi_byte')
|
||||
return
|
||||
endif
|
||||
|
||||
call assert_equal(char2nr('á'), strgetchar('áxb', 0))
|
||||
call assert_equal(char2nr('x'), strgetchar('áxb', 1))
|
||||
|
||||
call assert_equal(char2nr('a'), strgetchar('àxb', 0))
|
||||
call assert_equal(char2nr(''), strgetchar('àxb', 1))
|
||||
call assert_equal(char2nr('x'), strgetchar('àxb', 2))
|
||||
endfunc
|
||||
|
||||
func Test_strcharpart()
|
||||
call assert_equal('a', strcharpart('axb', 0, 1))
|
||||
call assert_equal('x', strcharpart('axb', 1, 1))
|
||||
call assert_equal('b', strcharpart('axb', 2, 1))
|
||||
call assert_equal('xb', strcharpart('axb', 1))
|
||||
|
||||
call assert_equal('', strcharpart('axb', 1, 0))
|
||||
call assert_equal('', strcharpart('axb', 1, -1))
|
||||
call assert_equal('', strcharpart('axb', -1, 1))
|
||||
call assert_equal('', strcharpart('axb', -2, 2))
|
||||
|
||||
call assert_equal('a', strcharpart('axb', -1, 2))
|
||||
|
||||
if !has('multi_byte')
|
||||
return
|
||||
endif
|
||||
|
||||
call assert_equal('áxb', strcharpart('áxb', 0))
|
||||
call assert_equal('á', strcharpart('áxb', 0, 1))
|
||||
call assert_equal('x', strcharpart('áxb', 1, 1))
|
||||
|
||||
call assert_equal('a', strcharpart('àxb', 0, 1))
|
||||
call assert_equal('', strcharpart('àxb', 1, 1))
|
||||
call assert_equal('x', strcharpart('àxb', 2, 1))
|
||||
endfunc
|
@ -713,7 +713,7 @@ static int included_patches[] = {
|
||||
// 1733 NA
|
||||
1732,
|
||||
// 1731,
|
||||
// 1730,
|
||||
1730,
|
||||
// 1729 NA
|
||||
1728,
|
||||
// 1727,
|
||||
|
Loading…
Reference in New Issue
Block a user