Skip to content

Commit 2afb7fc

Browse files
authored
perf: improve general treesitter performance and markdown particular performance (#423)
* perf(treesitter): query only the necessary trees instead of all of them * perf(markdown): remove expensive latex query
1 parent 1c276e1 commit 2afb7fc

3 files changed

Lines changed: 35 additions & 40 deletions

File tree

after/queries/markdown/matchup.scm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
;; ====================
2-
;; fenced code block ```
3-
;; ====================
1+
; ====================
2+
; fenced code block ```
3+
; ====================
44
(fenced_code_block
55
(fenced_code_block_delimiter) @open.code_fence
6-
(fenced_code_block_delimiter) @close.code_fence) @scope.code_fence
6+
(fenced_code_block_delimiter) @close.code_fence) @scope.code_fence
Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,29 @@
1-
;; ===========
2-
;; inline code `
3-
;; ===========
1+
; ===========
2+
; inline code `
3+
; ===========
44
(code_span
55
(code_span_delimiter) @open.code
66
(code_span_delimiter) @close.code) @scope.code
77

8-
;; ===========================
9-
;; emphasis (italic, *...* / _..._)
10-
;; ===========================
8+
; ===========================
9+
; emphasis (italic, *...* / _..._)
10+
; ===========================
1111
(emphasis
1212
(emphasis_delimiter) @open.emphasis
1313
(emphasis_delimiter) @close.emphasis) @scope.emphasis
1414

15-
;; ===========================
16-
;; strong emphasis (bold, **...** / __...__)
17-
;; ===========================
15+
; ===========================
16+
; strong emphasis (bold, **...** / __...__)
17+
; ===========================
1818
(strong_emphasis
1919
(emphasis_delimiter) @open.strong
2020
(emphasis_delimiter) @open.strong
2121
(emphasis_delimiter) @close.strong
2222
(emphasis_delimiter) @close.strong) @scope.strong
2323

24-
;; ===========================
25-
;; strikethrough (~~...~~)
26-
;; ===========================
24+
; ===========================
25+
; strikethrough (~~...~~)
26+
; ===========================
2727
(strikethrough
2828
(emphasis_delimiter) @open.strikethrough
2929
(emphasis_delimiter) @close.strikethrough) @scope.strikethrough
30-
31-
;; ===========================
32-
;; LaTeX math ($...$ / $$...$$)
33-
;; ===========================
34-
(latex_block
35-
(latex_span_delimiter) @open.math
36-
(latex_span_delimiter) @close.math) @scope.math

lua/treesitter-matchup/internal.lua

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ end
7878
---@param lang string
7979
---@return matchup.treesitter.Match[]
8080
local get_memoized_matches = memoize(function(bufnr, root, lang)
81-
local query_name = 'matchup'
82-
local query = ts.query.get(lang, query_name)
81+
local query = ts.query.get(lang, 'matchup')
8382

8483
if not query then
8584
return {}
@@ -137,28 +136,31 @@ end, buf_root_lang_hash)
137136
---@param bufnr integer
138137
---@return matchup.treesitter.Match[]
139138
M.get_matches = function(bufnr)
140-
local parser = ts.get_parser(bufnr)
139+
local lang_tree = ts.get_parser(bufnr)
141140
local matches = {} ---@type matchup.treesitter.Match[]
142141

143-
if parser then
142+
if lang_tree then
144143
-- NOTE: assummes that we are always parsing the current window. May cause
145144
-- issues if that's not always the case
146-
local win = api.nvim_get_current_win()
147-
local cur_row = unpack(api.nvim_win_get_cursor(win))
145+
local cursor = vim.api.nvim_win_get_cursor(0)
148146
local stopline = vim.g.matchup_treesitter_stopline ---@type integer
149-
local start_row = math.max(cur_row - stopline, 0)
150-
local end_row = math.min(cur_row + stopline, api.nvim_buf_line_count(bufnr))
151-
152-
parser:parse({start_row, end_row})
153-
parser:for_each_tree(function(tree, lang_tree)
154-
if not tree or lang_tree:lang() == 'comment' then
155-
return
147+
local start_row = math.max(cursor[1] - stopline, 0)
148+
local end_row = math.min(cursor[1] + stopline, api.nvim_buf_line_count(bufnr))
149+
150+
lang_tree:parse({ start_row, end_row })
151+
---@type vim.treesitter.LanguageTree?
152+
local nested_lang_tree = lang_tree:language_for_range({ cursor[1]-1, cursor[2], cursor[1]-1, cursor[2] })
153+
while vim.tbl_isempty(matches) and nested_lang_tree ~= nil do
154+
local lang = nested_lang_tree:lang()
155+
if lang ~= 'comment' then
156+
for _, tree in ipairs(nested_lang_tree:trees()) do
157+
local group_results = get_memoized_matches(bufnr, tree:root(), lang)
158+
vim.list_extend(matches, group_results)
159+
end
156160
end
157161

158-
local lang = lang_tree:lang()
159-
local group_results = get_memoized_matches(bufnr, tree:root(), lang)
160-
vim.list_extend(matches, group_results)
161-
end)
162+
nested_lang_tree = nested_lang_tree:parent()
163+
end
162164
end
163165

164166
return matches

0 commit comments

Comments
 (0)