mirror of
https://github.com/neovim/neovim.git
synced 2026-03-28 03:12:00 +00:00
refactor(treesitter)!: get_parser return nil on error #37276
This commit is contained in:
@@ -489,7 +489,8 @@ REMOVED FEATURES *news-removed*
|
||||
|
||||
These deprecated features were removed.
|
||||
|
||||
• todo
|
||||
• |vim.treesitter.get_parser()| instead of throwing an error
|
||||
`get_parser()` now always returns nil when it fails to create a parser.
|
||||
|
||||
==============================================================================
|
||||
DEPRECATIONS *news-deprecations*
|
||||
|
||||
@@ -1041,10 +1041,7 @@ get_parser({bufnr}, {lang}, {opts}) *vim.treesitter.get_parser()*
|
||||
|
||||
If needed, this will create the parser.
|
||||
|
||||
If no parser can be created, an error is thrown. Set `opts.error = false`
|
||||
to suppress this and return nil (and an error message) instead. WARNING:
|
||||
This behavior will become default in Nvim 0.12 and the option will be
|
||||
removed.
|
||||
If no parser can be created, nil (and an error message) is returned.
|
||||
|
||||
Parameters: ~
|
||||
• {bufnr} (`integer?`) Buffer the parser should be tied to (default:
|
||||
|
||||
@@ -66,7 +66,7 @@ vim.keymap.set('n', '[[', function()
|
||||
require('vim.treesitter._headings').jump({ count = -1 })
|
||||
end, { buffer = 0, silent = false, desc = 'Jump to previous section' })
|
||||
|
||||
local parser = assert(vim.treesitter.get_parser(0, 'vimdoc', { error = false }))
|
||||
local parser = assert(vim.treesitter.get_parser(0, 'vimdoc'))
|
||||
|
||||
local function runnables()
|
||||
---@type table<integer, { lang: string, code: string }>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
local function get_commentstring(ref_position)
|
||||
local buf_cs = vim.bo.commentstring
|
||||
|
||||
local ts_parser = vim.treesitter.get_parser(0, '', { error = false })
|
||||
local ts_parser = vim.treesitter.get_parser(0, '')
|
||||
if not ts_parser then
|
||||
return buf_cs
|
||||
end
|
||||
|
||||
@@ -70,8 +70,8 @@ end
|
||||
--- @param line2 integer End line (1-indexed)
|
||||
--- @return boolean True if the range is in a Lua injection
|
||||
function M.source_is_lua(bufnr, line1, line2)
|
||||
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
|
||||
if not ok or not parser then
|
||||
local parser = vim.treesitter.get_parser(bufnr)
|
||||
if not parser then
|
||||
return false
|
||||
end
|
||||
-- Parse from buffer start through one line past line2 to include injection closing markers
|
||||
|
||||
@@ -70,9 +70,7 @@ end
|
||||
---
|
||||
--- If needed, this will create the parser.
|
||||
---
|
||||
--- If no parser can be created, an error is thrown. Set `opts.error = false` to suppress this and
|
||||
--- return nil (and an error message) instead. WARNING: This behavior will become default in Nvim
|
||||
--- 0.12 and the option will be removed.
|
||||
--- If no parser can be created, nil (and an error message) is returned.
|
||||
---
|
||||
---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer)
|
||||
---@param lang (string|nil) Language of this parser (default: from buffer filetype)
|
||||
@@ -82,7 +80,6 @@ end
|
||||
---@return string? error message, if applicable
|
||||
function M.get_parser(bufnr, lang, opts)
|
||||
opts = opts or {}
|
||||
local should_error = opts.error == nil or opts.error
|
||||
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
@@ -92,25 +89,17 @@ function M.get_parser(bufnr, lang, opts)
|
||||
|
||||
if not valid_lang(lang) then
|
||||
if not parsers[bufnr] then
|
||||
local err_msg =
|
||||
return nil,
|
||||
string.format('Parser not found for buffer %s: language could not be determined', bufnr)
|
||||
if should_error then
|
||||
error(err_msg)
|
||||
end
|
||||
return nil, err_msg
|
||||
end
|
||||
elseif parsers[bufnr] == nil or parsers[bufnr]:lang() ~= lang then
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
error(('Buffer %s must be loaded to create parser'):format(bufnr))
|
||||
return nil, string.format('Buffer %s must be loaded to create parser', bufnr)
|
||||
end
|
||||
local parser = vim.F.npcall(M._create_parser, bufnr, lang, opts)
|
||||
if not parser then
|
||||
local err_msg =
|
||||
return nil,
|
||||
string.format('Parser could not be created for buffer %s and language "%s"', bufnr, lang)
|
||||
if should_error then
|
||||
error(err_msg)
|
||||
end
|
||||
return nil, err_msg
|
||||
end
|
||||
parsers[bufnr] = parser
|
||||
end
|
||||
@@ -414,7 +403,7 @@ function M.get_node(opts)
|
||||
|
||||
local ts_range = { row, col, row, col }
|
||||
|
||||
local root_lang_tree = M.get_parser(bufnr, opts.lang, { error = false })
|
||||
local root_lang_tree = M.get_parser(bufnr, opts.lang)
|
||||
if not root_lang_tree then
|
||||
return
|
||||
end
|
||||
@@ -457,7 +446,7 @@ function M.start(bufnr, lang)
|
||||
vim.fn.bufload(bufnr)
|
||||
end
|
||||
end
|
||||
local parser = assert(M.get_parser(bufnr, lang, { error = false }))
|
||||
local parser = assert(M.get_parser(bufnr, lang))
|
||||
M.highlighter.new(parser)
|
||||
end
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ function FoldInfo.new(bufnr)
|
||||
return setmetatable({
|
||||
levels0 = {},
|
||||
levels = {},
|
||||
parser = ts.get_parser(bufnr, nil, { error = false }),
|
||||
parser = ts.get_parser(bufnr, nil),
|
||||
}, FoldInfo)
|
||||
end
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ local get_headings = function(bufnr)
|
||||
if not lang then
|
||||
return {}
|
||||
end
|
||||
local parser = assert(ts.get_parser(bufnr, lang, { error = false }))
|
||||
local parser = assert(ts.get_parser(bufnr, lang))
|
||||
local query = ts.query.parse(lang, heading_queries[lang])
|
||||
local root = parser:parse()[1]:root()
|
||||
local headings = {}
|
||||
|
||||
@@ -180,7 +180,7 @@ function M.lint(buf, opts)
|
||||
is_first_lang = i == 1,
|
||||
}
|
||||
|
||||
local parser = assert(vim.treesitter.get_parser(buf, nil, { error = false }))
|
||||
local parser = assert(vim.treesitter.get_parser(buf, nil))
|
||||
parser:parse()
|
||||
parser:for_each_tree(function(tree, ltree)
|
||||
if ltree:lang() == 'query' then
|
||||
|
||||
@@ -79,7 +79,7 @@ end
|
||||
function TSTreeView:new(bufnr, lang)
|
||||
bufnr = bufnr or 0
|
||||
lang = lang or vim.treesitter.language.get_lang(vim.bo[bufnr].filetype)
|
||||
local parser = vim.treesitter.get_parser(bufnr, lang, { error = false })
|
||||
local parser = vim.treesitter.get_parser(bufnr, lang)
|
||||
if not parser then
|
||||
return nil,
|
||||
string.format(
|
||||
@@ -585,7 +585,7 @@ local function update_editor_highlights(query_win, base_win, lang)
|
||||
local base_buf = api.nvim_win_get_buf(base_win)
|
||||
local query_buf = api.nvim_win_get_buf(query_win)
|
||||
local root_lang = vim.treesitter.language.get_lang(vim.bo[base_buf].filetype)
|
||||
local parser = assert(vim.treesitter.get_parser(base_buf, root_lang, { error = false }))
|
||||
local parser = assert(vim.treesitter.get_parser(base_buf, root_lang))
|
||||
api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1)
|
||||
local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n')
|
||||
|
||||
@@ -655,7 +655,7 @@ function M.edit_query(lang)
|
||||
end
|
||||
vim.cmd(cmd)
|
||||
|
||||
local parser = vim.treesitter.get_parser(buf, lang, { error = false })
|
||||
local parser = vim.treesitter.get_parser(buf, lang)
|
||||
if not parser then
|
||||
return nil,
|
||||
string.format('Failed to show query editor for buffer %s: no parser for lang "%s"', buf, lang)
|
||||
|
||||
@@ -857,7 +857,7 @@ local function parse_buf(fname, text)
|
||||
buf = fname
|
||||
vim.cmd('sbuffer ' .. tostring(fname)) -- Buffer number.
|
||||
end
|
||||
local lang_tree = assert(vim.treesitter.get_parser(buf, nil, { error = false }))
|
||||
local lang_tree = assert(vim.treesitter.get_parser(buf, nil))
|
||||
lang_tree:parse()
|
||||
return lang_tree, buf
|
||||
end
|
||||
|
||||
@@ -15,12 +15,11 @@ before_each(clear)
|
||||
describe('treesitter language API', function()
|
||||
-- error tests not requiring a parser library
|
||||
it('handles missing language', function()
|
||||
eq(
|
||||
'.../treesitter.lua:0: Parser could not be created for buffer 1 and language "borklang"',
|
||||
pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')")
|
||||
)
|
||||
|
||||
eq(NIL, exec_lua("return vim.treesitter.get_parser(0, 'borklang', { error = false })"))
|
||||
local parser, error = exec_lua(function()
|
||||
return vim.treesitter.get_parser(0, 'borklang')
|
||||
end)
|
||||
eq(NIL, parser)
|
||||
eq('Parser could not be created for buffer 1 and language "borklang"', error)
|
||||
|
||||
-- actual message depends on platform
|
||||
matches(
|
||||
@@ -107,11 +106,11 @@ describe('treesitter language API', function()
|
||||
eq('c', exec_lua('return vim.treesitter.get_parser(0):lang()'))
|
||||
command('set filetype=borklang')
|
||||
-- Should throw an error when filetype changes to borklang
|
||||
eq(
|
||||
'.../treesitter.lua:0: Parser could not be created for buffer 1 and language "borklang"',
|
||||
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')")
|
||||
)
|
||||
eq(NIL, exec_lua("return vim.treesitter.get_parser(0, 'borklang', { error = false })"))
|
||||
local parser, error = exec_lua(function()
|
||||
return vim.treesitter.get_parser(0, 'borklang')
|
||||
end)
|
||||
eq(NIL, parser)
|
||||
eq('Parser could not be created for buffer 1 and language "borklang"', error)
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ local dedent = t.dedent
|
||||
local eq = t.eq
|
||||
local insert = n.insert
|
||||
local exec_lua = n.exec_lua
|
||||
local pcall_err = t.pcall_err
|
||||
local feed = n.feed
|
||||
local run_query = ts_t.run_query
|
||||
local assert_alive = n.assert_alive
|
||||
@@ -382,10 +381,11 @@ describe('treesitter parser API', function()
|
||||
it('does not get parser for empty filetype', function()
|
||||
insert(test_text)
|
||||
|
||||
eq(
|
||||
'.../treesitter.lua:0: Parser not found for buffer 1: language could not be determined',
|
||||
pcall_err(exec_lua, 'vim.treesitter.get_parser(0)')
|
||||
)
|
||||
local parser, error = exec_lua(function()
|
||||
return vim.treesitter.get_parser(0)
|
||||
end)
|
||||
eq(vim.NIL, parser)
|
||||
eq('Parser not found for buffer 1: language could not be determined', error)
|
||||
|
||||
-- Must provide language for buffers with an empty filetype
|
||||
exec_lua("vim.treesitter.get_parser(0, 'c')")
|
||||
|
||||
Reference in New Issue
Block a user