feat(filetype): expand environment variables in filetype patterns (#20145)

This commit is contained in:
Jonas Strittmatter
2022-09-21 23:58:57 +02:00
committed by GitHub
parent 37a71d1f28
commit b4b05f160d
2 changed files with 38 additions and 28 deletions

View File

@@ -2082,7 +2082,10 @@ add({filetypes}) *vim.filetype.add()*
Filename patterns can specify an optional priority to resolve cases when a Filename patterns can specify an optional priority to resolve cases when a
file path matches multiple patterns. Higher priorities are matched first. file path matches multiple patterns. Higher priorities are matched first.
When omitted, the priority defaults to 0. When omitted, the priority defaults to 0. A pattern can contain
environment variables of the form "${SOME_VAR}" that will be automatically
expanded. If the environment variable is not set, the pattern won't be
matched.
See $VIMRUNTIME/lua/vim/filetype.lua for more examples. See $VIMRUNTIME/lua/vim/filetype.lua for more examples.
@@ -2112,6 +2115,8 @@ add({filetypes}) *vim.filetype.add()*
['.*/etc/foo/.*'] = 'fooscript', ['.*/etc/foo/.*'] = 'fooscript',
-- Using an optional priority -- Using an optional priority
['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } }, ['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } },
-- A pattern containing an environment variable
['${XDG_CONFIG_HOME}/foo/git'] = 'git',
['README.(a+)$'] = function(path, bufnr, ext) ['README.(a+)$'] = function(path, bufnr, ext)
if ext == 'md' then if ext == 'md' then
return 'markdown' return 'markdown'

View File

@@ -1296,7 +1296,6 @@ local filename = {
WORKSPACE = 'bzl', WORKSPACE = 'bzl',
BUILD = 'bzl', BUILD = 'bzl',
['cabal.project'] = 'cabalproject', ['cabal.project'] = 'cabalproject',
[vim.env.HOME .. '/cabal.config'] = 'cabalconfig',
['cabal.config'] = 'cabalconfig', ['cabal.config'] = 'cabalconfig',
calendar = 'calendar', calendar = 'calendar',
catalog = 'catalog', catalog = 'catalog',
@@ -1704,6 +1703,7 @@ local pattern = {
['.*/meta%-.*/conf/.*%.conf'] = 'bitbake', ['.*/meta%-.*/conf/.*%.conf'] = 'bitbake',
['bzr_log%..*'] = 'bzr', ['bzr_log%..*'] = 'bzr',
['.*enlightenment/.*%.cfg'] = 'c', ['.*enlightenment/.*%.cfg'] = 'c',
['${HOME}/cabal%.config'] = 'cabalconfig',
['cabal%.project%..*'] = starsetf('cabalproject'), ['cabal%.project%..*'] = starsetf('cabalproject'),
['.*/%.calendar/.*'] = starsetf('calendar'), ['.*/%.calendar/.*'] = starsetf('calendar'),
['.*/share/calendar/.*/calendar%..*'] = starsetf('calendar'), ['.*/share/calendar/.*/calendar%..*'] = starsetf('calendar'),
@@ -1828,41 +1828,21 @@ local pattern = {
['.*/%.config/git/config'] = 'gitconfig', ['.*/%.config/git/config'] = 'gitconfig',
['.*%.git/config%.worktree'] = 'gitconfig', ['.*%.git/config%.worktree'] = 'gitconfig',
['.*%.git/worktrees/.*/config%.worktree'] = 'gitconfig', ['.*%.git/worktrees/.*/config%.worktree'] = 'gitconfig',
['.*/git/config'] = function(path, bufnr) ['${XDG_CONFIG_HOME}/git/config'] = 'gitconfig',
if vim.env.XDG_CONFIG_HOME and path:find(vim.env.XDG_CONFIG_HOME .. '/git/config') then
return 'gitconfig'
end
end,
['.*%.git/info/attributes'] = 'gitattributes', ['.*%.git/info/attributes'] = 'gitattributes',
['.*/etc/gitattributes'] = 'gitattributes', ['.*/etc/gitattributes'] = 'gitattributes',
['.*/%.config/git/attributes'] = 'gitattributes', ['.*/%.config/git/attributes'] = 'gitattributes',
['.*/git/attributes'] = function(path, bufnr) ['${XDG_CONFIG_HOME}/git/attributes'] = 'gitattributes',
if vim.env.XDG_CONFIG_HOME and path:find(vim.env.XDG_CONFIG_HOME .. '/git/attributes') then
return 'gitattributes'
end
end,
['.*%.git/info/exclude'] = 'gitignore', ['.*%.git/info/exclude'] = 'gitignore',
['.*/%.config/git/ignore'] = 'gitignore', ['.*/%.config/git/ignore'] = 'gitignore',
['.*/git/ignore'] = function(path, bufnr) ['${XDG_CONFIG_HOME}/git/ignore'] = 'gitignore',
if vim.env.XDG_CONFIG_HOME and path:find(vim.env.XDG_CONFIG_HOME .. '/git/ignore') then
return 'gitignore'
end
end,
['%.gitsendemail%.msg%.......'] = 'gitsendemail', ['%.gitsendemail%.msg%.......'] = 'gitsendemail',
['gkrellmrc_.'] = 'gkrellmrc', ['gkrellmrc_.'] = 'gkrellmrc',
['.*/usr/.*/gnupg/options%.skel'] = 'gpg', ['.*/usr/.*/gnupg/options%.skel'] = 'gpg',
['.*/%.gnupg/options'] = 'gpg', ['.*/%.gnupg/options'] = 'gpg',
['.*/%.gnupg/gpg%.conf'] = 'gpg', ['.*/%.gnupg/gpg%.conf'] = 'gpg',
['.*/options'] = function(path, bufnr) ['${GNUPGHOME}/options'] = 'gpg',
if vim.env.GNUPGHOME and path:find(vim.env.GNUPGHOME .. '/options') then ['${GNUPGHOME}/gpg%.conf'] = 'gpg',
return 'gpg'
end
end,
['.*/gpg%.conf'] = function(path, bufnr)
if vim.env.GNUPGHOME and path:find(vim.env.GNUPGHOME .. '/gpg%.conf') then
return 'gpg'
end
end,
['.*/etc/group'] = 'group', ['.*/etc/group'] = 'group',
['.*/etc/gshadow'] = 'group', ['.*/etc/gshadow'] = 'group',
['.*/etc/group%.edit'] = 'group', ['.*/etc/group%.edit'] = 'group',
@@ -1876,7 +1856,7 @@ local pattern = {
['.*/etc/grub%.conf'] = 'grub', ['.*/etc/grub%.conf'] = 'grub',
-- gtkrc* and .gtkrc* -- gtkrc* and .gtkrc*
['%.?gtkrc.*'] = starsetf('gtkrc'), ['%.?gtkrc.*'] = starsetf('gtkrc'),
[vim.env.VIMRUNTIME .. '/doc/.*%.txt'] = 'help', ['${VIMRUNTIME}/doc/.*%.txt'] = 'help',
['hg%-editor%-.*%.txt'] = 'hgcommit', ['hg%-editor%-.*%.txt'] = 'hgcommit',
['.*/etc/host%.conf'] = 'hostconf', ['.*/etc/host%.conf'] = 'hostconf',
['.*/etc/hosts%.deny'] = 'hostsaccess', ['.*/etc/hosts%.deny'] = 'hostsaccess',
@@ -2280,6 +2260,9 @@ end
--- Filename patterns can specify an optional priority to resolve cases when a --- Filename patterns can specify an optional priority to resolve cases when a
--- file path matches multiple patterns. Higher priorities are matched first. --- file path matches multiple patterns. Higher priorities are matched first.
--- When omitted, the priority defaults to 0. --- When omitted, the priority defaults to 0.
--- A pattern can contain environment variables of the form "${SOME_VAR}" that will
--- be automatically expanded. If the environment variable is not set, the pattern
--- won't be matched.
--- ---
--- See $VIMRUNTIME/lua/vim/filetype.lua for more examples. --- See $VIMRUNTIME/lua/vim/filetype.lua for more examples.
--- ---
@@ -2308,6 +2291,8 @@ end
--- ['.*/etc/foo/.*'] = 'fooscript', --- ['.*/etc/foo/.*'] = 'fooscript',
--- -- Using an optional priority --- -- Using an optional priority
--- ['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } }, --- ['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } },
--- -- A pattern containing an environment variable
--- ['${XDG_CONFIG_HOME}/foo/git'] = 'git',
--- ['README.(%a+)$'] = function(path, bufnr, ext) --- ['README.(%a+)$'] = function(path, bufnr, ext)
--- if ext == 'md' then --- if ext == 'md' then
--- return 'markdown' --- return 'markdown'
@@ -2381,8 +2366,28 @@ local function dispatch(ft, path, bufnr, ...)
end end
end end
-- Lookup table/cache for patterns that contain an environment variable pattern, e.g. ${SOME_VAR}.
local expand_env_lookup = {}
---@private ---@private
local function match_pattern(name, path, tail, pat) local function match_pattern(name, path, tail, pat)
if expand_env_lookup[pat] == nil then
expand_env_lookup[pat] = pat:find('%${') ~= nil
end
if expand_env_lookup[pat] then
local return_early
pat = pat:gsub('%${(%S-)}', function(env)
-- If an environment variable is present in the pattern but not set, there is no match
if not vim.env[env] then
return_early = true
return nil
end
return vim.env[env]
end)
if return_early then
return false
end
end
-- If the pattern contains a / match against the full path, otherwise just the tail -- If the pattern contains a / match against the full path, otherwise just the tail
local fullpat = '^' .. pat .. '$' local fullpat = '^' .. pat .. '$'
local matches local matches