mini.nvim icon indicating copy to clipboard operation
mini.nvim copied to clipboard

Beta-testing 'mini.visits'

Open echasnovski opened this issue 7 months ago • 19 comments

Please leave your feedback about new mini.visits 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):

  • Is configuration intuitive enough?
  • Are default values of settings convenient for you?
  • Is documentation and examples clear enough?

Thanks!

echasnovski avatar Nov 28 '23 15:11 echasnovski

Hello. Thank you for all the effort you put in your plugins.

Since it is compared with Harpoon, I would like to know whether I can achieve the same workflow with mini.visits. The docs confused me a little, specifically these two parts in the comparisons section:

  1. "This module implements a more common labeling which does not imply order with the ability to make it automated depending on the task and/or preference."

    1. Is there a way to reorder the marks manually?
    2. If I can't reorder the marks manually, what's the benefit of mini.visits's approach in this specific use case?
    3. What do you mean by "automated" here? Can you please name a few examples?
  2. "Implements marks as positions in a path, while this module labels paths."

    1. There is no way to save the cursor position? That's too bad.

Thank you again.

amirhhashemi avatar Nov 28 '23 16:11 amirhhashemi

Hi!

My first suggestion would be to take a look at workflow and setup examples. It should clarify some of suggested ways to use this module.

Think about labels in a more broad sense: it is a mechanism to group paths. Good example is GitHub issues: they can have one or more labels which can be used to query issues. How users later order them is up to them.

  • Is there a way to reorder the marks manually?

It is technically possible with some custom sort function, but it is not and is never planned to be built-in. By default they are sorted by "robust frecency".

  • If I can't reorder the marks manually, what's the benefit of mini.visits's approach in this specific use case?

To be more general.

  • What do you mean by "automated" here? Can you please name a few examples?

After querying all paths containing label, they can be ordered by latest visit time, or by visit frequency, or by "robust frecency" (default), etc.

There is no way to save the cursor position? That's too bad.

Yes, there is no way. Labels are property of path. However, if that path is already opened in your current session, opening it will just focus the buffer at the current cursor position (not at the buffer start).

echasnovski avatar Nov 28 '23 17:11 echasnovski

Would there be a way to only allow files in a git repository, that way automatically parsing out sensitive/local files?

ndavd avatar Nov 29 '23 12:11 ndavd

Would there be a way to only allow files in a git repository, that way automatically parsing out sensitive/local files?

To parse when listing paths from index, there is config.list.filter which can filter path based on any its available data. To not autoregister visit in buffer, you can set vim.b.minivisits_disable inside of them.

I don't really understand how you define "sensitive/local" files, so can't help further.

echasnovski avatar Nov 29 '23 12:11 echasnovski

I don't really understand how you define "sensitive/local" files, so can't help further.

I meant that that'd be the most common reason for someone to only allow files in a .git repository, respecting .gitignore, etc.

ndavd avatar Nov 29 '23 12:11 ndavd

I don't really understand how you define "sensitive/local" files, so can't help further.

I meant that that'd be the most common reason for someone to only allow files in a .git repository, respecting .gitignore, etc.

I don't see this as a reason, to be honest. But can be done with autocommand on BufCreate which utilizes git CLI tool. No plans of being built-in, though.

echasnovski avatar Nov 29 '23 12:11 echasnovski

Is it possible to emit some sort of Event (LabelAdded / LabelRemoved) whenever a label is added/removed from a path/file? Trying to implement a statusline indicator to show whether a file is labeled or not.

zahidislm avatar Nov 30 '23 22:11 zahidislm

Is it possible to emit some sort of Event (LabelAdded / LabelRemoved) whenever a label is added/removed from a path/file? Trying to implement a statusline indicator to show whether a file is labeled or not.

It is possible, but I am not yet sure if this aligns with overall 'min.visits' design. Labels sure are important and built-in, but it is essentially just data about visits. I'll think about it.

My suggestion right now would be to write a wrapper for add_label() and remove_label(). Inside them do same things you'd do inside LabelAdded / LabelRemoved events plus actually calling add_label() / remove_label().

echasnovski avatar Dec 01 '23 08:12 echasnovski

add_path not working as expected

I am using visits to mark project in monorepo like rust project.

The code is like this:

function M.add_project(project_path, cwd)
  local visits = require('mini.visits')
  visits.add_path(project_path, cwd)
  visits.add_label('project', project_path, cwd)
  visits.write_index()
end

function M.list_projects_in_cwd(cwd)
  local extra = require('mini.extra')
  extra.pickers.visit_paths({ cwd = cwd, filter = 'project', recency_weight = 0 }, {
    source = {
      choose = function(item)
        vim.print(item)
      end
    }
  })
end

use it like:

    {
      '<leader>pp',
      function()
        require('userlib.mini.visits').list_projects_in_cwd(vim.cfg.runtime__starts_cwd)
      end,
      desc = 'List projects in cwd',
    },
    {
      '<leader>pa',
      function()
        require('userlib.mini.visits').add_project(vim.uv.cwd(), vim.cfg.runtime__starts_cwd)
      end,
      desc = 'Add project',
    },
    {
      '<leader>pP',
      function()
        require('mini.visits').write_index()
      end,
      desc = 'Write index',
    }

So when I am inside folder './git-repos/rust'(runtime_starts_cwd, monorepo path) and do open a file in one project and the vim cwd will be changed to the child project's root(managed by other plugin), I did use vim.print and cwd and project_path is correct. but after write_index, the results is not what I expected, the result is:

  ["/Users/towry/workspace/git-repos/rust/compiler/rustc"] = {
    ["/Users/towry/workspace/git-repos/rust/compiler/rustc"] = {
      count = 2,
      latest = 1701441739
    },
    ["/Users/towry/workspace/git-repos/rust/compiler/rustc/build.rs"] = {
      count = 14,
      latest = 1701443386
    }
  }

why git-repos/rust not used ? this make the list projects in cwd not working.

towry avatar Dec 01 '23 15:12 towry

What does vim.cfg.runtime__starts_cwd show? As it is used as cwd under which you add path. Where does it come from (as it is not built-in)?

echasnovski avatar Dec 01 '23 15:12 echasnovski

vim.cfg.runtime__starts_cwd is vim.uv.cwd() when starting nvim in a folder(the folder path that nvim starts from).

in monorepo, multiple project root can be the current cwd. I am using https://github.com/ahmedkhalf/project.nvim to manage projects.

When I open a buffer, project_nvim will use lsp or project patterns(.git, package.json etc) to determine current project root, then use vim.cmd.tcd to change the cwd.

So I want to

  1. enter git-repos/rust, the starts_cwd will be git-repos/rust.
  2. open any buffer in any project, I can add this project path under starts_cwd, so next time I start nvim in starts_cwd, I can quickly list last added projects paths in this specific path(starts_cwd), and then use other tools to find files or open oil.nvim in the chosen project. https://github.com/echasnovski/mini.nvim/discussions/33#discussioncomment-7626736

towry avatar Dec 01 '23 15:12 towry

vim.cfg.runtime__starts_cwd is vim.uv.cwd() when starting nvim in a folder(the folder path that nvim starts from).

Could you, please, execute :=vim.cfg.runtime__starts_cwd prior to typing <Leader>pa and tell if it prints git-repos/rust (as you'd expect)? Ideally when Neovim is started without any mini-visits-index (so that results are the cleanest possible here).


Also, there is no need to call add_path() before add_label(). The latter will ensure that path is added.

echasnovski avatar Dec 01 '23 15:12 echasnovski

https://github.com/echasnovski/mini.nvim/assets/8279858/4198a778-b317-4515-a66e-d2b3dc67188d

@echasnovski


  vim.print(index)

  -- Normalize index
  index = MiniVisits.normalize_index(index)
  vim.print(index)

the first print is ok with expected output:

截屏2023-12-02 00 05 05

after normalize, the labeld paths is lost.


seems because count is 0 and meet the condition local should_prune = should_prune_path or path_tbl.count < threshold ?

towry avatar Dec 01 '23 15:12 towry

seems because count is 0 and meet the condition local should_prune = should_prune_path or path_tbl.count < threshold ?

Yes, it was exactly the issue. It should now work on latest main.

echasnovski avatar Dec 01 '23 18:12 echasnovski

Hey! First off, big thanks for putting together this module – it's really impressive, and I'm excited to see mini.picker and mini.extra continue to evolve! 😊 I've got a few questions that I thought I'd put here instead of creating multiple issues.

  1. I was wondering if it's possible to enable searching in multiple directories simultaneously within grep_live? It would be super handy to widen the search scope.

  2. The scrolling with C-f and C-b feels a bit disorienting to me in Pickers. Is there a way to manage that to be more "smooth" or can we incorporate something like neoscroll to enhance the scrolling experience?

  3. Is there a way to display the frecency score on the picker? While I'm on the topic, I've found the original frecency a bit quirky; it seems to calculate file scores independently, potentially leading to files with high scores sticking around indefinitely. I read the new scoring you code and now I'm trying to play with it a bit (see below pic when I tried in the past the telescope one 🫣)

  4. I've noticed some inconsistency with Pick hunks. Can it be configured to display hunks across the entire workspace? Currently, it seems like adding % to the args shows hunks for the current file, and without any arguments, it displays nothing. (I read the filter thing but I need to show all hunks before staged)

On a side note, kudos on the fantastic new Neovim colorscheme! I've been eagerly waiting for an improved default colorscheme, and you nailed it. Thanks a bunch for your hard work! 😄

Telescope frecency: Screenshot 2023-12-06 at 10 51 46 PM

bassamsdata avatar Dec 07 '23 03:12 bassamsdata

Thanks for kind words!

Asking not 'mini.visits' related questions would have been better in a "Q&A" section of Discussions, but no worries for this time.

  1. I was wondering if it's possible to enable searching in multiple directories simultaneously within grep_live? It would be super handy to widen the search scope.

It uses either rg or git under the hood. As far as I can tell, both of them only search inside single directory. You can search in some parent directory, but that might result in some false positives.

2. The scrolling with C-f and C-b feels a bit disorienting to me in Pickers. Is there a way to manage that to be more "smooth" or can we incorporate something like neoscroll to enhance the scrolling experience?

Sorry, this is definitely not planned. Proper smooth scrolling proved to be extra troublesome during development of mini.animate. Mostly because it needs to have side effects and change what is actually shown.

3. Is there a way to display the frecency score on the picker? While I'm on the topic, I've found the original frecency a bit quirky; it seems to calculate file scores independently, potentially leading to files with high scores sticking around indefinitely. I read the new scoring you code and now I'm trying to play with it a bit (see below pic when I tried in the past the telescope one 🫣)

As 'mini.pick' can customize what is displayed in the window with source.show, this is, of course, possible. Yet it is not built-in and probably won't ever be for at least these reasons:

  • Sorting mechanism in general doesn't need to depend on some kind of value to sort on. So having it displayed should be tailored to the default sort, which is not really clean.
  • I don't find any practical new information in them, as in default sort they are used merely to have something to sort on.

4. I've noticed some inconsistency with Pick hunks. Can it be configured to display hunks across the entire workspace? Currently, it seems like adding % to the args shows hunks for the current file, and without any arguments, it displays nothing. (I read the filter thing but I need to show all hunks before staged)

It should already by default show all hunks from the Git repository of the current directory. I.e. using either MiniExtra.pickers.git_hunks() or :Pick git_hunks should already do that.

echasnovski avatar Dec 07 '23 08:12 echasnovski

thank you so much for the detailed response.

As 'mini.pick' can customize what is displayed in the window with source.show, this is, of course, possible. Yet it is not built-in and probably won't ever be for at least these reasons:

I was specifically attempting to implement the scoring feature in pick visit_paths since that's where my interest lies. however, i encountered difficulty in displaying it. unfortunately, I couldn't find an api to retrieve it from the function minivisits.gen_sort.default.

I believe it would be particularly useful only in the paths picker, but I understand it may not be implemented, and that's perfectly fine.

Sorry, this is definitely not planned. Proper smooth scrolling proved to be extra troublesome during development of mini.animate. Mostly because it needs to have side effects and change what is actually shown.

I totally understand that, but would it be possible to allow users to define the number of lines scrolled? for instance, when using c-f and c-b, it would be great to have the option to set it to, say, 4 lines only. or this is have to do with neovim default for C-b and C-f in general? I tried doing neo scrolling action with new mappings with 4<C-y> and 4<C-E> but didn't work. I'm not sure how to do it if that's the case tbh.

It should already by default show all hunks from the Git repository of the current directory. I.e. using either MiniExtra.pickers.git_hunks() or :Pick git_hunks should already do that.

regarding the hunks picker, i suspect there might be an issue with repositories that have a big number of hunks. i'll go ahead and open an issue to discuss it further.

thanks again!

bassamsdata avatar Dec 10 '23 04:12 bassamsdata

unfortunately, I couldn't find an api to retrieve it from the function minivisits.gen_sort.default.

Yes, because I really think it should not be that important. The whole algorithm is described in help or you can look at source code for it.

I totally understand that, but would it be possible to allow users to define the number of lines scrolled? for instance, when using c-f and c-b, it would be great to have the option to set it to, say, 4 lines only. or this is have to do with neovim default for C-b and C-f in general?

I've thought about it and it is definitely possible. The main obstacle here is that 'mini.pick' is already overloaded by options and I don't quite want to add another ones.

Besides this one, scrolling in main view (when items are shown) is implemented in a particular way that is not very compatible with the idea of "scroll by variable number of lines". It is mostly designed to be "don't scroll if the new current item is visible, try to center it otherwise". You can see what I mean by continuously pressing <C-n> and see how items view change.

echasnovski avatar Dec 10 '23 13:12 echasnovski

scrolling in main view (when items are shown) is implemented in a particular way that is not very compatible with the idea of "scroll by variable number of lines".

hey! thanks for the reply. 😊 totally get your point about scrolling. but I think most users seem use scrolling in the preview window for quick navigation, since usually we get the needed item whithin the 4 or 5 first items.

In the end, I found an easy solution and I was trying in the right direction and turns out, using special characters did the trick.

Screenshot 2023-12-10 at 1 09 00 PM

here's my scrolling implementation, which can be adjusted to any line count. also added a copy-to-register feature, handy for commands like pick history for : or searches with /.

-- copy the item under the cursor
local copy_to_register = {
  char = "<C-y>",
  func = function()
    local current_line = vim.fn.getline(".")
    vim.fn.setreg('"', current_line)
    end,
}
-- scrll by margin of 4 lines to not disorient eyes
local scroll_up = {
  char = "<C-k>",
  func = function()
    -- this is special character in insert mode press C-v then y
    -- while holding Ctrl to invoke
    vim.cmd("normal! 4�") -- it look like this `^Y`
    end,
}
local scroll_down = {
  char = "<C-j>",
  func = function()
    vim.cmd("norm! 4�") -- it look like this `^E`
    end,
}

MiniPick.setup({ 
    mappings = {
    copy_to_register = copy_to_register,
    scroll_up_a_bit = scroll_up,
    scroll_down_a_bit = scroll_down,
    },
    })

The main obstacle here is that 'mini.pick' is already overloaded by options and I don't quite want to add another ones.

absolutely get it. 'mini.pick' does wear quite a few hats already. 😅 it's a bit of an ambitious plugin (as I think you said it already), but that's what makes it versatile. it's like building an ecosystem, right?

bassamsdata avatar Dec 10 '23 18:12 bassamsdata

I'd like to scope my visits to a branch, and I had kinda hoped that there would be an option to provide my own cwd generating function where I could append the current branch name to the actual cwd string.

What's the easiest way to achieve visits scoped by branch as well as cwd currently? I feel like having the option to provide a cwd-calculation function would be nice, but I might be missing something 🤔

debugloop avatar Feb 17 '24 14:02 debugloop

I'd like to scope my visits to a branch, and I had kinda hoped that there would be an option to provide my own cwd generating function where I could append the current branch name to the actual cwd string.

What's the easiest way to achieve visits scoped by branch as well as cwd currently? I feel like having the option to provide a cwd-calculation function would be nice, but I might be missing something 🤔

Sorry, configurable cwd is out of scope here. Mostly because it contradicts the widely used assumption about cwd actually being a file system path.

Here are suggestions I'd explore for your use case:

  • Use Git worktrees. This is basically a feature that creates a separate cwd for branch, which sound very close to the use case at hand.
  • Try labels with automated name for branch. Maybe you don't really want all visits to be registered, but only selected ones. In that case it can be a good alternative.

echasnovski avatar Feb 17 '24 14:02 echasnovski

I thought of both, but I'm kinda unwilling to change my git workflow and I've wanted to do this completely passively. I might try to figure out how to hook into the additions or create my own aucmd to label files I enter with your second suggestion 👍🏻

debugloop avatar Feb 17 '24 15:02 debugloop

With the release of 0.12.0, 'mini.visits' is now (finally) out of beta-testing. Many thanks to everyone for constructive feedback and actual use cases!

echasnovski avatar Feb 29 '24 16:02 echasnovski