hrsh7th / nvim-cmp

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

Disable autocomplete for certain events #2045

Open aymanbagabas opened 2 months ago

aymanbagabas commented 2 months ago

FAQ

Announcement

Minimal reproducible full config

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/vim-vsnip'
Plug 'neovim/nvim-lspconfig'
Plug 'zbirenbaum/copilot.lua'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
require("copilot").setup({
  suggestion = {
    enabled = true,
    auto_trigger = true,
    hide_during_completion = false,
    debounce = 75,
    keymap = {
      -- Use nvim-cmp
      accept = false,
      accept_word = false,
      accept_line = false,
      next = false,
      prev = false,
      dismiss = false,
    },
  },
})

local cmp = require "cmp"
cmp.setup {
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },

  mapping = {
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ["<Tab>"] = cmp.mapping(function(fallback)
      local suggestion = require("copilot.suggestion")
      if suggestion.is_visible() and cmp.visible() then
        cmp.close()
      elseif suggestion.is_visible() then
        suggestion.accept()
        cmp.abort()
      elseif cmp.visible() then
        -- You could replace select_next_item() with confirm({ select = true }) to get VS Code autocompletion behavior
        cmp.select_next_item()
      elseif vim.snippet.active({ direction = 1 }) then
        vim.schedule(function()
        vim.snippet.jump(1)
        end)
      else
        fallback()
      end
    end, { "i", "s" }),
  },

  sources = cmp.config.sources({
    { name = "nvim_lsp" },
    { name = "buffer" },
  }),
}
EOF

lua << EOF
local capabilities = require('cmp_nvim_lsp').default_capabilities()

require'lspconfig'.cssls.setup {
  capabilities = capabilities,
}
EOF

Description

I'm using Copilot.lua and trying to use super-tab like mappings so that when I accept a suggestion, it closes the menu as if nvim-cmp finished the completion. Right now, with the above super-tab configuration, once I hit tab to complete using Copilot.lua, nvim-cmp autocomplete feature kicks in and opens the menu as if I was typing.

Steps to reproduce

  1. Write some code.

    image
  2. Press tab to complete using Copilot, the menu opens up

    image

Expected behavior

I want to be able to control the autocomplete feature and perhaps set a buffer flag to disable the next auto complete. So basically make autocomplete take a function that returns a boolean.

Actual behavior

nvim-cmp always opens up the menu event after cmp.abort()

Additional context

As a workaround, I was able to achieve what I'm looking for by wrapping cmp.abort() after accepting a suggestion in a vim.schedule but this feels flaky

    ["<Tab>"] = cmp.mapping(function(fallback)
      local suggestion = require("copilot.suggestion")
      if suggestion.is_visible() and cmp.visible() then
        cmp.close()
      elseif suggestion.is_visible() then
        suggestion.accept()
        vim.schedule(function()
          -- We need to schedule this to close the completion menu after accepting the suggestion
          cmp.abort()
        end)
      elseif cmp.visible() then
        -- You could replace select_next_item() with confirm({ select = true }) to get VS Code autocompletion behavior
        cmp.select_next_item()
      elseif vim.snippet.active({ direction = 1 }) then
        vim.schedule(function()
          vim.snippet.jump(1)
        end)
      else
        fallback()
      end
    end, { "i", "s" }),
Shougo commented 2 months ago

It seems auto completion plugin feature.

local on_text_changed = function()
  if config.enabled() then
    cmp.core:on_change('TextChanged')
  end
end
autocmd.subscribe({ 'TextChangedI', 'TextChangedP' }, on_text_changed)

nvim-cmp works completion when TextChangedI. If you accept copilot candidate, it will trigger TextChangedI event.

xzbdmw commented 2 months ago

you can use

                local origin = vim.o.eventignore
                vim.o.eventignore = "all"
               // Accept copilot source
                vim.defer_fn(function()
                    vim.o.eventignore = origin
                end, 10)