fix: expand/normalize paths more selectively (#2628)
This commit is contained in:
@@ -5,6 +5,7 @@ local log = require "plenary.log"
|
|||||||
|
|
||||||
local async = require "plenary.async"
|
local async = require "plenary.async"
|
||||||
local channel = require("plenary.async").control.channel
|
local channel = require("plenary.async").control.channel
|
||||||
|
local utils = require "telescope.utils"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ function AsyncJob.new(opts)
|
|||||||
self.stderr = opts.stderr or M.NullPipe()
|
self.stderr = opts.stderr or M.NullPipe()
|
||||||
|
|
||||||
if opts.cwd and opts.cwd ~= "" then
|
if opts.cwd and opts.cwd ~= "" then
|
||||||
self.uv_opts.cwd = vim.fn.expand(vim.fn.escape(opts.cwd, "$"))
|
self.uv_opts.cwd = utils.path_expand(opts.cwd)
|
||||||
-- this is a "illegal" hack for windows. E.g. If the git command returns `/` rather than `\` as delimiter,
|
-- this is a "illegal" hack for windows. E.g. If the git command returns `/` rather than `\` as delimiter,
|
||||||
-- vim.fn.expand might just end up returning an empty string. Weird
|
-- vim.fn.expand might just end up returning an empty string. Weird
|
||||||
-- Because empty string is not allowed in libuv the job will not spawn. Solution is we just set it to opts.cwd
|
-- Because empty string is not allowed in libuv the job will not spawn. Solution is we just set it to opts.cwd
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ function histories.History:new(opts)
|
|||||||
if conf.history.limit then
|
if conf.history.limit then
|
||||||
obj.limit = conf.history.limit
|
obj.limit = conf.history.limit
|
||||||
end
|
end
|
||||||
obj.path = vim.fn.expand(conf.history.path)
|
obj.path = utils.path_expand(conf.history.path)
|
||||||
obj.content = {}
|
obj.content = {}
|
||||||
obj.index = 1
|
obj.index = 1
|
||||||
obj.cycle_wrap = conf.history.cycle_wrap
|
obj.cycle_wrap = conf.history.cycle_wrap
|
||||||
|
|||||||
@@ -115,12 +115,12 @@ files.live_grep = function(opts)
|
|||||||
end
|
end
|
||||||
local search_dirs = opts.search_dirs
|
local search_dirs = opts.search_dirs
|
||||||
local grep_open_files = opts.grep_open_files
|
local grep_open_files = opts.grep_open_files
|
||||||
opts.cwd = opts.cwd and vim.fn.expand(opts.cwd) or vim.loop.cwd()
|
opts.cwd = opts.cwd and utils.path_expand(opts.cwd) or vim.loop.cwd()
|
||||||
|
|
||||||
local filelist = get_open_filelist(grep_open_files, opts.cwd)
|
local filelist = get_open_filelist(grep_open_files, opts.cwd)
|
||||||
if search_dirs then
|
if search_dirs then
|
||||||
for i, path in ipairs(search_dirs) do
|
for i, path in ipairs(search_dirs) do
|
||||||
search_dirs[i] = vim.fn.expand(path)
|
search_dirs[i] = utils.path_expand(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ files.grep_string = function(opts)
|
|||||||
end
|
end
|
||||||
elseif opts.search_dirs then
|
elseif opts.search_dirs then
|
||||||
for _, path in ipairs(opts.search_dirs) do
|
for _, path in ipairs(opts.search_dirs) do
|
||||||
table.insert(args, vim.fn.expand(path))
|
table.insert(args, utils.path_expand(path))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ files.find_files = function(opts)
|
|||||||
|
|
||||||
if search_dirs then
|
if search_dirs then
|
||||||
for k, v in pairs(search_dirs) do
|
for k, v in pairs(search_dirs) do
|
||||||
search_dirs[k] = vim.fn.expand(v)
|
search_dirs[k] = utils.path_expand(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ files.find_files = function(opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if opts.cwd then
|
if opts.cwd then
|
||||||
opts.cwd = vim.fn.expand(opts.cwd)
|
opts.cwd = utils.path_expand(opts.cwd)
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
|
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
|
||||||
@@ -466,7 +466,7 @@ end
|
|||||||
|
|
||||||
files.current_buffer_fuzzy_find = function(opts)
|
files.current_buffer_fuzzy_find = function(opts)
|
||||||
-- All actions are on the current buffer
|
-- All actions are on the current buffer
|
||||||
local filename = vim.fn.expand(vim.api.nvim_buf_get_name(opts.bufnr))
|
local filename = vim.api.nvim_buf_get_name(opts.bufnr)
|
||||||
local filetype = vim.api.nvim_buf_get_option(opts.bufnr, "filetype")
|
local filetype = vim.api.nvim_buf_get_option(opts.bufnr, "filetype")
|
||||||
|
|
||||||
local lines = vim.api.nvim_buf_get_lines(opts.bufnr, 0, -1, false)
|
local lines = vim.api.nvim_buf_get_lines(opts.bufnr, 0, -1, false)
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ end
|
|||||||
local set_opts_cwd = function(opts)
|
local set_opts_cwd = function(opts)
|
||||||
opts.use_git_root = vim.F.if_nil(opts.use_git_root, true)
|
opts.use_git_root = vim.F.if_nil(opts.use_git_root, true)
|
||||||
if opts.cwd then
|
if opts.cwd then
|
||||||
opts.cwd = vim.fn.expand(opts.cwd)
|
opts.cwd = utils.path_expand(opts.cwd)
|
||||||
elseif opts.use_file_path then
|
elseif opts.use_file_path then
|
||||||
opts.cwd = current_path_toplevel()
|
opts.cwd = current_path_toplevel()
|
||||||
if not opts.cwd then
|
if not opts.cwd then
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ This file is still WIP, so expect some changes if you're trying to consume these
|
|||||||
This will provide standard mechanism for accessing information from an entry.
|
This will provide standard mechanism for accessing information from an entry.
|
||||||
|
|
||||||
--============================================================================= ]]
|
--============================================================================= ]]
|
||||||
|
local utils = require "telescope.utils"
|
||||||
|
|
||||||
local from_entry = {}
|
local from_entry = {}
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ function from_entry.path(entry, validate, escape)
|
|||||||
-- TODO(conni2461): we are not going to return the expanded path because
|
-- TODO(conni2461): we are not going to return the expanded path because
|
||||||
-- this would lead to cache misses in the perviewer.
|
-- this would lead to cache misses in the perviewer.
|
||||||
-- Requires overall refactoring in previewer interface
|
-- Requires overall refactoring in previewer interface
|
||||||
local expanded = vim.fn.expand(vim.fn.escape(path, "$?*[]"))
|
local expanded = utils.path_expand(path)
|
||||||
if (vim.fn.filereadable(expanded) + vim.fn.isdirectory(expanded)) == 0 then
|
if (vim.fn.filereadable(expanded) + vim.fn.isdirectory(expanded)) == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ do
|
|||||||
function make_entry.gen_from_file(opts)
|
function make_entry.gen_from_file(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
local cwd = vim.fn.expand(opts.cwd or vim.loop.cwd())
|
local cwd = utils.path_expand(opts.cwd or vim.loop.cwd())
|
||||||
|
|
||||||
local disable_devicons = opts.disable_devicons
|
local disable_devicons = opts.disable_devicons
|
||||||
|
|
||||||
@@ -310,7 +310,7 @@ do
|
|||||||
local display_string = "%s%s%s"
|
local display_string = "%s%s%s"
|
||||||
|
|
||||||
mt_vimgrep_entry = {
|
mt_vimgrep_entry = {
|
||||||
cwd = vim.fn.expand(opts.cwd or vim.loop.cwd()),
|
cwd = utils.path_expand(opts.cwd or vim.loop.cwd()),
|
||||||
|
|
||||||
display = function(entry)
|
display = function(entry)
|
||||||
local display_filename = utils.transform_path(opts, entry.filename)
|
local display_filename = utils.transform_path(opts, entry.filename)
|
||||||
@@ -592,7 +592,7 @@ function make_entry.gen_from_buffer(opts)
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local cwd = vim.fn.expand(opts.cwd or vim.loop.cwd())
|
local cwd = utils.path_expand(opts.cwd or vim.loop.cwd())
|
||||||
|
|
||||||
local make_display = function(entry)
|
local make_display = function(entry)
|
||||||
-- bufnr_width + modes + icon + 3 spaces + : + lnum
|
-- bufnr_width + modes + icon + 3 spaces + : + lnum
|
||||||
@@ -1011,7 +1011,7 @@ end
|
|||||||
function make_entry.gen_from_ctags(opts)
|
function make_entry.gen_from_ctags(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
local cwd = vim.fn.expand(opts.cwd or vim.loop.cwd())
|
local cwd = utils.path_expand(opts.cwd or vim.loop.cwd())
|
||||||
local current_file = Path:new(vim.api.nvim_buf_get_name(opts.bufnr)):normalize(cwd)
|
local current_file = Path:new(vim.api.nvim_buf_get_name(opts.bufnr)):normalize(cwd)
|
||||||
|
|
||||||
local display_items = {
|
local display_items = {
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ previewers.file_maker = function(filepath, bufnr, opts)
|
|||||||
end
|
end
|
||||||
if opts.bufname ~= filepath then
|
if opts.bufname ~= filepath then
|
||||||
if not vim.in_fast_event() then
|
if not vim.in_fast_event() then
|
||||||
filepath = vim.fn.expand(filepath)
|
filepath = utils.path_expand(filepath)
|
||||||
end
|
end
|
||||||
vim.loop.fs_stat(filepath, function(_, stat)
|
vim.loop.fs_stat(filepath, function(_, stat)
|
||||||
if not stat then
|
if not stat then
|
||||||
|
|||||||
@@ -13,17 +13,17 @@ local bat_options = { "--style=plain", "--color=always", "--paging=always" }
|
|||||||
local has_less = (vim.fn.executable "less" == 1) and conf.use_less
|
local has_less = (vim.fn.executable "less" == 1) and conf.use_less
|
||||||
|
|
||||||
local get_file_stat = function(filename)
|
local get_file_stat = function(filename)
|
||||||
return vim.loop.fs_stat(vim.fn.expand(filename)) or {}
|
return vim.loop.fs_stat(utils.path_expand(filename)) or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local list_dir = (function()
|
local list_dir = (function()
|
||||||
if vim.fn.has "win32" == 1 then
|
if vim.fn.has "win32" == 1 then
|
||||||
return function(dirname)
|
return function(dirname)
|
||||||
return { "cmd.exe", "/c", "dir", vim.fn.expand(dirname) }
|
return { "cmd.exe", "/c", "dir", utils.path_expand(dirname) }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return function(dirname)
|
return function(dirname)
|
||||||
return { "ls", "-la", vim.fn.expand(dirname) }
|
return { "ls", "-la", utils.path_expand(dirname) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
@@ -55,7 +55,7 @@ local bat_maker = function(filename, lnum, start, finish)
|
|||||||
command,
|
command,
|
||||||
bat_options,
|
bat_options,
|
||||||
"--",
|
"--",
|
||||||
vim.fn.expand(filename),
|
utils.path_expand(filename),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -74,15 +74,15 @@ local cat_maker = function(filename, _, start, _)
|
|||||||
|
|
||||||
if has_less then
|
if has_less then
|
||||||
if start then
|
if start then
|
||||||
return { "less", "-RS", string.format("+%s", start), vim.fn.expand(filename) }
|
return { "less", "-RS", string.format("+%s", start), utils.path_expand(filename) }
|
||||||
else
|
else
|
||||||
return { "less", "-RS", vim.fn.expand(filename) }
|
return { "less", "-RS", utils.path_expand(filename) }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return {
|
return {
|
||||||
"cat",
|
"cat",
|
||||||
"--",
|
"--",
|
||||||
vim.fn.expand(filename),
|
utils.path_expand(filename),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,6 +15,43 @@ local get_status = require("telescope.state").get_status
|
|||||||
|
|
||||||
local utils = {}
|
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
|
||||||
|
---@param path string
|
||||||
|
---@return string
|
||||||
|
local function path_normalize(path)
|
||||||
|
vim.validate {
|
||||||
|
path = { path, { "string" } },
|
||||||
|
}
|
||||||
|
|
||||||
|
if path:sub(1, 1) == "~" then
|
||||||
|
local home = vim.loop.os_homedir() or "~"
|
||||||
|
if home:sub(-1) == "\\" or home:sub(-1) == "/" then
|
||||||
|
home = home:sub(1, -2)
|
||||||
|
end
|
||||||
|
path = home .. path:sub(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
path = path:gsub("%$([%w_]+)", vim.loop.os_getenv)
|
||||||
|
path = path:gsub("\\", "/"):gsub("/+", "/")
|
||||||
|
if iswin and path:match "^%w:/$" then
|
||||||
|
return path
|
||||||
|
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()
|
utils.get_separator = function()
|
||||||
return Path.path.sep
|
return Path.path.sep
|
||||||
end
|
end
|
||||||
@@ -244,7 +281,7 @@ utils.transform_path = function(opts, path)
|
|||||||
if opts.cwd then
|
if opts.cwd then
|
||||||
cwd = opts.cwd
|
cwd = opts.cwd
|
||||||
if not vim.in_fast_event() then
|
if not vim.in_fast_event() then
|
||||||
cwd = vim.fn.expand(opts.cwd)
|
cwd = utils.path_expand(opts.cwd)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
cwd = vim.loop.cwd()
|
cwd = vim.loop.cwd()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ local make_entry = require "telescope.make_entry"
|
|||||||
local previewers = require "telescope.previewers"
|
local previewers = require "telescope.previewers"
|
||||||
local pickers = require "telescope.pickers"
|
local pickers = require "telescope.pickers"
|
||||||
local sorters = require "telescope.sorters"
|
local sorters = require "telescope.sorters"
|
||||||
|
local utils = require "telescope.utils"
|
||||||
|
|
||||||
local helpers = {}
|
local helpers = {}
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ helpers.auto_find_files = function(opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if opts.cwd then
|
if opts.cwd then
|
||||||
opts.cwd = vim.fn.expand(opts.cwd)
|
opts.cwd = utils.path_expand(opts.cwd)
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
|
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
|
||||||
|
|||||||
Reference in New Issue
Block a user