fix(vim.fs): joinpath() does not normalize slashes on Windows #31782

This commit is contained in:
Gustav Eikaas
2024-12-31 16:40:05 +01:00
committed by GitHub
parent b3bdba5cb1
commit 0bef3b911c
3 changed files with 27 additions and 5 deletions

View File

@ -3062,8 +3062,11 @@ vim.fs.find({names}, {opts}) *vim.fs.find()*
items
vim.fs.joinpath({...}) *vim.fs.joinpath()*
Concatenate directories and/or file paths into a single path with
normalization (e.g., `"foo/"` and `"bar"` get joined to `"foo/bar"`)
Concatenates partial paths into one path. Slashes are normalized
(redundant slashes are removed, and on Windows backslashes are replaced
with forward-slashes) (e.g., `"foo/"` and `"/bar"` get joined to
`"foo/bar"`) (windows: e.g `"a\foo\"` and `"\bar"` are joined to
`"a/foo/bar"`)
Attributes: ~
Since: 0.10.0

View File

@ -105,14 +105,19 @@ function M.basename(file)
return file:match('/$') and '' or (file:match('[^/]*$'))
end
--- Concatenate directories and/or file paths into a single path with normalization
--- (e.g., `"foo/"` and `"bar"` get joined to `"foo/bar"`)
--- Concatenates partial paths into one path. Slashes are normalized (redundant slashes are removed, and on Windows backslashes are replaced with forward-slashes)
--- (e.g., `"foo/"` and `"/bar"` get joined to `"foo/bar"`)
--- (windows: e.g `"a\foo\"` and `"\bar"` are joined to `"a/foo/bar"`)
---
---@since 12
---@param ... string
---@return string
function M.joinpath(...)
return (table.concat({ ... }, '/'):gsub('//+', '/'))
local path = table.concat({ ... }, '/')
if iswin then
path = path:gsub('\\', '/')
end
return (path:gsub('//+', '/'))
end
---@alias Iterator fun(): string?, string?

View File

@ -323,6 +323,20 @@ describe('vim.fs', function()
eq('foo/bar/baz', vim.fs.joinpath('foo', 'bar', 'baz'))
eq('foo/bar/baz', vim.fs.joinpath('foo', '/bar/', '/baz'))
end)
it('rewrites backslashes on Windows', function()
if is_os('win') then
eq('foo/bar/baz/zub/', vim.fs.joinpath([[foo]], [[\\bar\\\\baz]], [[zub\]]))
else
eq([[foo/\\bar\\\\baz/zub\]], vim.fs.joinpath([[foo]], [[\\bar\\\\baz]], [[zub\]]))
end
end)
it('strips redundant slashes', function()
if is_os('win') then
eq('foo/bar/baz/zub/', vim.fs.joinpath([[foo//]], [[\\bar\\\\baz]], [[zub\]]))
else
eq('foo/bar/baz/zub/', vim.fs.joinpath([[foo]], [[//bar////baz]], [[zub/]]))
end
end)
end)
describe('normalize()', function()