mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
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.
3445320839
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -638,6 +638,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.
|
||||||
{lnum} is used like with |getline()|.
|
{lnum} is used like with |getline()|.
|
||||||
Returns 1 for failure ({lnum} out of range or out of memory),
|
Returns 1 for failure ({lnum} out of range or out of memory),
|
||||||
@@ -7054,6 +7055,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.
|
||||||
|
@@ -229,13 +229,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 ~
|
||||||
|
@@ -808,26 +808,26 @@ static linenr_T debuggy_find(bool file, char_u *fname, linenr_T after, garray_T
|
|||||||
typval_T *const tv = eval_expr_no_emsg(bp);
|
typval_T *const tv = eval_expr_no_emsg(bp);
|
||||||
if (tv != NULL) {
|
if (tv != NULL) {
|
||||||
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 {
|
||||||
if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK
|
if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK
|
||||||
&& tv->vval.v_number == false) {
|
&& tv->vval.v_number == false) {
|
||||||
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 "tv".
|
// Need to evaluate again, typval_compare() overwrites "tv".
|
||||||
typval_T *const v = eval_expr_no_emsg(bp);
|
typval_T *const v = eval_expr_no_emsg(bp);
|
||||||
debug_newval = typval_tostring(v);
|
debug_newval = typval_tostring(v, true);
|
||||||
tv_free(bp->dbg_val);
|
tv_free(bp->dbg_val);
|
||||||
bp->dbg_val = v;
|
bp->dbg_val = v;
|
||||||
}
|
}
|
||||||
tv_free(tv);
|
tv_free(tv);
|
||||||
}
|
}
|
||||||
} 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);
|
||||||
tv_free(bp->dbg_val);
|
tv_free(bp->dbg_val);
|
||||||
bp->dbg_val = NULL;
|
bp->dbg_val = NULL;
|
||||||
line = true;
|
line = true;
|
||||||
|
@@ -5592,9 +5592,9 @@ void screenchar_adjust(ScreenGrid **grid, int *row, int *col)
|
|||||||
*col -= (*grid)->comp_col;
|
*col -= (*grid)->comp_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set line or list of lines in buffer "buf".
|
/// Set line or list of lines in buffer "buf" to "lines".
|
||||||
void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines,
|
/// Any type is allowed and converted to a string.
|
||||||
typval_T *rettv)
|
void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, typval_T *lines, typval_T *rettv)
|
||||||
FUNC_ATTR_NONNULL_ARG(4, 5)
|
FUNC_ATTR_NONNULL_ARG(4, 5)
|
||||||
{
|
{
|
||||||
linenr_T lnum = lnum_arg + (append ? 1 : 0);
|
linenr_T lnum = lnum_arg + (append ? 1 : 0);
|
||||||
@@ -5632,7 +5632,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
|
|||||||
|
|
||||||
list_T *l = NULL;
|
list_T *l = NULL;
|
||||||
listitem_T *li = NULL;
|
listitem_T *li = NULL;
|
||||||
const char *line = NULL;
|
char *line = NULL;
|
||||||
if (lines->v_type == VAR_LIST) {
|
if (lines->v_type == VAR_LIST) {
|
||||||
l = lines->vval.v_list;
|
l = lines->vval.v_list;
|
||||||
if (l == NULL || tv_list_len(l) == 0) {
|
if (l == NULL || tv_list_len(l) == 0) {
|
||||||
@@ -5644,7 +5644,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
|
|||||||
}
|
}
|
||||||
li = tv_list_first(l);
|
li = tv_list_first(l);
|
||||||
} else {
|
} else {
|
||||||
line = tv_get_string_chk(lines);
|
line = typval_tostring(lines, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default result is zero == OK.
|
// Default result is zero == OK.
|
||||||
@@ -5654,7 +5654,8 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
|
|||||||
if (li == NULL) {
|
if (li == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
line = tv_get_string_chk(TV_LIST_ITEM_TV(li));
|
xfree(line);
|
||||||
|
line = typval_tostring(TV_LIST_ITEM_TV(li), false);
|
||||||
li = TV_LIST_ITEM_NEXT(l, li);
|
li = TV_LIST_ITEM_NEXT(l, li);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5674,7 +5675,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
|
|||||||
// Existing line, replace it.
|
// Existing line, replace it.
|
||||||
int old_len = (int)strlen(ml_get(lnum));
|
int old_len = (int)strlen(ml_get(lnum));
|
||||||
if (u_savesub(lnum) == OK
|
if (u_savesub(lnum) == OK
|
||||||
&& ml_replace(lnum, (char *)line, true) == OK) {
|
&& ml_replace(lnum, line, true) == OK) {
|
||||||
inserted_bytes(lnum, 0, old_len, (int)strlen(line));
|
inserted_bytes(lnum, 0, old_len, (int)strlen(line));
|
||||||
if (is_curbuf && lnum == curwin->w_cursor.lnum) {
|
if (is_curbuf && lnum == curwin->w_cursor.lnum) {
|
||||||
check_cursor_col();
|
check_cursor_col();
|
||||||
@@ -5684,7 +5685,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
|
|||||||
} else if (added > 0 || u_save(lnum - 1, lnum) == OK) {
|
} else if (added > 0 || u_save(lnum - 1, lnum) == OK) {
|
||||||
// append the line.
|
// append the line.
|
||||||
added++;
|
added++;
|
||||||
if (ml_append(lnum - 1, (char *)line, 0, false) == OK) {
|
if (ml_append(lnum - 1, line, 0, false) == OK) {
|
||||||
rettv->vval.v_number = 0; // OK
|
rettv->vval.v_number = 0; // OK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5694,6 +5695,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
|
|||||||
}
|
}
|
||||||
lnum++;
|
lnum++;
|
||||||
}
|
}
|
||||||
|
xfree(line);
|
||||||
|
|
||||||
if (added > 0) {
|
if (added > 0) {
|
||||||
appended_lines_mark(append_lnum, added);
|
appended_lines_mark(append_lnum, added);
|
||||||
@@ -8965,10 +8967,16 @@ int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, bool ic)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *typval_tostring(typval_T *arg)
|
/// Convert any type to a string, never give an error.
|
||||||
|
/// When "quotes" is true add quotes to a string.
|
||||||
|
/// Returns an allocated string.
|
||||||
|
char *typval_tostring(typval_T *arg, bool quotes)
|
||||||
{
|
{
|
||||||
if (arg == NULL) {
|
if (arg == NULL) {
|
||||||
return xstrdup("(does not exist)");
|
return xstrdup("(does not exist)");
|
||||||
}
|
}
|
||||||
|
if (!quotes && arg->v_type == VAR_STRING) {
|
||||||
|
return xstrdup(arg->vval.v_string == NULL ? "" : arg->vval.v_string);
|
||||||
|
}
|
||||||
return encode_tv2string(arg, NULL);
|
return encode_tv2string(arg, NULL);
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user