diff options
-rw-r--r-- | runtime/doc/builtin.txt | 3 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 6 | ||||
-rw-r--r-- | src/nvim/debugger.c | 12 | ||||
-rw-r--r-- | src/nvim/eval.c | 26 | ||||
-rw-r--r-- | src/nvim/testdir/test_bufline.vim | 7 |
5 files changed, 36 insertions, 18 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index fa9fb286ae..a6eafbf2b9 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -638,6 +638,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. {lnum} is used like with |getline()|. 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()|. 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. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index e4f8030f16..eb42e10338 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -229,13 +229,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 ~ diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index 71959cfa29..6f7d6a27ef 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -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); if (tv != NULL) { 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 { if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK && tv->vval.v_number == false) { 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". 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); bp->dbg_val = v; } tv_free(tv); } } 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); tv_free(bp->dbg_val); bp->dbg_val = NULL; line = true; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8e7eead62c..59dd689fa3 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5592,9 +5592,9 @@ void screenchar_adjust(ScreenGrid **grid, int *row, int *col) *col -= (*grid)->comp_col; } -/// Set line or list of lines in buffer "buf". -void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines, - typval_T *rettv) +/// Set line or list of lines in buffer "buf" to "lines". +/// Any type is allowed and converted to a string. +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) { 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; listitem_T *li = NULL; - const char *line = NULL; + char *line = NULL; if (lines->v_type == VAR_LIST) { l = lines->vval.v_list; 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); } else { - line = tv_get_string_chk(lines); + line = typval_tostring(lines, false); } // 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) { 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); } @@ -5674,7 +5675,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T // Existing line, replace it. int old_len = (int)strlen(ml_get(lnum)); 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)); if (is_curbuf && lnum == curwin->w_cursor.lnum) { 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) { // append the line. 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 } } @@ -5694,6 +5695,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T } lnum++; } + xfree(line); if (added > 0) { 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; } -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) { 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); } diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim index fae6b1dab7..0553774819 100644 --- a/src/nvim/testdir/test_bufline.vim +++ b/src/nvim/testdir/test_bufline.vim @@ -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 |