hrsh7th / nvim-cmp

A completion plugin for neovim coded in Lua.
MIT License
8.08k stars 400 forks source link

When copilot.vim plugin is enabled, "<Plug>(cmp.utils.keymap.recursive: )" is written on <Tab> in the insert mode #459

Closed meinside closed 3 years ago

meinside commented 3 years ago

Describe the bug

When I have copilot.vim enabled in my init.lua file,

"\<Plug>(cmp.utils.keymap.recursive: )" is written on \<Tab> press in the insert mode.

nvim-cmp

Minimal config based on this

Here is my (hopefully) minimal init.lua file for reproducing this problem:

local fn = vim.fn
local check_back_space = function()
  local col = fn.col('.') - 1
  if col == 0 or fn.getline('.'):sub(col, col):match('%s') then
    return true
  else
    return false
  end
end

local install_path = fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim'
if fn.empty(fn.glob(install_path)) > 0 then
  fn.execute('!git clone https://github.com/wbthomason/packer.nvim '..install_path)
end
local use = require('packer').use
require('packer').startup(function()
  use 'wbthomason/packer.nvim'

  -- luasnip
  use 'L3MON4D3/LuaSnip'

  -- nvim-cmp
  use {
    'hrsh7th/nvim-cmp',
    requires = {
      'hrsh7th/cmp-nvim-lsp',
      'hrsh7th/cmp-buffer',
      'hrsh7th/cmp-nvim-lua',
      'saadparwaiz1/cmp_luasnip',
    },
    config = function ()
      local cmp = require'cmp'
      local luasnip = require'luasnip'
      cmp.setup {
        completion = {
          completeopt = 'menuone,noselect'
        },
        snippet = {
          expand = function(args)
            luasnip.lsp_expand(args.body)
          end,
        },
        mapping = {
          ['<C-d>'] = cmp.mapping.scroll_docs(-4),
          ['<C-f>'] = cmp.mapping.scroll_docs(4),
          ['<C-Space>'] = cmp.mapping.complete(),
          ['<C-e>'] = cmp.mapping.close(),
          ['<CR>'] = cmp.mapping.confirm {
            behavior = cmp.ConfirmBehavior.Replace,
            select = true,
          },
          ['<Tab>'] = function(fallback)
            if cmp.visible() == 1 then
              cmp.select_next_item()
            elseif luasnip.expand_or_jumpable() then
              vim.fn.feedkeys(vim.api.nvim_replace_termcodes('<Plug>luasnip-expand-or-jump', true, true, true), '')
            else
              fallback()
            end
          end,
          ['<S-Tab>'] = function(fallback)
            if cmp.visible() == 1 then
              cmp.select_prev_item()
            elseif luasnip.jumpable(-1) then
              vim.fn.feedkeys(vim.api.nvim_replace_termcodes('<Plug>luasnip-jump-prev', true, true, true), '')
            else
              fallback()
            end
          end,
        },
        sources = {
          { name = 'nvim_lsp' },
          { name = 'buffer' },
          { name = 'nvim_lua' },
          { name = 'luasnip' },
        },
      }
    end
  }

  -- github copilot
  use 'github/copilot.vim'

end)

To Reproduce

  1. With the init.lua file above, open any file and press \<Tab> in the insert mode.

Expected behavior

  1. '\t' is inserted.

Additional context

When I just remove copilot.vim, it just works as expected.

But I'm not sure if it is an issue from any interference between copilot.vim and nvim-cmp, and I suspect there may be some mistakes in my configuration.

hrsh7th commented 3 years ago

Thank you. I hadn't ever used copilot.vim. I will check it.

meinside commented 3 years ago

Maybe there was some key mapping clash between copilot.vim and nvim-cmp.

For your information, by changing the \<Tab> mapping of copilot.vim, the problem goes away:

  imap <silent><script><expr> <C-L> copilot#Accept()
  let g:copilot_no_tab_map = v:true
hrsh7th commented 3 years ago

@meinside At least, the error will be gone if you update nvim-cmp.

But I found a problem with nvim-cmp and copilot.vim.

The copilot.vim and nvim-cmp both has a mapping fallback mechanism. And copilot.vim checks the mapping is defined or not by hasmapto('copilot#Accept(', 'i') but it will overwrite by nvim-cmp. So copilot.vim doesn't work with nvim-cmp.

hrsh7th commented 3 years ago

If copilot.vim has a programatic api such copilot#CanAccept, we can manage the combination with nvim-cmp but it hasn't at the moment.

hrsh7th commented 3 years ago

Ah. No. It can be managed even now.

Your solution is the correct solution. 👍🏼

meinside commented 3 years ago

Thank you very much for your investigation!

bangedorrunt commented 3 years ago

You can use Tab with copilot.vim following this commit https://github.com/jose-elias-alvarez/dotfiles/commit/7ab0a3d66915b5d97f01b8bc0815ac50af9a7ed1

Chaitanyabsprip commented 3 years ago

I am still facing this same issue

hrsh7th commented 3 years ago

Please read this post https://github.com/hrsh7th/nvim-cmp/issues/459#issuecomment-957112601 and copilot.vim's README.md

thled commented 3 years ago

I have the same issue, too. I wrote a small Dockerfile to reproduce the issue with a minimal setup: https://github.com/thled/vim_copilot_cmp_issue This setup uses the solution mentioned by @meinside but still Tab is not working correctly.

Edit: Nvm! It was not working because I used the after directory to load the Copilot.vim configuration.

mawkler commented 2 years ago

@babygau

You can use Tab with copilot.vim following this commit jose-elias-alvarez/dotfiles@7ab0a3d

Thank you! I tried to solve it the same way but couldn't get it working until I found your comment.

However, whenever I accept a Copilot now suggestion the following gets printed in red:

=copilot#TextQueuedForInsertion()

Does anyone know how I can suppress this?

mawkler commented 2 years ago

@babygau I'm having another problem with your suggested <Tab> configuration. If I press <Tab> with neither a copilot or nvim-cmp suggestion available, Neovim freezes completely until I press <C-c>. Do you experience the same thing and/or know how to fix it?

Edit: I think I solved it by changing

local copilot_keys = vim.fn["copilot#Accept"]()

to

local copilot_keys = vim.fn["copilot#Accept"]("")
sitiom commented 2 years ago

https://github.com/LunarVim/LunarVim/issues/1856#issuecomment-1001502992 works for me.

rainux commented 2 years ago

For anyone struggling with this issue, I found by only using <Tab> to jump between snippet placeholder, do not use it to toggle complete menu or navigate to the next item, will result in a better user experience.

With this config, you can accept Copilot suggestions while the completion menu shows, and you can still use <C-n> or <C-j> to navigate between completion items.

    ['<Tab>'] = cmp.mapping(function(fallback)
      if vim.fn['vsnip#jumpable'](1) == 1 then
        feedkey('<Plug>(vsnip-jump-next)', '')
      else
        local copilot_keys = vim.fn['copilot#Accept']()
        if copilot_keys ~= '' then
          vim.api.nvim_feedkeys(copilot_keys, 'i', true)
        else
          fallback()
        end
      end
    end, { 'i', 's' }),
yueyingjuesha commented 2 years ago

I don't have copilot installed but I still got this wired (cmp.u.k.recursive: ) innserted

davidask commented 2 years ago

No copilot installed. For me this happens on mapping <CR>. Removing that mapping resolves the issue, except for the fact that the mapping sure would be nice to have 😊

ZachariahPang commented 2 years ago

No copilot installed. For me this happens on mapping <CR>. Removing that mapping resolves the issue, except for the fact that the mapping sure would be nice to have 😊

I have the exact same issue and I don't have copilot installed either.

macintacos commented 2 years ago

I think this might be a new issue, because I'm seeing the same thing (hit <CR>, see <Plug>(cmp.u.k.recursive: printed out). Haven't been able to repro with a minimal config though, which is why I haven't opened it yet.

Shougo commented 2 years ago

It seems plugins conflict. You need to create minimal init.vim.

EthanWng97 commented 2 years ago

@babygau

You can use Tab with copilot.vim following this commit jose-elias-alvarez/dotfiles@7ab0a3d

Thank you! I tried to solve it the same way but couldn't get it working until I found your comment.

However, whenever I accept a Copilot now suggestion the following gets printed in red:

=copilot#TextQueuedForInsertion()

Does anyone know how I can suppress this?

I am struggling this problem now.. Did you solve it?

ZachariahPang commented 2 years ago

Seems to be related to nvim-autopairs as everything works as expected when I don't load nvim-autopairs. I'll try to clean out a minimal config but I'm quite busy this week. Hopefully this can at least save you all some time tracking the conflicts.

EthanWng97 commented 2 years ago

Seems to be related to nvim-autopairs as everything works as expected when I don't load nvim-autopairs. I'll try to clean out a minimal config but I'm quite busy this week. Hopefully this can at least save you all some time tracking the conflicts.

Unfortunately not working. I disable all plugins except lsp and cmp but it still shows up.

hrsh7th commented 2 years ago

I can't fix this without minimal reproducible configuration based on https://github.com/hrsh7th/nvim-cmp/blob/main/utils/vimrc.vim

creativecreature commented 2 years ago

This is happening for me too when I press CR with this cmp config:

cmp.setup({
  snippet = {expand = function(args) vim.fn["vsnip#anonymous"](args.body) end},
  mapping = {
    ["<C-d>"] = cmp.mapping.scroll_docs(-4),
    ["<C-f>"] = cmp.mapping.scroll_docs(4),
    ["<C-Space>"] = cmp.mapping.complete(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<Tab>'] = cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'}),
    ['<S-Tab>'] = cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})
  },
  sources = {{name = "nvim_lsp"}, {name = "nvim_lua"}, {name = "buffer"}, {name = "path"}, {name = 'emoji'}},
  documentation = {border = {"╭", "─", "╮", "│", "╯", "─", "╰", "│"}},
  experimental = {ghost_text = {hl_group = "LineNr"}}
})

If I comment out the binding for CR the issue goes away:

cmp.setup({
  snippet = {expand = function(args) vim.fn["vsnip#anonymous"](args.body) end},
  mapping = {
    ["<C-d>"] = cmp.mapping.scroll_docs(-4),
    ["<C-f>"] = cmp.mapping.scroll_docs(4),
    ["<C-Space>"] = cmp.mapping.complete(),
    -- ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<Tab>'] = cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'}),
    ['<S-Tab>'] = cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})
  },
  sources = {{name = "nvim_lsp"}, {name = "nvim_lua"}, {name = "buffer"}, {name = "path"}, {name = 'emoji'}},
  documentation = {border = {"╭", "─", "╮", "│", "╯", "─", "╰", "│"}},
  experimental = {ghost_text = {hl_group = "LineNr"}}
})
davidask commented 2 years ago

Seems to be related to nvim-autopairs as everything works as expected when I don't load nvim-autopairs. I'll try to clean out a minimal config but I'm quite busy this week. Hopefully this can at least save you all some time tracking the conflicts.

Nice find, this solves the issue as well.

ipod825 commented 2 years ago

Seems to be related to nvim-autopairs as everything works as expected when I don't load nvim-autopairs. I'll try to clean out a minimal config but I'm quite busy this week. Hopefully this can at least save you all some time tracking the conflicts.

I got the same inserted text with <cr>. require'nvim-autopairs'.setup({ map_cr = false }) solves my issue.

EthanWng97 commented 2 years ago

I can't fix this without minimal reproducible configuration based on https://github.com/hrsh7th/nvim-cmp/blob/main/utils/vimrc.vim

I create a mini config to reproduce the =copilot#TextQueuedForInsertion() problem. #864

EthanWng97 commented 2 years ago

Seems to be related to nvim-autopairs as everything works as expected when I don't load nvim-autopairs. I'll try to clean out a minimal config but I'm quite busy this week. Hopefully this can at least save you all some time tracking the conflicts.

Nice find, this solves the issue as well.

I can't fix this without minimal reproducible configuration based on https://github.com/hrsh7th/nvim-cmp/blob/main/utils/vimrc.vim

I found that this problem shows up when i use tmux. If I use nvim standalone, everything works fine. But problems exists when in tmux.

amiel commented 2 years ago

For anyone using LunarVim and having this issue on , this worked for me:

lvim.builtin.autopairs.map_cr = false
abzrg commented 2 years ago

I got the same inserted text with <cr>. require'nvim-autopairs'.setup({ map_cr = false }) solves my issue.

That didn't work for me. So far, it only gets fixed if I remove autopair.