From 87440e7bc5441b3672471df4f51ad44fe0182bd8 Mon Sep 17 00:00:00 2001 From: Emilia Simmons Date: Sun, 15 Dec 2024 13:28:16 -0500 Subject: [PATCH] fix(runtime): let matchit and matchparen skips fallback on treesitter captures When treesitter is enabled, by default syntax groups are not defined, but these groups are used to identify where to skip matches in matchit and matchparen. This patch does three things: 1. If syntax is enabled regardless of treesitter (`vim.bo.syntax='on'`): Use original implementation. 2. If treesitter is enabled and syntax is not: Match the syntax groups (i.e. `comment\|string`) against treesitter captures to check for skipped groups. 3. Add an explicit treesitter syntax for marking captures to skip: matchit uses `b:match_skip` to determine what counts as skippable Where 's:comment\|string' uses a match of the named syntax groups against a regex match of comment\|string, 't:comment\|string' now uses vim regex to match against the names of the treesitter capture groups. (cherry picked from commit 69aa33d890468c1024beef0d97d0f9424516c9ef) --- runtime/pack/dist/opt/matchit/autoload/matchit.vim | 10 +++++++++- runtime/pack/dist/opt/matchit/doc/matchit.txt | 2 ++ runtime/plugin/matchparen.vim | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/runtime/pack/dist/opt/matchit/autoload/matchit.vim b/runtime/pack/dist/opt/matchit/autoload/matchit.vim index dc2aba696d..70f148a077 100644 --- a/runtime/pack/dist/opt/matchit/autoload/matchit.vim +++ b/runtime/pack/dist/opt/matchit/autoload/matchit.vim @@ -218,6 +218,7 @@ function matchit#Match_wrapper(word, forward, mode) range let view = winsaveview() call cursor(0, curcol + 1) if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) + \ || skip =~ 'v:lua.vim.treesitter' && !exists('b:ts_highlight') let skip = "0" else execute "if " .. skip .. "| let skip = '0' | endif" @@ -672,6 +673,7 @@ fun! matchit#MultiMatch(spflag, mode) let middlepat = substitute(middlepat, ',', '\\|', 'g') if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) + \ || skip =~ 'v:lua.vim.treesitter' && !exists('b:ts_highlight') let skip = '0' else try @@ -754,10 +756,16 @@ endfun " S:foo becomes (current syntax item) !~ foo " r:foo becomes (line before cursor) =~ foo " R:foo becomes (line before cursor) !~ foo +" t:foo becomes (current treesitter captures) =~ foo +" T:foo becomes (current treesitter captures) !~ foo fun! s:ParseSkip(str) let skip = a:str if skip[1] == ":" - if skip[0] ==# "s" + if skip[0] ==# "t" || skip[0] ==# "s" && &syntax != 'on' && exists("b:ts_highlight") + let skip = "match(v:lua.vim.treesitter.get_captures_at_cursor(), '" .. strpart(skip,2) .. "') != -1" + elseif skip[0] ==# "T" || skip[0] ==# "S" && &syntax != 'on' && exists("b:ts_highlight") + let skip = "match(v:lua.vim.treesitter.get_captures_at_cursor(), '" .. strpart(skip,2) .. "') == -1" + elseif skip[0] ==# "s" let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .. \ strpart(skip,2) .. "'" elseif skip[0] ==# "S" diff --git a/runtime/pack/dist/opt/matchit/doc/matchit.txt b/runtime/pack/dist/opt/matchit/doc/matchit.txt index 88d0c38e4d..02dfed8c12 100644 --- a/runtime/pack/dist/opt/matchit/doc/matchit.txt +++ b/runtime/pack/dist/opt/matchit/doc/matchit.txt @@ -237,6 +237,8 @@ supported by matchit.vim: S:foo becomes (current syntax item) !~ foo r:foo becomes (line before cursor) =~ foo R:foo becomes (line before cursor) !~ foo + t:foo becomes (current treesitter captures) =~ foo + T:foo becomes (current treesitter captures) !~ foo (The "s" is meant to suggest "syntax", and the "r" is meant to suggest "regular expression".) diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim index 2899612dce..73dc699a0d 100644 --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -106,6 +106,10 @@ func s:Highlight_Matching_Pair() if !has("syntax") || !exists("g:syntax_on") let s_skip = "0" + elseif exists("b:ts_highlight") && &syntax != 'on' + let s_skip = "match(v:lua.vim.treesitter.get_captures_at_cursor(), '" + \ .. 'string\|character\|singlequote\|escape\|symbol\|comment' + \ .. "') != -1" else " Build an expression that detects whether the current cursor position is " in certain syntax types (string, comment, etc.), for use as