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

redundant candidates from different source. #32

Closed
ccshao opened this issue Aug 17, 2021 · 29 comments
Closed

redundant candidates from different source. #32

ccshao opened this issue Aug 17, 2021 · 29 comments
Labels
bug Something isn't working

Comments

@ccshao
Copy link

ccshao commented Aug 17, 2021

How should I config to remove the redundant candidates from popmenu, e.g. library from both buffer and lsp, I would like to only keep buffer candidates. Thanks!

Screenshot_2021-08-17_16-24-08

my settings.

lua << EOF
local cmp = require'cmp'
cmp.setup {
  mapping = {
    ['<C-p>'] = cmp.mapping.prev_item(),
    ['<C-n>'] = cmp.mapping.next_item(),
    ['<C-d>'] = cmp.mapping.scroll(-4),
    ['<C-f>'] = cmp.mapping.scroll(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    })
  },

  sources = {
      { name = 'buffer' },
      { name = 'nvim_lsp' },
      { name = 'path' },
  },

  documentation = false,
}

require('cmp_nvim_lsp').setup {}
EOF
@hrsh7th
Copy link
Owner

hrsh7th commented Aug 17, 2021

@ccshao nvim-cmp respects sources order. and the cmp-buffer source avoid duplicated items by default.

So you can use the following config for the problem.

cmp.setup {
  mapping = {
    ['<C-p>'] = cmp.mapping.prev_item(),
    ['<C-n>'] = cmp.mapping.next_item(),
    ['<C-d>'] = cmp.mapping.scroll(-4),
    ['<C-f>'] = cmp.mapping.scroll(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    })
  },

  sources = {
      { name = 'nvim_lsp' },
      { name = 'path' },
      { name = 'buffer' },
  },

  documentation = false,
}

@rhcher
Copy link

rhcher commented Aug 17, 2021

@ccshao nvim-cmp respects sources order. and the cmp-buffer source avoid duplicated items by default.

So you can use the following config for the problem.

cmp.setup {
  mapping = {
    ['<C-p>'] = cmp.mapping.prev_item(),
    ['<C-n>'] = cmp.mapping.next_item(),
    ['<C-d>'] = cmp.mapping.scroll(-4),
    ['<C-f>'] = cmp.mapping.scroll(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    })
  },

  sources = {
      { name = 'nvim_lsp' },
      { name = 'path' },
      { name = 'buffer' },
  },

  documentation = false,
}

This looks like there is no difference

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 17, 2021

No. The sources order is changed.

@ccshao
Copy link
Author

ccshao commented Aug 17, 2021

Inddeed swapping the order works.

I just found something interesting, that buffer could find other candidates in other buffers.

In the example bellow, I have a few words in 1.R, and split 2.R in the same window. When I type libr, there are no candidates from 1.R, namely, libre, librart, but only from lsp. The order of buffer does not matter.

What do I need to add to the config to let nvim-cmp see other buffers?
Screenshot 2021-08-17 at 18 30 59

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 17, 2021

It is a source-related customization. See https://github.com/hrsh7th/cmp-buffer

cmp.setup {
  mapping = {
    ['<C-p>'] = cmp.mapping.prev_item(),
    ['<C-n>'] = cmp.mapping.next_item(),
    ['<C-d>'] = cmp.mapping.scroll(-4),
    ['<C-f>'] = cmp.mapping.scroll(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    })
  },

  sources = {
      { name = 'nvim_lsp' },
      { name = 'path' },
      {
        name = 'buffer',
        opts = {
          get_bufnrs = function()
            local bufs = {}
            for _, win in ipairs(vim.api.nvim_list_wins()) do
              bufs[vim.api.nvim_win_get_buf(win)] = true
            end
            return vim.tbl_keys(bufs)
          end
        }
      },
  },
}

@rhcher
Copy link

rhcher commented Aug 17, 2021

No. The sources order is changed.

Big shock, it's time to adjust my configuration again

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 17, 2021

Sorry for confusion. I thoughts it is intuitive way.... TT

@ccshao
Copy link
Author

ccshao commented Aug 17, 2021

Thanks!

May I bother you with another small issue? The reason I put buffer ahead of lsp is buffer candidates are usually more relevant.

Now the lsp are top candidates, how could I give more weights to buffer candiates? I think it is related to priority_weight but I don't know how to tweak it.

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 18, 2021

@ccshao It is not supported as suitable way but nvim-cmp provides fully customizable vim's completion item by the user.

cmp.setup {
  formatting = {
    format = function(entry, vim_item)
      if entry.source.name == 'nvim_lsp' then
        vim_item.dup = 0
      end
      return vim_item
    end
  }
}

@ccshao
Copy link
Author

ccshao commented Aug 18, 2021

Thanks for the suggestions, sorry I don't know much about vimscript/lua. The above formating codes seems not put the lsp candidates behind all buffer candidates.

In the example, I would like to get TEXT candidates in front of Function/Module/Feld from lsp.

Screenshot 2021-08-18 at 08 58 56

lua << EOF
local cmp = require'cmp'
cmp.setup {
  mapping = {
    ['<C-p>'] = cmp.mapping.prev_item(),
    ['<C-n>'] = cmp.mapping.next_item(),
    ['<C-d>'] = cmp.mapping.scroll(-4),
    ['<C-f>'] = cmp.mapping.scroll(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    })
  },

  sources = {
        { name = 'nvim_lsp' },
        { name = 'path' },
        { name = 'buffer',
          opts = {
            get_bufnrs = function()
              local bufs = {}
              for _, win in ipairs(vim.api.nvim_list_wins()) do
                bufs[vim.api.nvim_win_get_buf(win)] = true
              end
              return vim.tbl_keys(bufs)
            end
          }
        },
  },

  formatting = {
    format = function(entry, vim_item)
      if entry.source.name == 'nvim_lsp' then
        vim_item.dup = 0
      end
      return vim_item
    end
  },

  documentation = false,
}

require('cmp_nvim_lsp').setup {}
EOF

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 18, 2021

  1. Prefer buffer source than nvim-lsp source
    You should change the sources option order. The first item will be show to the top.

  2. nvim-lsp source should hide if the buffer source's same word item exists.
    You can specify the above formatting.format option

@ccshao
Copy link
Author

ccshao commented Aug 18, 2021

I might get the logic, so the buffer is ahead of lsp in the source setting, and add the formation options.

  sources = {
      { name = 'buffer',
        opts = {
          get_bufnrs = function()
            local bufs = {}
            for _, win in ipairs(vim.api.nvim_list_wins()) do
              bufs[vim.api.nvim_win_get_buf(win)] = true
            end
            return vim.tbl_keys(bufs)
          end
        }
      },
      { name = 'path' },
      { name = 'nvim_lsp' },
  },

  formatting = {
    format = function(entry, vim_item)
      if entry.source.name == 'nvim_lsp' then
        vim_item.dup = 0
      end
      return vim_item
    end
  },

However, now I get duplicated candidates from buffer...

Screenshot_2021-08-18_09-58-11

@rhcher
Copy link

rhcher commented Aug 18, 2021

However, now I get duplicated candidates from buffer...

If you don't want to have dup items you can delete formatting section. The cmp will hide dup items by default.

@ccshao
Copy link
Author

ccshao commented Aug 18, 2021

Strangely I still see the duplicated candidates, with a miminum setting:

lua << EOF
local cmp = require'cmp'
cmp.setup {
  mapping = {
    ['<C-p>'] = cmp.mapping.prev_item(),
    ['<C-n>'] = cmp.mapping.next_item(),
    ['<C-d>'] = cmp.mapping.scroll(-4),
    ['<C-f>'] = cmp.mapping.scroll(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    })
  },

  sources = {
      { name = 'buffer' },
      { name = 'path' },
      { name = 'nvim_lsp' },

  },

  documentation = false,
}

require('cmp_nvim_lsp').setup {}
EOF

To get ride of duplicates, I have to put { name = 'nvim_lsp' },ahead of { name = 'buffer' },.

@Shougo
Copy link

Shougo commented Aug 18, 2021

I think nvim_lsp candidates set dup, so you need to set dup=0 if don't like the dup.

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 18, 2021

Hm... Could you share your environment to testing?

Language Server
File content
etc

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 18, 2021

Note: nvim-lsp source set dup=1 by default.

@hrsh7th hrsh7th added the bug Something isn't working label Aug 19, 2021
@hrsh7th
Copy link
Owner

hrsh7th commented Aug 19, 2021

It's may be a bug. I will investigate it.

@ccshao
Copy link
Author

ccshao commented Aug 19, 2021

I am bit of lost in the settings, so here is the summary, with nvim 0.5.0, all latest plugins, and R language server.

setting 1. Works great, no redundant candidates from buffer and lsp.

sources = {
      { name = 'nvim_lsp' },
      { name = 'path' },
      { name = 'buffer',
        opts = {
          get_bufnrs = function()
            local bufs = {}
            for _, win in ipairs(vim.api.nvim_list_wins()) do
              bufs[vim.api.nvim_win_get_buf(win)] = true
            end
            return vim.tbl_keys(bufs)
          end
        }
      },
  },

setting 2. Duplicated items from buffer (indicated by "Text" in the popup)

sources = {
      { name = 'buffer' },
      { name = 'path' },
      { name = 'nvim_lsp' },

  },

" or with buffer config
  sources = {
          { name = 'buffer',
            opts = {
              get_bufnrs = function()
                local bufs = {}
                for _, win in ipairs(vim.api.nvim_list_wins()) do
                  bufs[vim.api.nvim_win_get_buf(win)] = true
                end
                return vim.tbl_keys(bufs)
              end
            }
          },
          { name = 'nvim_lsp' },
          { name = 'path' },
  },

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 19, 2021

Thank you for your information.

I guess the R language server returns items that contain the same duplicated Text entries.

I will provide debuggable configuration for it. Please wait.

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 21, 2021

    formatting = {
      format = function(entry, vim_item)
        vim_item.kind = lspkind.presets.default[vim_item.kind]
        vim_item.menu = ({
          nvim_lsp = '[L]',
          emoji    = '[E]',
          path     = '[F]',
          calc     = '[C]',
          vsnip    = '[S]',
          buffer   = '[B]',
        })[entry.source.name]
        return vim_item
      end
    }

@ccshao Could you test with this config?

It can be used to detect which source returned the item.

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 21, 2021

Then can you try this?

  formatting = {
    format = function(entry, vim_item)
      vim_item.menu = ({
        nvim_lsp = '[L]',
        emoji    = '[E]',
        path     = '[F]',
        calc     = '[C]',
        vsnip    = '[S]',
        buffer   = '[B]',
      })[entry.source.name]
      return vim_item
    end

@ccshao
Copy link
Author

ccshao commented Aug 21, 2021

Seems the duplilcated from both lsp and buffer.
Screenshot 2021-08-21 at 18 42 42

sources = {
   { name = 'buffer',
     opts = {
       get_bufnrs = function()
         local bufs = {}
         for _, win in ipairs(vim.api.nvim_list_wins()) do
           bufs[vim.api.nvim_win_get_buf(win)] = true
         end
         return vim.tbl_keys(bufs)
       end
     }
   },
   { name = 'nvim_lsp' },
   { name = 'path' },
 },

 formatting = {
   format = function(entry, vim_item)
     vim_item.menu = ({
       nvim_lsp = '[L]',
       emoji    = '[E]',
       path     = '[F]',
       calc     = '[C]',
       vsnip    = '[S]',
       buffer   = '[B]',
     })[entry.source.name]
     return vim_item
   end
 },

If I put the buffer at the end of source, then all comes from lsp.
Screenshot 2021-08-21 at 18 46 10

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 21, 2021

Yes. It is understandable to me.

Your expected behavior can be realized with the following config maybe.

sources = {
   { name = 'buffer',
     opts = {
       get_bufnrs = function()
         local bufs = {}
         for _, win in ipairs(vim.api.nvim_list_wins()) do
           bufs[vim.api.nvim_win_get_buf(win)] = true
         end
         return vim.tbl_keys(bufs)
       end
     }
   },
   { name = 'nvim_lsp' },
   { name = 'path' },
 },

 formatting = {
   format = function(entry, vim_item)
     vim_item.menu = ({
       nvim_lsp = '[L]',
       emoji    = '[E]',
       path     = '[F]',
       calc     = '[C]',
       vsnip    = '[S]',
       buffer   = '[B]',
     })[entry.source.name]
     vim_item.dup = ({
       buffer = 1,
       path = 1,
       nvim_lsp = 0,
     })[entry.source.name] or 0
     return vim_item
   end
 },

@ccshao
Copy link
Author

ccshao commented Aug 21, 2021

I still get the duplicated candidates from both lsp and buffer with exactly the above settings ...

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 21, 2021

Thsnk you and Sorry for annoying.

I think the above config dhould work so I will investigate it.

@ccshao
Copy link
Author

ccshao commented Aug 21, 2021

I just try with a python script with pylsp, again duplicated candidates. So might not be an issue from lsp.

@hrsh7th
Copy link
Owner

hrsh7th commented Aug 21, 2021

I've fixed the bug! f3a5491

Now, You can fully customizable vim' completion item (See :help complete-items)

@ccshao
Copy link
Author

ccshao commented Aug 21, 2021

Thank you very much for bing patience on this small issue!

@ccshao ccshao closed this as completed Aug 21, 2021
ChrisAmelia pushed a commit to ChrisAmelia/dotfiles that referenced this issue Aug 26, 2021
ChrisAmelia pushed a commit to ChrisAmelia/dotfiles that referenced this issue Aug 26, 2021
ChrisAmelia pushed a commit to ChrisAmelia/dotfiles that referenced this issue Aug 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants