Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle more edge cases for Windows path escaping #1458

Merged
merged 2 commits into from
May 19, 2024

Conversation

bwpge
Copy link
Contributor

@bwpge bwpge commented May 4, 2024

This PR fixes #1448, among other edge cases that weren't previously handled.

Relevant notes were captured in the discussion for #1448, but the gist is that certain punctuation ([, ], backticks, $, etc.) causes Neovim to drop an escaped path separator on Windows. This requires us to use an additional \ (e.g. X:\[foo]\\\(bar)\baz.txt).

@bwpge
Copy link
Contributor Author

bwpge commented May 4, 2024

For anyone who wants to verify/test the logic, the following script was ran in Neovim with :luafile %:

local dpunc = {
  "()",
  "[]",
  -- "{}",
  "^",
  "&",
  ";",
  "`",
  -- these are left out because this causes exponentially longer runtime.
  -- they should have similar behavior to the above
  -- "!", "#", "$", "%", "+", ",", "-", "=", "@", "_", "~"
}
local fpunc = [[!#$%&'()+,-;=@[]^_`{}~ ]]

-- testing implementation for this function
local function escape_path_for_cmd(path)
  local escaped_path = vim.fn.fnameescape(path)
  if true then -- assume is windows
    local need_extra_esc = path:find("[%[%]`%$~]")
    local esc = need_extra_esc and "\\\\" or "\\"
    escaped_path = escaped_path:gsub("\\[%(%)%^&;]", esc .. "%1")
    if need_extra_esc then
      escaped_path = escaped_path:gsub("\\\\['` ]", "\\%1")
    end
  end
  return escaped_path
end

-- makes a value like `[foo]` from part='foo' and p='[]'
local function make_part(part, p)
  local open = p:sub(1, 1)
  local close = p:sub(2, 2)
  if close == "" then
    close = open
  end
  return (open .. part .. close)
end

-- create nested directories with leading/trailing punctuation
local dirs = {}
for _, p1 in ipairs(dpunc) do
  for _, p2 in ipairs(dpunc) do
    local part1 = make_part("foo", p1)
    local part2 = make_part("bar", p2)
    local path = string.format(".\\tests\\%s\\%s", part1, part2)
    vim.fn.mkdir(path, "p")

    table.insert(dirs, path)
  end
end

local files = { "baz.txt" }
for c in string.gmatch(fpunc, ".") do
  table.insert(files, c .. "baz.txt")
end

-- try to write files with weird path
for _, d in ipairs(dirs) do
  for _, f in ipairs(files) do
    local p = escape_path_for_cmd(d .. "\\" .. f)
    local ok, err = pcall(vim.cmd, "silent w " .. p)
    if not ok then
      print("fail:", p, "->", err)
    end
  end
end

@pysan3
Copy link
Collaborator

pysan3 commented May 6, 2024

Thank you so much for working in this @bwpge !!

Passing this to @cseickel .

@bwpge
Copy link
Contributor Author

bwpge commented May 18, 2024

@pysan3 wanted to ping you on this one.

I'm sure things are a bit hectic with the changeover in responsibilities so no rush, just a bump to keep on the radar :)

@pysan3
Copy link
Collaborator

pysan3 commented May 19, 2024

Thanks mate, I totally forgot this one my bad.

Merging! Thanks for your amazing work.

Copy link
Collaborator

@pysan3 pysan3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! And thanks for the comment to link to the PRs.

@pysan3 pysan3 merged commit 422a899 into nvim-neo-tree:main May 19, 2024
3 checks passed
@bwpge
Copy link
Contributor Author

bwpge commented May 19, 2024

Happy to help, have a good weekend!

@SuperSheykh
Copy link

Don't know why but still not working for me.

@pysan3
Copy link
Collaborator

pysan3 commented May 20, 2024

@SuperSheykh It's not released as a version yet. Are you sure you are on the latest master branch?

@SuperSheykh
Copy link

My bad it actually works fine. Thanks so much guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: Can not open file insde App router with parentheses in its name. (Windows only)
3 participants