-
Notifications
You must be signed in to change notification settings - Fork 1.3k
buffer: Store potential resolved symlinks as AbsPath
#3997
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -489,6 +489,40 @@ func DetermineEscapePath(dir string, path string) (string, string) { | |
| return url, "" | ||
| } | ||
|
|
||
| // ResolvePath provides the absolute file path for the given relative file path | ||
| // as well as resolves symlinks in both. It returns the relative path with | ||
| // symlinks resolved and the absolute path with symlinks resolved. If it fails | ||
| // to get the absolute path or to resolve symlinks, it returns unresolved path | ||
| // in place of resolved one. The only exception is the case in which the target | ||
| // file doesn't exist. We leave the path handling to EvalSymlinks() and use the | ||
| // path causing the error as target path. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This sounds too detailed, and at the same time completely unclear. What "path handling", etc. Why not just e.g. "In case the file does not exist, ResolvePath still resolves it, by resolving its directory path and keeping the file name." ? |
||
| func ResolvePath(path string) (string, string) { | ||
| resolvedPath, err := filepath.EvalSymlinks(path) | ||
| if err == nil { | ||
| path = resolvedPath | ||
| } else if errors.Is(err, fs.ErrNotExist) { | ||
| if e, ok := err.(*fs.PathError); ok { | ||
| path = e.Path | ||
| } | ||
| } | ||
|
|
||
| absPath, err := filepath.Abs(path) | ||
| if err != nil { | ||
| absPath = path | ||
| } | ||
|
|
||
| resolvedPath, err = filepath.EvalSymlinks(absPath) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've noticed another corner-case issue: if the file doesn't exist yet (so it is opened as an empty file) and its directory path contains symlinks, those symlinks are not resolved. E.g.: For comparison, again, vim correctly resolves it (thus correctly detects that
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very good catch! 👍
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we relying on some undocumented behavior here? There is another corner case: the file doesn't exist, and its directory doesn't exist either, but some of its ancestor directories exists and contains symlinks: As you can see, this newest version handles this case utterly incorrectly. Furthermore, even if there are no symlinks (e.g.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right,
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we should use a similar approach as First tests seem promising and mkdir dir1 dir3
ln -s dir1 dir2
ln -s ../dir1/file dir3/file
micro dir1/file dir2/file dir3/file
vim -p dir1/file dir2/file dir3/file
cd dir2/
micro ../dir1/file file ../dir3/file
vim -p ../dir1/file file ../dir3/file
cd ..
micro dir/dir/file
micro dir1/dir/file
PS:
Yes, it was a bad hack 😓 |
||
| if err == nil { | ||
| absPath = resolvedPath | ||
| } else if errors.Is(err, fs.ErrNotExist) { | ||
| if e, ok := err.(*fs.PathError); ok { | ||
| absPath = e.Path | ||
| } | ||
| } | ||
|
|
||
| return path, absPath | ||
| } | ||
|
|
||
| // GetLeadingWhitespace returns the leading whitespace of the given byte array | ||
| func GetLeadingWhitespace(b []byte) []byte { | ||
| ws := []byte{} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.