-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
Add option to always open files at their canonical path #130082
Comments
This has not been fixed yet? This is so annoying. |
Getting this onto the Backlog milestone is not much to celebrate. There are currently over 2900 tickets in that milestone. How do we get this bumped to a milestone that will actually happen? |
Hello, how would one approach fixing this? Is this time-consuming? |
Any updates? |
We closed this issue because we don't plan to address it in the foreseeable future. If you disagree and feel that this issue is crucial: we are happy to listen and to reconsider. If you wonder what we are up to, please see our roadmap and issue reporting guidelines. Thanks for your understanding, and happy coding! |
I think the issue is crucial. For environments / folders with lots of links, the usability of VS Code is below average. |
Please see #167999 for our plan this month to clean up and "groom" all opened issues. This issue was closed as part of that initiative. |
I also think this issue is crucial. Let me explain why. Even though not expanding symlinks to a canonical path may look benign, the impact is much bigger than it seems. In fact, this symlink issue is at the core of multiple bugs with very different symptoms, in VS Code itself as well as in multiple extensions. Here are just a few examples:
The variety of these symptoms "dilutes" the votes from affected users, because most of the time users didn't get directed to a central tracking issue. The same applies to all the other issues I haven't mentioned above. And to duplicates of those issues. And to symlink-related issues whose root cause was never identified. This amounts to a large user impact, unfortunately very hard to track by votes alone due to the nature of the issue. IIUC, resolving symlinks to their canonical path was the previous behavior of VS Code. I don't think this decision should be reverted, because it unblocked multiple use cases (see e.g. #18837), which shouldn't be broken again. Expecting the entire ecosystem to fix these issues might work in the very long-term, but if issues keep getting resolved as "out-of scope" (like microsoft/vscode-java-test#630 or #74104), this won't be happening anytime soon. In the meantime, users have to pay attention to always using canonical paths when opening files and folders... assuming they are even aware of the issue. I like @koenlek's proposal in this issue for a few reasons:
I sincerely hope you will reconsider the decision to close this issue. But regardless of what you decide, I also want to thank you for all the amazing work on VS Code! |
I think this is a crucial issue too. I was going to explain my reasons, but @ipkiss42 said it better. |
@ipkiss42 that is a great summary, thanks! However, here the ask is to follow symlinks of files that get opened, though you list issues about opening a folder that is a symlink. If I understand the original ask here then it is to resolve symlinks when opening an editor, i.e. always check if it is a link or not. But this issue is not about resolving the possible symlink when opening a folder? Or would the setting apply to both scenarios? |
It should apply to both scenarios. And also to opening a workspace file, if this is not covered by the regular way of opening a file. My mental model is that all these issues, at their core, boil down to a file path comparison done somewhere. For example, the logic to decide between reusing a tab vs. creating a new one checks if there is already a tab open for the given path. If not, it opens a new one. When faced with two representations of the same path (e.g. a canonical one and one with symlinks), the comparison treats them as different and we end up with two tabs. You can easily reproduce it:
In this example, the path of the first file was constructed from the non-canonical folder path and from the relative path to the root, so it was different from the canonical path of the second file. Conclusion: the setting is effective only if it applies to every "entry point" from where we get absolute paths. This brings an interesting question: why do we end up with different representations of file paths today, since the UI never expands them to canonical paths? Shouldn't they all be non-canonical, thus avoiding any issue when comparing paths? Unfortunately, there is no reason why tools should all agree on using canonical or non-canonical paths. As a result:
I believe this is still better than the current situation, because:
So instead of having tools deciding independently whether or not to canonicalize paths, the setting provides a path forward for eventually aligning every tool in the ecosystem, either natively (in the tool itself) or in the integration layer. |
BTW, another way to look at it is that the setting would buy us time to figure out a better approach. Maybe paths should be made canonical in all the places where path comparisons are done? I don't know, but it may take time to decide and act on it. I'd rather be unblocked via the setting in the meantime. |
Just a quick reply without going deep (yet): VS Code internally uses and identifies everything via However, things are more complicate than that: not only can a file be expressed by different cases and still point to the same file on disk, symbolic links can as well. However, symbolic links cannot be resolved synchronous, you need to ask the OS for its resolved form, which is a long running call. All our Bottom line: it would probably be relatively easy to resolve a symbolic link when it comes to opening a folder because that happens very early on startup and I think a setting for that could be added. However, resolving a link as part of opening an editor will be more tricky because essentially this requires us to make canonical |
IIUC, it wouldn't be necessary to do it when opening an editor, if the editor is opened via the explorer or via any other mechanism which relies on the (already resolved) folder path. It would be needed only when opening a file "from nothing", e.g. from the UI, in which case doing it synchronously might be acceptable. |
I would argue that in 99% of all cases the editor is opened from a component or piece of code that does NOT resolve the symbolic link if there is one. Not to speak about extensions who can also open any |
Yes, the issue is comparing paths, or in our case vscode/src/vs/base/common/map.ts Line 44 in d1f42f4
When deciding if a vscode/src/vs/base/common/map.ts Line 46 in d1f42f4
For editors to decide if an editor is already opened we do something similar:
The key thing here is that when a
We cannot make any assumptions about the form of the In order to support symbolic links, we essentially need to resolve the symbolic link and then use the resolved value as canonical form, not the symbolic link one. The issues at hand are:
Happy to discuss this further. Again, I think resolving a link when opening VS Code would be straight forward but it does not seem to address all the issues. |
Since there is a good amount of discussion and value in this issue (esp. #130082 (comment)), I am good to reopen but would still not make any promises as to when and if ever this issue is being addressed. There are blockers and questions on the way:
|
This issue is the bane of my existence. I work in a large codebase that - as part of its build system - symlinks all headers into a single path, to keep the include path list managable. Compile errors in the terminal list the symlinks as the error location, so when clicking those errors the editor opens the symlink. However the actual file is likely to be open as well due to teh header/source switching plugin we use. Both symlink and file open leads to frequent corruption of header files when enabling format on save (C++). These errors are sometimes not obvious and if not caught right away will mess up your day when you continue editing the files. |
This is a frequent issue during remote debug on servers with environments that use symlinks e.g. to streamline paths. Fyi, PyCharm's approach was to allow the user to define path mappings: Note, the case there was different: they work with local and remote copies of the code, while VSCode works only with a remote copy. However, using a mapping approach would allow the user to configure with prefix path differences to "ignore" and hence avoid opening a separate copy of the same file under a different path. For example: /home/user/code could be mapped to underlying path /mounts/<deep_and_complex_path_structure>/user/code avoiding the issues. |
It looks like part of this (Bazel sandbox python files open into a window) was turned into a issue here: microsoft/vscode-python#17002 we (Boston Dynamics) are using debugpy and it really gets annoying that this doesn't work better, its there any way to get this improved, @brettcannon I'm happy to get you 5 upvotes if that's what it takes. |
@gedalia voting is different per repo (if they use voting at all). But if there's a specific Python issue you can open it on the Python extension. |
@brettcannon it looks like you opened it and then closed it. Should I just create a new request with the same contents? or is this a issue with https://github.com/microsoft/debugpy hard for me to tell. |
looks like it might have been done in: microsoft/debugpy#743 I'll have to test that. |
@gedalia if the debugpy fix doesn't work, open a new issue on the Python debugger repo. |
Problem
Symlinks can sometimes lead to the same files being opened more than once in VSCode. An example in which this happens is in a
bazel run
sandbox, which symlinks files together into a sandbox environment. Another example I've seen is when python modules (spread over various folders in a git repo) are symlinked into 1 virtual env python path tree. More generally speaking, symlinks are sometimes used by build tooling to create one consolidated environment out of files spread over different places.Unfortunately, this can lead to a poor user experience in VS Code. Debuggers can start opening multiple copies of the same file (the one you'd like to edit, which likely is under source control, and one at the path at which it appears in the sandbox) and the UI/UX experience is clumsy at best (breakpoints can be set in each copy of the file and actually work for both, but visually aren't synced). Language servers like pylance can resolve imports to the symlinked venv. So opening the definition of a function can open the symlinked copy, rather than the original (which is likely under source control and the one that you'd actually like to edit)... Again: clumsy UI/UX, such as that that symlinked copy doesn't show source control change info (lines added/rm/changed, gitlens).
Proposed solution
I've seen various tickets related to this and generally things seem to get stuck in the discussion on defining a solution. I'd like to take another attempt at that.
How about we introduce a boolean option
openFilesAtCanonicalPath
(which people can set on a user or a workspace level)?The "canonical path" would be the path that
readlink -f {some_path}
would give on linux: i.e. the path with all symlinks resolved. This is the 'original' path for the file. This would:I wonder what VS Code devs thinks of this.
Related tickets: microsoft/pylance-release#478, #34627, #100533, microsoft/vscode-python#15897
Final remarks
We could even expand this idea to extensions if desired (extensions could retrieve both the requested path and canonical path of a file through extensions api), though I think many of the discussions around better extension support for symlinked files are maybe already solved by just opening the canonical file instead.
Please note that I'm focussing purely on this problem as introduced by symlinks in macOS and Linux. I'm not sure about Windows or other types of links like hard links, macOS aliases, etc. So far, I've seen build tooling use symlinks for these kind of things so addressing that can hopefully solve the majority of issues out there.
The text was updated successfully, but these errors were encountered: