aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/fs.lua
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2024-05-14 17:29:28 +0100
committerLewis Russell <me@lewisr.dev>2024-05-15 12:38:26 +0100
commitdcdefd042840c7a6db5dce2963ac23c45a5287da (patch)
tree334b021fa547da0ace5c6bef188accf626966092 /runtime/lua/vim/fs.lua
parent87a45ad9b98e2e69c36091d397ad5b70a688b23f (diff)
downloadrneovim-dcdefd042840c7a6db5dce2963ac23c45a5287da.tar.gz
rneovim-dcdefd042840c7a6db5dce2963ac23c45a5287da.tar.bz2
rneovim-dcdefd042840c7a6db5dce2963ac23c45a5287da.zip
perf(loader): use a quicker version of vim.fs.normalize
Problem: vim.fs.normalize() normalizes too much vim.loader and is slow. Solution: Make it faster by doing less. This reduces the times spent in vim.fs.normalize in vim.loader from ~13ms -> 1-2ms. Numbers from a relative benchmark: - Skipping `vim.validate()`: 285ms -> 230ms - Skipping `path_resolve_dot()`: 285ms -> 60ms - Skipping `double_slash`: 60ms -> 35ms
Diffstat (limited to 'runtime/lua/vim/fs.lua')
-rw-r--r--runtime/lua/vim/fs.lua37
1 files changed, 26 insertions, 11 deletions
diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua
index e70175bcbd..58e79db0b4 100644
--- a/runtime/lua/vim/fs.lua
+++ b/runtime/lua/vim/fs.lua
@@ -488,6 +488,8 @@ end
--- (default: `true`)
--- @field expand_env? boolean
---
+--- @field package _fast? boolean
+---
--- Path is a Windows path.
--- (default: `true` in Windows, `false` otherwise)
--- @field win? boolean
@@ -527,11 +529,13 @@ end
function M.normalize(path, opts)
opts = opts or {}
- vim.validate({
- path = { path, { 'string' } },
- expand_env = { opts.expand_env, { 'boolean' }, true },
- win = { opts.win, { 'boolean' }, true },
- })
+ if not opts._fast then
+ vim.validate({
+ path = { path, { 'string' } },
+ expand_env = { opts.expand_env, { 'boolean' }, true },
+ win = { opts.win, { 'boolean' }, true },
+ })
+ end
local win = opts.win == nil and iswin or not not opts.win
local os_sep_local = win and '\\' or '/'
@@ -555,11 +559,17 @@ function M.normalize(path, opts)
path = path:gsub('%$([%w_]+)', vim.uv.os_getenv)
end
- -- Convert path separator to `/`
- path = path:gsub(os_sep_local, '/')
+ if win then
+ -- Convert path separator to `/`
+ path = path:gsub(os_sep_local, '/')
+ end
-- Check for double slashes at the start of the path because they have special meaning
- local double_slash = vim.startswith(path, '//') and not vim.startswith(path, '///')
+ local double_slash = false
+ if not opts._fast then
+ double_slash = vim.startswith(path, '//') and not vim.startswith(path, '///')
+ end
+
local prefix = ''
if win then
@@ -576,10 +586,15 @@ function M.normalize(path, opts)
prefix = prefix:gsub('/+', '/')
end
- -- Resolve `.` and `..` components and remove extraneous slashes from path, then recombine prefix
- -- and path. Preserve leading double slashes as they indicate UNC paths and DOS device paths in
+ if not opts._fast then
+ -- Resolve `.` and `..` components and remove extraneous slashes from path, then recombine prefix
+ -- and path.
+ path = path_resolve_dot(path)
+ end
+
+ -- Preserve leading double slashes as they indicate UNC paths and DOS device paths in
-- Windows and have implementation-defined behavior in POSIX.
- path = (double_slash and '/' or '') .. prefix .. path_resolve_dot(path)
+ path = (double_slash and '/' or '') .. prefix .. path
-- Change empty path to `.`
if path == '' then