mirror of
https://github.com/zoriya/telescope.nvim.git
synced 2026-08-16 02:45:09 +00:00
fix(utils.path_expand): improve windows support (#2999)
In order to maintain plenary compatibility (for now, and slightly for
other edgecase reasons), avoid converting backslashes to forward
slashes.
(cherry picked from commit 1e59188575)
This commit is contained in:
+14
-3
@@ -2262,9 +2262,20 @@ UTILS *telescope.utils*
|
||||
Utilities for writing telescope pickers
|
||||
|
||||
utils.path_expand({path}) *telescope.utils.path_expand()*
|
||||
Selective `expand`. `vim.fn.expand` is overly aggressive, sometimes
|
||||
expanding valid absolute paths into non-existent paths or straight up
|
||||
erroring
|
||||
Hybrid of `vim.fn.expand()` and custom `vim.fs.normalize()`
|
||||
|
||||
Paths starting with '%', '#' or '<' are expanded with `vim.fn.expand()`.
|
||||
Otherwise avoids using `vim.fn.expand()` due to its overly aggressive
|
||||
expansion behavior which can sometimes lead to errors or the creation of
|
||||
non-existent paths when dealing with valid absolute paths.
|
||||
|
||||
Other paths will have '~' and environment variables expanded. Unlike
|
||||
`vim.fs.normalize()`, backslashes are preserved. This has better
|
||||
compatibility with `plenary.path` and also avoids mangling valid Unix paths
|
||||
with literal backslashes.
|
||||
|
||||
Trailing slashes are trimmed. With the exception of root paths. eg. `/` on
|
||||
Unix or `C:\` on Windows
|
||||
|
||||
|
||||
|
||||
|
||||
+28
-16
@@ -17,15 +17,32 @@ local utils = {}
|
||||
|
||||
local iswin = vim.loop.os_uname().sysname == "Windows_NT"
|
||||
|
||||
--- `vim.fs.normalize` co-opted for 0.1.x (neovim 0.7) compat
|
||||
--- TODO: get rid of this and use `vim.fs.normalize` directly for future releases
|
||||
--- Hybrid of `vim.fn.expand()` and custom `vim.fs.normalize()`
|
||||
---
|
||||
--- Paths starting with '%', '#' or '<' are expanded with `vim.fn.expand()`.
|
||||
--- Otherwise avoids using `vim.fn.expand()` due to its overly aggressive
|
||||
--- expansion behavior which can sometimes lead to errors or the creation of
|
||||
--- non-existent paths when dealing with valid absolute paths.
|
||||
---
|
||||
--- Other paths will have '~' and environment variables expanded.
|
||||
--- Unlike `vim.fs.normalize()`, backslashes are preserved. This has better
|
||||
--- compatibility with `plenary.path` and also avoids mangling valid Unix paths
|
||||
--- with literal backslashes.
|
||||
---
|
||||
--- Trailing slashes are trimmed. With the exception of root paths.
|
||||
--- eg. `/` on Unix or `C:\` on Windows
|
||||
---
|
||||
---@param path string
|
||||
---@return string
|
||||
local function path_normalize(path)
|
||||
utils.path_expand = function(path)
|
||||
vim.validate {
|
||||
path = { path, { "string" } },
|
||||
}
|
||||
|
||||
if path:match "^[%%#<]" then
|
||||
path = vim.fn.expand(path)
|
||||
end
|
||||
|
||||
if path:sub(1, 1) == "~" then
|
||||
local home = vim.loop.os_homedir() or "~"
|
||||
if home:sub(-1) == "\\" or home:sub(-1) == "/" then
|
||||
@@ -35,23 +52,18 @@ local function path_normalize(path)
|
||||
end
|
||||
|
||||
path = path:gsub("%$([%w_]+)", vim.loop.os_getenv)
|
||||
path = path:gsub("\\", "/"):gsub("/+", "/")
|
||||
if iswin and path:match "^%w:/$" then
|
||||
return path
|
||||
path = path:gsub("/+", "/")
|
||||
if iswin then
|
||||
path = path:gsub("\\+", "\\")
|
||||
if path:match "^%w:\\$" then
|
||||
return path
|
||||
else
|
||||
return (path:gsub("(.)\\$", "%1"))
|
||||
end
|
||||
end
|
||||
return (path:gsub("(.)/$", "%1"))
|
||||
end
|
||||
|
||||
--- Selective `expand`.
|
||||
--- `vim.fn.expand` is overly aggressive, sometimes expanding valid absolute paths into
|
||||
--- non-existent paths or straight up erroring
|
||||
---
|
||||
---@param path string
|
||||
---@return string
|
||||
utils.path_expand = function(path)
|
||||
return path:match "^[%%#<]" and vim.fn.expand(path) or path_normalize(path)
|
||||
end
|
||||
|
||||
utils.get_separator = function()
|
||||
return Path.path.sep
|
||||
end
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
local utils = require "telescope.utils"
|
||||
|
||||
describe("path_expand()", function()
|
||||
it("removes trailing /", function()
|
||||
assert.is.equal("/home/user", utils.path_expand "/home/user/")
|
||||
end)
|
||||
|
||||
it("works with /", function()
|
||||
assert.is.equal("/", utils.path_expand "/")
|
||||
end)
|
||||
|
||||
it("works with ~", function()
|
||||
assert.is.equal(vim.loop.os_homedir() .. "/src/foo", utils.path_expand "~/src/foo")
|
||||
end)
|
||||
|
||||
it("handles duplicate /", function()
|
||||
assert.is.equal("/home/user", utils.path_expand "/home///user")
|
||||
end)
|
||||
|
||||
it("preserves fake whitespace characters and whitespace", function()
|
||||
local path_space = "/home/user/hello world"
|
||||
assert.is.equal(path_space, utils.path_expand(path_space))
|
||||
local path_newline = [[/home/user/hello\nworld]]
|
||||
assert.is.equal(path_newline, utils.path_expand(path_newline))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("is_uri", function()
|
||||
describe("detects valid uris", function()
|
||||
local uris = {
|
||||
|
||||
Reference in New Issue
Block a user