From 1ed493cc9607305d22faecbbcd47dbeef739b31d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 25 Aug 2024 06:07:43 +0800 Subject: [PATCH] vim-patch:9.1.0694: matchparen is slow on a long line (#30134) Problem: The matchparen plugin is slow on a long line. Solution: Don't use a regexp to get char at and before cursor. (zeertzjq) Example: ```vim call setline(1, repeat(' foobar', 100000)) runtime plugin/matchparen.vim normal! $hhhhhhhh ``` closes: vim/vim#15568 https://github.com/vim/vim/commit/81e7513c86459c40676bd983f73c2722096d67a9 (cherry picked from commit cf44121f7fb6f55a22e644a1e5e1f1dc6b90c27a) --- runtime/plugin/matchparen.vim | 8 +-- test/functional/legacy/matchparen_spec.lua | 79 ++++++++++++++++++++-- test/old/testdir/test_matchparen.vim | 30 ++++++++ 3 files changed, 107 insertions(+), 10 deletions(-) diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim index 6c061c9fb8..2899612dce 100644 --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -60,12 +60,8 @@ func s:Highlight_Matching_Pair() let before = 0 let text = getline(c_lnum) - let matches = matchlist(text, '\(.\)\=\%'.c_col.'c\(.\=\)') - if empty(matches) - let [c_before, c] = ['', ''] - else - let [c_before, c] = matches[1:2] - endif + let c_before = text->strpart(0, c_col - 1)->slice(-1) + let c = text->strpart(c_col - 1)->slice(0, 1) let plist = split(&matchpairs, '.\zs[:,]') let i = index(plist, c) if i < 0 diff --git a/test/functional/legacy/matchparen_spec.lua b/test/functional/legacy/matchparen_spec.lua index 3841761515..df0d80f0ab 100644 --- a/test/functional/legacy/matchparen_spec.lua +++ b/test/functional/legacy/matchparen_spec.lua @@ -120,8 +120,7 @@ describe('matchparen', function() ]]) feed('i') - screen:expect { - grid = [[ + screen:expect([[ aa | aaa | aaaa | @@ -131,7 +130,79 @@ describe('matchparen', function() {4: aaaa }{1: }| {1:~ }| {5:-- }{6:match 2 of 3} | - ]], - } + ]]) + end) + + -- oldtest: Test_matchparen_mbyte() + it("works with multibyte chars in 'matchpairs'", function() + local screen = Screen.new(30, 10) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Cyan }, + [2] = { bold = true }, + }) + screen:attach() + + exec([[ + source $VIMRUNTIME/plugin/matchparen.vim + call setline(1, ['aaaaaaaa(', 'bbbb)cc']) + set matchpairs+=(:) + ]]) + + screen:expect([[ + ^aaaaaaaa( | + bbbb)cc | + {0:~ }|*7 + | + ]]) + feed('$') + screen:expect([[ + aaaaaaaa{1:^(} | + bbbb{1:)}cc | + {0:~ }|*7 + | + ]]) + feed('j') + screen:expect([[ + aaaaaaaa( | + bbbb)c^c | + {0:~ }|*7 + | + ]]) + feed('2h') + screen:expect([[ + aaaaaaaa{1:(} | + bbbb{1:^)}cc | + {0:~ }|*7 + | + ]]) + feed('0') + screen:expect([[ + aaaaaaaa( | + ^bbbb)cc | + {0:~ }|*7 + | + ]]) + feed('kA') + screen:expect([[ + aaaaaaaa{1:(}^ | + bbbb{1:)}cc | + {0:~ }|*7 + {2:-- INSERT --} | + ]]) + feed('') + screen:expect([[ + aaaaaaaa( | + bbbb)cc^ | + {0:~ }|*7 + {2:-- INSERT --} | + ]]) + feed('') + screen:expect([[ + aaaaaaaa{1:(} | + bbbb{1:)}^ | + {0:~ }|*7 + {2:-- INSERT --} | + ]]) end) end) diff --git a/test/old/testdir/test_matchparen.vim b/test/old/testdir/test_matchparen.vim index ab425b046a..7d80e43046 100644 --- a/test/old/testdir/test_matchparen.vim +++ b/test/old/testdir/test_matchparen.vim @@ -108,5 +108,35 @@ func Test_matchparen_pum_clear() call StopVimInTerminal(buf) endfunc +" Test that matchparen works with multibyte chars in 'matchpairs' +func Test_matchparen_mbyte() + CheckScreendump + + let lines =<< trim END + source $VIMRUNTIME/plugin/matchparen.vim + call setline(1, ['aaaaaaaa(', 'bbbb)cc']) + set matchpairs+=(:) + END + + call writefile(lines, 'XmatchparenMbyte', 'D') + let buf = RunVimInTerminal('-S XmatchparenMbyte', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_1', {}) + call term_sendkeys(buf, "$") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_2', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_3', {}) + call term_sendkeys(buf, "2h") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_4', {}) + call term_sendkeys(buf, "0") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_5', {}) + call term_sendkeys(buf, "kA") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_6', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_7', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_8', {}) + + call StopVimInTerminal(buf) +endfunc " vim: shiftwidth=2 sts=2 expandtab