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

Beta-testing 'mini.pick' #513

Closed
echasnovski opened this issue Oct 13, 2023 · 108 comments
Closed

Beta-testing 'mini.pick' #513

echasnovski opened this issue Oct 13, 2023 · 108 comments

Comments

@echasnovski
Copy link
Owner

Please leave your feedback about new mini.pick module here. Feel free to either add new comment or positively upvote existing one.

Some things I am interested to find out (obviously, besides bugs):

  • Are configuration and function/picker names intuitive enough?
  • Are default values of settings convenient for you?
  • Is documentation and examples clear enough?
  • Does default matching algorithm give relevant enough results?

Thanks!

@echasnovski echasnovski pinned this issue Oct 13, 2023
@Wansmer
Copy link

Wansmer commented Oct 14, 2023

Hi, thanks for the cool plugin!

I'm trying to make a picker similar to telescope.pickers.current_buffer_fuzzy_find({ default_text = vim.fn.expand('<cword>') }), but failed.

How can I pass the word under the cursor as a query when creating the picker?

I tried using MiniPick.set_picker_query(), but it has no effect. I called both before MiniPick.start() and after.

Here is an example of what I tried to do:

    local pick = require('mini.pick')

    pick.registry.grep_live_current_buf = function()
      local lines = vim.api.nvim_buf_get_lines(0, 1, -1, false)
      local items = {}

      local path = vim.fn.expand('%p')
      for lnum, line in ipairs(lines) do
        items[lnum] = { text = line, lnum = lnum + 1, path = path }
      end

      pick.start({
        source = {
          items = items,
          name = 'Grep current buffer',
        },
      })
      pick.set_picker_query(vim.split(vim.fn.expand('<cword>'), ''))
    end

As I understood from the plugin code, the initial query is always set empty in the private function H.picker_new. Is it possible to add an option in opts.source to specify the initial query?

@echasnovski
Copy link
Owner Author

I'm trying to make a picker similar to telescope.pickers.current_buffer_fuzzy_find({ default_text = vim.fn.expand('<cword>') }), but failed.

If it wasn't for only current buffer restriction, I'd suggest using grep directly. There is even example of that in the help (although, not in a very visible place).

How can I pass the word under the cursor as a query when creating the picker?

Your code is good, it only misses one important design: although start() is a non-blocking (allows other things to be executed), it is not fully asynchronous (it waits for user to choose and then returns certain value). It is documented both in "Implementation details" of overview and (not entirely directly) in start() itself.

So in your code by the time set_picker_query() is executed, picker is already stopped and thus it fails silently (as it is allowed to be called without active picker). If you call it directly before start(), it would behave the same (as there is no active picker yet). The solution here is to use vim.schedule() prior to start().

Here is my attempt:

MiniPick.registry.buffer_lines = function(local_opts)
  -- Parse options
  local_opts = vim.tbl_deep_extend('force', { buf_id = nil, prompt = '' }, local_opts or {})
  local buf_id, prompt = local_opts.buf_id, local_opts.prompt
  local_opts.buf_id, local_opts.prompt = nil, nil

  -- Construct items
  if buf_id == nil or buf_id == 0 then buf_id = vim.api.nvim_get_current_buf() end
  local lines = vim.api.nvim_buf_get_lines(buf_id, 0, -1, false)
  local items = {}
  for i, l in ipairs(lines) do
    items[i] = { text = string.format('%d:%s', i, l), bufnr = buf_id, lnum = i }
  end

  -- Start picker while scheduling setting the query
  vim.schedule(function() MiniPick.set_picker_query(vim.split(prompt, '')) end)
  MiniPick.start({ source = { items = items, name = 'Buffer lines' } })
end

@Wansmer
Copy link

Wansmer commented Oct 14, 2023

Thanks for the quick reply!

UPD: works with your example, thanks again!

@beaumccartney
Copy link

I saw this issue after I filed mine, huge apologies. TLDR is Pick grep searches .git folder, which isn't really useful. Excellent plugin!

#516

@echasnovski
Copy link
Owner Author

I saw this issue after I filed mine, huge apologies. TLDR is Pick grep searches .git folder, which isn't really useful. Excellent plugin!

#516

No worries. I'll think about it.

@assistcontrol
Copy link
Contributor

Gosh this one is amazing! The speed increase compared to Telescope is staggering. You should be really proud of what you've created here.

I'm struggling to figure out how to browse files in another directory. With Telescope, I had to lcd first, otherwise each entry was ../foo/bar/... etc. Between the readme and the doc, I can't figure out the incantation here.

Is there a mechanism to tell builtin.files() to use a specific dir? If not, I'd definitely urge one as it's something that Telescope is sorely missing. MiniPick.builtin.files({dir = '../foo/bar'}) would be huge for me.

@echasnovski
Copy link
Owner Author

Gosh this one is amazing! The speed increase compared to Telescope is staggering. You should be really proud of what you've created here.

❤️

I'm struggling to figure out how to browse files in another directory. With Telescope, I had to lcd first, otherwise each entry was ../foo/bar/... etc. Between the readme and the doc, I can't figure out the incantation here.

Is there a mechanism to tell builtin.files() to use a specific dir? If not, I'd definitely urge one as it's something that Telescope is sorely missing. MiniPick.builtin.files({dir = '../foo/bar'}) would be huge for me.

It is possible, as every source can have "current working directory". So with builtin.files() you can do MiniPick.builtin.files(nil, { source = { cwd = '../foo/bar' } }). If you plan to do that often interactively, you can modify files in registry and use :Pick files cwd='../foo/bar'.

It is made a part of the source for it to be more persistent and not depend on current working directory. Allowing it also as the local option for built-in picker is a code duplication I would like to avoid. Thus the modification of registry approach.


To be honest, I did not realize that picking something from different directory is a common thing. I'd make it more prominent in the documentation.

Maybe this is a workflow thing. I use setup_auto_root() and can't really remember when I needed to pick something from outside of the root. If I need something, then I usually know the location and use 'mini.files' to quickly navigate to it.

@assistcontrol
Copy link
Contributor

It is possible, as every source can have "current working directory". So with builtin.files() you can do MiniPick.builtin.files(nil, { source = { cwd = '../foo/bar' } }). If you plan to do that often interactively, you can modify files in registry and use :Pick files cwd='../foo/bar'.

That first incantation is a little awkward, but works perfectly for me. Thanks!

To be honest, I did not realize that picking something from different directory is a common thing. I'd make it more prominent in the documentation.

I’d encourage that! I (hope) I’m not the only person who’s wanted to do that, because if so then I’ve missed the point somewhere along the way.

Maybe this is a workflow thing. I use setup_auto_root() and can't really remember when I needed to pick something from outside of the root. If I need something, then I usually know the location and use 'mini.files' to quickly navigate to it.

My use case there is primarily mini.starter. I have a couple projects that I often want to work on or examine a particular file in, and spawning nvim and browsing one of those dirs is a very common workflow for me.

@echasnovski
Copy link
Owner Author

I saw this issue after I filed mine, huge apologies. TLDR is Pick grep searches .git folder, which isn't really useful. Excellent plugin!

#516

Duplicating from #516: suggested approach is to set up custom rg config file. Thanks @Keyhart for the tip!

@fannheyward
Copy link

Hello @echasnovski, mini.pick is great! Two issues in my tests:

  1. file first matching. For example, foo/abc.ts and src/foo.ts, after I input foo, I want src/foo.ts to be the first matched. Like fzf --delimiter / --nth -1,..
  2. :Pick grep unable to paste to input?

@echasnovski
Copy link
Owner Author

1. file first matching. For example, `foo/abc.ts` and `src/foo.ts`, after I input `foo`, I want `src/foo.ts` to be the first matched. Like `fzf --delimiter / --nth -1,..`

Yes, this is working as intended because matching algorithm is the same by default for any picker. If you add . or t (as in first letter of extension), it should put src/foo.ts first because its match has smaller width.

2. `:Pick grep` unable to paste to input?

What do you mean by "paste to input"? builtin.grep takes pattern as local option, which if not supplied asks user to input it interactively. You can do at least these:

  • Execute :Pick grep and then paste manually to the interactive input (via <C-r> and register name, for example).
  • Execute :Pick grep pattern='<paste here manually>'.
  • Execute :Pick grep pattern='<cword>' to search for word under cursor.

@fannheyward
Copy link

:Pick grep unable to paste to input?

Sorry, my typo. I can't paste in :Pick grep_live.

@echasnovski
Copy link
Owner Author

:Pick grep unable to paste to input?

Sorry, my typo. I can't paste in :Pick grep_live.

What do you mean by "paste"? There is a paste action with default mapping of <C-r>. So you can :Pick grep_live followed by <C-r> and register name. If you want some automated functionality like preset query with certain word (like word under cursor), then yes, it needs extra manipulation along the lines of this comment.

@fannheyward
Copy link

What do you mean by "paste"?

Copy something from other then paste to grep_live by system clipboard.

@echasnovski
Copy link
Owner Author

What do you mean by "paste"?

Copy something from other then paste to grep_live by system clipboard.

System clipboard can be accessed via one of + or * registers. Take a look at :h quoteplus and :h quotestar.

So on my machine I can select text from this page (select, click with right mouse button, select "Copy"). Then go into Neovim, execute :Pick grep_live followed by <C-r> and +. This will add system clipboard entry to the query.

@Jackevansevo
Copy link

I'm triggering mini.pick by the following mechanism

vim.keymap.set("n", "<leader>f",  ":Pick files<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<leader>/",  ":Pick grep<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<leader>b",  ":Pick buffers<CR>", { noremap = true, silent = true })

I'm finding neither <C-n> / <Down> or <C-p> / <Up> bindings are working for me (as suggested in the docs).

- Type special keys to perform |MiniPick-actions|. Here are some basic ones:
    - `<C-n>` / `<Down>` moves down; `<C-p>` / `<Up>` moves up.

@echasnovski
Copy link
Owner Author

Would you mind go into a bit more detail? Like:

  • Do you press, for example, <Leader>f to start finding files. Does the floating window appear with the list of files?
  • If window is active, what does pressing <C-n> or <Down> result in? Just nothing happens or happens something else (not moving the current item down)?
  • Do other keys work? Like <C-f>, <Tab>, or <CR>?
  • Just for a good measure: what terminal emulator and OS do you use?

@Jackevansevo
Copy link

Jackevansevo commented Oct 16, 2023

Would you mind go into a bit more detail? Like:

  • Do you press, for example, <Leader>f to start finding files. Does the floating window appear with the list of files?
  • If window is active, what does pressing <C-n> or <Down> result in? Just nothing happens or happens something else (not moving the current item down)?
  • Do other keys work? Like <C-f>, <Tab>, or <CR>?
  • Just for a good measure: what terminal emulator and OS do you use?

I'm on Mac OS & iterm, using <leader>f causes a floating window to appear, it's focussed and I can fuzzy search + open files in tabs or splits.

Most of the other bindings appear to be working, <C-a>, <C-u>, <C-x>, <C-f>, <C-b>, <Tab>

When pressing <C-n> / <Down> moves down; <C-p> / <Up> nothing is happening at all.

@echasnovski
Copy link
Owner Author

echasnovski commented Oct 16, 2023

I'm on Mac OS & iterm, using <leader>f causes a floating window to appear, it's focussed and I can fuzzy search + open files in tabs or splits.

Most of the other bindings appear to be working, <C-a>, <C-u>, <C-x>, <C-f>, <C-b>

When pressing <C-n> / <Down> moves down; <C-p> / <Up> nothing is happening at all.

I think I have an idea what might be going on. What does :hi MiniPickMatchCurrent show? By default it is linked to CursorLine and if you have cleared it, then moving current item won't show any effect. However, there is still should be an effect. For example, right after you open the picker, press <Down> several times and then <S-Tab>. This would open the info view and Current index line should show number bigger than 1.

Edit: Hmm... But you seem to use 'mini.base16', which should set visible CursorLine. Still a confirmation of a visible MiniPickMatchCurrent would be good.

@Jackevansevo
Copy link

If I disable mini.base16 (i.e. by not setting a colourscheme and re-opening vim) I can see that it's actually working as expected.

As soon as I do colorscheme minicyan or similar I can see it breaks.

Running :hi MiniPickMatchCurrent consistently gives me:

MiniPickMatchCurrent xxx cterm= gui=links to CursorLine

whether I've got mini.base16 enabled or not

@echasnovski
Copy link
Owner Author

echasnovski commented Oct 16, 2023

If I disable mini.base16 (i.e. by not setting a colourscheme and re-opening vim) I can see that it's actually working as expected.

As soon as I do colorscheme minicyan or similar I can see it breaks.

Running :hi MiniPickMatchCurrent consistently gives me:

MiniPickMatchCurrent xxx cterm= gui=links to CursorLine

whether I've got mini.base16 enabled or not

Yep, it is a 'mini.base16' issue. I forgot that floating window in it has the same background as cursor line. I'll fix it soon.

Edit: @Jackevansevo, I've pushed a 'mini.base16' update with tweaked highlight groups for 'mini.pick'. Should be all visible on latest main.

@oncomouse
Copy link

oncomouse commented Oct 16, 2023

Is there any way H.actions could be made user-accessible? I'd like to make an action to mark and then move down, which should be as simple as:

require("mini.pick").setup({
  mappings = {
    mark = nil,
    mark_and_move = {
      char = "<C-X>",
      func = function(picker)
        H.actions.mark(picker)
        H.actions.move_down(picker)
      end
    }
  }
})

but isn't because of the way actions are defined, unless I'm missing something.

@echasnovski
Copy link
Owner Author

Is there any way H.actions could be made user-accessible? I'd like to make an action to mark and then move down,

Yeah, I thought about that. The main reason for not exporting this is that there are already too much exported and I would like to limit it.

The solution for this case I assumed would be to create custom mapping emulating "mark" and "move_down" key presses. Something like this:

require('mini.pick').setup({
  mappings = {
    mark_and_down = {
      char = '<C-d>',
      func = function() vim.api.nvim_input(vim.api.nvim_replace_termcodes('<C-x><C-n>', true, true, true)) end,
    },
  },
})

@oncomouse
Copy link

@echasnovski Yes, that worked. Not the most convenient. Personally, I prefer the way telescope and, I believe, fzf-lua do mappings, where you map keycodes to actions, but this does get there.

@oncomouse
Copy link

@echasnovski As a note, this works as well and can account for anything that would change the setup: vim.api.nvim_input(vim.api.nvim_replace_termcodes(string.format("%s%s", MiniPick.config.mappings.mark, MiniPick.config.mappings.move_down), true, true, true))

@echasnovski
Copy link
Owner Author

@echasnovski As a note, this works as well and can account for anything that would change the setup: vim.api.nvim_input(vim.api.nvim_replace_termcodes(string.format("%s%s", MiniPick.config.mappings.mark, MiniPick.config.mappings.move_down), true, true, true))

Well, to be even more precise, it should account for possible picker-local mappings. Like this:

local mark_and_move_down = function()
  local mappings = MiniPick.get_picker_opts().mappings
  local keys = mappings.mark .. mappings.move_down
  vim.api.nvim_input(vim.api.nvim_replace_termcodes(keys, true, true, true))
end
require('mini.pick').setup({
  mappings = {
    mark_and_down = { char = '<C-d>', func = mark_and_move_down },
  },
})

@Jackevansevo
Copy link

Edit: @Jackevansevo, I've pushed a 'mini.base16' update with tweaked highlight groups for 'mini.pick'. Should be all visible on latest main.

confirmed this is working perfectly now, cheers for the help 👍

@bethandtownes
Copy link

is there a way to enable preview automatically?

@echasnovski
Copy link
Owner Author

@JulesNP, today I realized that I can make builtin.help help custom mappings for <C-s>, <C-v>, and <C-t>. So those should now open the help window in horizontal, vertical, and tabpage splits.

@marcusandre
Copy link
Contributor

@JulesNP, today I realized that I can make builtin.help help custom mappings for <C-s>, <C-v>, and <C-t>. So those should now open the help window in horizontal, vertical, and tabpage splits.

Awesome. Just updated and can report that it is working fine 👍

@JulesNP
Copy link

JulesNP commented Nov 8, 2023

@JulesNP, today I realized that I can make builtin.help help custom mappings for <C-s>, <C-v>, and <C-t>. So those should now open the help window in horizontal, vertical, and tabpage splits.

Thanks! Everything's working great with the latest changes. I've fully switched over from Telescope now in my config.

@bassamsdata
Copy link

I want to express my gratitude first for creating all these fantastic modules.

I've been utilizing mini.Pick since its inception, and it has proven to be excellent, especially in terms of its responsiveness and speed. It has nearly replaced my telescope workflow, particularly after the launch of mini.extra, for which I extend my congratulations.

While mini.Pick and mini.extra cover most of my needs, I still rely on telescope for one specific tool: the telescope-undo extension. This extension has been truly amazing, especially with its yanking capabilities for addition or deletion. My suggestion or rather a request is to consider creating a dedicated pick for undo/history functionality (or dedicated Module eg. Mini.Unfasten 🫣). This module could stand out by integrating git history seamlessly into the same timeline as undo 🔥, a feature that, as of now, is absent in the vim universe but present in VS Code.

Additionally, I'm curious if there's a way to customize the appearance of each pick. For instance, I'd like pick buffers or files to be much smaller and positioned in the bottom right, unlike grep_live, which I prefer to have in a larger window.

On a related note, I'm wondering if there's a method to implement grep_live specifically for help files (not the one for only help tags). I attempted to do so, but the outcome was less than satisfactory. Apologies for the less-than-ideal implementation.

My attempt for Pick help_grep

Note: some of the code below borrowed and modified from another tele. ext.

    config = function(_, opts)
      local MiniPick = require("mini.pick")
      MiniPick.setup({})
      MiniPick.registry.help_files = function(local_opts)
        -- Parse options
        local_opts = vim.tbl_deep_extend("force", { prompt = "" }, local_opts or {})
        local prompt = local_opts.prompt
        local_opts.prompt = nil

        -- Get the paths of the help files
        local paths = vim.api.nvim_get_option("runtimepath")
        paths = vim.split(paths, ",")
        local dirs = {}
        for _, path in ipairs(paths) do
          local doc_path = path .. "/doc"
          if vim.fn.isdirectory(doc_path) == 1 then
            table.insert(dirs, doc_path)
          end
        end

        -- Start the picker based on CLI output
        MiniPick.builtin.cli({
          command = {
            "rg",
            prompt,
            "--color",
            "never",
            "--no-messages",
            "--line-buffered",
            "-g",
            "!*.log",
            "-n",
            "-H",
            unpack(dirs),
          },
          prompt_title = "Help Grep",
        }, local_opts)
      end
    end,

thank you for your time and assistance!

@echasnovski
Copy link
Owner Author

I want to express my gratitude first for creating all these fantastic modules.

I've been utilizing mini.Pick since its inception, and it has proven to be excellent, especially in terms of its responsiveness and speed. It has nearly replaced my telescope workflow, particularly after the launch of mini.extra, for which I extend my congratulations.

Thanks for kind words! Much appreciated 🙏

While mini.Pick and mini.extra cover most of my needs, I still rely on telescope for one specific tool: the telescope-undo extension. This extension has been truly amazing, especially with its yanking capabilities for addition or deletion. My suggestion or rather a request is to consider creating a dedicated pick for undo/history functionality (or dedicated Module eg. Mini.Unfasten 🫣). This module could stand out by integrating git history seamlessly into the same timeline as undo 🔥, a feature that, as of now, is absent in the vim universe but present in VS Code.

Thanks for the suggestion! I'll think about it, but initial reaction is that this is unlikely to happen. There is a certain novel undo integration in 'mini.bracketed' (see its undo() target). I vividly remember having quite a few problems dealing with the undo history (as in, it can be done but there are many hidden pitfalls).

Additionally, I'm curious if there's a way to customize the appearance of each pick. For instance, I'd like pick buffers or files to be much smaller and positioned in the bottom right, unlike grep_live, which I prefer to have in a larger window.

Yes, it is possible. All pickers in MiniPick.builtin and MiniExtra.pickers take two arguments: local_opts (specific to picker) and opts (configuration for MiniPick.start()).

Here is a quick example of how to create a new picker help_right inside a MiniPick.registry:

MiniPick.registry.help_right = function()
  local win_config =
    { relative = 'editor', anchor = 'SE', row = vim.o.lines, col = vim.o.columns, height = 20, width = 40 }
  return MiniPick.builtin.help({}, { window = { config = win_config } })
end

Having this executed (after require('mini.pick').setup()), you can now do :Pick help_right. Customize specific details of window config to your liking (see :h nvim_open_win).

On a related note, I'm wondering if there's a method to implement grep_live specifically for help files (not the one for only help tags). I attempted to do so, but the outcome was less than satisfactory. Apologies for the less-than-ideal implementation.
My attempt for Pick help_grep

Note: some of the code below borrowed and modified from another tele. ext.

    config = function(_, opts)
      local MiniPick = require("mini.pick")
      MiniPick.setup({})
      MiniPick.registry.help_files = function(local_opts)
        -- Parse options
        local_opts = vim.tbl_deep_extend("force", { prompt = "" }, local_opts or {})
        local prompt = local_opts.prompt
        local_opts.prompt = nil

        -- Get the paths of the help files
        local paths = vim.api.nvim_get_option("runtimepath")
        paths = vim.split(paths, ",")
        local dirs = {}
        for _, path in ipairs(paths) do
          local doc_path = path .. "/doc"
          if vim.fn.isdirectory(doc_path) == 1 then
            table.insert(dirs, doc_path)
          end
        end

        -- Start the picker based on CLI output
        MiniPick.builtin.cli({
          command = {
            "rg",
            prompt,
            "--color",
            "never",
            "--no-messages",
            "--line-buffered",
            "-g",
            "!*.log",
            "-n",
            "-H",
            unpack(dirs),
          },
          prompt_title = "Help Grep",
        }, local_opts)
      end
    end,

thank you for your time and assistance!

I would advise not to try and implement specifically a grep_live version, as it it is quite involved if you want it to work smoothly (or at all even, really). If you must, I'd start from grep_live source (there are couple of unexported helpers used, but they should be replaceable).

What you have is a variant of builtin.grep, which is a more reasonable idea. The general approach of using rg inside a dedicated runtime directories seems doable. The details of which arguments to use I'll leave to the audience :) One observation, though: prompt_title is not a part of builtin.cli arguments; you'd probably want a { source = { name = 'Help Grep' } } as the second, opts argument.

That said, I'd suggest to go another route completely. Take a look at :h helpgrep or :h lhelpgrep. With it you can do something like this:

  • :helpgrep <pattern> (like :helpgrep window). This creates a quickfix list (with lhelpgrep it creates a location list).
  • Use :Pick list scope='quickfix' to navigate through quickfix list (or use location list if needed).

You can wrap those two steps in a single function if you'd like.

@Aphosis
Copy link

Aphosis commented Nov 13, 2023

Hi ! Thanks a lot for mini.pick, it was a breeze to configure and works great ! Performance is really good too, which was my main reason for switching.

I've been wondering if there was something I could do to switch my rg configuration between pickers ?

For example, I'd like the default behavior of grep_live to use my default rg configuration, ignoring hidden and ignored files. But I'd also like to be able to call grep_live with another rg configuration, in case I need to find something in a hidden or ignored file.

To keep the configuration method consistent with the chosen solution, in the case of rg this would mean the ability, from mini.pick, to override RIPGREP_CONFIG_PATH for a given picker.

I saw that there is already support for cwd for the grep tool subprocess, mini.pick could also expose the env argument ?

And for simplicity, it would be nice to be able to concatenate arbitrary args to what mini.pick already uses, too.

This way, we could either do:

MiniPick.builtin.grep_live({tool = "rg"}, {source = {env = {"RIPGREP_CONFIG_PATH" = "/path/to/specific/configuration"}}})

or

MiniPick.builtin.grep_live({tool = "rg"}, {source = {args = {"--hidden"}}})

This wouldn't need any tool specific handling from mini.pick, but would allow users to customize the calls for convenience.

@echasnovski
Copy link
Owner Author

I've been wondering if there was something I could do to switch my rg configuration between pickers ?

For example, I'd like the default behavior of grep_live to use my default rg configuration, ignoring hidden and ignored files. But I'd also like to be able to call grep_live with another rg configuration, in case I need to find something in a hidden or ignored file.

To keep the configuration method consistent with the chosen solution, in the case of rg this would mean the ability, from mini.pick, to override RIPGREP_CONFIG_PATH for a given picker.

I think the best solution here would be to write a wrapper function which temporarily sets the environment variables. Something like this:

MiniPick.registry.grep_live_specific = function()
  local cache_rg_config = vim.uv.os_getenv('RIPGREP_CONFIG_PATH')
  vim.uv.os_setenv('RIPGREP_CONFIG_PATH', '/path/to/specific/configuration')
  MiniPick.builtin.grep_live({ tool = 'rg' })
  vim.uv.os_setenv('RIPGREP_CONFIG_PATH', cache_rg_config)
end

You can then call it with :Pick grep_live_specific.

I saw that there is already support for cwd for the grep tool subprocess, mini.pick could also expose the env argument ?

And for simplicity, it would be nice to be able to concatenate arbitrary args to what mini.pick already uses, too.

grep_live is a very unusual picker which doesn't operate as others. So having it affect the overall picker source design wouldn't be wise.

For other CLI related tasks there is a builtin.cli() picker which has spawn_opts local option to set anything vim.uv.spawn() allows as option.

@Aphosis
Copy link

Aphosis commented Nov 13, 2023

You can then call it with :Pick grep_live_specific.

Thanks, this works like a charm !

@EddieFAF
Copy link

I really like your work. My setup contains only mini.nvim and a few others for LSP. But I'm having trouble getting mini.pick to work.
On 2 out of 3 systems, I only get the floating window with no content. I can ESC to close that window, but nothing else happens. That's independent of the picker I choose, neither files nor buffers shows anything. On the third system, everything works as intended. I'm using exactly the same config (same init.lua file) on all three systems.
Any hints what might causing this? :checkhealth on all three shows nothing obviously wrong.

@echasnovski
Copy link
Owner Author

I really like your work. My setup contains only mini.nvim and a few others for LSP. But I'm having trouble getting mini.pick to work. On 2 out of 3 systems, I only get the floating window with no content. I can ESC to close that window, but nothing else happens. That's independent of the picker I choose, neither files nor buffers shows anything. On the third system, everything works as intended. I'm using exactly the same config (same init.lua file) on all three systems. Any hints what might causing this? :checkhealth on all three shows nothing obviously wrong.

Hi, thanks!

Without additional information I can not really help. For example:

  • What is the working system and what are two that don't work?
  • Does any built-in picker work? For example, builtin.help?
  • Does a direct picker start work? Try executing :lua require('mini.pick').start({ source = { items = { 'a', 'b' } } }) which should result into a picker with two items "a" and "b".

@EddieFAF
Copy link

EddieFAF commented Nov 17, 2023

Without additional information I can not really help. For example:

  • What is the working system and what are two that don't work?

working: Arch, neovim 0.9.4
nonworking: debian 12, neovim 0.10.0 and debian 11, neovim 0.10.0

  • Does any built-in picker work? For example, builtin.help?

I'm using those via keybinding, but nothing shows beside the empty window :(

  • Does a direct picker start work? Try executing :lua require('mini.pick').start({ source = { items = { 'a', 'b' } } }) which should result into a picker with two items "a" and "b".

Nothing shown

EDIT:
Rebuilding nvim from source on one system (still 0.10.0) solved the problem. Rebuilding on the other aswell... lets wait and see...

@echasnovski
Copy link
Owner Author

working: Arch, neovim 0.9.4
nonworking: debian 12, neovim 0.10.0 and debian 11, neovim 0.10.0

My guess would be that both 0.10.0 versions are too old and don't have the floating window footer feature. Either using latest Nightly appimage or indeed rebuilding latest nightly from source should solve the issue in this case.

@EddieFAF
Copy link

working: Arch, neovim 0.9.4
nonworking: debian 12, neovim 0.10.0 and debian 11, neovim 0.10.0

My guess would be that both 0.10.0 versions are too old and don't have the floating window footer feature. Either using latest Nightly appimage or indeed rebuilding latest nightly from source should solve the issue in this case.

As usual, you are absolutly right :) Rebuild both nvim versions solved my problem. Thanks.

@juantascon
Copy link

Is there a way to resume just one individual picker? I would like to set a keymap to always open live_grep with the last searched word, basically something similar to fzf live_grep_resume.

@echasnovski
Copy link
Owner Author

Is there a way to resume just one individual picker? I would like to set a keymap to always open live_grep with the last searched word, basically something similar to fzf live_grep_resume.

Unfortunately, no. It would require storing too much data, so there is only one builtin.resume() to resume the latest used picker.

You can kind of implement this by overriding choose action to store the latest query and then implement other picker to use that query as initial. Something like this:

local latest_grep_live_query = {}
MiniPick.registry.grep_live = function(local_opts)
  local cache_query_and_choose = function(...)
    latest_grep_live_query = MiniPick.get_picker_query()
    return MiniPick.default_choose(...)
  end

  return MiniPick.builtin.grep_live(local_opts, { source = { choose = cache_query_and_choose } })
end

MiniPick.registry.grep_live_resume = function(local_opts)
  vim.schedule(function() MiniPick.set_picker_query(latest_grep_live_query) end)
  return MiniPick.registry.grep_live(local_opts)
end

With this you can use :Pick grep_live_resume to resume latest search. Note that it will resume with the query when the latest chosen item was chosen. So if you looked for something and hit <Esc>, it doesn't store the query. You can also override <Esc> to also store it, but I would like to leave to actual users.

@echasnovski
Copy link
Owner Author

With the release of 0.11.0, 'mini.pick' is now out of beta-testing. Huge thanks to everyone for constructive feedback and participation!

@echasnovski echasnovski unpinned this issue Nov 17, 2023
@marcusandre
Copy link
Contributor

@echasnovski Thank you for your work and dedication! I immediately switched to it and I don't see any point to switch back.

@endir
Copy link

endir commented Nov 21, 2023

Thank you for the very nice plugin. Is there a way to have ignorecase when doing grep_live?

@echasnovski
Copy link
Owner Author

Thank you for the very nice plugin. Is there a way to have ignorecase when doing grep_live?

builtin.grep_live uses CLI tool with only a minimal set of arguments to make it work. To configure it further, configure corresponding tool. If you use rg, then it is a matter of putting a --ignore-case line in some file and setting RIPGREP_CONFIG_PATH environment variable to point to it. See this part of rg guide.

@endir
Copy link

endir commented Nov 22, 2023

Thanks a lot Evgeni! Did not know about ripgrep's config file. Works beautifully!

@ghost
Copy link

ghost commented Nov 26, 2023

Hi, thanks for the great plugin!
How would I go about configuring a grep and grep_live picker that would use GNU grep?

@echasnovski
Copy link
Owner Author

Hi, thanks for the great plugin! How would I go about configuring a grep and grep_live picker that would use GNU grep?

builtin.grep_live only supports rg or git (which is git grep and very close to GNU grep) tools. I'd recommend using git tool with something like :Pick grep_live tool='git'.

builtin.grep also supports git tool, but if you really need GNU, you can use builtin.cli() picker to call grep CLI tool in a way similar to the output of git grep.

@ghost
Copy link

ghost commented Nov 26, 2023

Thanks for the quick reply!

It's just that I don't want to have a dependency on rg. Using git is acceptable, but is it possible to pass additional flags like --untracked to git grep for grep_live picker?

@echasnovski
Copy link
Owner Author

Thanks for the quick reply!

It's just that I don't want to have a dependency on rg. Using git is acceptable, but is it possible to pass additional flags like --untracked to git grep for grep_live picker?

As grep_live is a fairly unique picker in how it works, there are some limitations as to it. The suggested approach is to configure each CLI tool separately, but I am not sure if git can be configured to use --untracked for only git grep command.

My suggestion would be to either use builtin.cli() with desired flags (but no "live" behavior) or use rg.

@GitMurf
Copy link

GitMurf commented Oct 4, 2024

Note

@echasnovski I'm not sure if this is appropriate to add here on this older gh issue but thought it was better than opening a new gh issue or something (since it is not an issue but a question / request). Please let me know for the future what protocol you would prefer I follow for items like these!

For mini pickers, is there a way to have preview split out to side of the main picker items? similar to how telescope does it so you can cycle through the items in the picker and have the preview shown on the right side for example. Also similar to how you have mini.files working in concept where you can navigate the list of items and the preview is shown to the right.

Thanks!

@echasnovski
Copy link
Owner Author

Please let me know for the future what protocol you would prefer I follow for items like these!

There is a separate Q&A category for discussion which is dedicated for this type of interaction.

For mini pickers, is there a way to have preview split out to side of the main picker items? similar to how telescope does it so you can cycle through the items in the picker and have the preview shown on the right side for example. Also similar to how you have mini.files working in concept where you can navigate the list of items and the preview is shown to the right.

I am afraid, no. The whole idea is to have it be single window only while separate preview needs extra window. The 'mini.pick' approach is to have preview enabled with <Tab> and then navigate up/down: this will stay in preview mode.

@GitMurf
Copy link

GitMurf commented Oct 4, 2024

I am afraid, no. The whole idea is to have it be single window only while separate preview needs extra window. The 'mini.pick' approach is to have preview enabled with <Tab> and then navigate up/down: this will stay in preview mode.

No worries! Thanks for the response. I kind of figured as such given your approach (which I appreciate) with trying to keep code as simple and concise as possible while maximizing features/value. Cycling through while in preview gets me most the way there.

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

No branches or pull requests