diff options
author | Christian Clason <c.clason@uni-graz.at> | 2024-08-03 13:04:47 +0200 |
---|---|---|
committer | Christian Clason <c.clason@uni-graz.at> | 2024-08-03 14:14:42 +0200 |
commit | 3b58d93aaeaea363ff1066fc791f5d8af1946218 (patch) | |
tree | e68ee09a74dbe8c1ee46aaac2399e3e4d9ec8af4 | |
parent | 37910f270341d8b36f2f26b6d628274b85e2522b (diff) | |
download | rneovim-3b58d93aaeaea363ff1066fc791f5d8af1946218.tar.gz rneovim-3b58d93aaeaea363ff1066fc791f5d8af1946218.tar.bz2 rneovim-3b58d93aaeaea363ff1066fc791f5d8af1946218.zip |
docs(filetype): consolidate comments in dev_vimpatch.txt
-rw-r--r-- | runtime/doc/dev_vimpatch.txt | 51 | ||||
-rw-r--r-- | runtime/lua/vim/filetype.lua | 30 |
2 files changed, 42 insertions, 39 deletions
diff --git a/runtime/doc/dev_vimpatch.txt b/runtime/doc/dev_vimpatch.txt index a36b2a613b..9a2380b162 100644 --- a/runtime/doc/dev_vimpatch.txt +++ b/runtime/doc/dev_vimpatch.txt @@ -308,41 +308,54 @@ used in new documentation: FILETYPE DETECTION *dev-vimpatch-filetype* 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): > "*[mM]akefile" regex -> "makefile", "Makefile" filenames "*.js\c" regex -> "js", "jS", "Js", "jS" extensions 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: > "*/debian/changelog" -> "/debian/changelog$" "*/bind/db.*" -> "/bind/db%." < - Filetype patterns are grouped by their parent pattern to improve matching - performance. For this to work properly, parent pattern should: - - Match at least the same set of strings as filetype patterns inside it. - But not too much more. - - Be fast to match. + performance: If the parent pattern does not match, skip testing all child + patterns. Note that unlike leaf patterns, parent patterns do not have + special matching behaviour if they contain a `/`. 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 can be a fast and specific enough pattern to group at least - 3 filetype patterns, add it as a separate grouped entry. + - If there can be a fast and specific enough pattern to group at least 3 + filetype patterns, add it as a separate grouped entry. - Good new parent pattern should be: - - Fast. Good rule of thumb is that it should be a short explicit string - (i.e. no quantifiers or character sets). - - Specific. Good rules of thumb (from best to worst): - - Full directory name (like "/etc/", "/log/"). - - Part of a rare enough directory name (like "/conf", "git/"). - - String reasonably rarely used in real full paths (like "nginx"). + New parent patterns should be + - fast: rule of thumb is that it should be a short explicit string + (i.e. no quantifiers or character sets); + - specific: rules of thumb, in order: + - full directory name (e.g., `"/etc/"`, `"/log/"`); + - part of a rare enough directory name (e.g., `"/conf"`, `"git/"`); + - string rarely used in real full paths (e.g., `"nginx"`). Example: - - Filetype pattern: ".*/etc/a2ps/.*%.cfg" - - Good parent: "/etc/"; "%.cfg$" - - Bad parent: "%." - fast, not specific; "/a2ps/.*%." - slow, specific + - Filetype pattern: `".*/etc/a2ps/.*%.cfg"` + - Good parents: `"/etc/"` or `"%.cfg$"` + - 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: diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 4192645acb..71a49445de 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -174,9 +174,15 @@ end -- luacheck: push no unused args -- 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 ---- @type vim.filetype.mapping +---@type vim.filetype.mapping local extension = { -- BEGIN EXTENSION ['8th'] = '8th', @@ -273,8 +279,6 @@ local extension = { cfm = 'cf', cfi = 'cf', 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, @@ -1418,7 +1422,7 @@ local extension = { -- END EXTENSION } ---- @type vim.filetype.mapping +---@type vim.filetype.mapping local filename = { -- BEGIN FILENAME ['a2psrc'] = 'a2ps', @@ -1884,21 +1888,7 @@ local detect_muttrc = starsetf('muttrc', { parent = 'utt' }) local detect_neomuttrc = starsetf('neomuttrc', { parent = 'utt' }) local detect_xkb = starsetf('xkb', { parent = '/usr/' }) ---- Table of filetype pattern matching rules grouped by their parent pattern. ---- ---- 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> +---@type table<string,vim.filetype.mapping> local pattern = { -- BEGIN PATTERN ['/debian/'] = { |