hrsh7th / nvim-cmp

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

statusline flashes when using Super-Tab like mapping from the wiki and cmdheight=0 #1396

Open gmr458 opened 1 year ago

gmr458 commented 1 year 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'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
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)
      if cmp.visible() then
        cmp.select_next_item()
      elseif luasnip.expand_or_jumpable() then
        luasnip.expand_or_jump()
      elseif has_words_before() then
        cmp.complete()
      else
        fallback()
      end
    end, { "i", "s" }),
    ["<S-Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      elseif luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, { "i", "s" }),
  },

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

### Description

Statusline flashes when using Super-Tab like mapping from the wiki, when I use the "up" and "down" keys the statusline stays normal.

### Steps to reproduce

use de option `vim.opt.cmdheight = 0` and the super tab like mapping from the wiki:
```lua
local has_words_before = function()
  unpack = unpack or table.unpack
  local line, col = unpack(vim.api.nvim_win_get_cursor(0))
  return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end

local luasnip = require("luasnip")
local cmp = require("cmp")

cmp.setup({

  -- ... Your other configuration ...

  mapping = {

    -- ... Your other mappings ...

    ["<Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      elseif luasnip.expand_or_jumpable() then
        luasnip.expand_or_jump()
      elseif has_words_before() then
        cmp.complete()
      else
        fallback()
      end
    end, { "i", "s" }),

    ["<S-Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      elseif luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, { "i", "s" }),

    -- ... Your other mappings ...
  },

  -- ... Your other configuration ...
})

Expected behavior

statusline doesn't flashes when using Super-Tab like mapping from the wiki

Actual behavior

statusline flashes when using Super-Tab like mapping from the wiki, using up and down keys doesn't have this problem

Additional context

No response

mehalter commented 1 year ago

@gmr458 I think this is probably the same bug I reported a couple weeks ago in #1382 . Hopefully it gets fixed soon :/ I haven't heard anything about it, but I did link the commit before this bug is present/commit that causes this issue if you are interested! Let me know if using the older commit works and we can hopefully gain some traction on this bug :)

mehalter commented 1 year ago

Basically, it seems to be a lot more deep than having the super-tab stuff. You can replicate the statusline disappearing simply by setting cmdheight=0 and just setting up cmp

gmr458 commented 1 year ago

@mehalter using the older commit (https://github.com/hrsh7th/nvim-cmp/commit/a9c701fa7e12e9257b3162000e5288a75d280c28) didn't work, do you know why using the up and down keys doesn't have that same problem?, it seems to me that the up and down keys have the same behavior as tab and s-tab.

mehalter commented 1 year ago

Ah this might be a different problem then sorry! @gmr458 thought it seemed similar

yifan0414 commented 1 year ago

When I delete words, the statusline flickering between insert mode sign and command mode sign.

https://user-images.githubusercontent.com/45898625/211239021-6b7e6af3-85a8-418f-9450-179b7fb3b9e1.mp4

mehalter commented 1 year ago

@SnakeHit this is the exact bug I reported in the linked issue above. There is a previous commit you can check out before that bug was introduced

yifan0414 commented 1 year ago

@SnakeHit this is the exact bug I reported in the linked issue above. There is a previous commit you can check out before that bug was introduced

Sorry, I didn't look at it carefully. I am a rookie, could you tell me how use the previous version with lua? Thank you very much.

fitrh commented 1 year ago

I found out that this is related to InsertEnter autocmd as I didn't get this issue after removing the autocmd with

:au! ___cmp___ InsertEnter
:au! cmp_nvim_lsp InsertEnter
yifan0414 commented 1 year ago

What are the consequences of disabling this?

pocco81 commented 1 year ago

Hey @mehalter, did you ever find a solution for this (that doesn't involve rolling back to a previous commit)?

gmr458 commented 10 months ago

I'm using Neovim nightly right now and the flashes are gone.

NVIM v0.10.0-dev-49efdf8
Build type: Release
LuaJIT 2.1.1702233742

https://github.com/hrsh7th/nvim-cmp/assets/53343401/80177f1f-477a-4411-992a-b7bcba82f04a

My cmp config:

local ok, luasnip, cmp

ok, luasnip = pcall(require, 'luasnip')
if not ok then
    vim.notify 'luasnip could not be loaded'
    return
end

ok, cmp = pcall(require, 'cmp')
if not ok then
    vim.notify 'cmp could not be loaded'
    return
end

local has_words_before = function()
    unpack = unpack or table.unpack
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    return col ~= 0
        and vim.api
                .nvim_buf_get_lines(0, line - 1, line, true)[1]
                :sub(col, col)
                :match '%s'
            == nil
end

local cmp_kinds = {
    Text = ' ',
    Method = ' ',
    Function = ' ',
    Constructor = ' ',
    Field = ' ',
    Variable = ' ',
    Class = ' ',
    Interface = ' ',
    Module = ' ',
    Property = ' ',
    Unit = ' ',
    Value = ' ',
    Enum = ' ',
    Keyword = ' ',
    Snippet = ' ',
    Color = ' ',
    File = ' ',
    Reference = ' ',
    Folder = ' ',
    EnumMember = ' ',
    Constant = ' ',
    Struct = ' ',
    Event = ' ',
    Operator = ' ',
    TypeParameter = ' ',
}

cmp.setup {
    snippet = {
        expand = function(args)
            luasnip.lsp_expand(args.body)
        end,
    },
    window = {
        completion = cmp.config.window.bordered { border = 'single' },
        documentation = cmp.config.window.bordered { border = 'single' },
    },
    mapping = cmp.mapping.preset.insert {
        ['<C-b>'] = cmp.mapping.scroll_docs(-4),
        ['<C-f>'] = cmp.mapping.scroll_docs(4),
        ['<C-e>'] = cmp.mapping.abort(),
        ['<CR>'] = cmp.mapping.confirm { select = true },
        ['<C-Space>'] = cmp.mapping.complete(),
        ['<Tab>'] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_next_item()
            elseif luasnip.expand_or_jumpable() then
                luasnip.expand_or_jump()
            elseif has_words_before() then
                cmp.complete()
            else
                fallback()
            end
        end, { 'i', 's' }),
        ['<S-Tab>'] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_prev_item()
            elseif luasnip.jumpable(-1) then
                luasnip.jump(-1)
            else
                fallback()
            end
        end, { 'i', 's' }),
    },
    formatting = {
        fields = { 'kind', 'abbr' },
        format = function(_, vim_item)
            vim_item.kind = cmp_kinds[vim_item.kind] or ''
            return vim_item
        end,
    },
    sources = cmp.config.sources({
        { name = 'nvim_lsp' },
        { name = 'async_path' },
    }, {}),
}
Bekaboo commented 10 months ago

Still have those flashes on latest nightly when cmdheight=0 and auto-complete for cmdline is on.

diocletiann commented 5 months ago

Flashing for me on 0.10.0 release.

Shougo commented 5 months ago

Hm...

I have created the minimal vimrc.

set rtp+=~/src/nvim-cmp
set rtp+=~/src/cmp-buffer
set rtp+=~/src/cmp-cmdline
"set rtp+=~/src/nvim-lspconfig
"set rtp+=~/src/cmp-nvim-lsp
set rtp+=~/src/vim-vsnip
set rtp+=~/src/cmp-vsnip

set cmdheight=0

lua <<EOF
  -- Setup nvim-cmp.
  local cmp = require'cmp'

  cmp.setup({
    snippet = {
      expand = function(args)
        vim.fn["vsnip#anonymous"](args.body)
      end,
    },
    mapping = {
      ['<CR>'] = cmp.mapping.confirm {
        behavior = cmp.ConfirmBehavior.Replace,
        select = true,
      },
      ['<tab>'] = cmp.mapping(cmp.mapping.confirm({ select = true }), { 'i', 's', 'c' }),
      ['<C-p>'] = cmp.mapping.select_prev_item(),
      ['<C-n>'] = cmp.mapping.select_next_item(),
    },
    sources = {
      { name = 'buffer' },
    },
    completion = {
      autocomplete = {
        cmp.TriggerEvent.TextChanged,
        cmp.TriggerEvent.InsertEnter,
      },
      completeopt = 'menu,menuone,noselect'
    }
  })
  cmp.setup.cmdline(':', {
    mapping = cmp.mapping.preset.cmdline(),
    sources = {
      { name = 'cmdline' }
    }
  })
EOF

"lua << EOF
"-- Add additional capabilities supported by nvim-cmp
"local capabilities = vim.lsp.protocol.make_client_capabilities()
"capabilities = require('cmp_nvim_lsp').update_capabilities(capabilities)
"
"--require'lspconfig'.sumneko_lua.setup{}
"--require'lspconfig'.cssls.setup{}
"--require'lspconfig'.pylsp.setup{}
"require'lspconfig'.tailwindcss.setup{}
"--require'lspconfig'.gopls.setup{
"--  capabilities = capabilities,
"--  init_options = {
"--    usePlaceholders = true,
"--  },
"--}
"EOF

runtime! after/plugin/*.lua

When InsertEnter, the statuline seems gone.

Shougo commented 5 months ago

It seems set laststatus=0 is needed.

Shougo commented 5 months ago

OK. I have get the reason.

https://github.com/hrsh7th/nvim-cmp/blob/630cdf7d547c4461ef6d7362c3794a08abfad4fb/lua/cmp/utils/feedkeys.lua#L36

The feedkeys execution causes the problem.

It executes <80><fd>hcall v:lua.cmp.utils.feedkeys.call.run(1)^M text.

Shougo commented 5 months ago
diff --git a/lua/cmp/init.lua b/lua/cmp/init.lua
index 4aaf2fe..37687da 100644
--- a/lua/cmp/init.lua
+++ b/lua/cmp/init.lua
@@ -330,7 +330,7 @@ local on_insert_enter = function()
   end
 end
 autocmd.subscribe({ 'CmdlineEnter' }, async.debounce_next_tick(on_insert_enter))
-autocmd.subscribe({ 'InsertEnter' }, async.debounce_next_tick_by_keymap(on_insert_enter))
+--autocmd.subscribe({ 'InsertEnter' }, async.debounce_next_tick_by_keymap(on_insert_enter))

 -- async.throttle is needed for performance. The mapping `:<C-u>...<CR>` will fire `CmdlineChanged` for each character.
 local on_text_changed = function()

It fixes the problem though.

Shougo commented 5 months ago

And it is the dup of https://github.com/hrsh7th/nvim-cmp/issues/1382.