# HG changeset patch # User Christian Brabandt # Date 1485608404 -3600 # Node ID 44a1661f4cfaa091f12206458ff6ab8e9c122803 # Parent 85d402f74ef71080eebd50c82b47e5d7b9db676d patch 8.0.0250: virtcol() does not work well for multi-byte characters commit https://github.com/vim/vim/commit/0c0590d9827cb07a33c1552cb3558b94bddcb4dc Author: Bram Moolenaar Date: Sat Jan 28 13:48:10 2017 +0100 patch 8.0.0250: virtcol() does not work well for multi-byte characters Problem: When virtcol() gets a column that is not the first byte of a multi-byte character the result is unpredictable. (Christian Ludwig) Solution: Correct the column to the first byte of a multi-byte character. Change the utf-8 test to new style. diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -2058,7 +2058,6 @@ test1 \ test_listlbr \ test_listlbr_utf8 \ test_search_mbyte \ - test_utf8 \ test_wordcount \ test3 test4 test5 test6 test7 test8 test9 \ test11 test12 test14 test15 test17 test18 test19 \ @@ -2183,6 +2182,7 @@ test_arglist \ test_undo \ test_unlet \ test_usercommands \ + test_utf8 \ test_viminfo \ test_viml \ test_visual \ diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -1296,7 +1296,14 @@ getvcol( if (pos->col == MAXCOL) posptr = NULL; /* continue until the NUL */ else + { posptr = ptr + pos->col; +#ifdef FEAT_MBYTE + if (has_mbyte) + /* always start on the first byte */ + posptr -= (*mb_head_off)(line, posptr); +#endif + } /* * This function is used very often, do some speed optimizations. diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -84,7 +84,6 @@ SCRIPTS_ALL = \ test_listchars.out \ test_listlbr.out \ test_search_mbyte.out \ - test_utf8.out \ test_wordcount.out diff --git a/src/testdir/test_alot_utf8.vim b/src/testdir/test_alot_utf8.vim --- a/src/testdir/test_alot_utf8.vim +++ b/src/testdir/test_alot_utf8.vim @@ -9,3 +9,4 @@ source test_expr_utf8.vim source test_matchadd_conceal_utf8.vim source test_regexp_utf8.vim source test_source_utf8.vim +source test_utf8.vim diff --git a/src/testdir/test_utf8.in b/src/testdir/test_utf8.in deleted file mode 100644 --- a/src/testdir/test_utf8.in +++ /dev/null @@ -1,46 +0,0 @@ -Tests for Unicode manipulations vim: set ft=vim : - -STARTTEST -:so small.vim -:set encoding=utf-8 -:" -:" Visual block Insert adjusts for multi-byte char -:new -:call setline(1, ["aaa", "あああ", "bbb"]) -:exe ":norm! gg0l\jjIx\" -:let r = getline(1, '$') -:" -:bwipeout! -:$put=r -:" -:" Test for built-in function strchars() -:for str in ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"] -: $put=strchars(str) -: $put=strchars(str, 0) -: $put=strchars(str, 1) -:endfor -:" -:" Test for customlist completion -:function! CustomComplete1(lead, line, pos) -: return ['あ', 'い'] -:endfunction -:command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo -:call feedkeys(":Test1 \'\$put='\", 'it') -:" -:function! CustomComplete2(lead, line, pos) -: return ['あたし', 'あたま', 'あたりめ'] -:endfunction -:command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo -:call feedkeys(":Test2 \'\$put='\", 'it') -:" -:function! CustomComplete3(lead, line, pos) -: return ['Nこ', 'Nん', 'Nぶ'] -:endfunction -:command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo -:call feedkeys(":Test3 \'\$put='\", 'it') -:" -:call garbagecollect(1) -:/^start:/,$wq! test.out -ENDTEST - -start: diff --git a/src/testdir/test_utf8.ok b/src/testdir/test_utf8.ok deleted file mode 100644 --- a/src/testdir/test_utf8.ok +++ /dev/null @@ -1,22 +0,0 @@ -start: -axaa -xあああ -bxbb -1 -1 -1 -3 -3 -3 -2 -2 -1 -3 -3 -1 -1 -1 -1 -Test1 -Test2 あた -Test3 N diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim new file mode 100644 --- /dev/null +++ b/src/testdir/test_utf8.vim @@ -0,0 +1,65 @@ +" Tests for Unicode manipulations +if !has('multi_byte') + finish +endif + + +" Visual block Insert adjusts for multi-byte char +func Test_visual_block_insert() + new + call setline(1, ["aaa", "あああ", "bbb"]) + exe ":norm! gg0l\jjIx\" + call assert_equal(['axaa', 'xあああ', 'bxbb'], getline(1, '$')) + bwipeout! +endfunc + +" Test for built-in function strchars() +func Test_strchars() + let inp = ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"] + let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]] + for i in range(len(inp)) + call assert_equal(exp[i][0], strchars(inp[i])) + call assert_equal(exp[i][1], strchars(inp[i], 0)) + call assert_equal(exp[i][2], strchars(inp[i], 1)) + endfor +endfunc + +" Test for customlist completion +function! CustomComplete1(lead, line, pos) + return ['あ', 'い'] +endfunction + +function! CustomComplete2(lead, line, pos) + return ['あたし', 'あたま', 'あたりめ'] +endfunction + +function! CustomComplete3(lead, line, pos) + return ['Nこ', 'Nん', 'Nぶ'] +endfunction + +func Test_customlist_completion() + command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo + call feedkeys(":Test1 \\\"\", 'itx') + call assert_equal('"Test1 ', getreg(':')) + + command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo + call feedkeys(":Test2 \\\"\", 'itx') + call assert_equal('"Test2 あた', getreg(':')) + + command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo + call feedkeys(":Test3 \\\"\", 'itx') + call assert_equal('"Test3 N', getreg(':')) + + call garbagecollect(1) +endfunc + +" Yank one 3 byte character and check the mark columns. +func Test_getvcol() + new + call setline(1, "x\u2500x") + normal 0lvy + call assert_equal(2, col("'[")) + call assert_equal(4, col("']")) + call assert_equal(2, virtcol("'[")) + call assert_equal(2, virtcol("']")) +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 250, +/**/ 249, /**/ 248,