feat(fs): expose join_paths as vim.fs.joinpath (#23685)

This is a small function but used a lot in some plugins.
This commit is contained in:
Christian Clason 2023-05-20 17:30:48 +02:00 committed by GitHub
parent 073035a030
commit e3e6fadfd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 9 deletions

View File

@ -2576,6 +2576,16 @@ find({names}, {opts}) *vim.fs.find()*
(table) Normalized paths |vim.fs.normalize()| of all matching files or (table) Normalized paths |vim.fs.normalize()| of all matching files or
directories directories
joinpath({...}) *vim.fs.joinpath()*
Concatenate directories and/or file into a single path with normalization
(e.g., `"foo/"` and `"bar"` get joined to `"foo/bar"`)
Parameters: ~
• {...} (string)
Return: ~
(string)
normalize({path}, {opts}) *vim.fs.normalize()* normalize({path}, {opts}) *vim.fs.normalize()*
Normalize a path to a standard format. A tilde (~) character at the 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 beginning of the path is expanded to the user's home directory and any

View File

@ -72,15 +72,15 @@ function M.basename(file)
return file:match('[/\\]$') and '' or (file:match('[^\\/]*$'):gsub('\\', '/')) return file:match('[/\\]$') and '' or (file:match('[^\\/]*$'):gsub('\\', '/'))
end end
---@private --- Concatenate directories and/or file into a single path with normalization
--- (e.g., `"foo/"` and `"bar"` get joined to `"foo/bar"`)
---
---@param ... string ---@param ... string
---@return string ---@return string
function M._join_paths(...) function M.joinpath(...)
return (table.concat({ ... }, '/'):gsub('//+', '/')) return (table.concat({ ... }, '/'):gsub('//+', '/'))
end end
local join_paths = M._join_paths
---@alias Iterator fun(): string?, string? ---@alias Iterator fun(): string?, string?
--- Return an iterator over the files and directories located in {path} --- Return an iterator over the files and directories located in {path}
@ -120,14 +120,14 @@ function M.dir(path, opts)
local dirs = { { path, 1 } } local dirs = { { path, 1 } }
while #dirs > 0 do while #dirs > 0 do
local dir0, level = unpack(table.remove(dirs, 1)) local dir0, level = unpack(table.remove(dirs, 1))
local dir = level == 1 and dir0 or join_paths(path, dir0) local dir = level == 1 and dir0 or M.joinpath(path, dir0)
local fs = vim.loop.fs_scandir(M.normalize(dir)) local fs = vim.loop.fs_scandir(M.normalize(dir))
while fs do while fs do
local name, t = vim.loop.fs_scandir_next(fs) local name, t = vim.loop.fs_scandir_next(fs)
if not name then if not name then
break break
end end
local f = level == 1 and name or join_paths(dir0, name) local f = level == 1 and name or M.joinpath(dir0, name)
coroutine.yield(f, t) coroutine.yield(f, t)
if if
opts.depth opts.depth
@ -234,7 +234,7 @@ function M.find(names, opts)
local t = {} local t = {}
for name, type in M.dir(p) do for name, type in M.dir(p) do
if (not opts.type or opts.type == type) and names(name, p) then if (not opts.type or opts.type == type) and names(name, p) then
table.insert(t, join_paths(p, name)) table.insert(t, M.joinpath(p, name))
end end
end end
return t return t
@ -243,7 +243,7 @@ function M.find(names, opts)
test = function(p) test = function(p)
local t = {} local t = {}
for _, name in ipairs(names) do for _, name in ipairs(names) do
local f = join_paths(p, name) local f = M.joinpath(p, name)
local stat = vim.loop.fs_stat(f) local stat = vim.loop.fs_stat(f)
if stat and (not opts.type or opts.type == stat.type) then if stat and (not opts.type or opts.type == stat.type) then
t[#t + 1] = f t[#t + 1] = f
@ -280,7 +280,7 @@ function M.find(names, opts)
end end
for other, type_ in M.dir(dir) do for other, type_ in M.dir(dir) do
local f = join_paths(dir, other) local f = M.joinpath(dir, other)
if type(names) == 'function' then if type(names) == 'function' then
if (not opts.type or opts.type == type_) and names(other, dir) then if (not opts.type or opts.type == type_) and names(other, dir) then
if add(f) then if add(f) then

View File

@ -266,6 +266,17 @@ describe('vim.fs', function()
end) end)
end) end)
describe('joinpath()', function()
it('works', function()
eq('foo/bar/baz', exec_lua([[
return vim.fs.joinpath('foo', 'bar', 'baz')
]], nvim_dir))
eq('foo/bar/baz', exec_lua([[
return vim.fs.joinpath('foo', '/bar/', '/baz')
]], nvim_dir))
end)
end)
describe('normalize()', function() describe('normalize()', function()
it('works with backward slashes', function() it('works with backward slashes', function()
eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]]) eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]])