nvim-telescope / telescope.nvim

Find, Filter, Preview, Pick. All lua, all the time.
MIT License
15.97k stars 838 forks source link

Setting up fuzzy live grep #564

Closed jaywonchung closed 2 years ago

jaywonchung commented 3 years ago

I migrated from fzf.vim to telescope.nvim recently, and I'm trying to setup the :Ag command that fzf.vim provides. It basically does a live fuzzy search on the contents of every file in the current directory. For instance, typing in CPRT will match and show the line containing COPYRIGHT.

I did get ag working, but without fuzzy search. I tried setting sorters.get_fzy_sorters, but without ag returning a fuzzy-matched list this seemed meaningless. Is it possible to setup fuzzy live grep using telescope.nvim?

Thanks.

elianiva commented 3 years ago

the command is :Telescope live_grep

jaywonchung commented 3 years ago

I've been using :Telescope live_grep throughout. I don't think it fuzzy matches.

clason commented 3 years ago

live_grep works a bit differently: it passes the typed text straight to rg (or friends) and shows the results.

What you can do instead is :Telescope grep_string search='', which makes rg return all matches, and then you can use telescope to fuzzy filter. (Warning: this will be slow on large directories.)

Conni2461 commented 3 years ago

Its not fuzzy. Because it will send the current prompt to rg after each key press. If you want to do something fuzzy do:

require'telescope.builtin'.grep_string{ shorten_path = true, word_match = "-w", only_sort_text = true, search = '' }

important opts are only_sort_text = true which will exclude filenames from matching and search ='' which will basically get all line content in buffer

Edit: clason was 5 sec faster :sob: :rofl:

kkharji commented 3 years ago

I think this can be done by creating a command over grep_string, where it gets the q-args into search opts which passes to rg or ag.

I'll create a pr soon, if @Conni2461 haven't already created it :laughing: .

This is indeed in important use cases, specially in big directories and in working directories you are trying to find something in it by a pattern and not be overwhelmed by a big list of items

jaywonchung commented 3 years ago

Thank you all! grep_string with search = '' and only_sort_text = true indeed gives me fuzzy live search. I read how fzf.vim does this, and it actually does the same thing. It retrieves all lines with either ag or rg, and filters the lines based on user input with fzf. It looks like it optimizes the fzf side by caching the search history in ~/.local/share/fzf-history/ag.

However, there is one small missing feature. Smart-case search is gone with grep_string + empty search query. fzf.vim does supprt smart-case search since fzf itself defaults to searching with smart-case.

Thank you again!

rorybyrne commented 3 years ago

This still doesn't work well for me. For example, the search term fordake should find the following line but it doesn't:

for key in data.keys()

fzf handles this case much better.

Conni2461 commented 2 years ago

I wanna close this issue and sum it up once more and also present a new feature.

live_grep is not comparable with :Rg. If you want :Rg the following command should work for you :Telescope grep_string search=

live_grep allows you to basically have a dynamic way to perform a ripgrep search where the whole prompt gets passed to ripgrep after each key press. It can't be fuzzy unless ripgrep provides a fuzzy engine, but it can be regex which can be quite handy.

The new feature is that you can now perform a live_grep search and then refine your search over the live_grep results in a fuzzy environment after pressing <c-space>. In combination with fzf-native this can be handy to filter out specific files/... in your live_grep results. You can configure the keymap, see https://github.com/nvim-telescope/telescope.nvim/pull/2034

For me there is nothing left to do here, so i would close this issue.

otavioschwanck commented 2 years ago

I wanna close this issue and sum it up once more and also present a new feature.

live_grep is not comparable with :Rg. If you want :Rg the following command should work for you :Telescope grep_string search=

live_grep allows you to basically have a dynamic way to perform a ripgrep search where the whole prompt gets passed to ripgrep after each key press. It can't be fuzzy unless ripgrep provides a fuzzy engine, but it can be regex which can be quite handy.

The new feature is that you can now perform a live_grep search and then refine your search over the live_grep results in a fuzzy environment after pressing <c-space>. In combination with fzf-native this can be handy to filter out specific files/... in your live_grep results. You can configure the keymap, see #2034

For me there is nothing left to do here, so i would close this issue.

awesome, this is exactly what i wanted.

linrongbin16 commented 1 year ago

Hi @Conni2461 , thanks for your commit #2034.

I'm quite new to telescope.nvim. Would you please help me understand: how could I use this to_fuzzy_refine to make live_grep behave like :Rg from fzf? Since in your answer, it looks like still needs some key mapping () to do this? which is different with my needs.

dshoreman commented 1 year ago

@linrongbin16 There is an example you can use in the first comment on that PR. It works differently to :Rg though.

The PR example uses <C-f> not <c-space>, but to quote an earlier comment (emphasis mine):

The new feature is that you can now perform a live_grep search and then refine your search over the live_grep results in a fuzzy environment after pressing <c-space>.

I'm also new to Telescope (and lua) but if you want something more like :Rg, I set mine up like this:

-- ~/.config/nvim/configs/telescope.lua - completely arbitrary filename, can be anywhere in runtimepath
local telescope, builtin = require('telescope'), require('telescope.builtin')

telescope.setup{
}

telescope.load_extension('fzf')        -- without this there's no 'foo | ^bar | baz$' style filtering
                                       -- requires telescope-fzf-native, check the readme/wiki

function fuzzyFindFiles()
  builtin.grep_string({
    path_display = { 'smart' },
    only_sort_text = true,
    word_match = "-w",
    search = '',
  })
end

vim.keymap.set('n', '<C-g>', '<cmd>lua fuzzyFindFiles{}<cr>', {}) -- map whatever you want, I use ctrl-g

...which I source into init.vim. There are better ways than using a global function, but I'm lazy.

You could also use this in the map if you prefer one-liners.

While the sorting isn't perfect (note the base64 matches), I'm still getting better matches overall than I had previously using fzf/rg: image

leikoilja commented 1 year ago

For ppl missing original FZF, there seems to finally be a solution https://github.com/ibhagwan/fzf-lua The blazing fast FZF search is finally back :)

stephenmckinney commented 1 year ago

if you want to be able to e.g. !lua on file names you have to use only_sort_text = false. The sorting can be a lil wonky but helps to filter out certain files.