aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-11-13 08:29:05 +0800
committerGitHub <noreply@github.com>2022-11-13 08:29:05 +0800
commit849394e4e26f487586761a3640475c27ceca30b9 (patch)
tree9d77b58ace60d150dd42c617cdab2af0495c2a5e /src
parentec449c27fdad6cc907a6f4835ce28f31990ad519 (diff)
downloadrneovim-849394e4e26f487586761a3640475c27ceca30b9.tar.gz
rneovim-849394e4e26f487586761a3640475c27ceca30b9.tar.bz2
rneovim-849394e4e26f487586761a3640475c27ceca30b9.zip
vim-patch:9.0.0863: col() and charcol() only work for the current window (#21038)
Problem: col() and charcol() only work for the current window. Solution: Add an optional winid argument. (Yegappan Lakshmanan, closes vim/vim#11466, closes vim/vim#11461) https://github.com/vim/vim/commit/4c8d2f02b3ce037bbe1d5ee12887e343c6bde88f Cherry-pick test_functions.vim change from patch 8.2.0633. Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.lua4
-rw-r--r--src/nvim/eval/funcs.c29
-rw-r--r--src/nvim/eval/typval.c13
-rw-r--r--src/nvim/testdir/test_cursor_func.vim24
-rw-r--r--src/nvim/testdir/test_functions.vim12
5 files changed, 77 insertions, 5 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 8bfa6797d0..dd30f51eb4 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -73,12 +73,12 @@ return {
chansend={args=2},
char2nr={args={1, 2}, base=1},
charclass={args=1, base=1},
- charcol={args=1, base=1},
+ charcol={args={1, 2}, base=1},
charidx={args={2, 3}, base=1},
chdir={args=1, base=1},
cindent={args=1, base=1},
clearmatches={args={0, 1}, base=1},
- col={args=1, base=1},
+ col={args={1, 2}, base=1},
complete={args=2, base=2},
complete_add={args=1, base=1},
complete_check={},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index be48dc7732..8acdc3256c 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -846,9 +846,32 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
/// otherwise the byte index of the column.
static void get_col(typval_T *argvars, typval_T *rettv, bool charcol)
{
+ if (tv_check_for_string_or_list_arg(argvars, 0) == FAIL
+ || tv_check_for_opt_number_arg(argvars, 1) == FAIL) {
+ return;
+ }
+
+ switchwin_T switchwin;
+ bool winchanged = false;
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ // use the window specified in the second argument
+ tabpage_T *tp;
+ win_T *wp = win_id2wp_tp((int)tv_get_number(&argvars[1]), &tp);
+ if (wp == NULL || tp == NULL) {
+ return;
+ }
+
+ if (switch_win_noblock(&switchwin, wp, tp, true) != OK) {
+ return;
+ }
+
+ check_cursor();
+ winchanged = true;
+ }
+
colnr_T col = 0;
int fnum = curbuf->b_fnum;
-
pos_T *fp = var2fpos(&argvars[0], false, &fnum, charcol);
if (fp != NULL && fnum == curbuf->b_fnum) {
if (fp->col == MAXCOL) {
@@ -876,6 +899,10 @@ static void get_col(typval_T *argvars, typval_T *rettv, bool charcol)
}
}
rettv->vval.v_number = col;
+
+ if (winchanged) {
+ restore_win_noblock(&switchwin, true);
+ }
}
/// "charcol()" function
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index e09fda173b..7e4066adb7 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -46,6 +46,8 @@ static char e_non_empty_string_required_for_argument_nr[]
= N_("E1175: Non-empty string required for argument %d");
static char e_number_required_for_argument_nr[]
= N_("E1210: Number required for argument %d");
+static char e_string_or_list_required_for_argument_nr[]
+ = N_("E1222: String or List required for argument %d");
bool tv_in_free_unref_items = false;
@@ -3880,6 +3882,17 @@ int tv_check_for_opt_number_arg(const typval_T *const args, const int idx)
|| tv_check_for_number_arg(args, idx) != FAIL) ? OK : FAIL;
}
+/// Give an error and return FAIL unless "args[idx]" is a string or a list.
+int tv_check_for_string_or_list_arg(const typval_T *const args, const int idx)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
+{
+ if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_LIST) {
+ semsg(_(e_string_or_list_required_for_argument_nr), idx + 1);
+ return FAIL;
+ }
+ return OK;
+}
+
/// Get the string value of a "stringish" VimL object.
///
/// @param[in] tv Object to get value of.
diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim
index 9801a45915..7f9e74e94b 100644
--- a/src/nvim/testdir/test_cursor_func.vim
+++ b/src/nvim/testdir/test_cursor_func.vim
@@ -241,8 +241,9 @@ endfunc
" Test for the charcol() function
func Test_charcol()
- call assert_fails('call charcol({})', 'E731:')
- call assert_equal(0, charcol(0))
+ call assert_fails('call charcol({})', 'E1222:')
+ call assert_fails('call charcol(".", [])', 'E1210:')
+ call assert_fails('call charcol(0)', 'E1222:')
new
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
@@ -298,6 +299,25 @@ func Test_charcol()
call assert_equal([1, 10, 2, 10, 7], g:InsertCurrentCol)
iunmap <F3>
+ " Test for getting the column number in another window.
+ let winid = win_getid()
+ new
+ call win_execute(winid, 'normal 1G')
+ call assert_equal(1, charcol('.', winid))
+ call assert_equal(1, charcol('$', winid))
+ call win_execute(winid, 'normal 2G6l')
+ call assert_equal(7, charcol('.', winid))
+ call assert_equal(10, charcol('$', winid))
+
+ " calling from another tab page also works
+ tabnew
+ call assert_equal(7, charcol('.', winid))
+ call assert_equal(10, charcol('$', winid))
+ tabclose
+
+ " unknown window ID
+ call assert_equal(0, charcol('.', 10001))
+
%bw!
endfunc
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index aaef01bdf5..5ff544ab55 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -1288,6 +1288,9 @@ func Test_col()
call assert_equal(0, col([2, '$']))
call assert_equal(0, col([1, 100]))
call assert_equal(0, col([1]))
+ call assert_equal(0, col(v:_null_list))
+ call assert_fails('let c = col({})', 'E1222:')
+ call assert_fails('let c = col(".", [])', 'E1210:')
" test for getting the visual start column
func T()
@@ -1317,6 +1320,15 @@ func Test_col()
call assert_equal(4, col('.'))
set virtualedit&
+ " Test for getting the column number in another window
+ let winid = win_getid()
+ new
+ call win_execute(winid, 'normal 1G$')
+ call assert_equal(3, col('.', winid))
+ call win_execute(winid, 'normal 2G')
+ call assert_equal(8, col('$', winid))
+ call assert_equal(0, col('.', 5001))
+
bw!
endfunc