blink.cmp icon indicating copy to clipboard operation
blink.cmp copied to clipboard

Completion menu render doesn't get cleared

Open gepbird opened this issue 6 months ago • 15 comments

Make sure you have done the following

  • [x] Updated to the latest version of blink.cmp
  • [x] Searched for existing issues and documentation (try <C-k> on https://cmp.saghen.dev)

Bug Description

The rendered completion menu stays on the screen after closing the menu, or the menu becoming smaller.

This happens when completion.documentation.auto_show is enabled and you "type faster" than auto_show_delay_ms (for a consistent repro set it to lower numbers like 100), having other plugins installed (bufferline) and using the nixd language server. After waiting for the lsp to start up and typing {in, you will get some "dead" completion items that are only rendered but can't be selected, and doesn't get cleared.

This video illustrates the issue better:

https://github.com/user-attachments/assets/421b6f41-a91b-443a-8f15-c96bb7bc388e

Relevant configuration

vim.env.LAZY_STDPATH = '.repro'
load(vim.fn.system 'curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua')()

require 'lazy.minit'.repro {
  spec = {
    {
      'saghen/blink.cmp',
      opts = {
        fuzzy = {
          implementation = 'lua',
        },
        completion = {
          documentation = {
            auto_show = true,
            auto_show_delay_ms = 100,
          },
        },
      },
    },
    {
      'mason-org/mason.nvim',
      build = ':MasonUpdate',
      opts = {},
    },
    {
      'mason-org/mason-lspconfig.nvim',
      dependencies = { 'mason-org/mason.nvim', 'neovim/nvim-lspconfig' },
      opts = {
        ensure_installed = { 'nix' },
      },
      config = function()
        vim.lsp.enable 'nixd'

        -- optional, also reproducible without passing capabilities
        local config = {
          capabilities = require 'blink.cmp'.get_lsp_capabilities(),
        }
        vim.lsp.config('nixd', config)
      end,
    },
    {
      'akinsho/bufferline.nvim',
      opts = {
        options = {
          diagnostics = 'nvim_lsp',
        },
      },
    },
  },
}

neovim version

NVIM v0.12.0-nightly+0d65866

blink.cmp version

2096cf158133884738fef07f7b7d5bbf9accc237

gepbird avatar Jun 20 '25 18:06 gepbird

Could you please give it another try using the new v1.6.0 release? I can't seem to reproduce the issue anymore.

soifou avatar Jul 24 '25 16:07 soifou

I have tried the new release and it's still happening.

PalanixYT avatar Jul 24 '25 17:07 PalanixYT

I have a feeling it may be a neovim rendering bug, are you on the latest neovim nightly?

saghen avatar Jul 24 '25 17:07 saghen

NVIM v0.12.0-dev-822+ga945686444 Build type: RelWithDebInfo LuaJIT 2.1.1748459687

PalanixYT avatar Jul 24 '25 17:07 PalanixYT

I'm not able to find ga945686444 in the neovim commit history, so not sure how new that is

saghen avatar Jul 24 '25 17:07 saghen

In debian, you need to strip the g, so it's a945686444, 10 days ago, fairly new.

soifou avatar Jul 24 '25 17:07 soifou

I just retried using latest master commit and it's still happening

PalanixYT avatar Jul 24 '25 17:07 PalanixYT

Confirmed on my side, interestingly enough this works in nvim 0.11.3 but not in nightly.

soifou avatar Jul 24 '25 17:07 soifou

Since I reported the bug, I encountered this issue multiple times even with completion.documentation.auto_show = false, seemingly randomly

Current nvim: NVIM v0.12.0-nightly+d9465e9

gepbird avatar Jul 24 '25 18:07 gepbird

came here from #2099.

I've set my label to always be the same size and that seems to be solving the artifacts issues mostly now as the last menu always gets cleaned up and I pretty much always have enough copilot suggestions and what not sitting on scroll to always get to at least the max-height of the completion window. it's not a perfect fix though.

HendrikPetertje avatar Aug 20 '25 12:08 HendrikPetertje

Hello! I get this issue literally all the time. After writing ~5 lines I'll have multiple overlayed "artifacts" from previous blink completion menus. Is there anything I can do to provide more info on the cause?

rohrsben avatar Aug 24 '25 17:08 rohrsben

I'm also getting this issue.

Image

Here is my blink config: https://github.com/Davey-Hughes/.vim/blob/main/lua/plugins/completion.lua#L31-L178 neovim version: NVIM v0.12.0-dev-1375+gc2a196f19b

Strangely, setting auto_show_delay_ms to basically any value (I've tried values between 10ms to 1000ms) seems to make it impossible for me to reproduce. The most reliable way I can get this to reproduce is to not set auto_show_delay_ms, start neovim (in my case a typescript file), and while the LSP is initializing, start typing something that will cause the completion menu to get narrower as I type.

It makes me think that maybe something in blink is resetting when a source becomes available, and blink/neovim loses track of a previous draw. Completely guessing though, I'm not familiar with neovim or blink's codebase.

Davey-Hughes avatar Oct 07 '25 10:10 Davey-Hughes

I'm also getting this issue. Image

Here is my blink config: https://github.com/Davey-Hughes/.vim/blob/main/lua/plugins/completion.lua#L31-L178 neovim version: NVIM v0.12.0-dev-1375+gc2a196f19b

Strangely, setting auto_show_delay_ms to basically any value (I've tried values between 10ms to 1000ms) seems to make it impossible for me to reproduce. The most reliable way I can get this to reproduce is to not set auto_show_delay_ms, start neovim (in my case a typescript file), and while the LSP is initializing, start typing something that will cause the completion menu to get narrower as I type.

It makes me think that maybe something in blink is resetting when a source becomes available, and blink/neovim loses track of a previous draw. Completely guessing though, I'm not familiar with neovim or blink's codebase.

I'm having the same issue.

For me, it was caused by the following configuration option:

    completion = {
      list = { selection = { preselect = false } },
    },

@Davey-Hughes I took a look at your configuration and noticed you have the same option. Try commenting it out and see if it changes anything.

lpnh avatar Oct 26 '25 11:10 lpnh

I'm also getting this issue. Image Here is my blink config: https://github.com/Davey-Hughes/.vim/blob/main/lua/plugins/completion.lua#L31-L178 neovim version: NVIM v0.12.0-dev-1375+gc2a196f19b Strangely, setting auto_show_delay_ms to basically any value (I've tried values between 10ms to 1000ms) seems to make it impossible for me to reproduce. The most reliable way I can get this to reproduce is to not set auto_show_delay_ms, start neovim (in my case a typescript file), and while the LSP is initializing, start typing something that will cause the completion menu to get narrower as I type. It makes me think that maybe something in blink is resetting when a source becomes available, and blink/neovim loses track of a previous draw. Completely guessing though, I'm not familiar with neovim or blink's codebase.

I'm having the same issue.

For me, it was caused by the following configuration option:

completion = {
  list = { selection = { preselect = false } },
},

@Davey-Hughes I took a look at your configuration and noticed you have the same option. Try commenting it out and see if it changes anything.

@lpnh Wow this does seem to fix it. I wonder if this is fixing a symptom or the cause. I do generally prefer having preselect = false, but it's a compromise I can live with.

Davey-Hughes avatar Oct 27 '25 06:10 Davey-Hughes

I haven't changed completion.list.selection.preselect, so it's true by default, but I still experience this bug.

gepbird avatar Oct 27 '25 07:10 gepbird

So I have the same issue and the latest git doesn't fix it.

Odly enough, the menu stop glitching when I remove my bars.nvim plugin. This was tested on a clean config repository with only bars.nvim, nvim-treesitter and blink.cmp.

From what I see, bars.nvim runs autocmd on WinNew and ModeChanged, then proceed to call nvim__redraw() inside a timer (debounce = 100).

I don't know much about Nvim, could this be adding some delay that would result in a race condition somewhere inside blink event/renderer logic? Plugin like bufferline.nvim may be using intensive call to redraw too.

Due to the nature of how blink handle events there is no lock on the menu, instead it rely on api:nvim_win_is_valid() to know if the window is open or not, then proceed to ignores the multiple calls to open received, until accepting one.

To make blink usable in my case, I just went the most straightforward way and implicitly closed the menu when a call to open is accepted.

Kind of a work around for people having the issue:

diff --git a/lua/blink/cmp/completion/windows/menu.lua b/lua/blink/cmp/completion/windows/menu.lua
index 377d057..2015c34 100644
--- a/lua/blink/cmp/completion/windows/menu.lua
+++ b/lua/blink/cmp/completion/windows/menu.lua
@@ -150,6 +150,8 @@ function menu.queue_auto_show(context, items)

   -- no delay, show immediately
   if delay_ms == 0 then
+    menu.win:close()
+    menu.close_emitter:emit()
     menu.open()
     menu.update_position()
     return

I also noticed that if we force a redraw inside menu.update_position() before emitting the update event, the issue is also fixed, but it has a higher cost than emitting a menu close event.

nqrk avatar Dec 08 '25 20:12 nqrk

I believe this is fixed in commit: 5beb962. The visual artifacts were caused by the menu trying to position itself before the window was fully created. This is now properly synchronized by deferring all operations through the event loop.

Would love confirmation from you guys and a big thanks to @nqrk and @Davey-Hughes for the investigation work that led to this fix.

soifou avatar Dec 10 '25 16:12 soifou

Unfortunately I can still reproduce it with the initial minimal config.

Image Image

gepbird avatar Dec 10 '25 17:12 gepbird

Thanks for the report, this 2d attempt should fix your issue.

soifou avatar Dec 10 '25 18:12 soifou

I believe this is fixed in commit: 5beb962. The visual artifacts were caused by the menu trying to position itself before the window was fully created. This is now properly synchronized by deferring all operations through the event loop. Would love confirmation from you guys and a big thanks to @nqrk and @Davey-Hughes for the investigation work that led to this fix.

No more issue here, I will continue to use the main and report if anything! Nice catch, thank you for the work 👍

nqrk avatar Dec 11 '25 10:12 nqrk

Thanks! I can't repro it anymore :)

gepbird avatar Dec 11 '25 11:12 gepbird

I still get this issue with the latest main branch (commit 3033d27) on the latest nightly neovim, I don't think it's been fixed. Does anyone else get this?

NVIM v0.12.0-dev-1810+g2b02dfa020
Build type: RelWithDebInfo
LuaJIT 2.1.1764593432
Run "nvim -V1 -v" for more info

mikavilpas avatar Dec 12 '25 06:12 mikavilpas

I only applied the patch d7f1c64f704ade8cdd0c9719796cdf0054455fde on top of v1.8.0, and I haven't had this issue (or my brain just learned to ignore it after seeing it so many times). I'm running neovim v0.12.0-nightly+b058a80. I'll reopen as I see you're not alone.

gepbird avatar Dec 12 '25 10:12 gepbird

A fresh repro would help a lot. The one from the OP's been fixed, I could take another look if someone can share something new.

soifou avatar Dec 12 '25 17:12 soifou

Amazing project. Everything works nicely, except for this issue.

I switched to blink.cmp today and found this bug. Here's my vim version:

NVIM v0.12.0-dev-1779+g647f11e6ae
Build type: RelWithDebInfo
LuaJIT 2.1.1764593432
Run "nvim -V1 -v" for more info

Here's my blink.cmp config from dotfiles:

https://github.com/s3rius/dotfiles/blob/033f9051d581fde964e52da49a8b96882d1ac4c8/dotfiles/nvim/lua/config/lsp.lua#L2

Blink version: f51535d3eed7a21f739cb3c19ea87bb1a8400c65 from main branch.

Here's how this bug looks like:

https://github.com/user-attachments/assets/561095b4-8f1a-4b3a-9311-8f1d35188377

I also noticed that menus don't have any artifacts when I select suggested items from the menu. But when I constantly update code under my cursor, so menu have to update its box sizes, it starts leaving those weird phantom traces.

I really like blink.cmp and don't want to go back to cmp. I'd be glad to assist with testing out

s3rius avatar Dec 14 '25 00:12 s3rius

After using blink for a while now, I confirm the issue is still occuring. It has become so rare that I can't find a way to reproduce it.

It occurs when menu overlap (resize) with different request and uninterrupted typing, its very random tho.

nqrk avatar Dec 14 '25 19:12 nqrk

I also experience it, but don't have a consistent repro yet. The completion popup stays between 2 splits, specifically on the the separator and the signcolumn, probably because other stuff like the number column and the main "buffer area" got updated and cleared.

Image

Edit: happened again between splits, this it got cleared in the split I was editing text but stayed in adjecent ones:

Image

gepbird avatar Dec 17 '25 13:12 gepbird

As discussed with saghen, it's likely due to a bug that started appearing in Neovim 0.12 when calling nvim__redraw. In prior versions, these artifacts don't occur. We should narrow it down and report it to the core team. We'll then revert the recent hacks that only mitigate this annoying issue.

soifou avatar Dec 17 '25 14:12 soifou