lsp icon indicating copy to clipboard operation
lsp copied to clipboard

feat: add completionInPreview option and preview filetype handling

Open Konfekt opened this issue 1 month ago • 40 comments

A stab at https://github.com/yegappan/lsp/issues/688 ; if @813ethan could test and comment

Konfekt avatar Nov 02 '25 12:11 Konfekt

looks nice, is there a reason why the preview window is so small? compared to :LspHover Screenshot_20251103-000805_Termux i think the builtins line could be removed to save some space

Also is it possible if the preview window can be automatically closed after exiting the autocompletion menu? like jedi-vim and ycm

813ethan avatar Nov 02 '25 13:11 813ethan

now the preview closes after the autocompletion got selected, but it's still opened when there're no completions

also the preview window's size is still too small?

https://github.com/user-attachments/assets/2c94eaf8-bd01-4f16-add2-4ad57015a8ab

813ethan avatar Nov 02 '25 14:11 813ethan

ok tried testing it for a bit, seems like

https://github.com/yegappan/lsp/blob/c57a2615891dc5400a63d8a54552873368877b5c/autoload/lsp/completion.vim#L277

the preview window's was initialized with 'Lazy doc', maybe this messed the window size up?

also can i suggest if there can be a toggle for (not) autoclosing the preview window? if it's not hard to implement

813ethan avatar Nov 03 '25 06:11 813ethan

I have no idea why the preview window height is not sufficiently high; by default it should be (=12) and Vim respect it?

Konfekt avatar Nov 03 '25 08:11 Konfekt

the height seems to change accordingly with the documentation's length (this is ycm btw)

https://github.com/user-attachments/assets/9caa6f03-b0e4-4df1-a3c9-a746477759a9

813ethan avatar Nov 03 '25 11:11 813ethan

maybe resize the window after the doc is shown? This works for me

*** completion.vim.old	2025-11-05 08:35:36.036497263 +1100
--- completion.vim	2025-11-05 08:36:08.768497250 +1100
***************
*** 456,461 ****
--- 456,462 ----
        infoText->append(0)
        [1, 1]->cursor()
        exe $'setlocal ft={infoKind}'
+       exe 'resize' &previewheight
        :wincmd p
      catch /E441/ # No preview window
      endtry

813ethan avatar Nov 04 '25 21:11 813ethan

Thank you! We should be good to go @yegappan

Konfekt avatar Nov 04 '25 22:11 Konfekt

One more problem, there's this error showing up when im using preview with clangd?

Screenshot_20251105-151838_Termux

this is my lsp config:

{
          'name': 'clangd',
          'filetype': ['c', 'cpp'],
          'path': TERMUX_PREFIX .. '/usr/bin/clangd',
          'args': ['--background-index', '--clang-tidy']
}

All good otherwise, the error didn't happen with other clients like python-language-server

813ethan avatar Nov 05 '25 04:11 813ethan

Could it be related to the just added

exe 'resize' &previewheight

?

Does it still show up without it? When using silent! exe ... or better try .. catch E565 ... endtry?

Konfekt avatar Nov 05 '25 05:11 Konfekt

Could it be related to the just added

exe 'resize' &previewheight

?

error still shows up with the line removed

Does it still show up without it? When using silent! exe ... or better try .. catch E565 ... endtry?

same error with try ... catch, prolly caused by something else

813ethan avatar Nov 05 '25 05:11 813ethan

ok nvm try ... catch E565 here silenced the errors, but markdown isn't applied to the preview window

https://github.com/yegappan/lsp/blob/5ded99487aab03513120a758fd5222d413284bf4/autoload/lsp/completion.vim#L631-L635

https://github.com/user-attachments/assets/85163cfa-4081-4233-850d-232720078e87

the error still exists after removing setlocal ft=lspgfm

813ethan avatar Nov 05 '25 07:11 813ethan

https://groups.google.com/g/vim_dev/c/UX9-Dgw86xA maybe this is related?

813ethan avatar Nov 05 '25 07:11 813ethan

Patch 8.2.2427 and 8.2.2426 disallow changing windows in the completefunc.

So with

   :wincmd P 
   setlocal ft=lspgfm 

make sure that P does not jump to the preview window

Konfekt avatar Nov 05 '25 11:11 Konfekt

Patch 8.2.2427 and 8.2.2426 disallow changing windows in the completefunc.

So with

   :wincmd P 
   setlocal ft=lspgfm 

make sure that P does not jump to the preview window

im unsure how it works, there's no error when im using python lsp, it only appears when using clangd

813ethan avatar Nov 05 '25 12:11 813ethan

Can you try to make sense of the solution https://github.com/justmao945/vim-clang/pull/140 ?

Konfekt avatar Nov 05 '25 19:11 Konfekt

Can you try to make sense of the solution justmao945/vim-clang#140 ?

it tried to move the problematic calls away from the autocomplete function?

I'm not an expert about the internals of this plugin (lsp), so i don't know if there's a way to adapt that here, not counting that this plugin is not clangd specific

yet something I noticed is that in python-language-server, LspSetPopupFileType() which causes the error was never called,

while clangd never uses lazy loading (lspserver.completionLazyDoc) and renders the documentation directly instead, maybe it's something about it?

813ethan avatar Nov 06 '25 09:11 813ethan

it tried to move the problematic calls away from the autocomplete function?

Yes, could you distill which?

Konfekt avatar Nov 06 '25 10:11 Konfekt

my understanding is LspSetPopupFileType() is called to setup the completion popup's markdown highlighting, while it works for popup windows, it fails with preview windows bc of the error,

while lazy loading uses ShowCompletionDocumentation(), which also setups the markdown but didn't get any errors

maybe something with the implementation or timing of those functions? I have no idea

813ethan avatar Nov 06 '25 11:11 813ethan

Thank you, so doing it the roundabout ShowCompletionDocumentation() way

#  autoload/lsp/completion.vim (lines 453-460)
  :wincmd P
  :setlocal modifiable
  bufnr()->deletebufline(1, '$')
  infoText->append(0)
  [1, 1]->cursor()
 setlocal ft=lspgfm
 :wincmd p
catch /E441/ # No preview window

solves that problem?

Konfekt avatar Nov 06 '25 16:11 Konfekt

ok nvm try ... catch E565 here silenced the errors, but markdown isn't applied to the preview window

https://github.com/yegappan/lsp/blob/5ded99487aab03513120a758fd5222d413284bf4/autoload/lsp/completion.vim#L631-L635

screen-20251105-181844.2.mp4 the error still exists after removing setlocal ft=lspgfm

won't, the error will still happen with :wincmd P..

813ethan avatar Nov 06 '25 20:11 813ethan

https://github.com/yegappan/lsp/blob/5ded99487aab03513120a758fd5222d413284bf4/autoload/lsp/completion.vim#L763-L766

actually can we even change the state of the preview window during CompleteChanged

813ethan avatar Nov 06 '25 22:11 813ethan

Changing windows while inside a completion function is forbidden now.

I think changing means less ambiguously switching here; so we can still change, say the filetype, but have to stay inside the window

Konfekt avatar Nov 07 '25 08:11 Konfekt

Here's the corresponding fix for php complete

Konfekt avatar Nov 07 '25 08:11 Konfekt

Thank you, so doing it the roundabout ShowCompletionDocumentation() way

#  autoload/lsp/completion.vim (lines 453-460)
  :wincmd P
  :setlocal modifiable
  bufnr()->deletebufline(1, '$')
  infoText->append(0)
  [1, 1]->cursor()
 setlocal ft=lspgfm
 :wincmd p
catch /E441/ # No preview window

How come then this doesn't give any errors ?

Konfekt avatar Nov 07 '25 08:11 Konfekt

More exactly, the file type is correctly set

Konfekt avatar Nov 07 '25 08:11 Konfekt

For short, get the popup window id and then call win_execute(..) to change it, say &filetype. Could you look into that?

Konfekt avatar Nov 07 '25 08:11 Konfekt

Thank you, so doing it the roundabout ShowCompletionDocumentation() way

#  autoload/lsp/completion.vim (lines 453-460)
  :wincmd P
  :setlocal modifiable
  bufnr()->deletebufline(1, '$')
  infoText->append(0)
  [1, 1]->cursor()
 setlocal ft=lspgfm
 :wincmd p
catch /E441/ # No preview window

How come then this doesn't give any errors ?

It wasn't run on CompleteChanged, it's a separate process called (during the completion?) from lspserver.vim

813ethan avatar Nov 07 '25 08:11 813ethan

Changing windows while inside a completion function is forbidden now.

I think changing means less ambiguously switching here; so we can still change, say the filetype, but have to stay inside the window

the buffer is still being changed via the markdown renderer (lspgfm.vim)

tried setting the file type indirectly via

setbufvar(winbufnr(winnr('#')), '&ft', 'lspgfm')

but it gives another error Screenshot_20251107-193318_Termux

813ethan avatar Nov 07 '25 08:11 813ethan

The culprit is the wincmd p/P dance; instead, get the popup window id and then call win_execute(..) to change &filetype

Konfekt avatar Nov 07 '25 08:11 Konfekt

Changing windows while inside a completion function is forbidden now.

I think changing means less ambiguously switching here; so we can still change, say the filetype, but have to stay inside the window

the buffer is still being changed via the markdown renderer (lspgfm.vim)

tried setting the file type indirectly via

setbufvar(winbufnr(winnr('#')), '&ft', 'lspgfm')

but it gives another error Screenshot_20251107-193318_Termux

This changes the &filetype of the preview buffer, without doing the wincmdP/p dance.

how can I get the window id for win_execute(...)?

813ethan avatar Nov 07 '25 09:11 813ethan