forked from aniani/vim
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
|
||||
@@ -293,13 +293,13 @@ is not available it returns zero or the default value you specify: >
|
||||
|
||||
|
||||
List concatenation ~
|
||||
|
||||
*list-concatenation*
|
||||
Two lists can be concatenated with the "+" operator: >
|
||||
:let longlist = mylist + [5, 6]
|
||||
:let mylist += [7, 8]
|
||||
|
||||
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.
|
||||
To prepend or append an item, turn the item into a list by putting [] around
|
||||
it. To change a list in-place, refer to |list-modification| below.
|
||||
|
||||
|
||||
Sublist ~
|
||||
@@ -3133,6 +3133,7 @@ append({lnum}, {text}) *append()*
|
||||
text line below line {lnum} in the current buffer.
|
||||
Otherwise append {text} as one text line below line {lnum} in
|
||||
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.
|
||||
Returns 1 for failure ({lnum} out of range or out of memory),
|
||||
0 for success. Example: >
|
||||
@@ -9409,6 +9410,8 @@ setline({lnum}, {text}) *setline()*
|
||||
{lnum} is used like with |getline()|.
|
||||
When {lnum} is just below the last line the {text} will be
|
||||
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
|
||||
because {lnum} is invalid) TRUE is returned.
|
||||
|
@@ -940,9 +940,9 @@ debuggy_find(
|
||||
{
|
||||
if (bp->dbg_val == NULL)
|
||||
{
|
||||
debug_oldval = typval_tostring(NULL);
|
||||
debug_oldval = typval_tostring(NULL, TRUE);
|
||||
bp->dbg_val = tv;
|
||||
debug_newval = typval_tostring(bp->dbg_val);
|
||||
debug_newval = typval_tostring(bp->dbg_val, TRUE);
|
||||
line = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -953,11 +953,11 @@ debuggy_find(
|
||||
typval_T *v;
|
||||
|
||||
line = TRUE;
|
||||
debug_oldval = typval_tostring(bp->dbg_val);
|
||||
debug_oldval = typval_tostring(bp->dbg_val, TRUE);
|
||||
// Need to evaluate again, typval_compare() overwrites
|
||||
// "tv".
|
||||
v = eval_expr(bp->dbg_name, NULL);
|
||||
debug_newval = typval_tostring(v);
|
||||
debug_newval = typval_tostring(v, TRUE);
|
||||
free_tv(bp->dbg_val);
|
||||
bp->dbg_val = v;
|
||||
}
|
||||
@@ -966,8 +966,8 @@ debuggy_find(
|
||||
}
|
||||
else if (bp->dbg_val != NULL)
|
||||
{
|
||||
debug_oldval = typval_tostring(bp->dbg_val);
|
||||
debug_newval = typval_tostring(NULL);
|
||||
debug_oldval = typval_tostring(bp->dbg_val, TRUE);
|
||||
debug_newval = typval_tostring(NULL, TRUE);
|
||||
free_tv(bp->dbg_val);
|
||||
bp->dbg_val = NULL;
|
||||
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
|
||||
set_buffer_lines(
|
||||
@@ -187,7 +188,7 @@ set_buffer_lines(
|
||||
li = l->lv_first;
|
||||
}
|
||||
else
|
||||
line = tv_get_string_chk(lines);
|
||||
line = typval_tostring(lines, FALSE);
|
||||
|
||||
// default result is zero == OK
|
||||
for (;;)
|
||||
@@ -197,7 +198,8 @@ set_buffer_lines(
|
||||
// list argument, get next string
|
||||
if (li == NULL)
|
||||
break;
|
||||
line = tv_get_string_chk(&li->li_tv);
|
||||
vim_free(line);
|
||||
line = typval_tostring(&li->li_tv, FALSE);
|
||||
li = li->li_next;
|
||||
}
|
||||
|
||||
@@ -238,6 +240,7 @@ set_buffer_lines(
|
||||
break;
|
||||
++lnum;
|
||||
}
|
||||
vim_free(line);
|
||||
|
||||
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);
|
||||
void copy_tv(typval_T *from, typval_T *to);
|
||||
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_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
|
||||
int eval_option(char_u **arg, typval_T *rettv, int evaluate);
|
||||
|
@@ -5,6 +5,7 @@ source screendump.vim
|
||||
source check.vim
|
||||
|
||||
func Test_setbufline_getbufline()
|
||||
" similar to Test_set_get_bufline()
|
||||
new
|
||||
let b = bufnr('%')
|
||||
hide
|
||||
@@ -38,6 +39,12 @@ func Test_setbufline_getbufline()
|
||||
call assert_equal(['e'], getbufline(b, 5))
|
||||
call assert_equal([], getbufline(b, 6))
|
||||
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
|
||||
endfunc
|
||||
|
||||
|
@@ -767,6 +767,54 @@ def Test_searchcount()
|
||||
bwipe!
|
||||
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()
|
||||
searchdecl('blah', true, true)->assert_equal(1)
|
||||
enddef
|
||||
|
23
src/typval.c
23
src/typval.c
@@ -927,8 +927,13 @@ typval_compare(
|
||||
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 *
|
||||
typval_tostring(typval_T *arg)
|
||||
typval_tostring(typval_T *arg, int quotes)
|
||||
{
|
||||
char_u *tofree;
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
@@ -936,10 +941,18 @@ typval_tostring(typval_T *arg)
|
||||
|
||||
if (arg == NULL)
|
||||
return vim_strsave((char_u *)"(does not exist)");
|
||||
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);
|
||||
if (!quotes && arg->v_type == VAR_STRING)
|
||||
{
|
||||
ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
|
||||
: 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;
|
||||
}
|
||||
|
||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2435,
|
||||
/**/
|
||||
2434,
|
||||
/**/
|
||||
|
@@ -879,7 +879,7 @@ do_2string(typval_T *tv, int is_2string_any)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
str = typval_tostring(tv);
|
||||
str = typval_tostring(tv, TRUE);
|
||||
clear_tv(tv);
|
||||
tv->v_type = VAR_STRING;
|
||||
tv->vval.v_string = str;
|
||||
|
Reference in New Issue
Block a user