]> granicus.if.org Git - vim/commitdiff
patch 8.2.3677: after a put the '] mark is on the last byte v8.2.3677
authorBram Moolenaar <Bram@vim.org>
Thu, 25 Nov 2021 19:31:15 +0000 (19:31 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 25 Nov 2021 19:31:15 +0000 (19:31 +0000)
Problem:    After a put the '] mark is on the last byte of a multi-byte
            character.
Solution:   Move it to the first byte. (closes #9047)

src/register.c
src/testdir/test_put.vim
src/version.c

index 268c839f749a3795692ef23a63787406958d6b76..00b8b4bb34b250757a775a906cb7b5839f6b9d0c 100644 (file)
@@ -2004,6 +2004,7 @@ do_put(
        {
            linenr_T    end_lnum = 0; // init for gcc
            linenr_T    start_lnum = lnum;
+           int         first_byte_off = 0;
 
            if (VIsual_active)
            {
@@ -2065,6 +2066,10 @@ do_put(
                    }
                    STRMOVE(ptr, oldp + col);
                    ml_replace(lnum, newp, FALSE);
+
+                   // compute the byte offset for the last character
+                   first_byte_off = mb_head_off(newp, ptr - 1);
+
                    // Place cursor on last putted char.
                    if (lnum == curwin->w_cursor.lnum)
                    {
@@ -2080,10 +2085,15 @@ do_put(
                    lnum--;
            }
 
+           // put '] at the first byte of the last character
            curbuf->b_op_end = curwin->w_cursor;
+           curbuf->b_op_end.col -= first_byte_off;
+
            // For "CTRL-O p" in Insert mode, put cursor after last char
            if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND)))
                ++curwin->w_cursor.col;
+           else
+               curwin->w_cursor.col -= first_byte_off;
            changed_bytes(lnum, col);
        }
        else
@@ -2198,12 +2208,14 @@ error:
                changed_lines(curbuf->b_op_start.lnum, 0,
                                           curbuf->b_op_start.lnum, nr_lines);
 
-           // put '] mark at last inserted character
+           // Put the '] mark on the first byte of the last inserted character.
+           // Correct the length for change in indent.
            curbuf->b_op_end.lnum = new_lnum;
-           // correct length for change in indent
            col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
            if (col > 1)
-               curbuf->b_op_end.col = col - 1;
+               curbuf->b_op_end.col = col - 1
+                               - mb_head_off(y_array[y_size - 1],
+                                               y_array[y_size - 1] + col - 1);
            else
                curbuf->b_op_end.col = 0;
 
index de66a6d7f513bbf85d91cbad0d2a3149865cd622..c390bbb612a1b4f9db53a3c5306c50fa12c0781c 100644 (file)
@@ -197,5 +197,18 @@ func Test_put_above_first_line()
   bwipe!
 endfunc
 
+func Test_multibyte_op_end_mark()
+  new
+  call setline(1, 'ั‚ะตัั‚')
+  normal viwdp
+  call assert_equal([0, 1, 7, 0], getpos("'>"))
+  call assert_equal([0, 1, 7, 0], getpos("']"))
+
+  normal Vyp
+  call assert_equal([0, 1, 2147483647, 0], getpos("'>"))
+  call assert_equal([0, 2, 7, 0], getpos("']"))
+  bwipe!
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
index 2c5163e8063712a35fd9b06c59b6b3c8a63bfc9b..0adbdb797c7a2d4fe1b29b7fe46d459bd9b31097 100644 (file)
@@ -757,6 +757,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3677,
 /**/
     3676,
 /**/