# HG changeset patch # User Bram Moolenaar # Date 1649679304 -7200 # Node ID 6e501ecd1bb77d88e5d80b75ce3c2f3922c2b7b6 # Parent 2da2c67d0db096f3cff79dbd90974021599e5b97 patch 8.2.4734: getcharpos() may change a mark position Commit: https://github.com/vim/vim/commit/3caf1cce2b85a8f24195d057f0ad63082543e99e Author: Bram Moolenaar Date: Mon Apr 11 13:05:16 2022 +0100 patch 8.2.4734: getcharpos() may change a mark position Problem: getcharpos() may change a mark position. Solution: Copy the mark position. (closes https://github.com/vim/vim/issues/10148) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -5636,34 +5636,35 @@ var2fpos( name = tv_get_string_chk(varp); if (name == NULL) return NULL; + + pos.lnum = 0; if (name[0] == '.' && (!in_vim9script() || name[1] == NUL)) { // 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; - if (charcol) - pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); - return &pos; } - if (name[0] == '\'' && (!in_vim9script() + else if (name[0] == '\'' && (!in_vim9script() || (name[1] != NUL && name[2] == NUL))) { // mark pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) return NULL; + pos = *pp; + } + if (pos.lnum != 0) + { if (charcol) - pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col); - return pp; + pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); + return &pos; } pos.coladd = 0; diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim --- a/src/testdir/test_cursor_func.vim +++ b/src/testdir/test_cursor_func.vim @@ -188,12 +188,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$ @@ -207,6 +207,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 = [] diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4734, +/**/ 4733, /**/ 4732,