From 356cff78ece597059133e33eceb955f72286a319 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 11 Apr 2022 21:29:18 +0800 Subject: [PATCH] vim-patch:8.2.4734: getcharpos() may change a mark position (#18077) Problem: getcharpos() may change a mark position. Solution: Copy the mark position. (closes vim/vim#10148) https://github.com/vim/vim/commit/3caf1cce2b85a8f24195d057f0ad63082543e99e --- src/nvim/eval.c | 33 ++++++++++++--------------- src/nvim/testdir/test_cursor_func.vim | 10 ++++++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c1905b31d0..3e855ece15 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7739,7 +7739,6 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { static pos_T pos; - pos_T *pp; // Argument can be [lnum, col, coladd]. if (tv->v_type == VAR_LIST) { @@ -7799,34 +7798,32 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret if (name == NULL) { return NULL; } - if (name[0] == '.') { // Cursor. + + pos.lnum = 0; + if (name[0] == '.') { + // cursor pos = curwin->w_cursor; - if (charcol) { - pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); - } - return &pos; - } - if (name[0] == 'v' && name[1] == NUL) { // Visual start. + } else if (name[0] == 'v' && name[1] == NUL) { + // Visual start if (VIsual_active) { pos = VIsual; } else { pos = curwin->w_cursor; } + } else if (name[0] == '\'') { + // mark + const pos_T *const pp = getmark_buf_fnum(curbuf, (uint8_t)name[1], false, ret_fnum); + if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) { + return NULL; + } + pos = *pp; + } + if (pos.lnum != 0) { if (charcol) { pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); } return &pos; } - if (name[0] == '\'') { // Mark. - pp = getmark_buf_fnum(curbuf, (uint8_t)name[1], false, ret_fnum); - if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) { - return NULL; - } - if (charcol) { - pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col); - } - return pp; - } pos.coladd = 0; diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim index 57825b4551..9ba82e3b70 100644 --- a/src/nvim/testdir/test_cursor_func.vim +++ b/src/nvim/testdir/test_cursor_func.vim @@ -140,12 +140,12 @@ func Test_getcharpos() call assert_fails('call getcharpos({})', 'E731:') call assert_equal([0, 0, 0, 0], getcharpos(0)) new - call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678']) + call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678', ' │ x']) " Test for '.' and '$' normal 1G call assert_equal([0, 1, 1, 0], getcharpos('.')) - call assert_equal([0, 4, 1, 0], getcharpos('$')) + call assert_equal([0, 5, 1, 0], getcharpos('$')) normal 2G6l call assert_equal([0, 2, 7, 0], getcharpos('.')) normal 3G$ @@ -159,6 +159,12 @@ func Test_getcharpos() delmarks m call assert_equal([0, 0, 0, 0], getcharpos("'m")) + " Check mark does not move + normal 5Gfxma + call assert_equal([0, 5, 5, 0], getcharpos("'a")) + call assert_equal([0, 5, 5, 0], getcharpos("'a")) + call assert_equal([0, 5, 5, 0], getcharpos("'a")) + " Test for the visual start column vnoremap SaveVisualStartCharPos() let g:VisualStartPos = []