aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/language.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/treesitter/language.lua')
-rw-r--r--runtime/lua/vim/treesitter/language.lua64
1 files changed, 45 insertions, 19 deletions
diff --git a/runtime/lua/vim/treesitter/language.lua b/runtime/lua/vim/treesitter/language.lua
index d0a74daa6c..9f7807e036 100644
--- a/runtime/lua/vim/treesitter/language.lua
+++ b/runtime/lua/vim/treesitter/language.lua
@@ -7,11 +7,15 @@ local ft_to_lang = {
help = 'vimdoc',
}
---- Get the filetypes associated with the parser named {lang}.
+--- Returns the filetypes for which a parser named {lang} is used.
+---
+--- The list includes {lang} itself plus all filetypes registered via
+--- |vim.treesitter.language.register()|.
+---
--- @param lang string Name of parser
--- @return string[] filetypes
function M.get_filetypes(lang)
- local r = {} ---@type string[]
+ local r = { lang } ---@type string[]
for ft, p in pairs(ft_to_lang) do
if p == lang then
r[#r + 1] = ft
@@ -20,6 +24,12 @@ function M.get_filetypes(lang)
return r
end
+--- Returns the language name to be used when loading a parser for {filetype}.
+---
+--- If no language has been explicitly registered via |vim.treesitter.language.register()|,
+--- default to {filetype}. For composite filetypes like `html.glimmer`, only the main filetype is
+--- returned.
+---
--- @param filetype string
--- @return string|nil
function M.get_lang(filetype)
@@ -29,9 +39,9 @@ function M.get_lang(filetype)
if ft_to_lang[filetype] then
return ft_to_lang[filetype]
end
- -- support subfiletypes like html.glimmer
+ -- for subfiletypes like html.glimmer use only "main" filetype
filetype = vim.split(filetype, '.', { plain = true })[1]
- return ft_to_lang[filetype]
+ return ft_to_lang[filetype] or filetype
end
---@deprecated
@@ -52,17 +62,27 @@ function M.require_language(lang, path, silent, symbol_name)
return installed
end
- M.add(lang, opts)
- return true
+ return M.add(lang, opts)
+end
+
+--- Load wasm or native parser (wrapper)
+--- todo(clason): move to C
+---
+---@param path string Path of parser library
+---@param lang string Language name
+---@param symbol_name? string Internal symbol name for the language to load (default lang)
+---@return boolean? True if parser is loaded
+local function loadparser(path, lang, symbol_name)
+ if vim.endswith(path, '.wasm') then
+ return vim._ts_add_language_from_wasm and vim._ts_add_language_from_wasm(path, lang)
+ else
+ return vim._ts_add_language_from_object(path, lang, symbol_name)
+ end
end
---@class vim.treesitter.language.add.Opts
---@inlinedoc
---
----Default filetype the parser should be associated with.
----(Default: {lang})
----@field filetype? string|string[]
----
---Optional path the parser is located at
---@field path? string
---
@@ -71,46 +91,52 @@ end
--- Load parser with name {lang}
---
---- Parsers are searched in the `parser` runtime directory, or the provided {path}
+--- Parsers are searched in the `parser` runtime directory, or the provided {path}.
+--- Can be used to check for available parsers before enabling treesitter features, e.g.,
+--- ```lua
+--- if vim.treesitter.language.add('markdown') then
+--- vim.treesitter.start(bufnr, 'markdown')
+--- end
+--- ```
---
---@param lang string Name of the parser (alphanumerical and `_` only)
---@param opts? vim.treesitter.language.add.Opts Options:
+---@return boolean? True if parser is loaded
+---@return string? Error if parser cannot be loaded
function M.add(lang, opts)
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 },
})
-- parser names are assumed to be lowercase (consistent behavior on case-insensitive file systems)
lang = lang:lower()
if vim._ts_has_language(lang) then
- M.register(lang, filetype)
- return
+ return true
end
if path == nil then
+ -- allow only safe language names when looking for libraries to load
if not (lang and lang:match('[%w_]+') == lang) then
- error("'" .. lang .. "' is not a valid language name")
+ return nil, string.format('Invalid language name "%s"', lang)
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")
+ return nil, string.format('No parser for language "%s"', lang)
end
path = paths[1]
end
- vim._ts_add_language(path, lang, symbol_name)
- M.register(lang, filetype)
+ return loadparser(path, lang, symbol_name) or nil,
+ string.format('Cannot load parser %s for language "%s"', path, lang)
end
--- @param x string|string[]