mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 14:08:32 +00:00
refactor(filetype): allow vim.filetype.match to accept buf and filename (#19114)
This is necessary in cases where filetype detection acts recursively. For example, when matching files that end with .bak, the "root" of the filename is matched again against the same buffer (e.g. a buffer named "foo.c.bak" will be matched again with the filename "foo.c", using the same underlying buffer).
This commit is contained in:
@@ -2086,23 +2086,33 @@ match({arg}) *vim.filetype.match()*
|
|||||||
-- Using a buffer number
|
-- Using a buffer number
|
||||||
vim.filetype.match({ buf = 42 })
|
vim.filetype.match({ buf = 42 })
|
||||||
|
|
||||||
-- Using a filename
|
-- Override the filename of the given buffer
|
||||||
vim.filetype.match({ filename = "main.lua" })
|
vim.filetype.match({ buf = 42, filename = 'foo.c' })
|
||||||
|
|
||||||
|
-- Using a filename without a buffer
|
||||||
|
vim.filetype.match({ filename = 'main.lua' })
|
||||||
|
|
||||||
-- Using file contents
|
-- Using file contents
|
||||||
vim.filetype.match({ contents = {"#!/usr/bin/env bash"} })
|
vim.filetype.match({ contents = {'#!/usr/bin/env bash'} })
|
||||||
<
|
<
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
{arg} (table) Table specifying which matching strategy to
|
{arg} (table) Table specifying which matching strategy to
|
||||||
use. It is an error to provide more than one
|
use. Accepted keys are:
|
||||||
strategy. Accepted keys are:
|
• buf (number): Buffer number to use for matching.
|
||||||
• buf (number): Buffer number to use for matching
|
Mutually exclusive with {contents}
|
||||||
• filename (string): Filename to use for matching.
|
• filename (string): Filename to use for matching.
|
||||||
Note that the file need not actually exist in the
|
When {buf} is given, defaults to the filename of
|
||||||
filesystem, only the name itself is used.
|
the given buffer number. The file need not
|
||||||
|
actually exist in the filesystem. When used
|
||||||
|
without {buf} only the name of the file is used
|
||||||
|
for filetype matching. This may result in failure
|
||||||
|
to detect the filetype in cases where the
|
||||||
|
filename alone is not enough to disambiguate the
|
||||||
|
filetype.
|
||||||
• contents (table): An array of lines representing
|
• contents (table): An array of lines representing
|
||||||
file contents to use for matching.
|
file contents to use for matching. Can be used
|
||||||
|
with {filename}. Mutually exclusive with {buf}.
|
||||||
|
|
||||||
Return: ~
|
Return: ~
|
||||||
(string|nil) If a match was found, the matched filetype.
|
(string|nil) If a match was found, the matched filetype.
|
||||||
|
@@ -2240,21 +2240,29 @@ end
|
|||||||
--- -- Using a buffer number
|
--- -- Using a buffer number
|
||||||
--- vim.filetype.match({ buf = 42 })
|
--- vim.filetype.match({ buf = 42 })
|
||||||
---
|
---
|
||||||
--- -- Using a filename
|
--- -- Override the filename of the given buffer
|
||||||
--- vim.filetype.match({ filename = "main.lua" })
|
--- vim.filetype.match({ buf = 42, filename = 'foo.c' })
|
||||||
|
---
|
||||||
|
--- -- Using a filename without a buffer
|
||||||
|
--- vim.filetype.match({ filename = 'main.lua' })
|
||||||
---
|
---
|
||||||
--- -- Using file contents
|
--- -- Using file contents
|
||||||
--- vim.filetype.match({ contents = {"#!/usr/bin/env bash"} })
|
--- vim.filetype.match({ contents = {'#!/usr/bin/env bash'} })
|
||||||
--- </pre>
|
--- </pre>
|
||||||
---
|
---
|
||||||
---@param arg table Table specifying which matching strategy to use. It is an error to provide more
|
---@param arg table Table specifying which matching strategy to use. Accepted keys are:
|
||||||
--- than one strategy. Accepted keys are:
|
--- * buf (number): Buffer number to use for matching. Mutually exclusive with
|
||||||
--- * buf (number): Buffer number to use for matching
|
--- {contents}
|
||||||
--- * filename (string): Filename to use for matching. Note that the file need not
|
--- * filename (string): Filename to use for matching. When {buf} is given,
|
||||||
--- actually exist in the filesystem, only the name itself is
|
--- defaults to the filename of the given buffer number. The
|
||||||
--- used.
|
--- file need not actually exist in the filesystem. When used
|
||||||
|
--- without {buf} only the name of the file is used for
|
||||||
|
--- filetype matching. This may result in failure to detect
|
||||||
|
--- the filetype in cases where the filename alone is not
|
||||||
|
--- enough to disambiguate the filetype.
|
||||||
--- * contents (table): An array of lines representing file contents to use for
|
--- * contents (table): An array of lines representing file contents to use for
|
||||||
--- matching.
|
--- matching. Can be used with {filename}. Mutually exclusive
|
||||||
|
--- with {buf}.
|
||||||
---@return string|nil If a match was found, the matched filetype.
|
---@return string|nil If a match was found, the matched filetype.
|
||||||
---@return function|nil A function that modifies buffer state when called (for example, to set some
|
---@return function|nil A function that modifies buffer state when called (for example, to set some
|
||||||
--- filetype specific buffer variables). The function accepts a buffer number as
|
--- filetype specific buffer variables). The function accepts a buffer number as
|
||||||
@@ -2265,26 +2273,30 @@ function M.match(arg)
|
|||||||
})
|
})
|
||||||
|
|
||||||
if not (arg.buf or arg.filename or arg.contents) then
|
if not (arg.buf or arg.filename or arg.contents) then
|
||||||
error('One of "buf", "filename", or "contents" must be given')
|
error('At least one of "buf", "filename", or "contents" must be given')
|
||||||
end
|
end
|
||||||
|
|
||||||
if (arg.buf and arg.filename) or (arg.buf and arg.contents) or (arg.filename and arg.contents) then
|
if arg.buf and arg.contents then
|
||||||
error('Only one of "buf", "filename", or "contents" must be given')
|
error('Only one of "buf" or "contents" must be given')
|
||||||
end
|
end
|
||||||
|
|
||||||
local bufnr = arg.buf
|
local bufnr = arg.buf
|
||||||
local name = bufnr and api.nvim_buf_get_name(bufnr) or arg.filename
|
local name = arg.filename
|
||||||
local contents = arg.contents
|
local contents = arg.contents
|
||||||
|
|
||||||
|
if bufnr and not name then
|
||||||
|
name = api.nvim_buf_get_name(bufnr)
|
||||||
|
end
|
||||||
|
|
||||||
if name then
|
if name then
|
||||||
name = normalize_path(name)
|
name = normalize_path(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
local ft, on_detect
|
local ft, on_detect
|
||||||
|
|
||||||
if not (bufnr or name) then
|
if contents then
|
||||||
-- Sanity check: this should not happen
|
-- Sanity check: this should not happen
|
||||||
assert(contents, 'contents should be non-nil when bufnr and filename are nil')
|
assert(not bufnr, '"buf" and "contents" are mutually exclusive')
|
||||||
-- TODO: "scripts.lua" content matching
|
-- TODO: "scripts.lua" content matching
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user