WIP: properly escape paths in Windows

Still not working with $ (try a file named a$PATH.txt).
:edit a$PATH.txt will expand the variable
:edit a\$PATH.txt will treat it as a path separator, so a/$PATH.txt
This commit is contained in:
Steven Arcangeli 2023-11-04 08:43:03 -07:00
parent 2e6996b075
commit 0cff2447b5
2 changed files with 32 additions and 22 deletions

View file

@ -423,6 +423,7 @@ end
M.select = function(opts, callback) M.select = function(opts, callback)
local cache = require("oil.cache") local cache = require("oil.cache")
local config = require("oil.config") local config = require("oil.config")
local fs = require("oil.fs")
opts = vim.tbl_extend("keep", opts or {}, {}) opts = vim.tbl_extend("keep", opts or {}, {})
local function finish(err) local function finish(err)
if err then if err then
@ -527,12 +528,12 @@ M.select = function(opts, callback)
local child = dir .. entry.name local child = dir .. entry.name
local url = scheme .. child local url = scheme .. child
local is_directory = entry.type == "directory" local is_directory = entry.type == "directory"
or ( or (
entry.type == "link" entry.type == "link"
and entry.meta and entry.meta
and entry.meta.link_stat and entry.meta.link_stat
and entry.meta.link_stat.type == "directory" and entry.meta.link_stat.type == "directory"
) )
if is_directory then if is_directory then
url = url .. "/" url = url .. "/"
-- If this is a new directory BUT we think we already have an entry with this name, disallow -- If this is a new directory BUT we think we already have an entry with this name, disallow
@ -558,9 +559,11 @@ M.select = function(opts, callback)
end end
end end
print("url", url, "entry", entry.name)
-- Normalize the url before opening to prevent needing to rename them inside the BufReadCmd -- Normalize the url before opening to prevent needing to rename them inside the BufReadCmd
-- Renaming buffers during opening can lead to missed autocmds -- Renaming buffers during opening can lead to missed autocmds
get_edit_path(function(normalized_url) get_edit_path(function(normalized_url)
print("Normalized url", normalized_url)
local mods = { local mods = {
vertical = opts.vertical, vertical = opts.vertical,
horizontal = opts.horizontal, horizontal = opts.horizontal,
@ -569,11 +572,14 @@ M.select = function(opts, callback)
emsg_silent = true, emsg_silent = true,
} }
-- If we're editing a file on disk, shorten the path prior to :edit so the -- If we're editing a file on disk, shorten the path prior to :edit so the
-- display name will show up shortened -- display name will show up shortened.
if adapter.name == "files" and not util.parse_url(normalized_url) then -- Don't do this on Windows, where ~/home/path.txt doesn't work
if adapter.name == "files" and not util.parse_url(normalized_url) and not fs.is_windows then
normalized_url = require("oil.fs").shorten_path(normalized_url) normalized_url = require("oil.fs").shorten_path(normalized_url)
print("Shortened", normalized_url)
end end
local filename = util.escape_filename(normalized_url) local filename = util.escape_filename(normalized_url)
print("Escaped", filename)
-- If we're previewing a file that hasn't been opened yet, make sure it gets deleted after we -- If we're previewing a file that hasn't been opened yet, make sure it gets deleted after we
-- close the window -- close the window
@ -617,9 +623,9 @@ M.select = function(opts, callback)
return finish(err) return finish(err)
end end
if if
opts.close opts.close
and vim.api.nvim_win_is_valid(prev_win) and vim.api.nvim_win_is_valid(prev_win)
and prev_win ~= vim.api.nvim_get_current_win() and prev_win ~= vim.api.nvim_get_current_win()
then then
vim.api.nvim_win_call(prev_win, function() vim.api.nvim_win_call(prev_win, function()
M.close() M.close()
@ -752,7 +758,7 @@ local function restore_alt_buf()
-- If we are editing the same buffer that we started oil from, set the alternate to be -- If we are editing the same buffer that we started oil from, set the alternate to be
-- what it was before we opened oil -- what it was before we opened oil
local has_orig_alt, alt_buffer = local has_orig_alt, alt_buffer =
pcall(vim.api.nvim_win_get_var, 0, "oil_original_alternate") pcall(vim.api.nvim_win_get_var, 0, "oil_original_alternate")
if has_orig_alt and vim.api.nvim_buf_is_valid(alt_buffer) then if has_orig_alt and vim.api.nvim_buf_is_valid(alt_buffer) then
vim.fn.setreg("#", alt_buffer) vim.fn.setreg("#", alt_buffer)
end end

View file

@ -1,5 +1,6 @@
local config = require("oil.config") local config = require("oil.config")
local constants = require("oil.constants") local constants = require("oil.constants")
local fs = require("oil.fs")
local M = {} local M = {}
@ -19,8 +20,11 @@ end
---@param filename string ---@param filename string
---@return string ---@return string
M.escape_filename = function(filename) M.escape_filename = function(filename)
local ret = filename:gsub("([%%#$])", "\\%1") if fs.is_windows then
return ret filename = filename:gsub("\\", "/")
filename = filename:gsub("([$])", "\\%1")
end
return vim.fn.fnameescape(filename)
end end
local _url_escape_chars = { local _url_escape_chars = {
@ -408,7 +412,7 @@ M.add_title_to_win = function(winid, opts)
end end
local new_title = get_title() local new_title = get_title()
local new_width = local new_width =
math.min(vim.api.nvim_win_get_width(winid) - 4, 2 + vim.api.nvim_strwidth(new_title)) math.min(vim.api.nvim_win_get_width(winid) - 4, 2 + vim.api.nvim_strwidth(new_title))
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, { " " .. new_title .. " " }) vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, { " " .. new_title .. " " })
vim.bo[bufnr].modified = false vim.bo[bufnr].modified = false
vim.api.nvim_win_set_width(title_winid, new_width) vim.api.nvim_win_set_width(title_winid, new_width)
@ -462,13 +466,13 @@ M.get_adapter_for_action = function(action)
local dest_adapter = assert(config.get_adapter_by_scheme(action.dest_url)) local dest_adapter = assert(config.get_adapter_by_scheme(action.dest_url))
if adapter ~= dest_adapter then if adapter ~= dest_adapter then
if if
adapter.supported_adapters_for_copy adapter.supported_adapters_for_copy
and adapter.supported_adapters_for_copy[dest_adapter.name] and adapter.supported_adapters_for_copy[dest_adapter.name]
then then
return adapter return adapter
elseif elseif
dest_adapter.supported_adapters_for_copy dest_adapter.supported_adapters_for_copy
and dest_adapter.supported_adapters_for_copy[adapter.name] and dest_adapter.supported_adapters_for_copy[adapter.name]
then then
return dest_adapter return dest_adapter
else else
@ -648,9 +652,9 @@ end
---@return nil|integer ---@return nil|integer
M.buf_get_win = function(bufnr, preferred_win) M.buf_get_win = function(bufnr, preferred_win)
if if
preferred_win preferred_win
and vim.api.nvim_win_is_valid(preferred_win) and vim.api.nvim_win_is_valid(preferred_win)
and vim.api.nvim_win_get_buf(preferred_win) == bufnr and vim.api.nvim_win_get_buf(preferred_win) == bufnr
then then
return preferred_win return preferred_win
end end