This commit is contained in:
Thomas Vigouroux 2020-07-27 11:41:00 +02:00
parent f9df9d55d7
commit 81daf86b3e
4 changed files with 120 additions and 5 deletions

View file

@ -9,7 +9,9 @@ local M = {
highlighters = {}
}
local hlmap = vim.treesitter.TSHighlighter.hl_map
local TSHighlighter = vim.treesitter.TSHighlighter
local hlmap = TSHighlighter.hl_map
-- Misc
hlmap.error = "TSError"
@ -52,6 +54,13 @@ hlmap["type.builtin"] = "TSTypeBuiltin"
hlmap["structure"] = "TSStructure"
hlmap["include"] = "TSInclude"
function M.create_highlighter(bufnr, lang)
local query = queries.get_query(lang, "highlights")
if not query then return end
M.highlighters[bufnr] = ts.TSHighlighter.new(query, bufnr, lang)
end
function M.attach(bufnr, lang)
local bufnr = bufnr or api.nvim_get_current_buf()
local lang = lang or parsers.get_buf_lang(bufnr)
@ -61,10 +70,7 @@ function M.attach(bufnr, lang)
hlmap[k] = v
end
local query = queries.get_query(lang, "highlights")
if not query then return end
M.highlighters[bufnr] = ts.TSHighlighter.new(query, bufnr, lang)
create_highlighter(bufnr, lang)
end
function M.detach(bufnr)

View file

@ -0,0 +1,63 @@
local api = vim.api
local ts = vim.treesitter
local parsers = require"nvim-tresitter.parsers"
local query = require"nvim-treesitter.query"
local hl = require"nvim-treesitter.highlight"
local ts_hs_ns = api.nvim_get_namespaces()["treesitter_hl"]
local M = {}
local LanguageTree = {}
function LanguageTree.new(bufnr, language, ranges)
local buffer = bufnr or api.nvim_get_current_buf()
local lang = language or parsers.get_buf_lang(bufnr)
if ranges then
parser.set_included_ranges(ranges)
end
local hl_query = hl.create_highlighter(bufnr, lang)
local injection_query = query.get_query(lang, "injections")
local self = setmetatable({
buf = buffer,
hl_query = hl_query,
injection_query = injection_query,
children = {}
}, LanguageTree)
self.parser = ts.get_parser(buffer, lang, {
on_changedtree = function(...) self:on_changedtree(...) end
})
return end
function LanguageTree:on_changedtree(changes)
-- Get a fresh root
if not self.injection_query then return end
local root = self.parser.tree:root()
for _, ch in ipairs(changes or {}) do
for match in query.iter_prepared_matches(self.injection_query, changed_node, self.buf, ch[1], ch[3] + 1) do
if match.content then
local start_row, start_col, end_row, end_col = match.content:range()
-- TODO(vigoux): this might be quite wrong
api.nvim_buf_clear_namespace(self.buf, ts_hs_ns, start_row, end_row)
-- Language injection here
if match.lang then
-- Prepare the child if not already done
if not self.children[match.lang] then
self.children[match.lang] = { ranges = {} }
end
end
end
end
end
end
return M

View file

@ -0,0 +1,3 @@
(fenced_code_block
(info_string) @injection.lang
(code_fence_content) @injection.content)

View file

@ -0,0 +1,43 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, command = helpers.clear, helpers.command
local feed, alter_slashes = helpers.feed, helpers.alter_slashes
local insert = helpers.insert
describe('nvim-treesitter', function()
local screen
before_each(function()
clear()
screen = Screen.new(81, 15)
screen:attach()
end)
after_each(function()
screen:detach()
end)
it('basically works', function()
insert("This is a line")
screen:expect([[
This is a lin^e |
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
{2:~ }|
|
]], {[2] = {bold = true, foreground = Screen.colors.Blue1}})
end)
end)