Skip to content
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

--abs-path and --rel-path instead of --full-path #839

Open
andreavaccari opened this issue Aug 29, 2021 · 21 comments
Open

--abs-path and --rel-path instead of --full-path #839

andreavaccari opened this issue Aug 29, 2021 · 21 comments

Comments

@andreavaccari
Copy link

fd --full-path matches a pattern against the absolute path instead of the relative one. This is not well documented and it's a possible cause of confusion (e.g. #769). In my opinion, it is also less ergonomic than matching against the relative path of a candidate.

My suggestion is:

  • Replace --full-path with --abs-path to make it clear this matches against the absolute path
  • Add a new flag --rel-path to allow matching against the relative path

Thank you for the great work and for your focus on usability!

@tmccombs
Copy link
Collaborator

I like that idea. Though we would probably want to keep --full-path as a (probably hidden) alias for --abs-path for backwards compatibility.

@andreavaccari
Copy link
Author

Thank you for taking this into consideration! It makes sense to maintain backward compat.

Separately, I realized there is --absolute-path to modify how results are printed but not how they are matched. Introducing --abs-path next to --absolute-path could itself cause confusion. One solution would be to rename the latter to --show-abs-path, which would align with --show-errors, but would break backward compat. Another solution would be to introduce the longer --match-abs-path and --match-rel-path.

@sharkdp
Copy link
Owner

sharkdp commented Sep 3, 2021

fd --full-path matches a pattern against the absolute path instead of the relative one. This is not well documented and it's a possible cause of confusion (e.g. #769).

Thank you for your request. I am definitely in favor of improving the documentation. It should be clear that we match on the full absolute path.

In my opinion, it is also less ergonomic than matching against the relative path of a candidate.

Could you explain this in more detail? What is your use case and why is it unergonomic to solve it with --full-path?

@andreavaccari
Copy link
Author

Could you explain this in more detail? What is your use case and why is it unergonomic to solve it with --full-path?

Say you have the following directory structure:

~
├── project/
│   ├── docs/
│   │   ├── some-doc.pdf
│   │   ├── some-doc.txt
│   │   └── secret.pdf
│   ├── repo/
│   │   ├── ...

Let's say I'm in project and I want to find all .pdf files in docs:

  • I could issue cd docs && fd ".*pdf$", but let's say I don't want to change directory.
  • Intuitively I'd want to issue fd --rel-path "^docs/.*pdf$"
  • Instead I'd have to issue fd --full-path ".*docs/.*pdf$" but this could also match docs dirs under repo.
  • Or I'd have to issue fd --full-path "$(cwd)/docs/.*pdf$" which works but seems unnecessarily convoluted.

fd will only report results under the current working directory (or the argument passed), so most of the time I'd want to search against those. I do think there are cases where you might want to still match against the full path, but my intuition is that they'd be less common.

@tmccombs
Copy link
Collaborator

tmccombs commented Sep 3, 2021

In that particular case, you could use

fd ".*\pdf$" docs

@andreavaccari
Copy link
Author

That's fair, and I should have listed it as an option. However, I think the point remains valid. Your suggestion requires to "spread" my search between the <pattern>, which uses regex by default, and one or more <path>s, which can only use shell expansion. I believe it would be more ergonomic to to express the entire search in the <pattern>.

Separately, the original use case that motivated this issue was to find a set of files under my working directory, some of which must be at a specific location, while others could be anywhere within the working directory. In the example above, starting from project, how could I search exactly for ./docs/secret.pdf and for all .pdf files under repo with one command?

@rafcamlet
Copy link

rafcamlet commented Sep 4, 2021

I can provide another case, which was very confusing for me. Let's assume that I'm working on a repository and I want to find all files related to home subject, that means home is a part of the filename or part of the directory name containing files. On the first try, I would do something like: fd -p home , but that query will return basically every file in the repository, because the repository is in the user home directory /home/user_name/projects/my_repository. So the working solution would be fd -p "$(pwd).*home" and that's something I wouldn't expect. I've never had need to match against the whole absolute path, but against the relative one, very often, that's why I've always wondered why it's not even an option.

@sharkdp
Copy link
Owner

sharkdp commented Nov 14, 2021

I'm sorry, but I find both use cases obscure enough to reject this feature request (please refer to the "majority of use cases" statement in the README). I will update the documentation though. Thank you very much for the discussion.

@sharkdp sharkdp added this to the fd 8.3 milestone Nov 14, 2021
@rafcamlet
Copy link

rafcamlet commented Nov 14, 2021

Honestly, I'm surprised by this decision. And now I'm wondering if I use find-like tools differently than others ppl, because this absolute path approach is the most counterintuitive thing for me. This topic was raised at least three times in gh issues, and it always ended the same, so I have no other choice than just accept your decision and never bring it up again. Third time's a charm, as they say.

Thanks for your hard work. This tool is nearly perfect. 👍

@sharkdp
Copy link
Owner

sharkdp commented Nov 14, 2021

Honestly, I'm surprised by this decision. And now I'm wondering if I use find-like tools differently than others ppl, because this absolute path approach is the most counterintuitive thing for me.

Did you see that I updated the documentation (21fd013)? Does this help, or do you still think it's confusing?

This topic was raised at least three times in gh issues, and it always ended the same

Could you please point to the other issues. I honestly cannot remember that this was discussed somewhere else. There have been questions about --full-path for sure, but did users really want --full-path to only search the displayed path? Or were they simply confused due to the inappropriate documentation?

so I have no other choice than just accept your decision and never bring it up again

Please don't. I'll reopen this for now.

@sharkdp sharkdp reopened this Nov 14, 2021
@sharkdp sharkdp removed this from the fd 8.3 milestone Nov 14, 2021
@rafcamlet
Copy link

rafcamlet commented Nov 14, 2021

Did you see that I updated the documentation (21fd013)? Does this help, or do you still think it's confusing?

Yes, I saw it, and yes, it is helpful improvement. 👍

Could you please point to the other issues

#306
#609

There have been questions about --full-path for sure, but did users really want --full-path to only search the displayed path? Or were they simply confused due to the inappropriate documentation?

Both. :)

@andreavaccari
Copy link
Author

Hi David, thank you for reopening the issue. Ultimately this is your project and it's your prerogative to decline requests. However, if you don't mind me asking for clarification, could you help me understand your mental mode for this? Here is mine.

When I search with fd, I model my usage like this: search in these directories for these criteria, and I image that the directories define the scope of the search, and the criteria define the filters within that scope. With this mental model, it makes life easier to expect directories and criteria to be orthogonal to each other.

In fact, I cannot think of a good example of when I'd want to match against the absolute path. If I had to pick only one of the two, I would favor relative paths to achieve the orthogonality mentioned above, but, assuming you have an equally reasonable mental model, supporting both options would support both mental models.

@Andrius-B
Copy link

Andrius-B commented Nov 16, 2021

I would also request the README to be changed to reflect this unintuitive behaviour. The current -p examples avoid this issue by using all-matching patterns for the beginnings of paths:

> fd -p -g '**/.git/config'
> fd -p '.*/lesson-\d+/[a-z]+.(jpg|png)'

I wish there was an example that shows how to use the absolute path functionality as rel-path e.g.:

> fd -p "$(pwd)/"'\w+/src/.*\.java'

on a side note, I think the > fd -p -g '**/.git/config' example would need the -HI flags, because the .git directory is not searched by default (though I might be mistaken)

@sharkdp
Copy link
Owner

sharkdp commented Nov 16, 2021

With this mental model, it makes life easier to expect directories and criteria to be orthogonal to each other.

Exactly! But if you want directories and criteria to be orthogonal (which I assume to mean: independent), the search criteria themselves shouldn't be modified by changing the search path. This is what we achieve by always taking the absolute path.

Let's say I want to find files that contain foo in the path:

▶ mkdir foo; touch foo/bar                          
▶ fd --full-path --type=file foo
foo/bar

Now I would personally like to see the exact same search result, independent of what folder I'm currently in. This is why …

▶ cd foo     
▶ fd --full-path --type=file foo
bar

… also returns the bar file. If we would only search the relative path, the second search would have returned no results.

@andreavaccari what do you think? Did I interpret your "orthogonal" property incorrectly?


I just noticed that fd --full-path --type=file foo .. returns all files in the parent folder, presumably because the absolute search path is transformed into /tmp/foo/../ instead of /tmp. This is why every path matches the "foo" pattern. This should be fixed.

@rafcamlet
Copy link

rafcamlet commented Nov 16, 2021

Now I would personally like to see the exact same search result, independent of what folder I'm currently in.

So it's a matter of taste. For others, it's quite unnatural behaviour. Especially if you were find user.
But it is not a request to change default behaviour, only for adding an option to alternate this mechanism, in order to have more ergonomic interface. Something like fd -P asdf instead of fd -p "$(pwd)/.*asdf"

I'm pretty sure that there are people who will use and appreciate such addition.
manzaltu/modus-emacs@dd6a1fe

@andreavaccari
Copy link
Author

@sharkdp Yes you understood correctly what I meant with "orthogonal", and I now better understand your mental model. It seems we all agree that directories and criteria should be orthogonal/independent, but we disagree on what that means specifically. I think this difference stems from looking at the problem as the implementer of the program versus the user.

From an implementation standpoint, it's easier to collect all the files in the user-specified directories, then independently match their (absolute) paths against the user-specified criteria. From an usage standpoint, it's more natural to define the directories to search and then the criteria assuming "nothing exists outside those directories".

My points may not resonate with you but I do believe this thread has built a decent case for supporting this feature, especially considering that, as mentioned by @rafcamlet, it does not require a breaking change. Independent of your decision, thank you for building such a great tool!

@benfleis
Copy link

Hi @sharkdp, I agree on the intuition miss, and desire for absolute/relative path to be crystal clear. I just wrote a script that optionally used ** or subpath based on inputs for this structure. In this case, I expected b-dir to be a legit, more specific substitute for **:

@ben|  ~/a $ fd
b-dir
b-dir/file
c-dir
c-dir/file
@ben|X ~/a $ fd --full-path --glob '**/file'
b-dir/file
c-dir/file
@ben|  ~/a $ fd --full-path --glob 'b-dir/file'
@ben|  ~/a $

It's quite counterintuitive that the matching expression I specify does not work against the outputs I receive -- I expect them to be the same "kind". (Plus it's also my in-built intuition after years of find.)

@jjjchens235
Copy link

+1 that relative path feature would be useful for my use-case(s) and that the current implementation is not as intuitive to me

@minad
Copy link

minad commented Sep 26, 2023

I also want to express my support for this feature. I maintain the popular Emacs package Consult, which provides various file search and grep utilities. There I've recently added the Fd-based command consult-fd after Fd gained support for the --and command line option. consult-fd allows you to enter multiple patterns to search for files name under the current project root directory, a little bit in the style of fzf. Right now consult-fd uses the --full-path option, such that the command is affected by unexpected matches of the path components of the project root directory - the problem described by @rafcamlet in #839 (comment).

hpfr added a commit to hpfr/doomemacs that referenced this issue Sep 27, 2023
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
hpfr added a commit to hpfr/doomemacs that referenced this issue Sep 28, 2023
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
hpfr added a commit to hpfr/doomemacs that referenced this issue Oct 15, 2023
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
@ChristianCiach
Copy link

For the longest time I just assumed that -p -g is buggy, but I finally found this issue. Coming from find, this behaviour is a bit unexpected.

What I find even more unexpected is the fact that the printed results are using the relative paths of the found files. This seems strange. Why do I need to filter by absolute paths but are shown the relative results?

iyefrat pushed a commit to iyefrat/doom-emacs that referenced this issue Dec 4, 2023
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
iyefrat pushed a commit to iyefrat/doom-emacs that referenced this issue Dec 9, 2023
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
iyefrat pushed a commit to iyefrat/doom-emacs that referenced this issue Dec 9, 2023
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
iyefrat pushed a commit to iyefrat/doom-emacs that referenced this issue Jan 27, 2024
Currently, fd does not expose a way to match against only the path
components beneath the target path. When --full-path is specified, the
pattern matches against all components. For example, executing
consult-fd from /home/hlissner/.emacs.d with `home` as the query would
match every file (not excluded by other arguments) under .emacs.d.
Despite this --full-path behavior, fd still outputs relative paths, so
the user cannot even determine why some candidates are returned.

Until there is a method to match only against subdirectories, use
--absolute-path to at least to show the user why all matches are
occurring.

Ref: sharkdp/fd#839
@Norlock
Copy link

Norlock commented Jun 9, 2024

Any progress on this? how do i search the relative path in full-path style?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants