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

tiebreak end,length not working as expected #926

Closed
3 of 15 tasks
IngoMeyer441 opened this issue May 19, 2017 · 8 comments
Closed
3 of 15 tasks

tiebreak end,length not working as expected #926

IngoMeyer441 opened this issue May 19, 2017 · 8 comments
Labels

Comments

@IngoMeyer441
Copy link

  • Category
    • fzf binary
    • fzf-tmux script
    • Key bindings
    • Completion
    • Vim
    • Neovim
    • Etc.
  • OS
    • Linux
    • Mac OS X
    • Windows
    • Windows Subsystem for Linux
    • Etc.
  • Shell
    • bash
    • zsh
    • fish

Hey,
I'm trying to filter a file list with files that are located in nested directories. The filename is most relevant. However, some files are duplicated into sub directories, so I am usuallay interested in files with a short filename as a second criterion. So I have added --tiebreak end,length to my fzf call but I always get the longer filename as first result. Is that a bug? As a concrete example I have the following two filepaths:

./src/gui/util/webview.py
./packaging/app/PrinterTray.app/Contents/MacOS/gui/util/webview.py

When filtering for webview.py I always get

./packaging/app/PrinterTray.app/Contents/MacOS/gui/util/webview.py

as first suggestion.

@junegunn
Copy link
Owner

webview gives the longer one, but webview.py or webpy gives the shorter one.

--tiebreak=end calculates the score based on the relative position of the right end of the matched substring, i.e. w for webview, or y for webpy.

  • ./src/gui/util/webvie*w*.py
    • 22 / 25 = 88%
  • ./packaging/app/PrinterTray.app/Contents/MacOS/gui/util/webvie*w*.py
    • 63 / 66 = 95%
  • ./src/gui/util/webview.p*y*
    • 25 / 25 = 100%
  • ./packaging/app/PrinterTray.app/Contents/MacOS/gui/util/webview.p*y*
    • 66 / 66 = 100%

So that explains the result we see. As you can see, the effect --tiebreak=end is rather hard to predict and control, so I suggest that you don't use --tiebreak except for --tiebreak=index. (The option used to make more sense when greedy algorithm was used, but fzf now finds the optimal result for the given keyword)

Instead you can take one of the following strategies:

  1. Use extended-search mode syntax, e.g. py$ webview
  2. Type in the file extension webpy, fzf will most likely produce better result
  3. --nth -1,.. --delimiter / to make fzf look at the last element in the path first. However, note that this can make the overal performance of fzf slower.

@IngoMeyer441
Copy link
Author

Hey thanks for your help!
I have adopted your third suggestion, added --tiebreak=begin --nth -1,.. --delimiter / and tried it with some directory lists. However, the filter results are a bit strange. If I type a search word that exactly matches one of the last path components I often get a subpath as first result.
Example list:

  • workspace/project
  • workspace

When searching for workspace I get workspace/project first.
However, if I add --with-nth -1,.. to transform the representation of the search results I get workspace as first result. That seems strange to me since the representation should not influence the search result.

You can use these commands to reproduce the behavior:

echo -e "workspace/project\nworkspace" | fzf --tiebreak begin --nth -1,.. --delimiter /

and

echo -e "workspace/project\nworkspace" | fzf --tiebreak begin --nth -1,.. --with-nth=-1,.. --delimiter /

@junegunn
Copy link
Owner

junegunn commented May 29, 2017

Both has the exactly same begin score; at the beginning. workspace/project appears before the other only because it comes earlier in the input. Compare the results of the following commands

# FIFO
echo -e "workspace/project\nworkspace" | fzf --tiebreak begin --nth -1,.. --delimiter / -fworkspace
echo -e "workspace\nworkspace/project" | fzf --tiebreak begin --nth -1,.. --delimiter / -fworkspace

# 'length' kicks in
echo -e "workspace/project\nworkspace" | fzf --tiebreak begin,length --nth -1,.. --delimiter / -fworkspace
echo -e "workspace\nworkspace/project" | fzf --tiebreak begin,length --nth -1,.. --delimiter / -fworkspace

That seems strange to me since the representation should not influence the search result.

The representation does influence the search result. If not, it would be very confusing (e.g. fzf returns matches that don't even seem to match the query, ^foo matches entries that do not start with foo on screen).

@IngoMeyer441
Copy link
Author

If both get the same begin score, does --nth -1,.. --delimiter / have no effect then? Maybe I am just a bit confused...

@IngoMeyer441
Copy link
Author

I hope I am not taking too much of your time. I really would like to understand how --nth -1,.. does influence the score calculation. It is clear to me that --nth can be used to limit the search scope to some data fields. But what exactly happens if a data field is specified twice (like the last field in -1,..)? Which effect does the order have on the scoring? I thought --nth -1,.. in combination with --tiebreak begin would match the beginning of the last path component but that is not the case.

@junegunn junegunn reopened this May 31, 2017
@junegunn
Copy link
Owner

Okay, I think this should be properly addressed. Actually, I haven't really used/tested --tiebreak option in conjunction with --nth and the expected result is not clearly defined/documented, and there may be some bugs. Let me look into that.

@junegunn
Copy link
Owner

Okay, it's official that --tiebreak is inconsistent/broken when it's used with --nth.

  • begin: Global. Offset in the whole string.
  • length: Local. Length of the matched component.
  • end: Broken 💩

There are cases where "global" decision makes more sense, for example, file paths, but there are also other cases where "local" decision makes more sense, such as tabular input. Anyway, I'll have to fix it in either way.

@IngoMeyer441
Copy link
Author

Ok, thanks for investigating. 😄

@NoSuck NoSuck mentioned this issue Aug 4, 2019
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants