docs(filetype): consolidate comments in dev_vimpatch.txt

This commit is contained in:
Christian Clason
2024-08-03 13:04:47 +02:00
parent 37910f2703
commit 3b58d93aae
2 changed files with 42 additions and 39 deletions

View File

@@ -308,41 +308,54 @@ used in new documentation:
FILETYPE DETECTION *dev-vimpatch-filetype* FILETYPE DETECTION *dev-vimpatch-filetype*
Nvim's filetype detection behavior matches Vim, but is implemented as part of Nvim's filetype detection behavior matches Vim, but is implemented as part of
|vim.filetype| (see $VIMRUNTIME/lua/vim/filetype.lua). |vim.filetype| (see `$VIMRUNTIME/lua/vim/filetype.lua`). The logic is encoded in
three tables, listed in order of precedence (the first match is returned):
1. `filename` for literal full path or basename lookup;
2. `pattern` for matching filenames or paths against |lua-patterns|, optimized
for fast lookup;
3. `extension` for literal extension lookup.
Prefer explicit filenames/extensions over patterns, especially for case Logic that requires checking file contents or buffer variables is implemented
in `$VIMRUNTIME/lua/vim/filetype/detect.lua`.
When porting filetype patches from Vim, keep the following in mind:
Prefer explicit filenames or extensions over patterns, especially for case
insensitive matches (see https://github.com/neovim/neovim/pull/29800): > insensitive matches (see https://github.com/neovim/neovim/pull/29800): >
"*[mM]akefile" regex -> "makefile", "Makefile" filenames "*[mM]akefile" regex -> "makefile", "Makefile" filenames
"*.js\c" regex -> "js", "jS", "Js", "jS" extensions "*.js\c" regex -> "js", "jS", "Js", "jS" extensions
Pattern matching has several differences: Pattern matching has several differences:
- It is done using explicit Lua patterns (without implicit anchoring) instead - It is done using explicit Lua patterns without implicit anchoring instead
of Vim regexes: > of Vim regexes: >
"*/debian/changelog" -> "/debian/changelog$" "*/debian/changelog" -> "/debian/changelog$"
"*/bind/db.*" -> "/bind/db%." "*/bind/db.*" -> "/bind/db%."
< <
- Filetype patterns are grouped by their parent pattern to improve matching - Filetype patterns are grouped by their parent pattern to improve matching
performance. For this to work properly, parent pattern should: performance: If the parent pattern does not match, skip testing all child
- Match at least the same set of strings as filetype patterns inside it. patterns. Note that unlike leaf patterns, parent patterns do not have
But not too much more. special matching behaviour if they contain a `/`.
- Be fast to match.
When adding a new filetype with pattern matching, consider the following: When adding a new filetype with pattern matching, consider the following:
- If there is already a group with appropriate parent pattern, use it. - If there is already a group with appropriate parent pattern, use it.
- If there can be a fast and specific enough pattern to group at least - If there can be a fast and specific enough pattern to group at least 3
3 filetype patterns, add it as a separate grouped entry. filetype patterns, add it as a separate grouped entry.
Good new parent pattern should be: New parent patterns should be
- Fast. Good rule of thumb is that it should be a short explicit string - fast: rule of thumb is that it should be a short explicit string
(i.e. no quantifiers or character sets). (i.e. no quantifiers or character sets);
- Specific. Good rules of thumb (from best to worst): - specific: rules of thumb, in order:
- Full directory name (like "/etc/", "/log/"). - full directory name (e.g., `"/etc/"`, `"/log/"`);
- Part of a rare enough directory name (like "/conf", "git/"). - part of a rare enough directory name (e.g., `"/conf"`, `"git/"`);
- String reasonably rarely used in real full paths (like "nginx"). - string rarely used in real full paths (e.g., `"nginx"`).
Example: Example:
- Filetype pattern: ".*/etc/a2ps/.*%.cfg" - Filetype pattern: `".*/etc/a2ps/.*%.cfg"`
- Good parent: "/etc/"; "%.cfg$" - Good parents: `"/etc/"` or `"%.cfg$"`
- Bad parent: "%." - fast, not specific; "/a2ps/.*%." - slow, specific - Bad parents: `"%."` (fast but not specific) or `"/a2ps/.*%."` (specific
but slow)
When modifying an existing regular pattern, make sure that it still fits its
group.
vim:tw=78:ts=8:noet:ft=help:norl: vim:tw=78:ts=8:noet:ft=help:norl:

View File

@@ -174,9 +174,15 @@ end
-- luacheck: push no unused args -- luacheck: push no unused args
-- luacheck: push ignore 122 -- luacheck: push ignore 122
-- Filetypes based on file extension -- Filetype detection logic is encoded in three tables:
-- 1. `extension` for literal extension lookup
-- 2. `filename` for literal full path or basename lookup;
-- 3. `pattern` for matching filenames or paths against Lua patterns,
-- optimized for fast lookup.
-- See `:h dev-vimpatch-filetype` for guidance when porting Vim filetype patches.
---@diagnostic disable: unused-local ---@diagnostic disable: unused-local
--- @type vim.filetype.mapping ---@type vim.filetype.mapping
local extension = { local extension = {
-- BEGIN EXTENSION -- BEGIN EXTENSION
['8th'] = '8th', ['8th'] = '8th',
@@ -273,8 +279,6 @@ local extension = {
cfm = 'cf', cfm = 'cf',
cfi = 'cf', cfi = 'cf',
hgrc = 'cfg', hgrc = 'cfg',
-- Extension match does not conflict with specific patterns such as '.*/etc/a2ps/.*%.cfg', etc.,
-- as it is done after those are tried to match
cfg = detect.cfg, cfg = detect.cfg,
cfG = detect.cfg, cfG = detect.cfg,
cFg = detect.cfg, cFg = detect.cfg,
@@ -1418,7 +1422,7 @@ local extension = {
-- END EXTENSION -- END EXTENSION
} }
--- @type vim.filetype.mapping ---@type vim.filetype.mapping
local filename = { local filename = {
-- BEGIN FILENAME -- BEGIN FILENAME
['a2psrc'] = 'a2ps', ['a2psrc'] = 'a2ps',
@@ -1884,21 +1888,7 @@ local detect_muttrc = starsetf('muttrc', { parent = 'utt' })
local detect_neomuttrc = starsetf('neomuttrc', { parent = 'utt' }) local detect_neomuttrc = starsetf('neomuttrc', { parent = 'utt' })
local detect_xkb = starsetf('xkb', { parent = '/usr/' }) local detect_xkb = starsetf('xkb', { parent = '/usr/' })
--- Table of filetype pattern matching rules grouped by their parent pattern. ---@type table<string,vim.filetype.mapping>
---
--- Every filetype pattern match is prefaced with a matching of its parent pattern.
--- If there is no match, skip all matching inside group.
--- Note that unlike leaf patterns, parent patterns do not have special matching behaviour if they
--- contain a `/`.
---
--- When modifying an existing regular pattern, make sure that it still fits its group.
---
--- Vim regexes are converted into explicit Lua patterns (without implicit anchoring):
--- '*/debian/changelog' -> '/debian/changelog$'
--- '*/bind/db.*' -> '/bind/db%.'
---
--- See more info in `:h dev-vimpatch-filetype`.
--- @type table<string,vim.filetype.mapping>
local pattern = { local pattern = {
-- BEGIN PATTERN -- BEGIN PATTERN
['/debian/'] = { ['/debian/'] = {