echasnovski / mini.nvim

Library of 40+ independent Lua modules improving overall Neovim (version 0.8 and higher) experience with minimal effort
MIT License
4.74k stars 179 forks source link

[mini.completion] using `mini.fuzzy` to process LSP items #812

Closed pkazmier closed 4 months ago

pkazmier commented 4 months ago

Contributing guidelines

Module(s)

mini.completion, mini.fuzzy

Description

Today I'm testing fuzzy completion with mini.completion using mini.fuzzy, but I'm not sure the behavior I'm seeing is what I should expect. As I type characters, the popup opens correctly initially, but then closes as I continue to type, and finally opens again sometime later with the correct match. For example, if my buffer contains:

local H = {}
H.test_is_this_working = function() end
H.test_or_am_i_crazy = function() end
H.test_or_both = function() end

This is what happens when I perform the following actions:

  1. Go, end of file, open line
  2. H.t, popup opens with 3 functions from LSP
  3. w, popup closes (not expected)
  4. o, popup remains closed
  5. r, popup opens again with "test_is_this_working() Function" (expected)

I was expecting the popup to remain open in step 3 and display the "test_is_this_working()" item as it was the only candidate with the letter "t" and "w" in it.

I have confirmed that executing the following returns the expected single result, so it does not appear to be an issue with mini.fuzzy:

:lua =require("mini.fuzzy").filtersort("tw", {"test_is_this_working", "test_or_am_i_crazy", "test_or_both"})
:lua =require("mini.fuzzy").filtersort("two", {"test_is_this_working", "test_or_am_i_crazy", "test_or_both"})
:lua =require("mini.fuzzy").filtersort("twor", {"test_is_this_working", "test_or_am_i_crazy", "test_or_both"})

Neovim version

NVIM v0.9.5, Build type: Release, LuaJIT 2.1.1703358377

Steps to reproduce

See steps in description.

Here is a minimal.lua configuration for testing if needed.

```lua -- Clone 'mini.nvim' manually in a way that it gets managed by 'mini.deps' local path_package = vim.fn.stdpath("data") .. "/site/" local mini_path = path_package .. "pack/deps/start/mini.nvim" if not vim.loop.fs_stat(mini_path) then vim.cmd('echo "Installing `mini.nvim`" | redraw') local clone_cmd = { "git", "clone", "--filter=blob:none", "https://github.com/echasnovski/mini.nvim", mini_path, } vim.fn.system(clone_cmd) vim.cmd("packadd mini.nvim | helptags ALL") vim.cmd('echo "Installed `mini.nvim`" | redraw') end -- Set up 'mini.deps' (customize to your liking) require("mini.deps").setup({ path = { package = path_package } }) MiniDeps.add("williamboman/mason.nvim") MiniDeps.add("williamboman/mason-lspconfig.nvim") MiniDeps.add("neovim/nvim-lspconfig") require("mini.completion").setup({ lsp_completion = { source_func = "completefunc", auto_setup = true, process_items = require("mini.fuzzy").process_lsp_items, }, }) require("mason").setup() require("mason-lspconfig").setup({ ensure_installed = { "lua_ls" } }) require("lspconfig").lua_ls.setup({ on_attach = function(client, bufnr) -- vim.bo[bufnr].omnifunc = "v:lua.MiniCompletion.completefunc_lsp" end, }) local H = {} H.test_is_this_working = function() end H.test_or_am_i_crazy = function() end H.test_or_both = function() end ```

Expected behavior

See description with actual vs expected behavior.

Actual behavior

See description with actual vs expected behavior.

echasnovski commented 4 months ago

Yes, this works as expected (albeit not ideally).

MiniCompletion.config.lsp_completion.process_items is a function which processes response items of LSP request. This is done only at completion initialization (to actually get a full list of completion items). After that, the built-in completion filtering is "in charge" which is not fuzzy.

  • H.t, popup opens with 3 functions from LSP
  • w, popup closes (not expected)
  • o, popup remains closed
  • r, popup opens again with "test_is_this_working() Function" (expected)

So what happens is that pressing w results into empty completion list (as filtering is not fuzzy) but the built-in completion is still active (you can do <BS> and it will show previous completion list immediately). Pressing o results into built-in completion being finished (without new completion initializing). Pressing r results into a new completion initialization which makes new LSP request and matches fuzzily.

Although a bit unintuitive, this is how built-in completion and 'mini.completion' works. I don't think this is a huge issue right now, as at any point pressing <C-Space> forces new LSP request with later showing up to date candidates.

Closing as "although not ideal, works as expected".

pkazmier commented 4 months ago

Thank you for the explanation.

In my opinion, this means that MiniCompletion.config.lsp_completion.process_items should not be used for interactive fuzzy completion. The main benefit of fuzzy completion is that I can quickly explore the list of candidates interactively as I'm typing and BS'ing and typing and BS'ing.

The actual behavior, as you state, is not intuitive when using MiniFuzzy.process_lsp_items. And, likely, not what most users would expect of fuzzy completion. I think process_items is better suited for filtering as most of MiniCompletion's documentation states.

Over the past several weekends, I've been incorporating more and more of the mini ecosystem. I've adopted all of them so far with the exception of mini.pairs (doesn't support several use cases in python) and mini.deps (haven't tried it yet, next weekend likely). I'm torn on mini.completion due to the fuzzy finding behavior as I'm so accustomed to nvim-cmp. I'll test for a week without fuzzy finding using the default configuration before I make a decision.

The balance you are trying to achieve with regards to simplicity and user experience is a tough act. For me, I think you have found a nice balance in most of the modules. And, since I've adopted most of these, I feel like my vim instance is not as sluggish. Maybe it's all in my head, but vim feels snappy again to me, so thank you.

echasnovski commented 4 months ago

I'm torn on mini.completion due to the fuzzy finding behavior as I'm so accustomed to nvim-cmp. I'll test for a week without fuzzy finding using the default configuration before I make a decision.

This is the current price to pay for 'mini.completion' to do as much as possible using built-in features. It is the main reason why this module is not as big as might have been with custom matching and visualization. I have hope that in some future there will be a fuzzy matching for built-in completion (there were open issues about it in Vim).