aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/language.lua
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:39:54 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:39:54 +0000
commit21cb7d04c387e4198ca8098a884c78b56ffcf4c2 (patch)
tree84fe5690df1551f0bb2bdfe1a13aacd29ebc1de7 /runtime/lua/vim/treesitter/language.lua
parentd9c904f85a23a496df4eb6be42aa43f007b22d50 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-colorcolchar.tar.gz
rneovim-colorcolchar.tar.bz2
rneovim-colorcolchar.zip
Merge remote-tracking branch 'upstream/master' into colorcolcharcolorcolchar
Diffstat (limited to 'runtime/lua/vim/treesitter/language.lua')
-rw-r--r--runtime/lua/vim/treesitter/language.lua148
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