aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeni Chasnovski <evgeni.chasnovski@gmail.com>2024-07-08 19:20:32 +0300
committerGitHub <noreply@github.com>2024-07-08 11:20:32 -0500
commitdc04ef2a20bf3457269e0c2aeb7dbfbb56c47012 (patch)
treec360ece342565c72150309b01b46d49ab4857842
parentb3d94b10870ce494941279f78387e1d98a7e48e7 (diff)
downloadrneovim-dc04ef2a20bf3457269e0c2aeb7dbfbb56c47012.tar.gz
rneovim-dc04ef2a20bf3457269e0c2aeb7dbfbb56c47012.tar.bz2
rneovim-dc04ef2a20bf3457269e0c2aeb7dbfbb56c47012.zip
perf(filetype): skip contents check in `match()` if there is no contents (#29596)
Problem: `vim.filetype.match()` tries to match on contents even if there is no contents (empty buffer or `{''}` explicit contents). This results in extra avoidable execution duration for cases. It matters, for example, when trying to match filetype based solely on file name (which still needs `contents` or `buf` to properly match earlier in the code path). Solution: skip matching based solely on contents if it is `{''}`. This works because: - Matching solely on content is done after any user-configured `vim.filetype.add()` hooks. - All default matching on content might depend on supplied path *only* if there is non-empty content (like in `require('vim.filetype.detect').match_from_hashbang()`).
-rw-r--r--runtime/lua/vim/filetype.lua30
1 files changed, 17 insertions, 13 deletions
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 179a6312de..18fa1ed658 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -2598,20 +2598,24 @@ function M.match(args)
contents = M._getlines(bufnr)
end
end
- -- If name is nil, catch any errors from the contents filetype detection function.
- -- If the function tries to use the filename that is nil then it will fail,
- -- but this enables checks which do not need a filename to still work.
- local ok
- ok, ft, on_detect = pcall(
- require('vim.filetype.detect').match_contents,
- contents,
- name,
- function(ext)
- return dispatch(extension[ext], name, bufnr)
+
+ -- Match based solely on content only if there is any content (for performance)
+ if not (#contents == 1 and contents[1] == '') then
+ -- If name is nil, catch any errors from the contents filetype detection function.
+ -- If the function tries to use the filename that is nil then it will fail,
+ -- but this enables checks which do not need a filename to still work.
+ local ok
+ ok, ft, on_detect = pcall(
+ require('vim.filetype.detect').match_contents,
+ contents,
+ name,
+ function(ext)
+ return dispatch(extension[ext], name, bufnr)
+ end
+ )
+ if ok then
+ return ft, on_detect
end
- )
- if ok then
- return ft, on_detect
end
end
end