mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.2435: setline() gives an error for some types
Problem: setline() gives an error for some types. Solution: Allow any type, convert each item to a string.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 22
|
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 31
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -293,13 +293,13 @@ is not available it returns zero or the default value you specify: >
|
|||||||
|
|
||||||
|
|
||||||
List concatenation ~
|
List concatenation ~
|
||||||
|
*list-concatenation*
|
||||||
Two lists can be concatenated with the "+" operator: >
|
Two lists can be concatenated with the "+" operator: >
|
||||||
:let longlist = mylist + [5, 6]
|
:let longlist = mylist + [5, 6]
|
||||||
:let mylist += [7, 8]
|
:let mylist += [7, 8]
|
||||||
|
|
||||||
To prepend or append an item turn the item into a list by putting [] around
|
To prepend or append an item, turn the item into a list by putting [] around
|
||||||
it. To change a list in-place see |list-modification| below.
|
it. To change a list in-place, refer to |list-modification| below.
|
||||||
|
|
||||||
|
|
||||||
Sublist ~
|
Sublist ~
|
||||||
@@ -3133,6 +3133,7 @@ append({lnum}, {text}) *append()*
|
|||||||
text line below line {lnum} in the current buffer.
|
text line below line {lnum} in the current buffer.
|
||||||
Otherwise append {text} as one text line below line {lnum} in
|
Otherwise append {text} as one text line below line {lnum} in
|
||||||
the current buffer.
|
the current buffer.
|
||||||
|
Any type of item is accepted and converted to a String.
|
||||||
{lnum} can be zero to insert a line before the first one.
|
{lnum} can be zero to insert a line before the first one.
|
||||||
Returns 1 for failure ({lnum} out of range or out of memory),
|
Returns 1 for failure ({lnum} out of range or out of memory),
|
||||||
0 for success. Example: >
|
0 for success. Example: >
|
||||||
@@ -9409,6 +9410,8 @@ setline({lnum}, {text}) *setline()*
|
|||||||
{lnum} is used like with |getline()|.
|
{lnum} is used like with |getline()|.
|
||||||
When {lnum} is just below the last line the {text} will be
|
When {lnum} is just below the last line the {text} will be
|
||||||
added below the last line.
|
added below the last line.
|
||||||
|
{text} can be any type or a List of any type, each item is
|
||||||
|
converted to a String.
|
||||||
|
|
||||||
If this succeeds, FALSE is returned. If this fails (most likely
|
If this succeeds, FALSE is returned. If this fails (most likely
|
||||||
because {lnum} is invalid) TRUE is returned.
|
because {lnum} is invalid) TRUE is returned.
|
||||||
|
@@ -940,9 +940,9 @@ debuggy_find(
|
|||||||
{
|
{
|
||||||
if (bp->dbg_val == NULL)
|
if (bp->dbg_val == NULL)
|
||||||
{
|
{
|
||||||
debug_oldval = typval_tostring(NULL);
|
debug_oldval = typval_tostring(NULL, TRUE);
|
||||||
bp->dbg_val = tv;
|
bp->dbg_val = tv;
|
||||||
debug_newval = typval_tostring(bp->dbg_val);
|
debug_newval = typval_tostring(bp->dbg_val, TRUE);
|
||||||
line = TRUE;
|
line = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -953,11 +953,11 @@ debuggy_find(
|
|||||||
typval_T *v;
|
typval_T *v;
|
||||||
|
|
||||||
line = TRUE;
|
line = TRUE;
|
||||||
debug_oldval = typval_tostring(bp->dbg_val);
|
debug_oldval = typval_tostring(bp->dbg_val, TRUE);
|
||||||
// Need to evaluate again, typval_compare() overwrites
|
// Need to evaluate again, typval_compare() overwrites
|
||||||
// "tv".
|
// "tv".
|
||||||
v = eval_expr(bp->dbg_name, NULL);
|
v = eval_expr(bp->dbg_name, NULL);
|
||||||
debug_newval = typval_tostring(v);
|
debug_newval = typval_tostring(v, TRUE);
|
||||||
free_tv(bp->dbg_val);
|
free_tv(bp->dbg_val);
|
||||||
bp->dbg_val = v;
|
bp->dbg_val = v;
|
||||||
}
|
}
|
||||||
@@ -966,8 +966,8 @@ debuggy_find(
|
|||||||
}
|
}
|
||||||
else if (bp->dbg_val != NULL)
|
else if (bp->dbg_val != NULL)
|
||||||
{
|
{
|
||||||
debug_oldval = typval_tostring(bp->dbg_val);
|
debug_oldval = typval_tostring(bp->dbg_val, TRUE);
|
||||||
debug_newval = typval_tostring(NULL);
|
debug_newval = typval_tostring(NULL, TRUE);
|
||||||
free_tv(bp->dbg_val);
|
free_tv(bp->dbg_val);
|
||||||
bp->dbg_val = NULL;
|
bp->dbg_val = NULL;
|
||||||
line = TRUE;
|
line = TRUE;
|
||||||
|
@@ -128,7 +128,8 @@ find_win_for_curbuf(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set line or list of lines in buffer "buf".
|
* Set line or list of lines in buffer "buf" to "lines".
|
||||||
|
* Any type is allowed and converted to a string.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
set_buffer_lines(
|
set_buffer_lines(
|
||||||
@@ -187,7 +188,7 @@ set_buffer_lines(
|
|||||||
li = l->lv_first;
|
li = l->lv_first;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
line = tv_get_string_chk(lines);
|
line = typval_tostring(lines, FALSE);
|
||||||
|
|
||||||
// default result is zero == OK
|
// default result is zero == OK
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -197,7 +198,8 @@ set_buffer_lines(
|
|||||||
// list argument, get next string
|
// list argument, get next string
|
||||||
if (li == NULL)
|
if (li == NULL)
|
||||||
break;
|
break;
|
||||||
line = tv_get_string_chk(&li->li_tv);
|
vim_free(line);
|
||||||
|
line = typval_tostring(&li->li_tv, FALSE);
|
||||||
li = li->li_next;
|
li = li->li_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +240,7 @@ set_buffer_lines(
|
|||||||
break;
|
break;
|
||||||
++lnum;
|
++lnum;
|
||||||
}
|
}
|
||||||
|
vim_free(line);
|
||||||
|
|
||||||
if (added > 0)
|
if (added > 0)
|
||||||
{
|
{
|
||||||
|
@@ -21,7 +21,7 @@ char_u *tv_stringify(typval_T *varp, char_u *buf);
|
|||||||
int tv_check_lock(typval_T *tv, char_u *name, int use_gettext);
|
int tv_check_lock(typval_T *tv, char_u *name, int use_gettext);
|
||||||
void copy_tv(typval_T *from, typval_T *to);
|
void copy_tv(typval_T *from, typval_T *to);
|
||||||
int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, int ic);
|
int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, int ic);
|
||||||
char_u *typval_tostring(typval_T *arg);
|
char_u *typval_tostring(typval_T *arg, int quotes);
|
||||||
int tv_islocked(typval_T *tv);
|
int tv_islocked(typval_T *tv);
|
||||||
int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
|
int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
|
||||||
int eval_option(char_u **arg, typval_T *rettv, int evaluate);
|
int eval_option(char_u **arg, typval_T *rettv, int evaluate);
|
||||||
|
@@ -5,6 +5,7 @@ source screendump.vim
|
|||||||
source check.vim
|
source check.vim
|
||||||
|
|
||||||
func Test_setbufline_getbufline()
|
func Test_setbufline_getbufline()
|
||||||
|
" similar to Test_set_get_bufline()
|
||||||
new
|
new
|
||||||
let b = bufnr('%')
|
let b = bufnr('%')
|
||||||
hide
|
hide
|
||||||
@@ -38,6 +39,12 @@ func Test_setbufline_getbufline()
|
|||||||
call assert_equal(['e'], getbufline(b, 5))
|
call assert_equal(['e'], getbufline(b, 5))
|
||||||
call assert_equal([], getbufline(b, 6))
|
call assert_equal([], getbufline(b, 6))
|
||||||
call assert_equal([], getbufline(b, 2, 1))
|
call assert_equal([], getbufline(b, 2, 1))
|
||||||
|
|
||||||
|
call setbufline(b, 2, [function('eval'), #{key: 123}, test_null_job()])
|
||||||
|
call assert_equal(["function('eval')",
|
||||||
|
\ "{'key': 123}",
|
||||||
|
\ "no process"],
|
||||||
|
\ getbufline(b, 2, 4))
|
||||||
exe "bwipe! " . b
|
exe "bwipe! " . b
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
@@ -767,6 +767,54 @@ def Test_searchcount()
|
|||||||
bwipe!
|
bwipe!
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_set_get_bufline()
|
||||||
|
# similar to Test_setbufline_getbufline()
|
||||||
|
var lines =<< trim END
|
||||||
|
new
|
||||||
|
var b = bufnr('%')
|
||||||
|
hide
|
||||||
|
assert_equal(0, setbufline(b, 1, ['foo', 'bar']))
|
||||||
|
assert_equal(['foo'], getbufline(b, 1))
|
||||||
|
assert_equal(['bar'], getbufline(b, '$'))
|
||||||
|
assert_equal(['foo', 'bar'], getbufline(b, 1, 2))
|
||||||
|
exe "bd!" b
|
||||||
|
assert_equal([], getbufline(b, 1, 2))
|
||||||
|
|
||||||
|
split Xtest
|
||||||
|
setline(1, ['a', 'b', 'c'])
|
||||||
|
b = bufnr('%')
|
||||||
|
wincmd w
|
||||||
|
|
||||||
|
assert_equal(1, setbufline(b, 5, 'x'))
|
||||||
|
assert_equal(1, setbufline(b, 5, ['x']))
|
||||||
|
assert_equal(1, setbufline(b, 5, []))
|
||||||
|
assert_equal(1, setbufline(b, 5, test_null_list()))
|
||||||
|
|
||||||
|
assert_equal(1, 'x'->setbufline(bufnr('$') + 1, 1))
|
||||||
|
assert_equal(1, ['x']->setbufline(bufnr('$') + 1, 1))
|
||||||
|
assert_equal(1, []->setbufline(bufnr('$') + 1, 1))
|
||||||
|
assert_equal(1, test_null_list()->setbufline(bufnr('$') + 1, 1))
|
||||||
|
|
||||||
|
assert_equal(['a', 'b', 'c'], getbufline(b, 1, '$'))
|
||||||
|
|
||||||
|
assert_equal(0, setbufline(b, 4, ['d', 'e']))
|
||||||
|
assert_equal(['c'], b->getbufline(3))
|
||||||
|
assert_equal(['d'], getbufline(b, 4))
|
||||||
|
assert_equal(['e'], getbufline(b, 5))
|
||||||
|
assert_equal([], getbufline(b, 6))
|
||||||
|
assert_equal([], getbufline(b, 2, 1))
|
||||||
|
|
||||||
|
setbufline(b, 2, [function('eval'), {key: 123}, test_null_job()])
|
||||||
|
assert_equal(["function('eval')",
|
||||||
|
"{'key': 123}",
|
||||||
|
"no process"],
|
||||||
|
getbufline(b, 2, 4))
|
||||||
|
|
||||||
|
exe 'bwipe! ' .. b
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_searchdecl()
|
def Test_searchdecl()
|
||||||
searchdecl('blah', true, true)->assert_equal(1)
|
searchdecl('blah', true, true)->assert_equal(1)
|
||||||
enddef
|
enddef
|
||||||
|
23
src/typval.c
23
src/typval.c
@@ -927,8 +927,13 @@ typval_compare(
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert any type to a string, never give an error.
|
||||||
|
* When "quotes" is TRUE add quotes to a string.
|
||||||
|
* Returns an allocated string.
|
||||||
|
*/
|
||||||
char_u *
|
char_u *
|
||||||
typval_tostring(typval_T *arg)
|
typval_tostring(typval_T *arg, int quotes)
|
||||||
{
|
{
|
||||||
char_u *tofree;
|
char_u *tofree;
|
||||||
char_u numbuf[NUMBUFLEN];
|
char_u numbuf[NUMBUFLEN];
|
||||||
@@ -936,10 +941,18 @@ typval_tostring(typval_T *arg)
|
|||||||
|
|
||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
return vim_strsave((char_u *)"(does not exist)");
|
return vim_strsave((char_u *)"(does not exist)");
|
||||||
ret = tv2string(arg, &tofree, numbuf, 0);
|
if (!quotes && arg->v_type == VAR_STRING)
|
||||||
// Make a copy if we have a value but it's not in allocated memory.
|
{
|
||||||
if (ret != NULL && tofree == NULL)
|
ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
|
||||||
ret = vim_strsave(ret);
|
: arg->vval.v_string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = tv2string(arg, &tofree, numbuf, 0);
|
||||||
|
// Make a copy if we have a value but it's not in allocated memory.
|
||||||
|
if (ret != NULL && tofree == NULL)
|
||||||
|
ret = vim_strsave(ret);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2435,
|
||||||
/**/
|
/**/
|
||||||
2434,
|
2434,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -879,7 +879,7 @@ do_2string(typval_T *tv, int is_2string_any)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str = typval_tostring(tv);
|
str = typval_tostring(tv, TRUE);
|
||||||
clear_tv(tv);
|
clear_tv(tv);
|
||||||
tv->v_type = VAR_STRING;
|
tv->v_type = VAR_STRING;
|
||||||
tv->vval.v_string = str;
|
tv->vval.v_string = str;
|
||||||
|
Reference in New Issue
Block a user