diff options
author | Gregory Anders <8965202+gpanders@users.noreply.github.com> | 2022-06-27 02:03:43 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-27 10:03:43 +0200 |
commit | 6f3508f8edbc48de1accd931a9d6e66bc99f174a (patch) | |
tree | 712b5871d3f8f1a13dc1f567abaf02131963d3bf | |
parent | eab8b998e9a964cbb72abb8dedb718326a8093e1 (diff) | |
download | rneovim-6f3508f8edbc48de1accd931a9d6e66bc99f174a.tar.gz rneovim-6f3508f8edbc48de1accd931a9d6e66bc99f174a.tar.bz2 rneovim-6f3508f8edbc48de1accd931a9d6e66bc99f174a.zip |
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).
-rw-r--r-- | runtime/doc/lua.txt | 28 | ||||
-rw-r--r-- | runtime/lua/vim/filetype.lua | 44 |
2 files changed, 47 insertions, 25 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index f40b32c469..b79699c89b 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2086,23 +2086,33 @@ match({arg}) *vim.filetype.match()* -- Using a buffer number vim.filetype.match({ buf = 42 }) - -- Using a filename - vim.filetype.match({ filename = "main.lua" }) + -- Override the filename of the given buffer + vim.filetype.match({ buf = 42, filename = 'foo.c' }) + + -- Using a filename without a buffer + vim.filetype.match({ filename = 'main.lua' }) -- Using file contents - vim.filetype.match({ contents = {"#!/usr/bin/env bash"} }) + vim.filetype.match({ contents = {'#!/usr/bin/env bash'} }) < Parameters: ~ {arg} (table) Table specifying which matching strategy to - use. It is an error to provide more than one - strategy. Accepted keys are: - • buf (number): Buffer number to use for matching + use. Accepted keys are: + • buf (number): Buffer number to use for matching. + Mutually exclusive with {contents} • filename (string): Filename to use for matching. - Note that the file need not actually exist in the - filesystem, only the name itself is used. + When {buf} is given, defaults to the filename of + 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 - file contents to use for matching. + file contents to use for matching. Can be used + with {filename}. Mutually exclusive with {buf}. Return: ~ (string|nil) If a match was found, the matched filetype. diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 3e86159489..73605413ee 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -2240,21 +2240,29 @@ end --- -- Using a buffer number --- vim.filetype.match({ buf = 42 }) --- ---- -- Using a filename ---- vim.filetype.match({ filename = "main.lua" }) +--- -- Override the filename of the given buffer +--- vim.filetype.match({ buf = 42, filename = 'foo.c' }) +--- +--- -- Using a filename without a buffer +--- vim.filetype.match({ filename = 'main.lua' }) --- --- -- Using file contents ---- vim.filetype.match({ contents = {"#!/usr/bin/env bash"} }) +--- vim.filetype.match({ contents = {'#!/usr/bin/env bash'} }) --- </pre> --- ----@param arg table Table specifying which matching strategy to use. It is an error to provide more ---- than one strategy. Accepted keys are: ---- * buf (number): Buffer number to use for matching ---- * filename (string): Filename to use for matching. Note that the file need not ---- actually exist in the filesystem, only the name itself is ---- used. +---@param arg table Table specifying which matching strategy to use. Accepted keys are: +--- * buf (number): Buffer number to use for matching. Mutually exclusive with +--- {contents} +--- * filename (string): Filename to use for matching. When {buf} is given, +--- defaults to the filename of 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 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 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 @@ -2265,26 +2273,30 @@ function M.match(arg) }) 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 - if (arg.buf and arg.filename) or (arg.buf and arg.contents) or (arg.filename and arg.contents) then - error('Only one of "buf", "filename", or "contents" must be given') + if arg.buf and arg.contents then + error('Only one of "buf" or "contents" must be given') end 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 + if bufnr and not name then + name = api.nvim_buf_get_name(bufnr) + end + if name then name = normalize_path(name) end local ft, on_detect - if not (bufnr or name) then + if contents then -- 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 return end |