0
0
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:
Bram Moolenaar
2021-01-31 13:08:38 +01:00
parent f2b26bcf8f
commit 3445320839
9 changed files with 96 additions and 20 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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)");
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;
}

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2435,
/**/
2434,
/**/

View File

@@ -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;