fix: expand/normalize paths more selectively (#2628)

This commit is contained in:
James Trew
2024-03-19 18:55:27 -04:00
committed by GitHub
parent c816406bd5
commit 3b8399c273
10 changed files with 64 additions and 24 deletions

View File

@@ -5,6 +5,7 @@ local log = require "plenary.log"
local async = require "plenary.async"
local channel = require("plenary.async").control.channel
local utils = require "telescope.utils"
local M = {}
@@ -21,7 +22,7 @@ function AsyncJob.new(opts)
self.stderr = opts.stderr or M.NullPipe()
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,
-- 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

View File

@@ -73,7 +73,7 @@ function histories.History:new(opts)
if conf.history.limit then
obj.limit = conf.history.limit
end
obj.path = vim.fn.expand(conf.history.path)
obj.path = utils.path_expand(conf.history.path)
obj.content = {}
obj.index = 1
obj.cycle_wrap = conf.history.cycle_wrap

View File

@@ -115,12 +115,12 @@ files.live_grep = function(opts)
end
local search_dirs = opts.search_dirs
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)
if search_dirs then
for i, path in ipairs(search_dirs) do
search_dirs[i] = vim.fn.expand(path)
search_dirs[i] = utils.path_expand(path)
end
end
@@ -246,7 +246,7 @@ files.grep_string = function(opts)
end
elseif opts.search_dirs then
for _, path in ipairs(opts.search_dirs) do
table.insert(args, vim.fn.expand(path))
table.insert(args, utils.path_expand(path))
end
end
@@ -299,7 +299,7 @@ files.find_files = function(opts)
if search_dirs then
for k, v in pairs(search_dirs) do
search_dirs[k] = vim.fn.expand(v)
search_dirs[k] = utils.path_expand(v)
end
end
@@ -376,7 +376,7 @@ files.find_files = function(opts)
end
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
opts.cwd = utils.path_expand(opts.cwd)
end
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)
-- 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 lines = vim.api.nvim_buf_get_lines(opts.bufnr, 0, -1, false)

View File

@@ -459,7 +459,7 @@ end
local set_opts_cwd = function(opts)
opts.use_git_root = vim.F.if_nil(opts.use_git_root, true)
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
opts.cwd = utils.path_expand(opts.cwd)
elseif opts.use_file_path then
opts.cwd = current_path_toplevel()
if not opts.cwd then

View File

@@ -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.
--============================================================================= ]]
local utils = require "telescope.utils"
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
-- this would lead to cache misses in the perviewer.
-- 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
return
end

View File

@@ -149,7 +149,7 @@ do
function make_entry.gen_from_file(opts)
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
@@ -310,7 +310,7 @@ do
local display_string = "%s%s%s"
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)
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)
-- bufnr_width + modes + icon + 3 spaces + : + lnum
@@ -1011,7 +1011,7 @@ end
function make_entry.gen_from_ctags(opts)
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 display_items = {

View File

@@ -262,7 +262,7 @@ previewers.file_maker = function(filepath, bufnr, opts)
end
if opts.bufname ~= filepath then
if not vim.in_fast_event() then
filepath = vim.fn.expand(filepath)
filepath = utils.path_expand(filepath)
end
vim.loop.fs_stat(filepath, function(_, stat)
if not stat then

View File

@@ -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 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
local list_dir = (function()
if vim.fn.has "win32" == 1 then
return function(dirname)
return { "cmd.exe", "/c", "dir", vim.fn.expand(dirname) }
return { "cmd.exe", "/c", "dir", utils.path_expand(dirname) }
end
else
return function(dirname)
return { "ls", "-la", vim.fn.expand(dirname) }
return { "ls", "-la", utils.path_expand(dirname) }
end
end
end)()
@@ -55,7 +55,7 @@ local bat_maker = function(filename, lnum, start, finish)
command,
bat_options,
"--",
vim.fn.expand(filename),
utils.path_expand(filename),
}
end
@@ -74,15 +74,15 @@ local cat_maker = function(filename, _, start, _)
if has_less 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
return { "less", "-RS", vim.fn.expand(filename) }
return { "less", "-RS", utils.path_expand(filename) }
end
else
return {
"cat",
"--",
vim.fn.expand(filename),
utils.path_expand(filename),
}
end
end

View File

@@ -15,6 +15,43 @@ local get_status = require("telescope.state").get_status
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()
return Path.path.sep
end
@@ -244,7 +281,7 @@ utils.transform_path = function(opts, path)
if opts.cwd then
cwd = opts.cwd
if not vim.in_fast_event() then
cwd = vim.fn.expand(opts.cwd)
cwd = utils.path_expand(opts.cwd)
end
else
cwd = vim.loop.cwd()

View File

@@ -3,6 +3,7 @@ local make_entry = require "telescope.make_entry"
local previewers = require "telescope.previewers"
local pickers = require "telescope.pickers"
local sorters = require "telescope.sorters"
local utils = require "telescope.utils"
local helpers = {}
@@ -24,7 +25,7 @@ helpers.auto_find_files = function(opts)
end
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
opts.cwd = utils.path_expand(opts.cwd)
end
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)