aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-09-12 17:10:31 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-09-12 17:28:07 +0800
commit245ac6f263b6017c050f885212ee80e5738d3b9f (patch)
treeca90a565370f46fd84ddf052c5769e04ede33e00 /src
parent4448fa88ecca11acd4742ef3d38f9e0d42c0b4a5 (diff)
downloadrneovim-245ac6f263b6017c050f885212ee80e5738d3b9f.tar.gz
rneovim-245ac6f263b6017c050f885212ee80e5738d3b9f.tar.bz2
rneovim-245ac6f263b6017c050f885212ee80e5738d3b9f.zip
vim-patch:8.2.5034: there is no way to get the byte index from a virtual column
Problem: There is no way to get the byte index from a virtual column. Solution: Add virtcol2col(). (Yegappan Lakshmanan, closes vim/vim#10477, closes vim/vim#10098) https://github.com/vim/vim/commit/5a6ec10cc80ab02eeff644ab19b82312630ea855 Cherry-pick tv_check_for_number_arg() from Vim. Cherry-pick pathshorten() doc change.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/typval.c13
-rw-r--r--src/nvim/move.c32
-rw-r--r--src/nvim/testdir/test_cursor_func.vim22
4 files changed, 68 insertions, 0 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 3e89489459..5c500af899 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -425,6 +425,7 @@ return {
uniq={args={1, 3}, base=1},
values={args=1, base=1},
virtcol={args=1, base=1},
+ virtcol2col={args=3, base=1},
visualmode={args={0, 1}},
wait={args={2,3}},
wildmenumode={},
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index c75d16e4fc..2089415ffa 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -44,6 +44,8 @@ static char e_string_required_for_argument_nr[]
= N_("E1174: String required for argument %d");
static char e_non_empty_string_required_for_argument_nr[]
= N_("E1142: Non-empty string required for argument %d");
+static char e_number_required_for_argument_nr[]
+ = N_("E1210: Number required for argument %d");
bool tv_in_free_unref_items = false;
@@ -3830,6 +3832,17 @@ int tv_check_for_nonempty_string_arg(const typval_T *const args, const int idx)
return OK;
}
+/// Give an error and return FAIL unless "args[idx]" is a number.
+int tv_check_for_number_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_NUMBER) {
+ semsg(_(e_number_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/move.c b/src/nvim/move.c
index 9e0662c141..481746881b 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -22,12 +22,14 @@
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
#include "nvim/grid.h"
#include "nvim/highlight.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/plines.h"
@@ -1004,6 +1006,36 @@ void f_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
tv_dict_add_nr(dict, S_LEN("endcol"), ecol);
}
+/// "virtcol2col({winid}, {lnum}, {col})" function
+void f_virtcol2col(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ rettv->vval.v_number = -1;
+
+ if (tv_check_for_number_arg(argvars, 0) == FAIL
+ || tv_check_for_number_arg(argvars, 1) == FAIL
+ || tv_check_for_number_arg(argvars, 2) == FAIL) {
+ return;
+ }
+
+ win_T *wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL) {
+ return;
+ }
+
+ bool error = false;
+ linenr_T lnum = (linenr_T)tv_get_number_chk(&argvars[1], &error);
+ if (error || lnum < 0 || lnum > wp->w_buffer->b_ml.ml_line_count) {
+ return;
+ }
+
+ int screencol = (int)tv_get_number_chk(&argvars[2], &error);
+ if (error || screencol < 0) {
+ return;
+ }
+
+ rettv->vval.v_number = vcol2col(wp, lnum, screencol);
+}
+
/// Scroll the current window down by "line_count" logical lines. "CTRL-Y"
///
/// @param line_count number of lines to scroll
diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim
index f13842edc8..2e625f2388 100644
--- a/src/nvim/testdir/test_cursor_func.vim
+++ b/src/nvim/testdir/test_cursor_func.vim
@@ -373,4 +373,26 @@ func Test_setcursorcharpos()
%bw!
endfunc
+" Test for virtcol2col()
+func Test_virtcol2col()
+ new
+ call setline(1, ["a\tb\tc"])
+ call assert_equal(1, virtcol2col(0, 1, 1))
+ call assert_equal(2, virtcol2col(0, 1, 2))
+ call assert_equal(2, virtcol2col(0, 1, 8))
+ call assert_equal(3, virtcol2col(0, 1, 9))
+ call assert_equal(4, virtcol2col(0, 1, 10))
+ call assert_equal(4, virtcol2col(0, 1, 16))
+ call assert_equal(5, virtcol2col(0, 1, 17))
+ call assert_equal(-1, virtcol2col(10, 1, 1))
+ call assert_equal(-1, virtcol2col(0, 10, 1))
+ call assert_equal(-1, virtcol2col(0, -1, 1))
+ call assert_equal(-1, virtcol2col(0, 1, -1))
+ call assert_equal(5, virtcol2col(0, 1, 20))
+ call assert_fails('echo virtcol2col("0", 1, 20)', 'E1210:')
+ call assert_fails('echo virtcol2col(0, "1", 20)', 'E1210:')
+ call assert_fails('echo virtcol2col(0, 1, "1")', 'E1210:')
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab