diff options
-rw-r--r-- | runtime/doc/lua.txt | 27 | ||||
-rw-r--r-- | runtime/lua/vim/fs.lua | 28 | ||||
-rw-r--r-- | test/functional/lua/fs_spec.lua | 19 |
3 files changed, 71 insertions, 3 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index ba59c67446..8a14f80856 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2166,7 +2166,8 @@ dir({path}) *vim.fs.dir()* Parameters: ~ {path} (string) An absolute or relative path to the - directory to iterate over + directory to iterate over. The path is first + normalized |vim.fs.normalize()|. Return: ~ Iterator over files and directories in {path}. Each @@ -2223,6 +2224,30 @@ find({names}, {opts}) *vim.fs.find()* Return: ~ (table) The paths of all matching files or directories +normalize({path}) *vim.fs.normalize()* + Normalize a path to a standard format. A tilde (~) character + at the beginning of the path is expanded to the user's home + directory and any backslash (\) characters are converted to + forward slashes (/). Environment variables are also expanded. + + Example: > + + vim.fs.normalize('C:\Users\jdoe') + => 'C:/Users/jdoe' + + vim.fs.normalize('~/src/neovim') + => '/home/jdoe/src/neovim' + + vim.fs.normalize('$XDG_CONFIG_HOME/nvim/init.vim') + => '/Users/jdoe/.config/nvim/init.vim' +< + + Parameters: ~ + {path} (string) Path to normalize + + Return: ~ + (string) Normalized path + parents({start}) *vim.fs.parents()* Iterate over all the parents of the given file or directory. diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 4519f2a1e4..9bf38f7bc3 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -51,14 +51,14 @@ end --- Return an iterator over the files and directories located in {path} --- ---@param path (string) An absolute or relative path to the directory to iterate ---- over +--- over. The path is first normalized |vim.fs.normalize()|. ---@return Iterator over files and directories in {path}. Each iteration yields --- two values: name and type. Each "name" is the basename of the file or --- directory relative to {path}. Type is one of "file" or "directory". function M.dir(path) return function(fs) return vim.loop.fs_scandir_next(fs) - end, vim.loop.fs_scandir(path) + end, vim.loop.fs_scandir(M.normalize(path)) end --- Find files or directories in the given path. @@ -178,4 +178,28 @@ function M.find(names, opts) return matches end +--- Normalize a path to a standard format. A tilde (~) character at the +--- beginning of the path is expanded to the user's home directory and any +--- backslash (\\) characters are converted to forward slashes (/). Environment +--- variables are also expanded. +--- +--- Example: +--- <pre> +--- vim.fs.normalize('C:\\Users\\jdoe') +--- => 'C:/Users/jdoe' +--- +--- vim.fs.normalize('~/src/neovim') +--- => '/home/jdoe/src/neovim' +--- +--- vim.fs.normalize('$XDG_CONFIG_HOME/nvim/init.vim') +--- => '/Users/jdoe/.config/nvim/init.vim' +--- </pre> +--- +---@param path (string) Path to normalize +---@return (string) Normalized path +function M.normalize(path) + vim.validate({ path = { path, 's' } }) + return (path:gsub('^~/', vim.env.HOME .. '/'):gsub('%$([%w_]+)', vim.env):gsub('\\', '/')) +end + return M diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 204bdc1567..2bcc84db0f 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -79,4 +79,23 @@ describe('vim.fs', function() ]], test_build_dir, nvim_prog_basename)) end) end) + + describe('normalize()', function() + it('works with backward slashes', function() + eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]]) + end) + it('works with ~', function() + if iswin() then + pending([[$HOME does not exist on Windows ¯\_(ツ)_/¯]]) + end + eq(os.getenv('HOME') .. '/src/foo', exec_lua [[ return vim.fs.normalize('~/src/foo') ]]) + end) + it('works with environment variables', function() + local xdg_config_home = test_build_dir .. '/.config' + eq(xdg_config_home .. '/nvim', exec_lua([[ + vim.env.XDG_CONFIG_HOME = ... + return vim.fs.normalize('$XDG_CONFIG_HOME/nvim') + ]], xdg_config_home)) + end) + end) end) |