-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Interactive global search #4687
Conversation
f4c8647
to
21647b9
Compare
I have been using this for a while and it's nice to be able to change the query quickly but there are some usability regressions:
It would also be useful to search in other pickers with multiple criteria (for example you could filter the symbol picker by symbol kind), so maybe we can come up with an improvement to the picker functionality that will benefit all pickers. I also wonder how telescope handles this? |
Another example where I also ran into a similar problem would.be a git commit picker. You could filter:
Irrespective of whether we want something like a commit picker in core I think this example also shows potential for filtering multiple queries . I think the easiest route to implement this would be to create some kind of |
Just to add one more usecase: in symbol picker it would be nice to be able to filter by the symbol type. What I have also seen elsewhere (which is imho inferior to what @pascalkuthe suggested) is having custom strings in the filter to filter for various things, e.g. in the example of symbol picker one could do
and a key binding (e.g. |
I think
Another nice thing to imorove the UI would be to display the full item while only filtering parts of it. For.example again for commits (but I can think of many other examoles) it would.be nice to print the full commit (sha author date message) in the picker even when filtering by author so you don't loose all context of what is being filtered. That will require some adjustment to to way we handle fuzzy indecies (currently if the That said all that won't be necessary for |
i have no idea if this code already but would be awesome to chain multiple searches based on previous searchs like telescope do now (with S-RET). Also, doom-emacs find-files has the best implementation of that i ever seen. Example of that: Press SPC / and search for
change the completion to
change the completion to
Every # picks the previous result and filters again. This is so powerful and awesome, the thing i most miss on emacs. |
I think what you're describing can be done by adding spaces between searches. That's specific to filtering pickers though which is not really related to this PR.
It might be best to start with the symbol picker for hacking on this idea - that picker only needs to be sorted by symbol type and name. Then the workspace symbol picker would be a good next step since that also uses a I think the extra filtering feature might also need #3053 |
Merges the code for the Picker and FilePicker into a single Picker that can show a file preview if a preview callback is provided. This change was mainly made to facilitate refactoring out a simple skeleton of a picker that does not do any filtering to be reused in a normal Picker and a DynamicPicker (see helix-editor#5714; in particular [mikes-comment] and [gokuls-comment]). The crux of the issue is that a picker maintains a list of predefined options (eg. list of files in the directory) and (re-)filters them every time the picker prompt changes, while a dynamic picker (eg. interactive global search, helix-editor#4687) recalculates the full list of options on every prompt change. Using a filtering picker to drive a dynamic picker hence does duplicate work of filtering thousands of matches for no reason. It could also cause problems like interfering with the regex pattern in the global search. I tried to directly extract a PickerBase to be reused in Picker and FilePicker and DynamicPicker, but the problem is that DynamicPicker is actually a DynamicFilePicker (i.e. it can preview file contents) which means we would need PickerBase, Picker, FilePicker, DynamicPicker and DynamicFilePicker and then another way of sharing the previewing code between a FilePicker and a DynamicFilePicker. By merging Picker and FilePicker into Picker, we only need PickerBase, Picker and DynamicPicker. [gokuls-comment]: helix-editor#5714 (comment) [mikes-comment]: helix-editor#5714 (comment)
Merges the code for the Picker and FilePicker into a single Picker that can show a file preview if a preview callback is provided. This change was mainly made to facilitate refactoring out a simple skeleton of a picker that does not do any filtering to be reused in a normal Picker and a DynamicPicker (see helix-editor#5714; in particular [mikes-comment] and [gokuls-comment]). The crux of the issue is that a picker maintains a list of predefined options (eg. list of files in the directory) and (re-)filters them every time the picker prompt changes, while a dynamic picker (eg. interactive global search, helix-editor#4687) recalculates the full list of options on every prompt change. Using a filtering picker to drive a dynamic picker hence does duplicate work of filtering thousands of matches for no reason. It could also cause problems like interfering with the regex pattern in the global search. I tried to directly extract a PickerBase to be reused in Picker and FilePicker and DynamicPicker, but the problem is that DynamicPicker is actually a DynamicFilePicker (i.e. it can preview file contents) which means we would need PickerBase, Picker, FilePicker, DynamicPicker and DynamicFilePicker and then another way of sharing the previewing code between a FilePicker and a DynamicFilePicker. By merging Picker and FilePicker into Picker, we only need PickerBase, Picker and DynamicPicker. [gokuls-comment]: helix-editor#5714 (comment) [mikes-comment]: helix-editor#5714 (comment)
This is great, I've really missed the behavior of With regards to cycling filters, |
By comparison this PR reruns the ripgrep based search automatically (we use ripgrep internals since it's written in rust) so you can change the regex and automatically get updated results. |
That is how
This is how |
You can configure it to behave the same as this PR but in that case you are not matching on filenames anymore either. From the README of
|
This will be used in a child commit to setup an async job on the compositor context within global_search's callback. The compositor context was already available at the callback's callsite but was being reduced to just the editor field.
This can be used to set an initial query from a register. Global search will use this and the file picker could also consider allowing an initial query using this helper.
This commit refactors global search to use a DynamicPicker rather than a prompt plus a picker based on the prompt entry. There aren't any actual changes: the display format is the same (changed in the parent commit) and the regex-matcher-builder and async collection are essentially unchanged. Now these same blocks are used in the dynamic picker's query callback. The only novel code here is in the Err case for RegexMatcherBuilder::build. We now open up a popup showing the failure message for regexs that fail to compile.
21647b9
to
3dbe90d
Compare
This is now part of #7265: it fixes the usability problems I mentioned in #4687 (comment) |
Merges the code for the Picker and FilePicker into a single Picker that can show a file preview if a preview callback is provided. This change was mainly made to facilitate refactoring out a simple skeleton of a picker that does not do any filtering to be reused in a normal Picker and a DynamicPicker (see #5714; in particular [mikes-comment] and [gokuls-comment]). The crux of the issue is that a picker maintains a list of predefined options (eg. list of files in the directory) and (re-)filters them every time the picker prompt changes, while a dynamic picker (eg. interactive global search, #4687) recalculates the full list of options on every prompt change. Using a filtering picker to drive a dynamic picker hence does duplicate work of filtering thousands of matches for no reason. It could also cause problems like interfering with the regex pattern in the global search. I tried to directly extract a PickerBase to be reused in Picker and FilePicker and DynamicPicker, but the problem is that DynamicPicker is actually a DynamicFilePicker (i.e. it can preview file contents) which means we would need PickerBase, Picker, FilePicker, DynamicPicker and DynamicFilePicker and then another way of sharing the previewing code between a FilePicker and a DynamicFilePicker. By merging Picker and FilePicker into Picker, we only need PickerBase, Picker and DynamicPicker. [gokuls-comment]: #5714 (comment) [mikes-comment]: #5714 (comment)
Merges the code for the Picker and FilePicker into a single Picker that can show a file preview if a preview callback is provided. This change was mainly made to facilitate refactoring out a simple skeleton of a picker that does not do any filtering to be reused in a normal Picker and a DynamicPicker (see helix-editor#5714; in particular [mikes-comment] and [gokuls-comment]). The crux of the issue is that a picker maintains a list of predefined options (eg. list of files in the directory) and (re-)filters them every time the picker prompt changes, while a dynamic picker (eg. interactive global search, helix-editor#4687) recalculates the full list of options on every prompt change. Using a filtering picker to drive a dynamic picker hence does duplicate work of filtering thousands of matches for no reason. It could also cause problems like interfering with the regex pattern in the global search. I tried to directly extract a PickerBase to be reused in Picker and FilePicker and DynamicPicker, but the problem is that DynamicPicker is actually a DynamicFilePicker (i.e. it can preview file contents) which means we would need PickerBase, Picker, FilePicker, DynamicPicker and DynamicFilePicker and then another way of sharing the previewing code between a FilePicker and a DynamicFilePicker. By merging Picker and FilePicker into Picker, we only need PickerBase, Picker and DynamicPicker. [gokuls-comment]: helix-editor#5714 (comment) [mikes-comment]: helix-editor#5714 (comment)
Merges the code for the Picker and FilePicker into a single Picker that can show a file preview if a preview callback is provided. This change was mainly made to facilitate refactoring out a simple skeleton of a picker that does not do any filtering to be reused in a normal Picker and a DynamicPicker (see helix-editor#5714; in particular [mikes-comment] and [gokuls-comment]). The crux of the issue is that a picker maintains a list of predefined options (eg. list of files in the directory) and (re-)filters them every time the picker prompt changes, while a dynamic picker (eg. interactive global search, helix-editor#4687) recalculates the full list of options on every prompt change. Using a filtering picker to drive a dynamic picker hence does duplicate work of filtering thousands of matches for no reason. It could also cause problems like interfering with the regex pattern in the global search. I tried to directly extract a PickerBase to be reused in Picker and FilePicker and DynamicPicker, but the problem is that DynamicPicker is actually a DynamicFilePicker (i.e. it can preview file contents) which means we would need PickerBase, Picker, FilePicker, DynamicPicker and DynamicFilePicker and then another way of sharing the previewing code between a FilePicker and a DynamicFilePicker. By merging Picker and FilePicker into Picker, we only need PickerBase, Picker and DynamicPicker. [gokuls-comment]: helix-editor#5714 (comment) [mikes-comment]: helix-editor#5714 (comment)
Merges the code for the Picker and FilePicker into a single Picker that can show a file preview if a preview callback is provided. This change was mainly made to facilitate refactoring out a simple skeleton of a picker that does not do any filtering to be reused in a normal Picker and a DynamicPicker (see helix-editor#5714; in particular [mikes-comment] and [gokuls-comment]). The crux of the issue is that a picker maintains a list of predefined options (eg. list of files in the directory) and (re-)filters them every time the picker prompt changes, while a dynamic picker (eg. interactive global search, helix-editor#4687) recalculates the full list of options on every prompt change. Using a filtering picker to drive a dynamic picker hence does duplicate work of filtering thousands of matches for no reason. It could also cause problems like interfering with the regex pattern in the global search. I tried to directly extract a PickerBase to be reused in Picker and FilePicker and DynamicPicker, but the problem is that DynamicPicker is actually a DynamicFilePicker (i.e. it can preview file contents) which means we would need PickerBase, Picker, FilePicker, DynamicPicker and DynamicFilePicker and then another way of sharing the previewing code between a FilePicker and a DynamicFilePicker. By merging Picker and FilePicker into Picker, we only need PickerBase, Picker and DynamicPicker. [gokuls-comment]: helix-editor#5714 (comment) [mikes-comment]: helix-editor#5714 (comment)
This refactors global search (
<space>/
) to be interactive. The idle timeout triggers an async callback which refills the picker with new search results.https://asciinema.org/a/536431
Closes #196