aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/treesitter.lua37
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua88
2 files changed, 73 insertions, 52 deletions
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua
index 77bbfaa3ad..0de3388356 100644
--- a/runtime/lua/vim/treesitter.lua
+++ b/runtime/lua/vim/treesitter.lua
@@ -59,6 +59,24 @@ function Parser:_on_bytes(bufnr, changed_tick,
end
end
+--- Registers callbacks for the parser
+-- @param cbs An `nvim_buf_attach`-like table argument with the following keys :
+-- `on_bytes` : see `nvim_buf_attach`, but this will be called _after_ the parsers callback.
+-- `on_changedtree` : a callback that will be called everytime the tree has syntactical changes.
+-- it will only be passed one argument, that is a table of the ranges (as node ranges) that
+-- changed.
+function Parser:register_cbs(cbs)
+ if not cbs then return end
+
+ if cbs.on_changedtree then
+ table.insert(self.changedtree_cbs, cbs.on_changedtree)
+ end
+
+ if cbs.on_bytes then
+ table.insert(self.bytes_cbs, cbs.on_bytes)
+ end
+end
+
--- Sets the included ranges for the current parser
--
-- @param ranges A table of nodes that will be used as the ranges the parser should include.
@@ -68,6 +86,11 @@ function Parser:set_included_ranges(ranges)
self.valid = false
end
+--- Gets the included ranges for the parsers
+function Parser:included_ranges()
+ return self._parser:included_ranges()
+end
+
local M = vim.tbl_extend("error", query, language)
setmetatable(M, {
@@ -127,11 +150,7 @@ end
--
-- @param bufnr The buffer the parser should be tied to
-- @param ft The filetype of this parser
--- @param buf_attach_cbs An `nvim_buf_attach`-like table argument with the following keys :
--- `on_lines` : see `nvim_buf_attach`, but this will be called _after_ the parsers callback.
--- `on_changedtree` : a callback that will be called everytime the tree has syntactical changes.
--- it will only be passed one argument, that is a table of the ranges (as node ranges) that
--- changed.
+-- @param buf_attach_cbs See Parser:register_cbs
--
-- @returns The parser
function M.get_parser(bufnr, lang, buf_attach_cbs)
@@ -147,13 +166,7 @@ function M.get_parser(bufnr, lang, buf_attach_cbs)
parsers[id] = M._create_parser(bufnr, lang, id)
end
- if buf_attach_cbs and buf_attach_cbs.on_changedtree then
- table.insert(parsers[id].changedtree_cbs, buf_attach_cbs.on_changedtree)
- end
-
- if buf_attach_cbs and buf_attach_cbs.on_bytes then
- table.insert(parsers[id].bytes_cbs, buf_attach_cbs.on_bytes)
- end
+ parsers[id]:register_cbs(buf_attach_cbs)
return parsers[id]
end
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index 47114a306f..decde08019 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -8,7 +8,7 @@ TSHighlighter.active = TSHighlighter.active or {}
local ns = a.nvim_create_namespace("treesitter/highlighter")
--- These are conventions defined by tree-sitter, though it
+-- These are conventions defined by nvim-treesitter, though it
-- needs to be user extensible also.
TSHighlighter.hl_map = {
["error"] = "Error",
@@ -56,21 +56,14 @@ TSHighlighter.hl_map = {
["include"] = "Include",
}
-function TSHighlighter.new(bufnr, ft, query)
- if bufnr == nil or bufnr == 0 then
- bufnr = a.nvim_get_current_buf()
- end
-
+function TSHighlighter.new(parser, query)
local self = setmetatable({}, TSHighlighter)
- self.parser = vim.treesitter.get_parser(
- bufnr,
- ft,
- {
- on_changedtree = function(...) self:on_changedtree(...) end,
- }
- )
-
- self.buf = self.parser.bufnr
+
+ self.parser = parser
+ parser:register_cbs {
+ on_changedtree = function(...) self:on_changedtree(...) end
+ }
+
self:set_query(query)
self.edit_count = 0
self.redraw_count = 0
@@ -79,7 +72,11 @@ function TSHighlighter.new(bufnr, ft, query)
a.nvim_buf_set_option(self.buf, "syntax", "")
-- TODO(bfredl): can has multiple highlighters per buffer????
- TSHighlighter.active[bufnr] = self
+ if not TSHighlighter.active[parser.bufnr] then
+ TSHighlighter.active[parser.bufnr] = {}
+ end
+
+ TSHighlighter.active[parser.bufnr][parser.lang] = self
-- Tricky: if syntax hasn't been enabled, we need to reload color scheme
-- but use synload.vim rather than syntax.vim to not enable
@@ -119,13 +116,6 @@ end
function TSHighlighter:set_query(query)
if type(query) == "string" then
query = vim.treesitter.parse_query(self.parser.lang, query)
- elseif query == nil then
- query = vim.treesitter.get_query(self.parser.lang, 'highlights')
-
- if query == nil then
- a.nvim_err_writeln("No highlights.scm query found for " .. self.parser.lang)
- query = vim.treesitter.parse_query(self.parser.lang, "")
- end
end
self.query = query
@@ -139,12 +129,16 @@ function TSHighlighter:set_query(query)
end
})
- a.nvim__buf_redraw_range(self.buf, 0, a.nvim_buf_line_count(self.buf))
+ a.nvim__buf_redraw_range(self.parser.bufnr, 0, a.nvim_buf_line_count(self.parser.bufnr))
end
-function TSHighlighter._on_line(_, _win, buf, line)
- -- on_line is only called when this is non-nil
- local self = TSHighlighter.active[buf]
+local function iter_active_tshl(buf, fn)
+ for _, hl in pairs(TSHighlighter.active[buf] or {}) do
+ fn(hl)
+ end
+end
+
+local function on_line_impl(self, buf, line)
if self.root == nil then
return -- parser bought the farm already
end
@@ -172,24 +166,38 @@ function TSHighlighter._on_line(_, _win, buf, line)
end
end
-function TSHighlighter._on_buf(_, buf)
- local self = TSHighlighter.active[buf]
- if self then
- local tree = self.parser:parse()
- self.root = (tree and tree:root()) or nil
+function TSHighlighter._on_line(_, _win, buf, line, highlighter)
+ -- on_line is only called when this is non-nil
+ if highlighter then
+ on_line_impl(highlighter, buf, line)
+ else
+ iter_active_tshl(buf, function(self)
+ on_line_impl(self, buf, line)
+ end)
end
end
+function TSHighlighter._on_buf(_, buf)
+ iter_active_tshl(buf, function(self)
+ if self then
+ local tree = self.parser:parse()
+ self.root = (tree and tree:root()) or nil
+ end
+ end)
+end
+
function TSHighlighter._on_win(_, _win, buf, _topline, botline)
- local self = TSHighlighter.active[buf]
- if not self then
- return false
- end
+ iter_active_tshl(buf, function(self)
+ if not self then
+ return false
+ end
- self.iter = nil
- self.nextrow = 0
- self.botline = botline
- self.redraw_count = self.redraw_count + 1
+ self.iter = nil
+ self.nextrow = 0
+ self.botline = botline
+ self.redraw_count = self.redraw_count + 1
+ return true
+ end)
return true
end