mirror of
https://github.com/neovim/neovim
synced 2025-07-17 17:51:48 +00:00
feat(treesitter)!: add default fallback to ft_to_lang
lookups
Problem: Language names are only registered for filetype<->language lookups when parsers are actually loaded; this means users cannot rely on `vim.treesitter.language.get_lang()` or `get_filetypes()` to return the correct value when language and filetype coincide and always need to add explicit fallbacks. Solution: Always return the language name as valid filetype in `get_filetypes()`, and default to the filetype in `get_lang()`. Document this behavior.
This commit is contained in:
@ -98,6 +98,12 @@ TREESITTER
|
|||||||
backwards compatibility, an option `all=false` (only return the last
|
backwards compatibility, an option `all=false` (only return the last
|
||||||
matching node) is provided that will be removed in a future release.
|
matching node) is provided that will be removed in a future release.
|
||||||
|
|
||||||
|
• |vim.treesitter.language.get_filetypes()| always includes the {language}
|
||||||
|
argument in addition to explicitly registered filetypes.
|
||||||
|
|
||||||
|
• |vim.treesitter.language.get_lang()| falls back to the {filetype} argument
|
||||||
|
if no languages are explicitly registered.
|
||||||
|
|
||||||
TUI
|
TUI
|
||||||
|
|
||||||
• TODO
|
• TODO
|
||||||
|
@ -969,14 +969,15 @@ add({lang}, {opts}) *vim.treesitter.language.add()*
|
|||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {lang} (`string`) Name of the parser (alphanumerical and `_` only)
|
• {lang} (`string`) Name of the parser (alphanumerical and `_` only)
|
||||||
• {opts} (`table?`) Options:
|
• {opts} (`table?`) Options:
|
||||||
• {filetype}? (`string|string[]`, default: {lang}) Default
|
|
||||||
filetype the parser should be associated with.
|
|
||||||
• {path}? (`string`) Optional path the parser is located at
|
• {path}? (`string`) Optional path the parser is located at
|
||||||
• {symbol_name}? (`string`) Internal symbol name for the
|
• {symbol_name}? (`string`) Internal symbol name for the
|
||||||
language to load
|
language to load
|
||||||
|
|
||||||
get_filetypes({lang}) *vim.treesitter.language.get_filetypes()*
|
get_filetypes({lang}) *vim.treesitter.language.get_filetypes()*
|
||||||
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()|.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {lang} (`string`) Name of parser
|
• {lang} (`string`) Name of parser
|
||||||
@ -985,6 +986,11 @@ get_filetypes({lang}) *vim.treesitter.language.get_filetypes()*
|
|||||||
(`string[]`) filetypes
|
(`string[]`) filetypes
|
||||||
|
|
||||||
get_lang({filetype}) *vim.treesitter.language.get_lang()*
|
get_lang({filetype}) *vim.treesitter.language.get_lang()*
|
||||||
|
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.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {filetype} (`string`)
|
• {filetype} (`string`)
|
||||||
|
@ -95,7 +95,7 @@ function M.get_parser(bufnr, lang, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not valid_lang(lang) then
|
if not valid_lang(lang) then
|
||||||
lang = M.language.get_lang(vim.bo[bufnr].filetype) or vim.bo[bufnr].filetype
|
lang = M.language.get_lang(vim.bo[bufnr].filetype)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not valid_lang(lang) then
|
if not valid_lang(lang) then
|
||||||
|
@ -41,7 +41,7 @@ local function guess_query_lang(buf)
|
|||||||
local filename = api.nvim_buf_get_name(buf)
|
local filename = api.nvim_buf_get_name(buf)
|
||||||
if filename ~= '' then
|
if filename ~= '' then
|
||||||
local resolved_filename = vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t')
|
local resolved_filename = vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t')
|
||||||
return resolved_filename and vim.treesitter.language.get_lang(resolved_filename) or nil
|
return resolved_filename and vim.treesitter.language.get_lang(resolved_filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -7,11 +7,15 @@ local ft_to_lang = {
|
|||||||
help = 'vimdoc',
|
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
|
--- @param lang string Name of parser
|
||||||
--- @return string[] filetypes
|
--- @return string[] filetypes
|
||||||
function M.get_filetypes(lang)
|
function M.get_filetypes(lang)
|
||||||
local r = {} ---@type string[]
|
local r = { lang } ---@type string[]
|
||||||
for ft, p in pairs(ft_to_lang) do
|
for ft, p in pairs(ft_to_lang) do
|
||||||
if p == lang then
|
if p == lang then
|
||||||
r[#r + 1] = ft
|
r[#r + 1] = ft
|
||||||
@ -20,6 +24,12 @@ function M.get_filetypes(lang)
|
|||||||
return r
|
return r
|
||||||
end
|
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
|
--- @param filetype string
|
||||||
--- @return string|nil
|
--- @return string|nil
|
||||||
function M.get_lang(filetype)
|
function M.get_lang(filetype)
|
||||||
@ -29,9 +39,9 @@ function M.get_lang(filetype)
|
|||||||
if ft_to_lang[filetype] then
|
if ft_to_lang[filetype] then
|
||||||
return ft_to_lang[filetype]
|
return ft_to_lang[filetype]
|
||||||
end
|
end
|
||||||
-- support subfiletypes like html.glimmer
|
-- for subfiletypes like html.glimmer use only "main" filetype
|
||||||
filetype = vim.split(filetype, '.', { plain = true })[1]
|
filetype = vim.split(filetype, '.', { plain = true })[1]
|
||||||
return ft_to_lang[filetype]
|
return ft_to_lang[filetype] or filetype
|
||||||
end
|
end
|
||||||
|
|
||||||
---@deprecated
|
---@deprecated
|
||||||
@ -59,10 +69,6 @@ end
|
|||||||
---@class vim.treesitter.language.add.Opts
|
---@class vim.treesitter.language.add.Opts
|
||||||
---@inlinedoc
|
---@inlinedoc
|
||||||
---
|
---
|
||||||
---Default filetype the parser should be associated with.
|
|
||||||
---(Default: {lang})
|
|
||||||
---@field filetype? string|string[]
|
|
||||||
---
|
|
||||||
---Optional path the parser is located at
|
---Optional path the parser is located at
|
||||||
---@field path? string
|
---@field path? string
|
||||||
---
|
---
|
||||||
@ -78,21 +84,18 @@ end
|
|||||||
function M.add(lang, opts)
|
function M.add(lang, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local path = opts.path
|
local path = opts.path
|
||||||
local filetype = opts.filetype or lang
|
|
||||||
local symbol_name = opts.symbol_name
|
local symbol_name = opts.symbol_name
|
||||||
|
|
||||||
vim.validate({
|
vim.validate({
|
||||||
lang = { lang, 'string' },
|
lang = { lang, 'string' },
|
||||||
path = { path, 'string', true },
|
path = { path, 'string', true },
|
||||||
symbol_name = { symbol_name, '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)
|
-- parser names are assumed to be lowercase (consistent behavior on case-insensitive file systems)
|
||||||
lang = lang:lower()
|
lang = lang:lower()
|
||||||
|
|
||||||
if vim._ts_has_language(lang) then
|
if vim._ts_has_language(lang) then
|
||||||
M.register(lang, filetype)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -117,7 +120,6 @@ function M.add(lang, opts)
|
|||||||
else
|
else
|
||||||
vim._ts_add_language_from_object(path, lang, symbol_name)
|
vim._ts_add_language_from_object(path, lang, symbol_name)
|
||||||
end
|
end
|
||||||
M.register(lang, filetype)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param x string|string[]
|
--- @param x string|string[]
|
||||||
|
Reference in New Issue
Block a user