ibhagwan / fzf-lua

Improved fzf.vim written in lua
MIT License
2.31k stars 150 forks source link

Possible to restrict several directories to pass to FZF? #683

Closed yangmillstheory closed 1 year ago

yangmillstheory commented 1 year ago

Hi,

I work on a codebase that's massive, millions of lines of code. In my Vim config, I have something like this to be able to manually set the directory I pass to rg (which is used by fzf).

" https://github.com/junegunn/fzf.vim#advanced-customization
"
" explicitly include/exclude directories from fzf + rg
" these aren't plugin options, but our own :)
let g:rg_in = []
let g:rg_ex = []
nnoremap <Leader>d q:ilet g:rg_in=['']<esc>hi
function! s:RgArgs(args) abort
  let rg_args = []
  if len(g:rg_ex)
    let rg_args += ["--glob=!{" . join(g:rg_ex, ",") . "}"]
  endif
  if len(a:args)
    let rg_args += [a:args]
  endif
  return join(rg_args + g:rg_in, " ")
endfunction
command! -bang -complete=dir -nargs=? FzfFiles
\ call fzf#run(fzf#wrap({
\     'source': $FZF_DEFAULT_COMMAND . " " . s:RgArgs(''),
\     'options': $FZF_DEFAULT_OPTS . " " . $FZF_CTRL_T_OPTS,
\   }),
\   <bang>0
\ )
command! -bang -nargs=* FzfRg
\ call fzf#vim#grep(
\   "rg --hidden --ignore-case --column --line-number --no-heading --color=always " . s:RgArgs(<q-args>), 1,
\   <bang>0 ? fzf#vim#with_preview('up:60%')
\           : fzf#vim#with_preview('right:50%'),
\   <bang>0)
" }}}

Would it be possible to do this via your plugin?

ibhagwan commented 1 year ago

It’s one of the most basic use cases, use the cwd option (works with all providers, not just grep):

require'fzf-lua'.live_grep({ cwd = <directory> })
ibhagwan commented 1 year ago

If you wish to use globs as your code snippet suggests, take a look at this: https://github.com/ibhagwan/fzf-lua/wiki#live-grep-glob

yangmillstheory commented 1 year ago

Thanks - is there a config option that would work with the files command?

ibhagwan commented 1 year ago

Thanks - is there a config option that would work with the files command?

cwd works with files too.

yangmillstheory commented 1 year ago

OK, thanks, I'll try this out!

yangmillstheory commented 1 year ago

Here's my after/plugin/fzf-lua.lua file:

local g = vim.g

-- https://github.com/junegunn/fzf.vim#advanced-customization
--
-- explicitly include/exclude directories from fzf + rg
g.rg_in = {}
g.rg_ex = {}

-- quickly edit g.rg_in
vim.api.nvim_set_keymap('n', '<leader>d', ":q:ilet g:rg_in=['']<esc>hi", {})

local fzf = require('fzf-lua')

fzf.setup({
  files = {
    cwd = table.concat(g.rg_in, " ")
  },
  grep = {
    cwd = table.concat(g.rg_in, " ")
  },
})

local keymap_opts = { silent = true, noremap = true }
vim.api.nvim_set_keymap('n', '<c-t>', ':FzfLua files<cr>',keymap_opts )
vim.api.nvim_set_keymap('n', '<c-f>', ':FzfLua live_grep<space>', keymap_opts) 
vim.api.nvim_set_keymap('n', '<c-b>', ':FzfLua buffers<cr>', keymap_opts) 
vim.api.nvim_set_keymap('n', '<c-_>', ':FzfLua blines<cr>', keymap_opts) 
vim.api.nvim_set_keymap('n', '<c-r>', ':FzfLua command_history<cr>', keymap_opts) 
vim.api.nvim_set_keymap('n', '<c-s>', ':FzfLua search_history<cr>', keymap_opts) 
vim.api.nvim_set_keymap('n', '<c-c>', ':FzfLua commands<cr>', keymap_opts) 
vim.api.nvim_set_keymap('n', '<c-q>', ':FzfLua quickfix<cr>', keymap_opts) 

I set g:rg_in to my home directory. When I try CTRL-T, I get

image

which is empty, but I should be finding files.

yangmillstheory commented 1 year ago

Also when I do <leader>d and set g:rg_in to any directory and press Enter, the FzfLua marks window pops up:

image

And when I try to quit out of the FZF panes (CTRL-C or Escape), the panes don't seem to go away.

ibhagwan commented 1 year ago

which is empty, but I should be finding files. What am I doing wrong?

Why are you using table.concat?

It seems you’re sending an empty cwd, in lua there is no g., change it to vim.g.rg_in instead.

You can also check if the var is set with :lua print(vim.g.rg_in) which should print the variable into :messages, once you verified the global var is set use :lua require'fzf-lua'.files({ cwd = vim.g.rg_in }) and see if it works.

ibhagwan commented 1 year ago

Why are there two panes there?

The second pane is the preview which you can hide with F4 (use F1 to see all the binds).

ibhagwan commented 1 year ago

And when I try to quit out of the FZF panes (CTRL-C or Escape), the panes don't seem to go away.

Perhaps you have something in your config taking over the binds?

First try with mini.sh and see that everything works, if it doesn’t work with min.sh it’s a bug (unlikely or there would be tons of issues about closing the panels):

sh -c "$(curl -s https://raw.githubusercontent.com/ibhagwan/fzf-lua/main/scripts/mini.sh)"
yangmillstheory commented 1 year ago

It seems I can somewhat leverage cwd via:

vim.api.nvim_set_keymap('n', '<c-t>',
  ':lua require("fzf-lua").files({ cwd = table.concat(vim.g.rg_in, " ") })<cr>',
  keymap_opts)

Why are you using table.concat?

I'd like to specify multiple paths, not a single root. This doesn't seem possible. Can it be supported?

image

Again I work in a codebase with O(1M), possibly O(100M) files, with directories of interest rooted in various places, not all under the same root.

ibhagwan commented 1 year ago

I'd like to specify multiple paths, not a single root. This doesn't seem possible. Can it be supported?

The underlying command runs rg --files inside a working directory, perhaps you can craft a shell command that combines multiple commands but it’s not supported natively.

yangmillstheory commented 1 year ago

Could you implement the feature request to allow passing multiple directories?

ibhagwan commented 1 year ago

Could you implement the feature request to allow passing multiple directories?

Not ATM, you can easily find a workaround for this with a custom shell command.

ibhagwan commented 1 year ago

You can easily do this with fd (install it first) and then craft your command as follows:

:lua require("fzf-lua").files({ cmd = 'fd . path1 path2 path3' })
-- in your case
:lua require("fzf-lua").files({ cmd = 'fd . ' .. table.concat(vim.g.rg_in, ' ') })

make sure to add other fd arguments you need (ignore .git, etc)

You can also do the same thing you posted in the OP with rg, use the cmd argument to pass whatever you want to grep or live grep, with some effort on your end almost any customization is possible, be sure to read the advanced Wiki

yangmillstheory commented 1 year ago

Is there a way to get the other default options and UI when using the raw command, or do I have to write it myself?

Also why use fd for files? Why not rg?

On Sun, Mar 12, 2023, 23:50 ibhagwan @.***> wrote:

You can easily do this with fd (install it first) and then craft your command as follows:

:lua require("fzf-lua").files({ cmd = 'fd . path1 path2 path3' })-- in your case :lua require("fzf-lua").files({ cmd = 'fd . ' .. table.concat(vim.g.rg_in, ' ') })

make sure to add other fd arguments you need (ignore .git, etc)

— Reply to this email directly, view it on GitHub https://github.com/ibhagwan/fzf-lua/issues/683#issuecomment-1465320967, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAU2I55PY5WURY3FW5E2OHDW3ZOMNANCNFSM6AAAAAAVYEJFSI . You are receiving this because you authored the thread.Message ID: @.***>

ibhagwan commented 1 year ago

Is there a way to get the other default options and UI when using the raw command, or do I have to write it myself?

You do get the default options when using cmd, it just replaces the underlying command, you can still override any default option if you send it to the command as well, read the README and wiki.

Also why use fd for files? Why not rg?

You can use whatever you wish, I just gave you an option for multiple folders, in general rg is better at grep’ing but fd is a specialized find replacement better at finding files within folders.

yangmillstheory commented 1 year ago

I think it would be best if the FR were implemented. It's a simple use case and it takes a lot of time and energy to figure hack around the API to make it work otherwise. Thanks for your help though.

ibhagwan commented 1 year ago

I think it would be best if the FR were implemented. It's a simple use case and it takes a lot of time and energy to figure hack around the API to make it work otherwise. Thanks for your help though.

I respectfully disagree, if you read the docs and the wiki and understand how the plug-in works and it’s integration with fzf and the shell this request is quite basic, the plug-in already has way too many customization options and does way more than fzf.vim out of the box without having to understand anything.

Sending a custom cmd to fzf isn’t a “hack” but a feature and IMHO doesn’t take lots of time and energy.

ibhagwan commented 1 year ago

Closing, if you’re still struggling with this feel free to reopen.