aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/debugger.c12
-rw-r--r--src/nvim/eval.c26
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c19
-rw-r--r--src/nvim/testdir/test_bufline.vim14
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