-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
feat: add vim.fs.relpath #31790
feat: add vim.fs.relpath #31790
Conversation
Alternative to #31702 |
@neovim/core: there's been some discussion in matrix chat without clear resolution whether this should work for target paths outside of the base directory. In other words, whether For reference: |
Returning '../apache' definitely makes If the requirement is dropped, then implementation is fairly straightforward and allows vim.fs.relpath = function(from, to)
from, to = vim.fs.normalize(vim.fs.abspath(from)), vim.fs.normalize(vim.fs.abspath(to))
to = to .. (to ~= '/' and '/' or '')
return vim.startswith(from, to) and from:sub(#to + 1) or nil
end
Resorting for what is commonly used in other languages might indeed be the way to go here. You can also add one of R's popular file system library to the list of "... would return |
This comment was marked as resolved.
This comment was marked as resolved.
0e32a14
to
8bdf932
Compare
The
|
Let's do that way then. We can add support for the "outside of target directory" case as a optional flag, later, if anyone actually requests it. But the default behavior should allow us to avoid |
d9f79ea
to
39d4c95
Compare
e816364
to
451b9b8
Compare
898c493
to
8f11cb7
Compare
1f7afe1
to
5ca0bf4
Compare
@@ -741,4 +741,35 @@ function M.abspath(path) | |||
return M.joinpath(cwd, path) | |||
end | |||
|
|||
--- Gets `target` path relative to `base`, or `nil` if `base` is not an ancestor. |
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.
or
nil
ifbase
is not an ancestor.
What's the main motivation behind this design? Wouldn't base="/var/lib", target="/var/foo"
=> relpath = "../foo"
also make sense (relpath
in other programming languages implements such a behavior)?
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.
Sorry for a duplicate comment, I missed the previous discussion. But I'm still worried about potential breaking changes in the future and the design of the API.
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.
See #31790 (comment)
The current behavior allows relpath()
to also provide "is relative to" functionality.
Wouldn't
base="/var/lib", target="/var/foo"
=>relpath = "../foo"
also make sense
We can get that in the future if it's wanted, by adding a opts
flag. I think it's uncommon. It also complicates the logic. So if people want it, we can add it later.
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.
I agree with we can avoid a complication for uncommon scenario, but as a low-level stdlib I believe the correct and reasonable default behavior is to make it behave the same and consistentyl as the common relpath
and other programming languages (including python's os.path.relpath
).
I believe eventually we will implement the remaining case ("walk_up") sometime in the future, or at least some people will find the behavior of API surprising (arguably). If the function would work correctly only under a certain opt
, that would sound weird in my humble opinion.
If the main purpose of adding this low-level vim.fs API is to implement is_descendant
(with being performant), why don't we add a dedicated API instead?
So please consider requiring an explicit option such as opt = {walk_up = False}
to achieve the (current) behavior, where the default option for the API ({ walk_up = true }
) could remain yet-to-be implemented for the time being.
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.
I guess we could do that, although adding an option for an unimplemented feature sounds a bit odd. I'm fine with either option, I guess you'd need to convince @justinmk and @echasnovski though.
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.
I believe the correct and reasonable default behavior is to make it behave the same and consistentyl as the common
relpath
and other programming languages (including python'sos.path.relpath
).
I didn't think about that. Though I can see that it would be useful for sibling files. But I have never needed that...
The common use-case for wanting a relative path is for a target that you know is descendant, and you want to avoid an absolute path (e.g. "workspace roots" for LSP or other project-like resolution).
Do you have some real-world examples where a "sibling" relative path is wanted?
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.
@wookayin I'd prefer not to delay with this for much longer. If you have any examples in mind let us know, otherwise I'll go ahead and merge this soon.
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.
If you have any examples in mind let us know, otherwise I'll go ahead and merge this soon.
Might be worth adding a third opts
argument for future use and explicitly say that it is "reserved for future use". Not mandatory, since adding it later seems to follow the API contract for Lua stdlib.
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.
OK, add an opts
argument
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.
I'll merge this, we can change the signature before release if it turns out doing the other way is more useful.
3bde16d
to
ffc4fd7
Compare
c4d16e5
to
19325be
Compare
This is needed to replace the nvim-lspconfig function is_descendant that some lspconfg configurations still use.
19325be
to
d3a7893
Compare
This is needed to replace the nvim-lspconfig function is_descendant that
some lspconfg configurations still use.