aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/filetype.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/filetype.lua')
-rw-r--r--runtime/lua/vim/filetype.lua127
1 files changed, 79 insertions, 48 deletions
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index c091e2f35c..536580c604 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -26,7 +26,7 @@ end
---@private
local function getline(bufnr, start_lnum, end_lnum)
end_lnum = end_lnum or start_lnum
- local lines = vim.api.nvim_buf_get_lines(bufnr, start_lnum - 1, end_lnum, false)
+ local lines = api.nvim_buf_get_lines(bufnr, start_lnum - 1, end_lnum, false)
return table.concat(lines) or ''
end
@@ -40,9 +40,9 @@ end
function M.getlines(bufnr, start_lnum, end_lnum)
if not end_lnum then
-- Return a single line as a string
- return vim.api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1]
+ return api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1]
end
- return vim.api.nvim_buf_get_lines(bufnr, start_lnum - 1, end_lnum, false)
+ return api.nvim_buf_get_lines(bufnr, start_lnum - 1, end_lnum, false)
end
---@private
@@ -1513,12 +1513,14 @@ local filename = {
['/.pinforc'] = 'pinfo',
['.povrayrc'] = 'povini',
['printcap'] = function(path, bufnr)
- vim.b[bufnr].ptcap_type = 'print'
- return 'ptcap'
+ return 'ptcap', function(b)
+ vim.b[b].ptcap_type = 'print'
+ end
end,
['termcap'] = function(path, bufnr)
- vim.b[bufnr].ptcap_type = 'term'
- return 'ptcap'
+ return 'ptcap', function(b)
+ vim.b[b].ptcap_type = 'term'
+ end
end,
['.procmailrc'] = 'procmail',
['.procmail'] = 'procmail',
@@ -1604,12 +1606,14 @@ local filename = {
['xdm-config'] = 'xdefaults',
['.Xdefaults'] = 'xdefaults',
['xorg.conf'] = function(path, bufnr)
- vim.b[bufnr].xf86conf_xfree86_version = 4
- return 'xf86conf'
+ return 'xf86conf', function(b)
+ vim.b[b].xf86conf_xfree86_version = 4
+ end
end,
['xorg.conf-4'] = function(path, bufnr)
- vim.b[bufnr].xf86conf_xfree86_version = 4
- return 'xf86conf'
+ return 'xf86conf', function(b)
+ vim.b[b].xf86conf_xfree86_version = 4
+ end
end,
['/etc/xinetd.conf'] = 'xinetd',
fglrxrc = 'xml',
@@ -1662,7 +1666,7 @@ local filename = {
bashrc = function(path, bufnr)
return require('vim.filetype.detect').sh(path, bufnr, 'bash')
end,
- crontab = starsetf('crontab'),
+ crontab = 'crontab',
['csh.cshrc'] = function(path, bufnr)
return require('vim.filetype.detect').csh(path, bufnr)
end,
@@ -1682,7 +1686,7 @@ local filename = {
return require('vim.filetype.detect').shell(path, bufnr, 'tcsh')
end,
['XF86Config'] = function(path, bufnr)
- return require('vim.filetype.detect').xf86conf(bufnr)
+ return require('vim.filetype.detect').xfree86(bufnr)
end,
-- END FILENAME
}
@@ -1830,8 +1834,9 @@ local pattern = {
['.*/etc/protocols'] = 'protocols',
['.*printcap.*'] = starsetf(function(path, bufnr)
if vim.fn.did_filetype() == 0 then
- vim.b[bufnr].ptcap_type = 'print'
- return 'ptcap'
+ return 'ptcap', function(b)
+ vim.b[b].ptcap_type = 'print'
+ end
end
end),
['.*baseq[2-3]/.*%.cfg'] = 'quake',
@@ -1881,8 +1886,9 @@ local pattern = {
['.*/%.config/systemd/user/%.#.*'] = 'systemd',
['.*termcap.*'] = starsetf(function(path, bufnr)
if vim.fn.did_filetype() == 0 then
- vim.b[bufnr].ptcap_type = 'term'
- return 'ptcap'
+ return 'ptcap', function(b)
+ vim.b[b].ptcap_type = 'term'
+ end
end
end),
['.*%.t%.html'] = 'tilde',
@@ -1966,12 +1972,14 @@ local pattern = {
['.*%.vhdl_[0-9].*'] = starsetf('vhdl'),
['.*/%.fvwm/.*'] = starsetf('fvwm'),
['.*fvwmrc.*'] = starsetf(function(path, bufnr)
- vim.b[bufnr].fvwm_version = 1
- return 'fvwm'
+ return 'fvwm', function(b)
+ vim.b[b].fvwm_version = 1
+ end
end),
['.*fvwm95.*%.hook'] = starsetf(function(path, bufnr)
- vim.b[bufnr].fvwm_version = 1
- return 'fvwm'
+ return 'fvwm', function(b)
+ vim.b[b].fvwm_version = 1
+ end
end),
['.*/%.gitconfig%.d/.*'] = starsetf('gitconfig'),
['.*/Xresources/.*'] = starsetf('xdefaults'),
@@ -2117,17 +2125,18 @@ local pattern = {
['.*/queries/.*%.scm'] = 'query', -- tree-sitter queries
['.*,v'] = 'rcs',
['.*/xorg%.conf%.d/.*%.conf'] = function(path, bufnr)
- vim.b[bufnr].xf86conf_xfree86_version = 4
- return 'xf86config'
+ return 'xf86config', function(b)
+ vim.b[b].xf86conf_xfree86_version = 4
+ end
end,
-- Increase priority to run before the pattern below
- ['XF86Config%-4'] = starsetf(function(path, bufnr)
- vim.b[bufnr].xf86conf_xfree86_version = 4
- return 'xf86config'
+ ['XF86Config%-4.*'] = starsetf(function(path, bufnr)
+ return 'xf86conf', function(b)
+ vim.b[b].xf86conf_xfree86_version = 4
+ end
end, { priority = -math.huge + 1 }),
['XF86Config.*'] = starsetf(function(path, bufnr)
- vim.b[bufnr].xf86conf_xfree86_version = 4
- return require('vim.filetype.detect').xf86conf(bufnr)
+ return require('vim.filetype.detect').xfree86(bufnr)
end),
['[cC]hange[lL]og.*'] = starsetf(function(path, bufnr)
local line = getline(bufnr, 1):lower()
@@ -2141,8 +2150,9 @@ local pattern = {
if vim.fn.fnamemodify(path, ':e') == 'm4' then
return 'fvwm2m4'
else
- vim.b[bufnr].fvwm_version = 2
- return 'fvwm'
+ return 'fvwm', function(b)
+ vim.b[b].fvwm_version = 2
+ end
end
end),
['.*%.[Ll][Oo][Gg]'] = function(path, bufnr)
@@ -2220,7 +2230,9 @@ end
--- filetype directly) or a function. If a function, it takes the full path and
--- buffer number of the file as arguments (along with captures from the matched
--- pattern, if any) and should return a string that will be used as the
---- buffer's filetype.
+--- buffer's filetype. Optionally, the function can return a second function
+--- value which, when called, modifies the state of the buffer. This can be used
+--- to, for example, set filetype-specific buffer variables.
---
--- Filename patterns can specify an optional priority to resolve cases when a
--- file path matches multiple patterns. Higher priorities are matched first.
@@ -2238,7 +2250,10 @@ end
--- foo = "fooscript",
--- bar = function(path, bufnr)
--- if some_condition() then
---- return "barscript"
+--- return "barscript", function(bufnr)
+--- -- Set a buffer variable
+--- vim.b[bufnr].barscript_version = 2
+--- end
--- end
--- return "bar"
--- end,
@@ -2283,13 +2298,13 @@ end
---@private
local function dispatch(ft, path, bufnr, ...)
+ local on_detect
if type(ft) == 'function' then
- ft = ft(path, bufnr, ...)
+ ft, on_detect = ft(path, bufnr, ...)
end
if type(ft) == 'string' then
- api.nvim_buf_set_option(bufnr, 'filetype', ft)
- return true
+ return ft, on_detect
end
-- Any non-falsey value (that is, anything other than 'nil' or 'false') will
@@ -2314,11 +2329,20 @@ local function match_pattern(name, path, tail, pat)
return matches
end
---- Set the filetype for the given buffer from a file name.
+--- Find the filetype for the given filename and buffer.
---
---@param name string File name (can be an absolute or relative path)
---@param bufnr number|nil The buffer to set the filetype for. Defaults to the current buffer.
+---@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
+--- its only argument.
function M.match(name, bufnr)
+ vim.validate({
+ name = { name, 's' },
+ bufnr = { bufnr, 'n', true },
+ })
+
-- When fired from the main filetypedetect autocommand the {bufnr} argument is omitted, so we use
-- the current buffer. The {bufnr} argument is provided to allow extensibility in case callers
-- wish to perform filetype detection on buffers other than the current one.
@@ -2326,16 +2350,20 @@ function M.match(name, bufnr)
name = normalize_path(name)
+ local ft, on_detect
+
-- First check for the simple case where the full path exists as a key
local path = vim.fn.resolve(vim.fn.fnamemodify(name, ':p'))
- if dispatch(filename[path], path, bufnr) then
- return
+ ft, on_detect = dispatch(filename[path], path, bufnr)
+ if ft then
+ return ft, on_detect
end
-- Next check against just the file name
local tail = vim.fn.fnamemodify(name, ':t')
- if dispatch(filename[tail], path, bufnr) then
- return
+ ft, on_detect = dispatch(filename[tail], path, bufnr)
+ if ft then
+ return ft, on_detect
end
-- Next, check the file path against available patterns with non-negative priority
@@ -2348,19 +2376,21 @@ function M.match(name, bufnr)
break
end
- local ft = v[k][1]
+ local filetype = v[k][1]
local matches = match_pattern(name, path, tail, k)
if matches then
- if dispatch(ft, path, bufnr, matches) then
- return
+ ft, on_detect = dispatch(filetype, path, bufnr, matches)
+ if ft then
+ return ft, on_detect
end
end
end
-- Next, check file extension
local ext = vim.fn.fnamemodify(name, ':e')
- if dispatch(extension[ext], path, bufnr) then
- return
+ ft, on_detect = dispatch(extension[ext], path, bufnr)
+ if ft then
+ return ft, on_detect
end
-- Finally, check patterns with negative priority
@@ -2368,11 +2398,12 @@ function M.match(name, bufnr)
local v = pattern_sorted[i]
local k = next(v)
- local ft = v[k][1]
+ local filetype = v[k][1]
local matches = match_pattern(name, path, tail, k)
if matches then
- if dispatch(ft, path, bufnr, matches) then
- return
+ ft, on_detect = dispatch(filetype, path, bufnr, matches)
+ if ft then
+ return ft, on_detect
end
end
end