diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7a263c315..7b4bd115a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,11 +29,11 @@ jobs: - windows-latest - macos-latest version: - - v0.10.3 - - v0.10.4 - v0.11.0 - v0.11.1 - v0.11.2 + - v0.11.3 + - v0.11.4 - nightly runs-on: ${{ matrix.os }} steps: diff --git a/lua/orgmode/colors/highlighter/init.lua b/lua/orgmode/colors/highlighter/init.lua index fada6970a..1e49560e1 100644 --- a/lua/orgmode/colors/highlighter/init.lua +++ b/lua/orgmode/colors/highlighter/init.lua @@ -5,13 +5,15 @@ ---@field private todos OrgTodosHighlighter ---@field private foldtext OrgFoldtextHighlighter ---@field private _ephemeral boolean ----@field private buffers table +---@field private buffers table +---@field private parsing table local OrgHighlighter = {} function OrgHighlighter:new() local data = { namespace = vim.api.nvim_create_namespace('org_custom_highlighter'), buffers = {}, + parsing = {}, -- Use ephemeral for highlights. Added to config to allow toggling from tests. _ephemeral = true, } @@ -38,29 +40,57 @@ function OrgHighlighter:_setup() }) end -function OrgHighlighter:_on_win(_, _, bufnr, topline, botline) +---@param bufnr number +---@param win number +---@param range { start_line: number, end_line: number } | false +function OrgHighlighter:_parse_tree(bufnr, win, range) + self.parsing[win] = self.parsing[win] + or nil + == self.buffers[bufnr].language_tree:parse(range, function(_, parsed_trees) + self.buffers[bufnr].tree = parsed_trees and parsed_trees[1] + if self.parsing[win] then + self.parsing[win] = false + if vim.api.nvim_win_is_valid(win) then + vim.api.nvim__redraw({ win = win, valid = false, flush = false }) + end + end + end) +end + +function OrgHighlighter:_on_win(_, win, bufnr, topline, botline) local is_org_buffer = vim.bo[bufnr].filetype == 'org' if not is_org_buffer then return false end - local parsed_trees = {} if not self.buffers[bufnr] then self.buffers[bufnr] = { language_tree = vim.treesitter.get_parser(bufnr, 'org') } - parsed_trees = self.buffers[bufnr].language_tree:parse() + self:_parse_tree(bufnr, win, false) self.buffers[bufnr].language_tree:register_cbs({ on_detach = function(buf) self:_on_detach(buf) end, }) else - parsed_trees = self.buffers[bufnr].language_tree:parse({ topline, botline + 1 }) + self:_parse_tree(bufnr, win, { topline, botline + 1 }) + if self.parsing[win] then + for line = topline, botline do + self:_on_line_impl(bufnr, line, true) + end + return false + end end - self.buffers[bufnr].tree = parsed_trees and parsed_trees[1] end function OrgHighlighter:_on_line(_, _, bufnr, line) + self:_on_line_impl(bufnr, line) +end + +---@param bufnr number +---@param line number +---@param use_cache? boolean +function OrgHighlighter:_on_line_impl(bufnr, line, use_cache) if self.buffers[bufnr].tree then - self.markup:on_line(bufnr, line, self.buffers[bufnr].tree) + self.markup:on_line(bufnr, line, self.buffers[bufnr].tree, use_cache) self.stars:on_line(bufnr, line) self.foldtext:on_line(bufnr, line) end diff --git a/lua/orgmode/colors/highlighter/markup/init.lua b/lua/orgmode/colors/highlighter/markup/init.lua index 0e1287cb7..08037b672 100644 --- a/lua/orgmode/colors/highlighter/markup/init.lua +++ b/lua/orgmode/colors/highlighter/markup/init.lua @@ -30,8 +30,9 @@ end ---@param bufnr number ---@param line number ---@param tree TSTree -function OrgMarkup:on_line(bufnr, line, tree) - local highlights = self:_get_highlights(bufnr, line, tree) +---@param use_cache? boolean +function OrgMarkup:on_line(bufnr, line, tree, use_cache) + local highlights = self:_get_highlights(bufnr, line, tree, use_cache) for type, highlight in pairs(highlights) do self.parsers[type]:highlight(highlight, bufnr) @@ -41,11 +42,16 @@ end ---@param bufnr number ---@param line number ---@param tree TSTree +---@param use_cache? boolean ---@return { emphasis: OrgMarkupHighlight[], link: OrgMarkupHighlight[], latex: OrgMarkupHighlight[], date: OrgMarkupHighlight[] } -function OrgMarkup:_get_highlights(bufnr, line, tree) +function OrgMarkup:_get_highlights(bufnr, line, tree, use_cache) local line_content = vim.api.nvim_buf_get_lines(bufnr, line, line + 1, false)[1] - if self.cache[bufnr] and self.cache[bufnr][line] and self.cache[bufnr][line].line_content == line_content then + if + self.cache[bufnr] + and self.cache[bufnr][line] + and (use_cache or self.cache[bufnr][line].line_content == line_content) + then return self.cache[bufnr][line].highlights end