diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/debugger.c | 12 | ||||
-rw-r--r-- | src/nvim/eval.c | 26 | ||||
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 19 | ||||
-rw-r--r-- | src/nvim/testdir/test_bufline.vim | 14 |
5 files changed, 54 insertions, 18 deletions
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/eval.lua b/src/nvim/eval.lua index dd30f51eb4..14be6aba73 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -146,6 +146,7 @@ return { get={args={2, 3}, base=1}, getbufinfo={args={0, 1}, base=1}, getbufline={args={2, 3}, base=1}, + getbufoneline={args=2, base=1}, getbufvar={args={2, 3}, base=1}, getchangelist={args={0, 1}, base=1}, getchar={args={0, 1}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 12568ec965..8666aa4f35 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2671,8 +2671,9 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli } } -/// "getbufline()" function -static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +/// @param retlist true: "getbufline()" function +/// false: "getbufoneline()" function +static void getbufline(typval_T *argvars, typval_T *rettv, bool retlist) { const int did_emsg_before = did_emsg; buf_T *const buf = tv_get_buf_from_arg(&argvars[0]); @@ -2684,7 +2685,19 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) ? lnum : tv_get_lnum_buf(&argvars[2], buf)); - get_buffer_lines(buf, lnum, end, true, rettv); + get_buffer_lines(buf, lnum, end, retlist, rettv); +} + +/// "getbufline()" function +static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + getbufline(argvars, rettv, true); +} + +/// "getbufoneline()" function +static void f_getbufoneline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + getbufline(argvars, rettv, false); } /// "getchangelist()" function diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim index fae6b1dab7..d4dee38620 100644 --- a/src/nvim/testdir/test_bufline.vim +++ b/src/nvim/testdir/test_bufline.vim @@ -5,12 +5,15 @@ source screendump.vim source check.vim func Test_setbufline_getbufline() + " similar to Test_set_get_bufline() new let b = bufnr('%') hide call assert_equal(0, setbufline(b, 1, ['foo', 'bar'])) call assert_equal(['foo'], getbufline(b, 1)) + call assert_equal('foo', getbufoneline(b, 1)) call assert_equal(['bar'], getbufline(b, '$')) + call assert_equal('bar', getbufoneline(b, '$')) call assert_equal(['foo', 'bar'], getbufline(b, 1, 2)) exe "bd!" b call assert_equal([], getbufline(b, 1, 2)) @@ -34,10 +37,21 @@ func Test_setbufline_getbufline() call assert_equal(0, setbufline(b, 4, ['d', 'e'])) call assert_equal(['c'], b->getbufline(3)) + call assert_equal('c', b->getbufoneline(3)) call assert_equal(['d'], getbufline(b, 4)) + call assert_equal('d', getbufoneline(b, 4)) call assert_equal(['e'], getbufline(b, 5)) + call assert_equal('e', getbufoneline(b, 5)) call assert_equal([], getbufline(b, 6)) call assert_equal([], getbufline(b, 2, 1)) + + if has('job') + call setbufline(b, 2, [function('eval'), #{key: 123}, test_null_job()]) + call assert_equal(["function('eval')", + \ "{'key': 123}", + \ "no process"], + \ getbufline(b, 2, 4)) + endif exe "bwipe! " . b endfunc |