-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Fixes issue #1344 - windows folder casing issue #1346
Conversation
…alidArgumentsError: <file> should be under <path>
…alidArgumentsError: <file> should be under <path>
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.
shouldn't we implement similar logic for renaming, s:TreeDirNode._glob
and other parts comparing paths?
It's already been done to some extent but there are so many problems with path casing on windows.
We do something similar for s:Path.equals
like this:
function! s:Path.equals(path)
if nerdtree#runningWindows()
return self.str() ==? a:path.str()
else
return self.str() ==# a:path.str()
endif
endfunction
in vim ==? means ignoring the case so there is no need for lower function calls
To sum up I suggest changing the lower function call to ==? instead, and adding similar implementations for other sections that work with path |
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.
Review comments from @rzvxa seem like they do need addressing. Comparison operators should always use the specific case (in)sensitive ones, and all path comparisons should be consistent.
@dangibson Hello, Do you want to work with me to make a new flag called I'm also re-requesting @alerque's review as my point earlier about the use of case insensitive equality check over using the If you don't have time for it or you are not interested anymore I understand, But if you have any objection to this way of doing it or if you want it to be done some other way let's talk about it. Thank you for your time, I'm sorry for my long comment. |
I didn't know about ==? which is why I used tolower. I use neovim and write in lua - I don't know vimscript at all. I fumbled just enough to get it working for me. |
@dangibson I totally understand. |
How do you make a directory case sensitive on ntfs? |
Instead of testing a flag, what about this: path.vim: Then my change would become: I'm not sure why "pAth/TO/foo.BAR" and "path/to/foo.bar" would not be equal when using ==? |
You can do it with something like this: I wanted to create a utility function to pass the path to it and find out if it's case sensitive or not, When I got to implementing it and thinking about the ways I can achieve this I found that the easiest way to do so is to do something like this: function! nerdtree#isPathCaseSensitive(path) abort
if nerdtree#runningWindows()
" This is pseudo-code, I'm sure & won't work in cmd(and almost everything else)
return system('type nul > FOO.BAR && type nul > foo.bar')
elseif executable('touch')
return system('touch foo.bar && touch FOO.BAR')
else
call nerdtree#echoWarning('Not implemented fallback to case sensitive')
return 1
endif
endfunction
This utility can get a path and check if the directory containing this file is case-sensitive or not. if !nerdtree#isPathCaseSensitive(path1) && !nerdtree#isPathCaseSensitive(path2) && path1 ==? path2
" same path
endif The second path could very well be |
Oh, I forgot about the last part, I was indeed hallucinating when I was writing that code, I couldn't get it to work maybe I just had a typo in my variable name when I wrote the original piece of code. I've just written a simple test case for it and it did pass. |
I think if we use the s:Path.isPathCaseSensitive function then for now we could assume Windows is case-insensitive since I really don't think anyone would set a folder to being case sensitive. Even if they did, it would only be an issue if they have two folders with the same name but different case. I think that would be a very rare edge case, which they could still get around by manually setting g:NERDTreeInsensitiveFS to 0. |
I agree about the fact that we should call the path.isCaseSensitive, This way we can extend upon it in the future and use it in many places. But other than having it as a method in the path class itself, We could have a global utility function that can be also behind the path.isCaseSensitive method so we can check paths for being case-sensitive without the need for creating a path object for them(for keeping the overhead in excess checks low). But for the other part of your comment, I should say I'm not really a big fan of assuming things when we are not sure about it being a fact. I would also like to add that we can always deprecate a flag, But I personally won't use a tool twice if it destroys my work. |
NTFS is insensitive by default. Therefore, NERDTree should also be insensitive on NTFS by default. If someone is going and changing NTFS to being sensitive then they can go and change their default in NERDTree also. I never knew about the (m) command to move/rename in nerdtree. Perhaps for moving / renaming then it could be case sensitive by default while being case insensitive for other operations (like my original issue). If they move/rename then nerdtree could see if they've specified a value for the flag and if they haven't, give a error message then and not do the operation. So there'd be 3 values for the flag - case-sensitive, case-insensitive, and not set. If the value is not set then non-destructive operations (like my original issue) would use whatever is default for the os, while destructive operations like move/rename would give an error with a helpful message about how to set the value. |
You have a good point and I like this approach, Do you want to implement it? 3 value flag seems alright to me, Some actions can fall back to case sensitive for safety and warn users to set this flag for more clarity and enhanced experience. |
You seem to know more about vimscript and nerdtree than I do so I think it's probably better if you do it. |
I'm no Vim script expert and I enjoy writing Lua like any other sane person out there. But I like to have the freedom to jump back to Vim if I find future Neovim path conflicts with my day-to-day goals. I switched to Neovim only because of my day job, I work in the game industry and I have to use Windows machines pretty often. I've found that Vim has some rendering artifacts when used on Windows and in those days vim development was pretty orthodox and revolved around the sole maintainer so I didn't bother fixing it and switched to Neovim. I've never been able to use NERDTree in huge monolith projects and as the technical lead of many projects, I'm ashamed to confess I've aggregated for the adoption of microservices so it plays nicely with my Vim setup. So sad to see this diversion between 2 branches. I would've liked to see more compatibility between them but it is totally understandable. TL;DR I'll work on this change in my own PR after you review my code and we decide to move on with merging it I would love to see you adopt it into this PR for unification. I prefer that you get full credit for this PR since only a minimal change to the current code you wrote is necessary. |
@dangibson if nerdtree#runningWindows()
if tolower(self.pathSegments[i]) !=# tolower(a:parent.pathSegments[i])
return 0
endif
else
if self.pathSegments[i] !=# a:parent.pathSegments[i]
return 0
endif
endif into this if nerdtree#pathEquals(self.pathSegments[i], a:parent.pathSegments[i]) or if you want to do some custom checks manually for example this: if nerdtree#runningWindows()
if stridx(tolower(a:path.str()), tolower(self.path.str()), 0) ==# -1
return {}
endif
else
if stridx(a:path.str(), self.path.str(), 0) ==# -1
return {}
endif
endif
can be turned into this if nerdtree#caseSensitiveFS()
if stridx(a:path.str(), self.path.str(), 0) ==# -1
return {}
endif
else
if stridx(tolower(a:path.str()), tolower(self.path.str()), 0) ==# -1
return {}
endif
endif Let me know what you think about it, also if you find any problem both in code and/or user experience let me know. |
It can potentially fix #1241 |
May or may not fix #1329 but if it doesn't now that we are tackling this problem we should go for this one too. |
if self.pathSegments[i] !=# a:parent.pathSegments[i] | ||
return 0 | ||
if nerdtree#runningWindows() | ||
if tolower(self.pathSegments[i]) !=# tolower(a:parent.pathSegments[i]) |
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.
Unless I read through the discussion comments too quickly, this still needs addressing. Using tolower()
should be unnecessary if explicitly using a case-insensitive matching operator.
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.
yes, I'm sorry my example was wrong.
something like this should replace the old version.
if !nerdtree#caseSensitiveFS()
if self.pathSegments[i] !=? a:parent.pathSegments[i]
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.
@dangibson
Hello sir,
Do you have any interest in completing this PR? If not I can create a PR containing your commits so I can add the requested changes while keeping the original author of the commits. But to be honest I would love it if you do these changes yourself, Since you already familiarized yourself with the codebase it can be an awesome thing to have somebody else contributing to the project.
If I wanted to implement this by myself it would've been a lot worse, since we had some conversation around implementing it we found many weak points and came up with a more solid implementation as a result. I love working with other developers, All of the good ideas come from people who cooperate for the greater good despite their takes on the subject matter.
I'll delay merging this PR for another week so you have time to read this comment and respond if you want to, And if you don't I totally understand.
Thanks for helping to Improve NERDTree, I've used this plugin since I was a kid in high school so It is literally keeping my childhood alive.
Sincerely yours,
Ali Rezvani
Description of Changes
Closes # 1344
New Version Info
Author's Instructions
MAJOR.MINOR.PATCH
version number. Increment the:MAJOR
version when you make incompatible API changesMINOR
version when you add functionality in a backwards-compatible mannerPATCH
version when you make backwards-compatible bug fixesCollaborator's Instructions