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

interactive global search #196

Closed
dofinn opened this issue Jun 9, 2021 · 42 comments · Fixed by #9647
Closed

interactive global search #196

dofinn opened this issue Jun 9, 2021 · 42 comments · Fixed by #9647
Assignees
Labels
A-helix-term Area: Helix term improvements C-enhancement Category: Improvements

Comments

@dofinn
Copy link

dofinn commented Jun 9, 2021

The reason I use vim is for ripgrep and fzf. This makes for extremly fast navigation.

Request:

  • Ability to index files in active directory and search via FZF
    20210609_224940_grim

  • Ability to grep through fies in active directory and pipe results in fzf

  • ripgrep file_config | fzf <- this opens up in same preview window that FZF provides.
    20210609_225128_grim
    20210609_225136_grim

There are many blogs etc writing about this method in vim. EG: https://sidneyliebrand.medium.com/how-fzf-and-ripgrep-improved-my-workflow-61c7ca212861

@pickfire pickfire added the C-enhancement Category: Improvements label Jun 9, 2021
@kirawi
Copy link
Member

kirawi commented Jun 9, 2021

Should this be a core feature of Helix or be implemented as a plugin?

@pickfire
Copy link
Contributor

pickfire commented Jun 9, 2021

I personally think this should be core feature. We already have like skim like thing, implementing ripgrep is just near.

@dofinn
Copy link
Author

dofinn commented Jun 10, 2021

is a dependecy on ripgrep something you want to make mandatory? I would imagine having these functions pluggable
grep=plugin(ripgrep)
find=plugin(fzf)

@pickfire
Copy link
Contributor

I don't think we will pull in ripgrep. We may be implementing our own which is slightly slower compared to ripgrep but work well for our usecase.

@vv9k
Copy link
Contributor

vv9k commented Jun 10, 2021

We could also just import the grep_searcher crate that ripgrep uses internally. It's published to crates.io

https://docs.rs/grep-searcher/0.1.7/grep_searcher/

And walkdir for recursive file system traversal https://docs.rs/walkdir/2.3.2/walkdir/

@dofinn
Copy link
Author

dofinn commented Jun 10, 2021

so excuse me for being an idiot. The file picker is already aweesome! cancel the FZF request

@archseer
Copy link
Member

I do think a preview window + some way to actually search through files would be useful though :)

I think there should be a general way to pipe data into the built-in picker.

@dofinn
Copy link
Author

dofinn commented Jun 11, 2021

I agree, after using it last night i did miss the preview window + the actual fuzzy finding where i could use multiple terms seperated by whitespace rather then the exact path/to/target/file

@archseer
Copy link
Member

The finding is fuzzy (we use skim's algorithm, we just don't highlight the matched characters yet.

@nrdxp
Copy link
Contributor

nrdxp commented Jun 15, 2021

Does Helix use skim as a library?

@sudormrfbin
Copy link
Member

Does Helix use skim as a library?

We're using the fuzzy-matcher crate which is used internally by skim.

@heliostatic
Copy link
Contributor

Another vote for searching via the grep_searcher crate in the preview UI used for the picker, per #196 (comment)

@kirawi kirawi added the A-helix-term Area: Helix term improvements label Aug 19, 2021
@pppKin
Copy link
Contributor

pppKin commented Aug 25, 2021

Hi! I too think that being able to perform a search in current workspace would be immensely helpful. So I started messing around and implemented something myself . It's not pretty I know, but it's something for us to talk about as least.
My implementation bind space + / to display a prompt (like the search prompt), and on Enter, start the search, gathers the result and pop up a FilePicker. A few necessary changes are made, such as regex_prompt now accepts an extra callback that would be invoked once Enter is pressed.
There may be some best practices I missed or some corner cases that I don't know about, but hopefully this can be improved by the community. So before I rush to create a PR, I just want to know if you guys have any thought on what this should look like and how it should be properly implemented. Thank you!

@archseer
Copy link
Member

That's pretty cool! I think instead of grep you will want to import grep_matcher and grep_regex so we avoid some of the extra deps (we don't need grep_printer for example). grep is just a facade that re-exports all these crates: https://github.com/BurntSushi/ripgrep/blob/master/crates/grep/src/lib.rs

I'm also wondering if we might want to do this without the prompt and just do this interactively in the picker as the user types. It's a bit wasteful though so maybe there could be a key to refresh (ctrl-r or something like it)

The binary detection part is really cool and we likely want to use that in the file preview as well to avoid displaying binary files (on space + f).

@pppKin
Copy link
Contributor

pppKin commented Aug 25, 2021

import grep_matcher and grep_regex so we avoid some of the extra deps (we don't need grep_printer for example)

You're right, I will be cleaning it up shortly :)

Edited: Updated. But I seem to have messed up my forked branch to include a commit that was not mine(due to some incorrect git rebase I think), after resolving that I'll be creating a PR so that it's easier for everyone to review:)

@pppKin
Copy link
Contributor

pppKin commented Aug 25, 2021

just do this interactively in the picker as the user types

@archseer
Interactive picker might be a more intuitive option, but I wonder what would be a proper way to fuzzily select a file in search results in said picker? Perhaps add another input field and another key binding to switch between them?

@archseer
Copy link
Member

That would be an option, but from what I've seen in other plugins (telescope.nvim) there's simply no fuzzy file select, you just scroll the list (we could probably add ctrl-d/u page up/down so the list is easier to scroll faster). When I'm searching for something I usually don't know the filename so I'll traverse the list to find the correct entry.

I do see a case for being able to limit the set of files we search for beforehand though, for example if I'm searching for results inside _test.go files. In that case I think we could space + f, _test.go to fuzzy find files, then space + \ should search through that subset of files.

@EpocSquadron
Copy link
Contributor

@archseer I think this is implemented, any reason to keep this open?

@pickfire
Copy link
Contributor

Interactive prompt is not available yet so it will be kept open.

@amstaniec
Copy link

I came up with nushell script command interactive global search (external to helix)
using rg and fzf, so also works on MS Windows
It shows only with single line of preview, but still quite usable.
For nushell users, put this in of your config.nu:

def rghx [] {
  let li = ((rg -e '.' --no-heading -n --color always | fzf --ansi) | lines |  split row ':')
  hx ([$li.0, ':', $li.1] | str join)  
}

run it in the repo root folder, and start typing to search, enter to open in helix

can be easily translated to different shell script

@davxy
Copy link
Contributor

davxy commented Feb 1, 2023

This is something I use in bash

#!/bin/bash

# Search using rg and fzf with preview
out=$(rg . --line-number --column --no-heading --glob '!.git' | \
      fzf +i --exact --delimiter : --preview 'batcat --style=full --color=always --highlight-line {2} {1}' --preview-window 'up,~4,+{2}+4/2')

# Remove cruft leaving something like: 'file:line:column'
ref=$(echo $out | sed -E 's/([a-zA-Z0-9/-_]*):([0-9]*):([0-9]*):.*/\1:\2:\3/')
hx $ref

Would be super useful to open the found file in a running instance of helix...
Is there a hack to do this?

@predmijat
Copy link

predmijat commented Feb 1, 2023

I'm not sure about the running instance, but you can open it in new one by editing FZF_DEFAULT_OPTS variable and adding something like this:

export FZF_DEFAULT_OPTS='... ,ctrl-o:execute(hx $(echo {} | cut -d ":" -f1))

I have this in my .zprofile since I'm using zsh, check where you shell sets FZF_DEFAULT_OPTS.

@obxhdx
Copy link

obxhdx commented Jun 1, 2023

@davxy, and anyone else interested: I hacked something together for this, you can read about it on my post on r/HelixEditor.

@pinpox
Copy link
Contributor

pinpox commented Jun 5, 2023

@davxy, and anyone else interested: I hacked something together for this, you can read about it on my post on r/HelixEditor.

This is cool, but limited to wezterm, right? Is there an option to do live-grep'ing project-wide inside helix itself or are there plans to add it?

@obxhdx
Copy link

obxhdx commented Jun 5, 2023

This is cool, but limited to wezterm, right? Is there an option to do live-grep'ing project-wide inside helix itself or are there plans to add it?

It’s like I said on the Reddit post, it’s a opinionated setup but I’m certain it can be adjusted. I’m pretty sure Kitty and Tmux have similar mechanisms for sending keys/text to another pane, for example.

Adding it natively in Helix is the whole point of this issue. I just wanted to share my workaround for those who (like me) are waiting for the native feature.

@matu3ba
Copy link

matu3ba commented Aug 30, 2023

Potential inspiration for a solution (does not have the matches in file preview due to being additionally complexity):
https://github.com/jake-stewart/jfind.nvim
and
https://github.com/jake-stewart/jfind

@gcanat
Copy link

gcanat commented Aug 31, 2023

Potential inspiration for a solution (does not have the matches in file preview due to being additionally complexity): https://github.com/jake-stewart/jfind.nvim and https://github.com/jake-stewart/jfind

More relevant would be to use this: #7814

@davxy
Copy link
Contributor

davxy commented Sep 1, 2023

Similar to #196 (comment) but using zellij+fzf

https://github.com/davxy/script-nest/blob/main/bin/helix-ext

The scripts allows to do a couple of IMO useful things (see the script help).

Modifications to helix config:

[keys.normal.'space'.'space']
# Extensions using custom script
# Interactive search in current working directory
s = ":pipe-to helix-ext search --current"
# Interactive search in current working directory (include path name in the search)
S = ":pipe-to helix-ext search --current-inc-path"
# Interactive search in current git directory
w = ":pipe-to helix-ext search --workspace"
# Interactive search in current git directory (include path name in the search)
W = ":pipe-to helix-ext search --workspace-inc-path"
# Interactive search in current buffer
b = ":pipe-to helix-ext search --buffer"
# Git status
m = ":pipe-to helix-ext git --status"
# Git blame
B = ":pipe-to helix-ext git --blame"
# Git browse github repo using default browser
O = ":pipe-to helix-ext git --browse"

@the-mikedavis the-mikedavis self-assigned this Sep 9, 2023
@chtenb
Copy link
Contributor

chtenb commented Sep 10, 2023

I think this feature is related to this issue: #2177
That thread also contains several ideas and workarounds to incorporate tools like broot that provide file-name and file-content search similar to fzf and ripgrep. Instead of re-inventing the wheel one could also consider supporting interaction with external tools through some kind of interface.

@pascalkuthe
Copy link
Member

pascalkuthe commented Sep 10, 2023

That would involve building in a terminal emulator insixe helix which is much much more work while also being a lot less integrated with the rest of our UI.

@the-mikedavis already has a working implementation of this based on #8021 and #7265. I have deamoed it and find it quite a bitee nicer tgab other options (and especially since it integrates well with the rest of the editor, which is the reason the picker is builtin to begin with). The columary picker really is a very nice approach.

So this issue just needs time for the implementation to be finished and land in master

@the-mikedavis
Copy link
Member

Ah I meant to post a demo here after assigning myself: https://asciinema.org/a/607253

Global search becomes a DynamicPicker like workspace symbol search (<space>S). You input a regex that runs across the workspace / cwd and new results are streamed in (like on master after #7814) so the picker doesn't block on become unresponsive, even when you're searching a large directory (my ~/src is ~120GB).

It needs some more tweaking but I plan to make a draft PR for it after #8021 is merged.

@TornaxO7
Copy link
Contributor

As far as I know, Helix uses nucleo when opening the fuzzy file finder. Maybe we could use that for grepping text as well?

@hakan-demirli
Copy link

hakan-demirli commented Dec 5, 2023

@davxy, and anyone else interested: I hacked something together for this, you can read about it on my post on r/HelixEditor.

Until this issue is fixed here is what I use. I ported the wezterm specific method mentioned in the blog post to tmux since it is terminal agnostic.

Kooha-2023-12-05-15-02-36.online-video-cutter.com.mp4

Add these three files to your path:

Add it to your config:

[keys.normal.space]
"/" = ":pipe-to live-grep-in-split-tmux"

@cyruseuros
Copy link

@the-mikedavis - don't mean to rush things, just pinging in case this got buried (always does for me). Is there a draft of the code to build/play around with now that #8021 has been merged?

@gabydd
Copy link
Member

gabydd commented Apr 16, 2024

It's implemented in #9647

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements C-enhancement Category: Improvements
Projects
None yet
Development

Successfully merging a pull request may close this issue.