-
Notifications
You must be signed in to change notification settings - Fork 251
fix: improve path escaping for commands on Windows #1353
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
Conversation
@pysan3 Can you review this? I know we have planned to incorporate pathlib but this is probably a good patch while we wait for that. Besides, making that library makes you the resident expert on path issues, and it would also be good for you to know about this bug to make sure it is handled in pathlib. |
@bwpge Could you test it with Unfortunately I don't have a Windows machine at hand and I can't test it right now. This might bring what you want, but we need to make sure that this doesn't start breaking things in other places. If |
@bwpge Could you also test simply passing the path to
|
@pysan3 sure thing, I am headed to bed but I will test these in the morning and post findings. And I totally understand the apprehension, this is a big change so we should take extra time to explore its effects. |
I tried a couple things just in command mode to avoid any extra complications with the plugin. To setup:
Output of
Attempting to set working directory with:
All cause the same error, I believe due to the double quotes introduced by
Just to note from the
I could be wrong but I think this behavior comes from |
Thank you very much @bwpge ! So after all my ideas are not working so doing I'll remember this issue and will try to fix it in the rewrite but this is a good fix for now. |
Just adding some extra notes someone can reference when tackling this in a rewrite:
|
@pysan3 I apologize to hit you with so many pings, but I just stumbled across another Windows-path issue The way neo-tree.nvim/lua/neo-tree/utils/init.lua Line 763 in f3941c5
Unfortunately this affects the rendered path at the top of Neotree -- drive letters will be lowercase, which is a bit ugly. I suppose that could be cleaned up in the UI/renderer (just transform the string before rendering without changing the node path), but would require more changes.
EDIT: Never mind, that change breaks git status colors in filesystem view. I'll open an issue to track separately. |
Could you instead capitalize the input from lsp? That's what is done in
|
I've been playing with a simple solution this morning/afternoon to avoid touching too many things, I think it's a "good enough" solution without touching too much of the plugin behavior. I've added bwpge@8afd209 to this PR so you can see what I've changed (the explanation in a comment was getting too long and hard to follow) -- if we don't like it I can revert. Basically we just change how we try to index into The benefit of this solution is it catches other case-sensitivity issues Windows people might see since Windows doesn't treat different casing as different files. Also Linux/macOS users wouldn't have impact from this change, the function would just fall through and basically only pay the cost of two |
Amazing work. I'll remember to revisit this after I manage to fully move to pathlib. (I'm not gonna say a due date here, as it might be forever lol).
|
LGTM @cseickel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bwpge Looks like we unfortunately hit an edge case: #1382 These are the chars what will be matched with -- The entire list [[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]]
-- This is from a google search; What characters are forbidden in Windows and Linux directory names?
-- < (less than)
-- > (greater than)
-- : (colon - sometimes works, but is actually NTFS Alternate Data Streams)
-- " (double quote)
-- / (forward slash)
-- \ (backslash)
-- | (vertical bar or pipe)
-- ? (question mark)
-- * (asterisk)
-- I deleted those from the list. But added `<Space>`.
local puncts = [[!#$%&'()+,-;=@[]^_`{}~ ]]
-- Please remove characters that don't need to be escaped from the list.
-- Here's an easy way to test.
for char in string.gmatch(puncts, ".") do
vim.cmd.edit(string.format([[.\tests\%sfoo.txt]], char))
end
-- See the buffer list `:ls!` and if no need to escape, buffer name will be `.\tests\_foo.txt`
-- but if it needs to be escaped, buffer name will be like `.\tests'foo.txt` (outside tests dir). (tests-foo altogether is the file name). From my experiments, I see the following letters NOT working i.e. needs another backslash to escape. Is it the same for your case as well? Not Working: #%&'();^` and <Space>
Working: !$+,-=@[]_{}~\ |
@pysan3 here's the raw output from
Looks like the following is our list:
I'll work on fixing this today and do some testing to make sure we don't have any regressions. |
@bwpge When you are done, could you change the regarding code using escaped_path = vim.fn.escape(escaped_path, puncts) |
Just to sanity check, my intent would be to do something like this: M.escape_path_for_cmd = function(path)
-- this is working on unix paths, don't touch for now
local escaped_path = vim.fn.fnameescape(path)
if M.is_windows then
local puncts = [[!$+,-=@[]_{}~]]
-- do extra windows escapes
end
return escaped_path
end |
Yes and Under Please double check if it actually works tho. Thanks in advance. |
Sorry meant to send this earlier: Regarding Will post when I have more info to share. |
Oh shoot. You are right. I guess we need some kind of a complex regex. |
This PR changes the handling of paths on Windows systems to address a few open issues. This builds on the work originally introduced in #1023 (to address #889). Realistically, this is another attempt to deal with a (neo)vim issue as mentioned in neovim/neovim#3912 (no real update since 2015).
I've added some doc comments to help with maintainability, but if it's too verbose I'm happy to edit.
I've run tests locally and all pass, but I would really love to add regression tests for path escaping so we don't run into more problems in the future. However, I'm having trouble figuring out how to deal with platform-specific behavior of
vim.fn.fnameescape
(e.g., if you run tests on WSL or macOS, you won't get Windows path escaping). If anyone has any ideas for adding tests, I'm definitely all ears. Ideally, we would test both Windows and Unix-style path escaping regardless of the platform running the tests.This PR fixes the following issues I could find:
set_root
#1352 (opened by me when testing this fix)This also fixes the following external issues:
The following issues may be fixed, but I have not confirmed:
I think there are definitely more issues that could be addressed by this, but I'm reaching my issue-searching capability limits :)
I feel like I have a good grasp of how paths are being used in this limited capacity (such as with
set_cwd
andopen_file
) but I know this change could have cascading effects because it's modifying the input to commands like:cd
,:b
,:vs
, etc. If anyone sees anything problematic with more context of the full codebase, I'm happy to discuss.