Shougo / ddc-source-lsp

lsp source for ddc.vim
Other
66 stars 20 forks source link

`getPreviewer` does not work when using `lspEngine: 'vim-lsp'` #61

Open k-86 opened 2 months ago

k-86 commented 2 months ago

Problems summary

When calling ddc#get_previewer({item}) while configuring lspEngine: 'vim-lsp', getPreviewer does not work due to timeout.

Expected

It gets additional information for a given completion item.

Environment Information

Provide a minimal init.vim/vimrc without plugin managers (Required!)

if &compatible
  set nocompatible
endif

filetype on

set rtp+=/path/to/github.com/vim-denops/denops.vim
set rtp+=/path/to/github.com/Shougo/ddc-ui-none
set rtp+=/path/to/github.com/Shougo/ddc.vim
set rtp+=/path/to/github.com/Shougo/ddc-source-lsp
set rtp+=/path/to/github.com/prabirshrestha/vim-lsp
set rtp+=/path/to/github.com/mattn/vim-lsp-settings

call ddc#custom#patch_global('ui', 'none')
call ddc#custom#patch_global('sources', ['lsp'])
call ddc#custom#patch_global('sourceParams', #{
  \   lsp: #{
  \     lspEngine: 'vim-lsp',
  \   },
  \ })
call ddc#enable()

function Test() abort
  let path_to_test_ts = 'file:///path/to/test.ts' " Replace file path

  let lspitem = {
    \ 'label':'at',
    \ 'commitCharacters':['.',',',';'],
    \ 'data':{
    \   'tsc':{
    \     'specifier':path_to_test_ts,
    \     'name':'at',
    \     'position':3,
    \     'useCodeSnippet':v:true,
    \     },
    \   },
    \ 'sortText':'11',
    \ 'kind':2,
    \ }

  let item = {
    \ 'word':'at',
    \ 'menu':'',
    \ 'highlights':[],
    \ 'user_data':{
    \   'clientId':'deno',
    \   'suggestCharacter':3,
    \   'requestCharacter':3,
    \   'offsetEncoding':'utf-16',
    \   'lspitem': json_encode(lspitem),
    \   'lineOnRequest':'[].',
    \   'resolvable':v:true,
    \   },
    \ 'info':'',
    \ '__sourceName':'lsp',
    \ 'kind':'Method',
    \ 'abbr':'at',
    \ 'dup':v:true,
    \ '__dup':'ignore',
    \ }

  let start_time = reltime()
  let res = ddc#get_previewer(item)
  let end_time = reltime()

  echom 'ddc#get_previewer: ' . string(res)
  echom 'Elapsed time: ' . reltimestr(reltime(start_time, end_time))
endfunction

How to reproduce the problem from neovim/Vim startup (Required!)

  1. echo "[]." > test.ts
  2. Replace path_to_test_ts in init.vim/vimrc
  3. (n)vim -u init.vim/vimrc test.ts
  4. install deno lsp if it is not installed (call :LspManageServers)
  5. call Test()

Upload the log messages by :redir and :message (if errored)

ddc#get_previewer: {'kind': 'markdown', 'contents': []}
Elapsed time:   1.106308

Note

Where timeout error occurs is https://github.com/Shougo/ddc-source-lsp/blob/395828936c153a628c1d4c669c878ef062f892a0/denops/%40ddc-sources/lsp.ts#L255-L270

debug code https://github.com/Shougo/ddc-source-lsp/blob/395828936c153a628c1d4c669c878ef062f892a0/denops/%40ddc-sources/lsp.ts#L267-L270 ``` return result as LSP.CompletionItem; } catch (e) { console.log(e); return lspItem; } ``` https://github.com/Shougo/ddc-source-lsp/blob/395828936c153a628c1d4c669c878ef062f892a0/denops/ddc-source-lsp/request.ts#L47-L51 ``` const id = register( denops, (res: unknown) => { console.log(res); waiter.resolve(res); }, { once: true }, ); ``` :message ``` [denops] Error: No response from server deno [denops] at request (file:///path/to/github.com/Shougo/ddc-source-lsp/denops/ddc-source-lsp/request.ts:75:15) [denops] at eventLoopTick (ext:core/01_core.js:207:9) [denops] at async Source.#resolve (file:///path/to/github.com/Shougo/ddc-source-lsp/denops/@ddc-sources/lsp.ts:256:24) [denops] at async Source.getPreviewer (file:///path/to/github.com/Shougo/ddc-source-lsp/denops/@ddc-sources/lsp.ts:284:21) [denops] at async getPreviewer (file:///path/to/github.com/Shougo/ddc.vim/denops/ddc/ext.ts:218:21) [denops] at async Object.getPreviewer (file:///path/to/github.com/Shougo/ddc.vim/denops/ddc/app.ts:142:14) [denops] at async Plugin.call (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/service.ts:138:12) [denops] at async Service.#dispatch (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/service.ts:68:12) [denops] at async Service.dispatch (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/service.ts:73:14) [denops] at async Vim.#dispatch (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/host/vim.ts:114:14) ddc#get_previewer: {'kind': 'markdown', 'contents': []} Elapsed time: 1.074064 [denops] {"response":{"id":5,"jsonrpc":"2.0","result":{"label":"at","insertText":"at(${1:index})","sortText":"11","kind":2,"insertTextFormat":2,"documentation":{"kind":"markdown","value":"Returns the item located at the specified index.\n\n*@param* - index The zero-based index of the desired code unit. A negative index will count back from the last item."},"detail":"(method) Array.at(index: number): undefined"}},"request":{"id":5,"jsonrpc":"2.0","method":"completionItem/resolve","params":{"label":"at","commitCharacters":[".",",",";"],"data":{"tsc":{"specifier":"file:///path/to/test.ts","name":"at","position":3,"useCodeSnippet":true}},"sortText":"11","kind":2}},"server_name":"deno"} ```
Shougo commented 2 months ago

Reproduced. But I don't know what fix is correct.

k-86 commented 1 month ago

Timeout error was resolved by inserting vim sleep command.

https://github.com/Shougo/ddc-source-lsp/blob/2bdd53ca866d4f38339498b89846e0cbaaa842d2/denops/ddc-source-lsp/request.ts#L61-L65

    bufnr: opts.bufnr ?? await fn.bufnr(denops),
  },
);

await denops.cmd("sleep 500m");

const resolvedData = await deadline(waiter.promise, opts.timeout);
const { response: { result } } = u.ensure(

However, it failed the validation check.

https://github.com/Shougo/ddc-source-lsp/blob/2bdd53ca866d4f38339498b89846e0cbaaa842d2/denops/%40ddc-sources/lsp.ts#L267-L269 ``` return result as LSP.CompletionItem; } catch (e) { console.log(e); return lspItem; ``` :message ``` [denops] AssertError: Expected a value that satisfies the predicate isObjectOf({ [denops] result: isObjectOf({label: isString}) [denops] }), got object: { [denops] "label": "at", [denops] "insertText": "at(${1:index})", [denops] "sortText": "11", [denops] "kind": 2, [denops] "insertTextFormat": 2, [denops] "documentation": { [denops] "kind": "markdown", [denops] "value": "Returns the item located at the specified index.\n\n*@param* - index The zero-based index of the desired code unit. A negative index will count back from the last item." [denops] }, [denops] "detail": "(method) Array.at(index: number): undefined" [denops] } ```

It is caused by the difference in the format of the returned object depending on opts.sync. It should be unified.

lspEngine === "nvim-lsp" && opt.sync === true
return: { result: { label: ...     // expected return: { label: ...

lspEngine === "nvim-lsp" && opt.sync === false
return: { isIncomplete : false, items: [{ label: ...

lspEngine === "vim-lsp"
return: { label: ...
return: { isIncomplete : false, items: [{ label: ...
Shougo commented 1 month ago

I don't reproduce the timeout error unfortunately, but lsp#send_request() does not return...

Shougo commented 1 month ago

Please test the latest plugins and Vim again.

k-86 commented 1 month ago

I updated the plugins, Vim, and "How to reproduce the problem", and tested. No timeout error occurred, but it failed the validation check.

How to reproduce the problem

  1. echo "[]." > test.ts
  2. Replace path_to_test_ts in init.vim/vimrc
  3. (n)vim -u init.vim/vimrc test.ts
  4. Install deno lsp if it is not installed (call :LspManageServers)
  5. Wait until Identifier expected. is displayed on the screen
  6. Wait until denops#plugin#is_loaded("ddc") returns 1
  7. call Test()
Modified ddc-source-lsp ``` --- a/denops/@ddc-sources/lsp.ts +++ b/denops/@ddc-sources/lsp.ts @@ -265,7 +265,8 @@ export class Source extends BaseSource { is.ObjectOf({ result: is.ObjectOf({ label: is.String }) }), ); return result as LSP.CompletionItem; - } catch { + } catch(e) { + console.log(e); return lspItem; } } ``` ``` --- a/denops/ddc-source-lsp/request.ts +++ b/denops/ddc-source-lsp/request.ts @@ -61,6 +61,7 @@ export async function request( bufnr: opts.bufnr ?? await fn.bufnr(denops), }, ); + await denops.cmd("sleep 500m"); const resolvedData = await deadline(waiter.promise, opts.timeout); const { response: { result } } = u.ensure( resolvedData, ``` If `await denops.cmd("sleep 500m")` does not work, please try the code below. ``` --- a/denops/ddc-source-lsp/request.ts +++ b/denops/ddc-source-lsp/request.ts @@ -61,12 +61,21 @@ export async function request( bufnr: opts.bufnr ?? await fn.bufnr(denops), }, ); - const resolvedData = await deadline(waiter.promise, opts.timeout); - const { response: { result } } = u.ensure( - resolvedData, - is.ObjectOf({ response: is.ObjectOf({ result: is.Any }) }), - ); - return result; + const pResolvedData = deadline(waiter.promise, opts.timeout); + while (true) { + const resolvedData = await Promise.race([ + pResolvedData, + denops.cmd("sleep 1m"), + ]); + if (resolvedData) { + const { response: { result } } = u.ensure( + resolvedData, + is.ObjectOf({ response: is.ObjectOf({ result: is.Any }) }), + ); + return result; + } + } } catch (e) { if (e instanceof DeadlineError) { throw new Error(`No response from server ${opts.client.id}`); ```
:message ``` [denops] AssertError: Expected a value that satisfies the predicate isObjectOf({ [denops] result: isObjectOf({label: isString}) [denops] }), got object: { [denops] "label": "at", [denops] "insertText": "at(${1:index})", [denops] "sortText": "11", [denops] "kind": 2, [denops] "insertTextFormat": 2, [denops] "documentation": { [denops] "kind": "markdown", [denops] "value": "Returns the item located at the specified index.\n\n*@param* - index The zero-based index of the desired code unit. A negative index will count back from the last item." [denops] }, [denops] "detail": "(method) Array.at(index: number): undefined" [denops] } [denops] at assert (https://jsr.io/@core/unknownutil/3.18.0/util.ts:90:11) [denops] at Module.ensure (https://jsr.io/@core/unknownutil/3.18.0/util.ts:117:3) [denops] at Source.#resolve (file:///path/to/github.com/Shougo/ddc-source-lsp/denops/@ddc-sources/lsp.ts:263:28) [denops] at eventLoopTick (ext:core/01_core.js:168:7) [denops] at async Source.getPreviewer (file:///path/to/github.com/Shougo/ddc-source-lsp/denops/@ddc-sources/lsp.ts:284:21) [denops] at async getPreviewer (file:///path/to/github.com/Shougo/ddc.vim/denops/ddc/ext.ts:218:21) [denops] at async Object.getPreviewer (file:///path/to/github.com/Shougo/ddc.vim/denops/ddc/app.ts:150:14) [denops] at async Plugin.call (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/service.ts:158:12) [denops] at async Service.#dispatch (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/service.ts:88:12) [denops] at async Service.dispatch (file:///path/to/github.com/vim-denops/denops.vim/denops/@denops-private/service.ts:93:14) ddc#get_previewer: {'kind': 'markdown', 'contents': []} Elapsed time: 0.534230 ```
Environment Information - ddc-source-lsp version (SHA1): 2bdd53c - ddc-ui-none version (SHA1): 1c12bc3 - ddc.vim version (SHA1): 1ba1179 - denops.vim version (SHA1): 9dd9ae9 - vim-lsp version (SHA1): f7ccf00 - vim-lsp-settings version (SHA1): 54ade15 - deno version(`deno -V` output): deno 1.43.4 - OS: Ubuntu 22.04.4 LTS in WSL2 - neovim/Vim `:version` output: NVIM v0.10.0 Build type: Release LuaJIT 2.1.1713484068 VIM - Vi IMproved 9.1 Included patches: 1-414 Compiled by asdf Huge version without GUI. Features included (+) or not (-): +acl +file_in_path +mouse_urxvt -tag_any_white +arabic +find_in_path +mouse_xterm -tcl +autocmd +float +multi_byte +termguicolors +autochdir +folding +multi_lang +terminal -autoservername -footer -mzscheme +terminfo -balloon_eval +fork() +netbeans_intg +termresponse +balloon_eval_term -gettext +num64 +textobjects -browse -hangul_input +packages +textprop ++builtin_terms +iconv +path_extra +timers +byte_offset +insert_expand -perl +title +channel +ipv6 +persistent_undo -toolbar +cindent +job +popupwin +user_commands -clientserver +jumplist +postscript +vartabs -clipboard +keymap +printer +vertsplit +cmdline_compl +lambda +profile +vim9script +cmdline_hist +langmap -python +viminfo +cmdline_info +libcall -python3 +virtualedit +comments +linebreak +quickfix +visual +conceal +lispindent +reltime +visualextra +cryptv +listcmds +rightleft +vreplace +cscope +localmap -ruby +wildignore +cursorbind -lua +scrollbind +wildmenu +cursorshape +menu +signs +windows +dialog_con +mksession +smartindent +writebackup +diff +modify_fname -sodium -X11 +digraphs +mouse -sound +xattr -dnd -mouseshape +spell -xfontset -ebcdic +mouse_dec +startuptime -xim +emacs_tags -mouse_gpm +statusline -xpm +eval -mouse_jsbterm -sun_workshop -xsmp +ex_extra +mouse_netterm +syntax -xterm_clipboard +extra_search +mouse_sgr +tag_binary -xterm_save -farsi -mouse_sysmouse -tag_old_static
Shougo commented 1 month ago

I don't reproduce your error but the error message is displayed.

[denops] Error: Failed to call denops#api#eval("lsp#send_request(l:server, extend(l:request,{'on_notification': {data -> denops#notify(l:name, l:id, [data])}})
)", {"server":"deno","request":{"method":"completionItem/resolve","params":{"label":"at","commitCharacters":[".",",",";"],"data":{"tsc":{"specifier":"file:///h
ome/shougo/work/test.ts","name":"at","position":3,"useCodeSnippet":true}},"sortText":"11","kind":2}},"name":"ddc","id":"lambda:ddc:1bfebdd2-4f95-4d3f-8e8c-b5f8
34e9df8f","bufnr":1}): Vim(echomsg):E121: Undefined variable: request
[denops] function Test[40]..ddc#get_previewer[1]..ddc#denops#_request[1]..denops#request[1]..denops#_internal#server#chan#request[6]..denops#_internal#rpc#vim#
request[1]..denops#api#vim#call[2]..denops#api#eval[2]..lsp#send_request, line 1
[denops]     at Vim.call (file:///home/shougo/work/denops.vim/denops/@denops-private/host/vim.ts:56:13)
[denops]     at eventLoopTick (ext:core/01_core.js:168:7)
[denops]     at async request (file:///home/shougo/work/ddc-source-lsp/denops/ddc-source-lsp/request.ts:53:7)
[denops]     at async Source.#resolve (file:///home/shougo/work/ddc-source-lsp/denops/@ddc-sources/lsp.ts:256:24)
[denops]     at async Source.getPreviewer (file:///home/shougo/work/ddc-source-lsp/denops/@ddc-sources/lsp.ts:284:21)
[denops]     at async getPreviewer (file:///home/shougo/work/ddc.vim/denops/ddc/ext.ts:218:21)
[denops]     at async Object.getPreviewer (file:///home/shougo/work/ddc.vim/denops/ddc/app.ts:150:14)
[denops]     at async Plugin.call (file:///home/shougo/work/denops.vim/denops/@denops-private/service.ts:158:12)
[denops]     at async Service.#dispatch (file:///home/shougo/work/denops.vim/denops/@denops-private/service.ts:88:12)
[denops]     at async Service.dispatch (file:///home/shougo/work/denops.vim/denops/@denops-private/service.ts:93:14)
[denops] Error: Unsupported method: completionItem/resolve
[denops]     at request (file:///home/shougo/work/ddc-source-lsp/denops/ddc-source-lsp/request.ts:76:15)
[denops]     at eventLoopTick (ext:core/01_core.js:168:7)
[denops]     at async Source.#resolve (file:///home/shougo/work/ddc-source-lsp/denops/@ddc-sources/lsp.ts:256:24)
[denops]     at async Source.getPreviewer (file:///home/shougo/work/ddc-source-lsp/denops/@ddc-sources/lsp.ts:284:21)
[denops]     at async getPreviewer (file:///home/shougo/work/ddc.vim/denops/ddc/ext.ts:218:21)
[denops]     at async Object.getPreviewer (file:///home/shougo/work/ddc.vim/denops/ddc/app.ts:150:14)
[denops]     at async Plugin.call (file:///home/shougo/work/denops.vim/denops/@denops-private/service.ts:158:12)
[denops]     at async Service.#dispatch (file:///home/shougo/work/denops.vim/denops/@denops-private/service.ts:88:12)
[denops]     at async Service.dispatch (file:///home/shougo/work/denops.vim/denops/@denops-private/service.ts:93:14)
[denops]     at async Vim.#dispatch (file:///home/shougo/work/denops.vim/denops/@denops-private/host/vim.ts:114:14)
ddc#get_previewer: {'kind': 'markdown', 'contents': []}
Elapsed time:   0.125625
Press ENTER or type command to continue
k-86 commented 1 month ago

I've tried various things such as rebuilding the environment, updating Vim and the plugins, and testing with gVim, but I could not reproduce your error.

Since I'm getting nowhere, should I create a pull request for the ddc-source-lsp that works in my environment? Or should I create a new init.vim/vimrc with pum.vim preview enabled, a How to reproduce the problem, and the solution to the problem?

Shougo commented 1 month ago

Since I'm getting nowhere, should I create a pull request for the ddc-source-lsp that works in my environment?

OK. Please create it. I will test it later.

k-86 commented 1 month ago

OK. Please create it. I will test it later.

OK. I'll create some PRs because there are a few things to fix.