From ce30ccc06af7f2c03762e5b18dde37b26ea6ec42 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 21 Nov 2022 19:57:04 +0000 Subject: patch 9.0.0916: getbufline() is inefficient for getting a single line Problem: getbufline() is inefficient for getting a single line. Solution: Add getbufoneline(). --- src/evalbuffer.c | 27 +++++++++++++++++++++++---- src/evalfunc.c | 2 ++ src/proto/evalbuffer.pro | 1 + src/testdir/test_bufline.vim | 5 +++++ src/testdir/test_vim9_builtin.vim | 8 ++++++++ src/version.c | 2 ++ 6 files changed, 41 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/evalbuffer.c b/src/evalbuffer.c index 4b514ddab..52662a653 100644 --- a/src/evalbuffer.c +++ b/src/evalbuffer.c @@ -814,10 +814,11 @@ get_buffer_lines( } /* - * "getbufline()" function + * "retlist" TRUE: "getbufline()" function + * "retlist" FALSE: "getbufoneline()" function */ - void -f_getbufline(typval_T *argvars, typval_T *rettv) + static void +getbufline(typval_T *argvars, typval_T *rettv, int retlist) { linenr_T lnum = 1; linenr_T end = 1; @@ -842,7 +843,25 @@ f_getbufline(typval_T *argvars, typval_T *rettv) end = 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 + */ + void +f_getbufline(typval_T *argvars, typval_T *rettv) +{ + getbufline(argvars, rettv, TRUE); +} + +/* + * "getbufoneline()" function + */ + void +f_getbufoneline(typval_T *argvars, typval_T *rettv) +{ + getbufline(argvars, rettv, FALSE); } /* diff --git a/src/evalfunc.c b/src/evalfunc.c index 310fa784e..e4f28edb7 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1923,6 +1923,8 @@ static funcentry_T global_functions[] = ret_list_dict_any, f_getbufinfo}, {"getbufline", 2, 3, FEARG_1, arg3_buffer_lnum_lnum, ret_list_string, f_getbufline}, + {"getbufoneline", 2, 2, FEARG_1, arg2_buffer_lnum, + ret_string, f_getbufoneline}, {"getbufvar", 2, 3, FEARG_1, arg3_buffer_string_any, ret_any, f_getbufvar}, {"getchangelist", 0, 1, FEARG_1, arg1_buffer, diff --git a/src/proto/evalbuffer.pro b/src/proto/evalbuffer.pro index 41616e705..d8ccdecc7 100644 --- a/src/proto/evalbuffer.pro +++ b/src/proto/evalbuffer.pro @@ -16,6 +16,7 @@ void f_bufwinnr(typval_T *argvars, typval_T *rettv); void f_deletebufline(typval_T *argvars, typval_T *rettv); void f_getbufinfo(typval_T *argvars, typval_T *rettv); void f_getbufline(typval_T *argvars, typval_T *rettv); +void f_getbufoneline(typval_T *argvars, typval_T *rettv); void f_getline(typval_T *argvars, typval_T *rettv); void f_setbufline(typval_T *argvars, typval_T *rettv); void f_setline(typval_T *argvars, typval_T *rettv); diff --git a/src/testdir/test_bufline.vim b/src/testdir/test_bufline.vim index 6021a4ea8..9e4402f79 100644 --- a/src/testdir/test_bufline.vim +++ b/src/testdir/test_bufline.vim @@ -11,7 +11,9 @@ func Test_setbufline_getbufline() 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)) @@ -35,8 +37,11 @@ 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)) diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index ecbfeacd6..005f89ca1 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -1724,15 +1724,23 @@ def Test_getbufline() getbufline(-1, '$', '$')->assert_equal([]) getbufline(-1, 1, '$')->assert_equal([]) + getbufoneline('#', 1)->assert_equal(lines[0]) + assert_equal([7, 7, 7], getbufline('#', 1, '$')->map((_, _) => 7)) assert_fails('getbufline("", "$a", "$b")', ['E1030: Using a String as a Number: "$a"', 'E1030: Using a String as a Number: "$a"']) assert_fails('getbufline("", "$", "$b")', ['E1030: Using a String as a Number: "$b"', 'E1030: Using a String as a Number: "$b"']) bwipe! + assert_fails('getbufoneline("", "$a")', ['E1030: Using a String as a Number: "$a"', 'E1030: Using a String as a Number: "$a"']) + bwipe! + v9.CheckDefAndScriptFailure(['getbufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) v9.CheckDefAndScriptFailure(['getbufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2']) v9.CheckDefAndScriptFailure(['getbufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3']) + + v9.CheckDefAndScriptFailure(['getbufoneline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) + v9.CheckDefAndScriptFailure(['getbufoneline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2']) enddef def Test_getbufvar() diff --git a/src/version.c b/src/version.c index 136521d7b..8a71fd376 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 916, /**/ 915, /**/ -- cgit v1.2.1