autozimu / LanguageClient-neovim

Language Server Protocol (LSP) support for vim and neovim.
MIT License
3.55k stars 273 forks source link

Deoplete + ccls autocomplete to garbage #812

Closed AlxHnr closed 4 years ago

AlxHnr commented 5 years ago

Describe the bug

Members of certain classes/structs autocomplete to garbage. See Current Behaviour for more details.

Environment

NVIM v0.3.3
Build type: RelWithDebInfo
Lua 5.3
Compilation: /usr/bin/cc -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wconversion -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=1 -O2 -g -DMIN_LOG_LEVEL=3 -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=auto -Wno-array-bounds -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -I/builddir/build/BUILD/neovim-0.3.3/build/config -I/builddir/build/BUILD/neovim-0.3.3/src -I/usr/include -I/builddir/build/BUILD/neovim-0.3.3/build/src/nvim/auto -I/builddir/build/BUILD/neovim-0.3.3/build/include
Compiled by mockbuild

Features: +acl +iconv -jemalloc +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

Run :checkhealth for more info

To Reproduce

Create a minimal nvim runtime with plug.vim, the latest ccls, deoplete.vim and LanguageClient-neovim:

mkdir -p /tmp/vim-runtime/autoload
cd /tmp/vim-runtime

wget https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim \
  -O autoload/plug.vim

git clone --recurse-submodules https://github.com/MaskRay/ccls
mkdir -p ccls/build/
(cd ccls/build && cmake .. && make "-j$(nproc)")

Copy this to /tmp/vim-runtime/init.vim:

set runtimepath=/usr/local/share/nvim/site
set runtimepath+=/usr/share/nvim/site
set runtimepath+=/usr/share/nvim/runtime
set runtimepath+=/usr/share/nvim/site/after
set runtimepath+=/usr/local/share/nvim/site/after
set runtimepath+=/tmp/vim-runtime
set completeopt-=preview

call plug#begin('/tmp/vim-runtime/plugged')

Plug 'autozimu/LanguageClient-neovim',
  \ {
  \   'branch': 'next',
  \   'do': 'bash install.sh',
  \ }
let g:LanguageClient_serverCommands = { 'cpp': [ '/tmp/vim-runtime/ccls/build/ccls' ] }
let g:LanguageClient_useVirtualText = 0

Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
let g:deoplete#enable_at_startup = 1

call plug#end()

Copy this to /tmp/vim-runtime/example.cpp:

#include <memory>

class Foo {
public:
  Foo() = default;
  void setValue(const int value) { this->value = value; }
  int getValue() { return value; }
  void doNothing() {}

private:
  int value{7};
};

int main() {
  auto foo = std::make_unique<Foo>();

  /* Try to complete this. */
  foo->
}

Install all plugins and (re)start nvim with the example.cpp file:

nvim -u /tmp/vim-runtime/init.vim +PlugInstall +qall
nvim -u /tmp/vim-runtime/init.vim example.cpp

Current behavior

Members like doNothing get completed to hing().

preview

Expected behavior

Members like doNothing get completed to doNothing, without the parenthesis. There is an option in deoplete to disable parenthesis completion, but it seems to have no effect.

CCLS works, the contents of the pop-up are correct. It may be a deoplete problem, but I couldn't reproduce it in isolation without the other components. Maybe @Shougo could.

Shougo commented 5 years ago

I have tested old ccls, it works properly. And I have tested the new version of ccls. It does not work unfortunately. ccls behavior seems changed.

Shougo commented 5 years ago

Reproduced with ccls-git in Manjaro Linux.

Shougo commented 5 years ago

CCLS works, the contents of the pop-up are correct. It may be a deoplete problem, but I couldn't reproduce it in isolation without the other components. Maybe @Shougo could.

It is not deoplete problem. Candidates word is broken in LanguageClient source.

AlxHnr commented 5 years ago

Candidates word is broken in LanguageClient source.

Is the candidate word list different from the list displayed in the popup? The contents of the popup itself are correct, as seen in the screenshot. It is strange that it works properly with older versions of ccls. I doubt that ccls sends two lists: a proper one for the popup and a broken list for completion. Maybe @MaskRay could reproduce it.

It's possible that LanguageClient-neovim corrupts the stuff it receives. I've peeked into the logs on DEBUG but couldn't find anything suspicious.

MaskRay commented 5 years ago

https://github.com/MaskRay/ccls/pull/210

A completion item looks like:

{
  "label": "doNothing() -> void",
  "kind": 2,
  "detail": "Foo",
  "sortText": "   !",
  "filterTet": "->doNothing", /// it has to include -> to work around a VSCode issue
  "insertTextFormat": 1,
  "textEdit": {
    "range": {
      "start": {
        "line": 17,
        "character": 5
      },
      "end": {
        "line": 17,
        "character": 7
      }
    },
    "newText": "->doNothing()"
  }
}
AlxHnr commented 5 years ago

I don't think the -> is the issue. The first 7 characters of ->doNothing() are cut off. How do other lsp clients handle this (besides VSCode of course)? And is "newText" supposed to have closing parens?

AlxHnr commented 5 years ago

Using clangd with the same deoplete and LanguageClient-neovim does not have this problem:

let g:LanguageClient_serverCommands = { 'cpp': [ 'clangd' ] }

CCLS still completes to broken results. I just tried it using the latest ccls, deoplete and LanguageClient-neovim from today:

languageclient 0.1.146

ccls version 0.20190314.1-16-g990925d8
clang version 8.0.0 (Fedora 8.0.0-1.fc30)
AlxHnr commented 5 years ago

This problem does not occur anymore using the latest ccls, LanguageClient-neovim and deoplete.vim.

Now there is a new problem, which causes the completion to insert full function signatures instead of just the function name. E.g. setValue completes wrongfully to setValue(const int value) -> void. This seems to be addressed in #857 so I'm going to close this one.

AlxHnr commented 5 years ago

This issue is back with 0.1.155. You can use the same code I've posted above in the initial example to reproduce the bug.

Note: You have to download 0.1.155 manually to LanguageClient-neovim/bin/ because the install script is still stuck at 0.1.154.

This time hing() gets completed to hing (without the parenthesis):

autocomplete

Output of languageclient --version:

languageclient 0.1.155

Output of ccls --version:

ccls version 0.20190314.2-5-gbfac2162
clang version 8.0.0 (Fedora 8.0.0-3.fc30)

I'm using the latest deoplete, freshly cloned from master at the time of writing.

AlxHnr commented 5 years ago

I doubt this issue is a problem with ccls or deoplete. I've tried all other LSP plugins, some of which also rely on deoplete and ccls. They don't have this particular issue, but are unfortunately broken in their own ways. I hope one day we will have working and reliable LSP support in Neovim.

Note: For those who who came here sharing the same dissatisfaction with the state of LSP plugins, I can only recommend you to configure YouCompleteMe to act as an LSP client for ccls. It works pretty good. You just have to rebuild YCM without its own clang-based semantic features and configure g:ycm_language_server to use ccls.

MaskRay commented 5 years ago

It has been a while since I tried LanguageClient-neovim, but I think this may be a duplicate of https://github.com/autozimu/LanguageClient-neovim/issues/662 The root cause is that a new completion mechanism is not supported in LanguageClient-neovim, or the snippet engine it uses.

clangd still supports insertText for backward compatibility but ccls does not do that since Nov, 2018.

I don't know the state of snippet support in the neovim ecosystem. ccls supports 3 different completion styles (https://github.com/MaskRay/ccls/wiki/Customization)

dimbleby commented 5 years ago

So far as I know, g:LanguageClient_completionPreferTextEdit works well since #858.

ccls and LanguageClient-neovim and snippet support all work well together, in my recent experience.

Perhaps it's time to make prefer-text-edit the client default; then so far as I can see both this and #662 can be closed.

Edit: one caveat on this is that I use NCM2 and not deoplete. So it may be that the deoplete integration is not correct, I wouldn't know about that.

martskins commented 4 years ago

I'll close this one as it seems stale and it has been fixed (at least for NCM2) but feel free to re-open if anyone is still experiences this issue.