diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
commit | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch) | |
tree | d8c1843a95da5ea0bb4acc09f7e37843d9995c86 /runtime/lua/vim/treesitter/language.lua | |
parent | 142d9041391780ac15b89886a54015fdc5c73995 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-931bffbda3668ddc609fc1da8f9eb576b170aa52.tar.gz rneovim-931bffbda3668ddc609fc1da8f9eb576b170aa52.tar.bz2 rneovim-931bffbda3668ddc609fc1da8f9eb576b170aa52.zip |
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'runtime/lua/vim/treesitter/language.lua')
-rw-r--r-- | runtime/lua/vim/treesitter/language.lua | 148 |
1 files changed, 124 insertions, 24 deletions
diff --git a/runtime/lua/vim/treesitter/language.lua b/runtime/lua/vim/treesitter/language.lua index c92d63b8c4..15bf666a1e 100644 --- a/runtime/lua/vim/treesitter/language.lua +++ b/runtime/lua/vim/treesitter/language.lua @@ -1,42 +1,132 @@ -local a = vim.api +local api = vim.api +---@class TSLanguageModule local M = {} ---- Asserts that a parser for the language {lang} is installed. +---@type table<string,string> +local ft_to_lang = { + help = 'vimdoc', +} + +--- Get the filetypes associated with the parser named {lang}. +--- @param lang string Name of parser +--- @return string[] filetypes +function M.get_filetypes(lang) + local r = {} ---@type string[] + for ft, p in pairs(ft_to_lang) do + if p == lang then + r[#r + 1] = ft + end + end + return r +end + +--- @param filetype string +--- @return string|nil +function M.get_lang(filetype) + if filetype == '' then + return + end + if ft_to_lang[filetype] then + return ft_to_lang[filetype] + end + -- support subfiletypes like html.glimmer + filetype = vim.split(filetype, '.', { plain = true })[1] + return ft_to_lang[filetype] +end + +---@deprecated +function M.require_language(lang, path, silent, symbol_name) + local opts = { + silent = silent, + path = path, + symbol_name = symbol_name, + } + + if silent then + local installed = pcall(M.add, lang, opts) + return installed + end + + M.add(lang, opts) + return true +end + +---@class treesitter.RequireLangOpts +---@field path? string +---@field silent? boolean +---@field filetype? string|string[] +---@field symbol_name? string + +--- Load parser with name {lang} --- --- Parsers are searched in the `parser` runtime directory, or the provided {path} --- ----@param lang string Language the parser should parse ----@param path (string|nil) Optional path the parser is located at ----@param silent (boolean|nil) Don't throw an error if language not found ----@param symbol_name (string|nil) Internal symbol name for the language to load ----@return boolean If the specified language is installed -function M.require_language(lang, path, silent, symbol_name) +---@param lang string Name of the parser (alphanumerical and `_` only) +---@param opts (table|nil) Options: +--- - filetype (string|string[]) Default filetype the parser should be associated with. +--- Defaults to {lang}. +--- - path (string|nil) Optional path the parser is located at +--- - symbol_name (string|nil) Internal symbol name for the language to load +function M.add(lang, opts) + ---@cast opts treesitter.RequireLangOpts + opts = opts or {} + local path = opts.path + local filetype = opts.filetype or lang + local symbol_name = opts.symbol_name + + vim.validate({ + lang = { lang, 'string' }, + path = { path, 'string', true }, + symbol_name = { symbol_name, 'string', true }, + filetype = { filetype, { 'string', 'table' }, true }, + }) + if vim._ts_has_language(lang) then - return true + M.register(lang, filetype) + return end + if path == nil then - local fname = 'parser/' .. vim.fn.fnameescape(lang) .. '.*' - local paths = a.nvim_get_runtime_file(fname, false) - if #paths == 0 then - if silent then - return false - end + if not (lang and lang:match('[%w_]+') == lang) then + error("'" .. lang .. "' is not a valid language name") + end + local fname = 'parser/' .. lang .. '.*' + local paths = api.nvim_get_runtime_file(fname, false) + if #paths == 0 then error("no parser for '" .. lang .. "' language, see :help treesitter-parsers") end path = paths[1] end - if silent then - return pcall(function() - vim._ts_add_language(path, lang, symbol_name) - end) - else - vim._ts_add_language(path, lang, symbol_name) + vim._ts_add_language(path, lang, symbol_name) + M.register(lang, filetype) +end + +--- @param x string|string[] +--- @return string[] +local function ensure_list(x) + if type(x) == 'table' then + return x end + return { x } +end - return true +--- Register a parser named {lang} to be used for {filetype}(s). +--- @param lang string Name of parser +--- @param filetype string|string[] Filetype(s) to associate with lang +function M.register(lang, filetype) + vim.validate({ + lang = { lang, 'string' }, + filetype = { filetype, { 'string', 'table' } }, + }) + + for _, f in ipairs(ensure_list(filetype)) do + if f ~= '' then + ft_to_lang[f] = lang + end + end end --- Inspects the provided language. @@ -45,9 +135,19 @@ end --- ---@param lang string Language ---@return table -function M.inspect_language(lang) - M.require_language(lang) +function M.inspect(lang) + M.add(lang) return vim._ts_inspect_language(lang) end +---@deprecated +function M.inspect_language(...) + vim.deprecate( + 'vim.treesitter.language.inspect_language()', + 'vim.treesitter.language.inspect()', + '0.10' + ) + return M.inspect(...) +end + return M |