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

[Feature] Action to change --nth and --with-nth dynamically #3109

Open
10 tasks done
cibinmathew opened this issue Dec 30, 2022 · 11 comments
Open
10 tasks done

[Feature] Action to change --nth and --with-nth dynamically #3109

cibinmathew opened this issue Dec 30, 2022 · 11 comments

Comments

@cibinmathew
Copy link

cibinmathew commented Dec 30, 2022

  • I have read through the manual page (man fzf)
  • I have the latest version of fzf
  • I have searched through the existing issues

Info

  • OS
    • Linux
    • Mac OS X
    • Windows
    • Etc.
  • Shell
    • bash
    • zsh
    • fish

Problem / Steps to reproduce

Add action to change nth and with-nth value during runtime similar to change-prompt action

Sample use case:
grep -n . dir1 dir2 dir2 | fzf --delimiter : --with-nth=3.. --preview "cat {1}"

  • This displays only the text lines from file
    (Prefer this most of the time as displaying the filepath and line number makes it more crowded to fit in the screen).
  • --with-nth=1.. If I can bind a shortcut to toggle with-nth value during runtime, it would be very useful to see the file path as well.
@LangLangBart
Copy link
Contributor

As a workaround you could use the reload action, see #1750 for details.

rtf() {
	GREP_COMMAND="grep --color=always --line-number . ${@:?Provide at least one argument.}"
	FZF_DEFAULT_COMMAND="$GREP_COMMAND | cut -d : -f3-" \
		fzf --ansi \
		--preview-window 'hidden' \
		--bind "ctrl-r:reload:$GREP_COMMAND || true"
}

rtf

@cibinmathew
Copy link
Author

cibinmathew commented Dec 31, 2022

Thanks @LangLangBart
My original script has a preview of the file with the matching line focussed (using scroll offset).

Edited: grep -n . dir1 dir2 dir2 | fzf --delimiter : --with-nth=3.. --preview "cat {1}"
Is there be a way to achieve that too in both case.

@cibinmathew cibinmathew changed the title [Feature] Action to change --nth and --with-nth dynamically [Feature] Action to change --nth and --with-nth dynamically Dec 31, 2022
@benthorner
Copy link

benthorner commented Jan 7, 2023

Seems to be a duplicate of #2743.

Would love this feature ➕ 🤩. I use Fzf as my "primary" search tool: it gets every line of every file, which means I can type all my searches dynamically like in other editors, without having to "pre-think" what the source query is.

This works really well, except sometimes I specifically want the search to just filter file content (especially if the content I'm searching for matches a file name!) and other times I want to filter file content and file names e.g. to find usages in some files but not others (like tests). So switching between no filter and "--nth=3" (in my case) would be perfect.

Here's a screenshot to illustrate:

Screenshot 2023-01-07 at 12 58 07

Here I'm trying to find all occurrences of "influxdb import" in a codebase. As you can see, it's also picking up the file name - again, sometimes I want it to do that - so there are lots of extra results. I know in this case I can just change the query to e.g. "influxdb\ import" or have another command that uses "--nth=3" instead (or try the workaround above), but it would be so much easier if there were an action I could bind to that would just switch to / from "--nth=3" in-place.

@junegunn
Copy link
Owner

junegunn commented Jan 7, 2023

@benthorner There are some strategies you can take to get better results in that case.

  • Since you're searching for influxdb import, not import influxdb, you can remove space from your query. i.e. influxdbimport. You'll likely get better results this way; influx import will be ranked higher than influx blah blah blah import. I rarely type spaces when using fzf, they are only needed when you expect multiple search terms to appear in any order in an item.
  • You can prefix your search term with : so that it doesn't match the file path. e.g. :influxdbimport
    • On the other hand, you can add : suffix to your term to limit the search scope to the file path part. e.g. influxpy:

@benthorner
Copy link

@junegunn thanks for the suggestions. This is what I usually do but it's not as good as nth:

  • Different searches need different "tricks" to filter/sort correctly.
  • Sometimes I'm not sure exactly what I'm looking for syntax-wise.

you can remove space from your query. i.e. influxdbimport

Normally that would help but I've got --exact set as I found that easier on average. Sorry, another quirk from me. Actually, toggling that on and off would also be useful, now I come to think of it!

What do you think about this proposal? I'm just wondering if there's an architectural reason why this wouldn't work - I haven't looked into the code yet - or just something I've not thought of.

@junegunn
Copy link
Owner

junegunn commented Jan 7, 2023

I'd advise that you remove --exact from your default and take some time getting used to the fuzzy matching algorithm and the search syntax of fzf. Like I said above, you'll get better results with fuzzy matching in this case with less typing. If you really want, you can enable exact matching term-wise by pretending '. See https://github.com/junegunn/fzf#search-syntax (Conversely, you can make a search term fuzzy by prepending ' in --exact mode)

  • Different searches need different "tricks" to filter/sort correctly.
  • Sometimes I'm not sure exactly what I'm looking for syntax-wise.

I'm not sure about the argument. You can use the search syntax with any type of input, while nth is applicable to a specific form of input. I don't see typing influxdbimport instead of influxdb import as a "trick". It's a more natural way to use a "fuzzy finder" with a proper ranking algorithm. Actually, I wouldn't even type the whole words, something like influimp would usually suffice.

I'm just wondering if there's an architectural reason why this wouldn't work

fzf is heavily optimized for performance and memory footprint and some parts of the code are not easy to change without compromising the optimizations. Changing nth and with-nth runtime will require complete reindexing of the list. And of course, it will increase the complexity of the code.

@benthorner
Copy link

benthorner commented Jan 7, 2023

@junegunn using --exact works well for me in the majority of cases. In the above example, the goal is to get an exact list of locations to investigate. Whereas I found fuzzy mode is more useful when searching for a single location, where I only care about the highest ranking result. When I'm searching for multiple locations, I find it hard to visually distinguish between the exact matches I care about and the fuzzy ones, hence preferring --exact in general. I do appreciate though that Fzf is primarily intended for fuzzy search, which isn't how I'm using it here - it does work well though!

you can make a search term fuzzy by prepending ' in --exact mode

Ahh, I forgot about that - thanks!

Changing nth and with-nth runtime will require complete reindexing of the list.

That makes sense and seems OK if we assume a user would only toggle once per Fzf session; based on my experience, it takes a second or two to reload, which seems reasonable versus starting all over again with --nth.

In terms of code complexity, it's of course up to you if you think this feature is worth more than the maintenance pain it will create. For me it's a complementary to the other actions and search techniques, giving users a bit more flexibility in how they solve their search problem efficiently - admittedly, it's not really a fuzzy searching problem.

@cibinmathew what was your usecase for this, by the way? I realise I'm hogging your issue!

@junegunn
Copy link
Owner

junegunn commented Jan 8, 2023

@benthorner Fair enough.

the goal is to get an exact list of locations to investigate

If that is your goal, you should probably pass the initial search query to the ripgrep process and use fzf only as the secondary filter. Or you can demote fzf to a mere selector interface by using change:reload binding combined with --disabled.

@cibinmathew
Copy link
Author

@cibinmathew what was your usecase for this, by the way? I realise I'm hogging your issue!

Paths can be hidden but cannot be stripped altogether as it impacts preview tools and actions to open matches. Quickly toggling paths on and off would still need actions for changing dynamically --nth/--with-nth

@junegunn Pls let us know if you think this can be taken up sooner in the roadmap

@junegunn
Copy link
Owner

junegunn commented Jan 12, 2023

Pls let us know if you think this can be taken up sooner in the roadmap

No, it won't be because of the reason I mentioned above. It's not a trivial task. Allowing dynamic change will likely affect the loading performance as the asynchronous loading thread should constantly check if the option has changed with a locking mechanism.

@junegunn
Copy link
Owner

Having said that, I also have the issue of the preview window taking too much space sometimes, and it helps to change the size or position of it using toggle-preview or change-preview-window binding.

# [CTRL-/] up,40% -> hidden -> (default, which is right,50%)
fzf --bind 'ctrl-/:change-preview-window(up,40%|hidden|)' --preview 'cat {}'

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

No branches or pull requests

4 participants