diff --git a/lua/snacks/health.lua b/lua/snacks/health.lua index 55e3e6af..8a485008 100644 --- a/lua/snacks/health.lua +++ b/lua/snacks/health.lua @@ -128,7 +128,7 @@ function M.has_lang(langs) local ret = {} ---@type table local available, missing = {}, {} ---@type string[], string[] for _, lang in ipairs(langs) do - local has_lang = pcall(vim.treesitter.get_string_parser, "", lang) + local has_lang = Snacks.util.get_lang(lang) ~= nil ret[lang] = has_lang lang = ("`%s`"):format(lang) if has_lang then diff --git a/lua/snacks/picker/core/preview.lua b/lua/snacks/picker/core/preview.lua index dc993259..b49ffc18 100644 --- a/lua/snacks/picker/core/preview.lua +++ b/lua/snacks/picker/core/preview.lua @@ -277,7 +277,7 @@ function M:highlight(opts) }) end self:check_big() - local lang = Snacks.picker.highlight.get_lang({ lang = opts.lang, ft = ft }) + local lang = Snacks.util.get_lang(opts.lang or ft) if not (lang and pcall(vim.treesitter.start, self.win.buf, lang)) and ft then vim.bo[self.win.buf].syntax = ft end diff --git a/lua/snacks/picker/util/highlight.lua b/lua/snacks/picker/util/highlight.lua index 6b2ecd96..274bebfa 100644 --- a/lua/snacks/picker/util/highlight.lua +++ b/lua/snacks/picker/util/highlight.lua @@ -3,19 +3,6 @@ local M = {} M.langs = {} ---@type table ----@param opts? {lang?:string, ft?:string} -function M.get_lang(opts) - opts = opts or {} - local lang = opts.lang or (opts.ft and vim.treesitter.language.get_lang(opts.ft)) or nil - if not lang then - return - end - if M.langs[lang] == nil then - M.langs[lang] = pcall(vim.treesitter.language.add, lang) - end - return M.langs[lang] and lang or nil -end - ---@param opts? {buf?:number, code?:string, ft?:string, lang?:string, file?:string, extmarks?:boolean} function M.get_highlights(opts) opts = opts or {} @@ -28,7 +15,7 @@ function M.get_highlights(opts) or (opts.buf and vim.bo[opts.buf].filetype) or (opts.file and vim.filetype.match({ filename = opts.file, buf = 0 })) or vim.bo.filetype - local lang = M.get_lang({ lang = opts.lang, ft = ft }) + local lang = Snacks.util.get_lang(opts.lang or ft) local parser ---@type vim.treesitter.LanguageTree? if lang then lang = lang:lower() diff --git a/lua/snacks/scope.lua b/lua/snacks/scope.lua index cd3a4d23..f1a0c70b 100644 --- a/lua/snacks/scope.lua +++ b/lua/snacks/scope.lua @@ -315,18 +315,6 @@ end local TSScope = setmetatable({}, Scope) TSScope.__index = TSScope -function TSScope.has_ts(buf) - if vim.b[buf].snacks_ts == nil then - if vim.b[buf].ts_highlight then - vim.b[buf].snacks_ts = true - else - local ok, parser = pcall(vim.treesitter.get_parser, buf) - vim.b[buf].snacks_ts = ok and parser ~= nil - end - end - return vim.b[buf].snacks_ts -end - -- Expand the scope to fill the range of the node function TSScope:fill() local n = self.node @@ -513,7 +501,7 @@ function M.get(cb, opts) end ---@type snacks.scope.Scope - local Class = (opts.treesitter.enabled and TSScope.has_ts(opts.buf)) and TSScope or IndentScope + local Class = (opts.treesitter.enabled and Snacks.util.get_lang(opts.buf)) and TSScope or IndentScope if rawequal(Class, TSScope) and opts.parse ~= false then TSScope:init(function() opts.parse = false diff --git a/lua/snacks/util/init.lua b/lua/snacks/util/init.lua index 2fad07ed..7d66719a 100644 --- a/lua/snacks/util/init.lua +++ b/lua/snacks/util/init.lua @@ -9,6 +9,7 @@ M.is_win = jit.os:find("Windows") local uv = vim.uv or vim.loop local key_cache = {} ---@type table +local langs = {} ---@type table ---@alias snacks.util.hl table @@ -22,6 +23,20 @@ vim.api.nvim_create_autocmd("ColorScheme", { end, }) +---@param lang string|number|nil +---@overload fun(buf:number):string? +---@overload fun(ft:string):string? +---@return string? +function M.get_lang(lang) + lang = type(lang) == "number" and vim.bo[lang].filetype or lang --[[@as string?]] + lang = lang and vim.treesitter.language.get_lang(lang) or lang + if lang and lang ~= "" and langs[lang] == nil then + local ok, ret = pcall(vim.treesitter.language.add, lang) + langs[lang] = (ok and ret) or (ok and vim.fn.has("nvim-0.11") == 0) + end + return langs[lang] and lang or nil +end + --- Ensures the hl groups are always set, even after a colorscheme change. ---@param groups snacks.util.hl ---@param opts? { prefix?:string, default?:boolean, managed?:boolean }