prabirshrestha / vim-lsp

async language server protocol plugin for vim and neovim
MIT License
3.14k stars 305 forks source link

Issues with Ruby sigils #212

Closed cvincent closed 4 years ago

cvincent commented 5 years ago

I'm seeing two different issues using vim-lsp with Solargraph which are possibly related.

First, when autocompleting an instance variable following @, the resulting completion includes the @ resulting in @@. Here is the RPC log resulting from triggering a completion by typing @:

[
  "--->",
  3,
  "solargraph",
  {
    "method": "textDocument/didChange",
    "params": {
      "contentChanges": [
        {
          "text": "class Test\n\tdef x\n\t\tmy_var = 'asfd'\n\t\t@my_var = 'asdf'\n\t\t$my_glob = 'asdf'\n\t\t@\n\tend\nend\n"
        }
      ],
      "textDocument": {
        "uri": "file:///home/me/src/map/test.rb",
        "version": 6
      }
    }
  }
]

[
  {
    "response": {
      "data": {
        "path": "file:///home/me/src/map/test.rb",
        "__data__": "vim-lsp",
        "server_name": "solargraph"
      },
      "message": "textDocument/didChange sent"
    }
  }
]

[
  "--->",
  3,
  "solargraph",
  {
    "method": "textDocument/completion",
    "on_notification": "---funcref---",
    "params": {
      "textDocument": {
        "uri": "file:///home/me/src/map/test.rb"
      },
      "position": {
        "character": 3,
        "line": 5
      }
    }
  }
]

[
  "<---",
  3,
  "solargraph",
  {
    "response": {
      "id": 5,
      "jsonrpc": "2.0",
      "result": {
        "isIncomplete": false,
        "items": [
          {
            "label": "@my_var",
            "data": {
              "return_type": "String",
              "path": null,
              "location": {
                "filename": "/home/me/src/map/test.rb",
                "range": {
                  "end": {
                    "character": 18,
                    "line": 3
                  },
                  "start": {
                    "character": 2,
                    "line": 3
                  }
                }
              },
              "deprecated": false
            },
            "textEdit": {
              "range": {
                "end": {
                  "character": 3,
                  "line": 5
                },
                "start": {
                  "character": 2,
                  "line": 5
                }
              },
              "newText": "@my_var"
            },
            "sortText": "0000@my_var",
            "kind": 6,
            "detail": "=> String"
          }
        ]
      }
    },
    "request": {
      "method": "textDocument/completion",
      "jsonrpc": "2.0",
      "id": 5,
      "params": {
        "textDocument": {
          "uri": "file:///home/me/src/map/test.rb"
        },
        "position": {
          "character": 3,
          "line": 5
        }
      }
    }
  }
]

Second, when using :LspRename on any variable with a sigil, such as @instance_var or $global_var, it appears to work when the cursor is on the character following the sigil (so on the i in @instance_var, but when the cursor is on the sigil itself (@), it does the replacement but removes the sigil (so @instance_var becomes instance_var_renamed everywhere). I can get around this by manually adding the missing sigil to the rename prompt, but it should already be present. Here is the RPC log output when I issue :LspRename on a variable's sigil:

[
    "--->",
    3,
    "solargraph",
    {
        "method": "textDocument/rename",
        "on_notification": "---funcref---",
        "params":
        {
            "newName": "my_varrrrr",
            "textDocument":
            {
                "uri": "file:///home/redplateaus/src/map/test.rb"
            },
            "position":
            {
                "character": 2,
                "line": 3
            }
        }
    }
]

[
    "<---",
    3,
    "solargraph",
    {
        "response":
        {
            "id": 6,
            "jsonrpc": "2.0",
            "result":
            {
                "changes":
                {
                    "file:///home/redplateaus/src/map/test.rb":
                    [
                        {
                            "range":
                            {
                                "end":
                                {
                                    "character": 9,
                                    "line": 3
                                },
                                "start":
                                {
                                    "character": 2,
                                    "line": 3
                                }
                            },
                            "newText": "my_varrrrr"
                        }
                    ]
                }
            }
        },
        "request":
        {
            "method": "textDocument/rename",
            "jsonrpc": "2.0",
            "id": 6,
            "params":
            {
                "newName": "my_varrrrr",
                "textDocument":
                {
                    "uri": "file:///home/redplateaus/src/map/test.rb"
                },
                "position":
                {
                    "character": 2,
                    "line": 3
                }
            }
        }
    }
]

["s:build_cmd", "keepjumps keepalt b 1 | execute 'keepjumps normal! 4G02lv4G09lcmy_varrrrr'"]

This could very well be an issue with ncm2, ncm2-vim-lsp, or Solargraph, but I have no idea where to begin.

Here's my minimal NeoVim config reproducing this issue:

scriptencoding utf-8

filetype off
call plug#begin('~/.config/nvim/plugged')
Plug 'prabirshrestha/async.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'ncm2/ncm2'
Plug 'roxma/nvim-yarp'
Plug 'ncm2/ncm2-vim-lsp'
call plug#end()
filetype plugin indent on

set completeopt=noinsert,menuone,noselect
autocmd BufEnter * call ncm2#enable_for_buffer()
inoremap <expr> <CR> (pumvisible() ? "\<c-y>\<cr>" : "\<CR>")
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"

if executable('solargraph')
  au User lsp_setup call lsp#register_server({
      \ 'name': 'solargraph',
      \ 'cmd': {server_info->[&shell, &shellcmdflag, 'solargraph stdio']},
      \ 'initialization_options': {"diagnostics": "true"},
      \ 'whitelist': ['ruby'],
      \ })
endif

And my nvim --version output:

NVIM v0.2.2
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/cc -g -O2 -fdebug-prefix-map=/build/neovim-_mzR4z/neovim-0.2.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -DDISABLE_LOG -Wdate-time -D_FORTIFY_SOURCE=2 -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -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 -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -I/build/neovim-_mzR4z/neovim-0.2.2/build/config -I/build/neovim-_mzR4z/neovim-0.2.2/src -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/build/neovim-_mzR4z/neovim-0.2.2/build/src/nvim/auto -I/build/neovim-_mzR4z/neovim-0.2.2/build/include
Compiled by pkg-vim-maintainers@lists.alioth.debian.org

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

Thank you for any help, and let me know if I can provide further information to assist.

mattn commented 5 years ago

First, As far as I looked this, solargraph does not handle @, Language server client just send whole content and cursor location.

image

In your log file, I can't find init_result. init_result include options completionProvider that have marker character. ex: @, ., ::

Second, you seems not set iskeyword option for ruby filetype. please try to add @-@ to iskeyword.

set iskeyword+=@-@
roxma commented 5 years ago

Unfortunately LSP does not define startcol and word_pattern. Plugins need to add workaround for this.

This issue is fixed in ncm2 https://github.com/ncm2/ncm2/commit/48058b7c5ff1dd47e1683c288e5b410be9ac4503

mattn commented 5 years ago

This should be fixed in https://github.com/prabirshrestha/vim-lsp/pull/253

LSP have prepareRename. vim-lsp added it in #253. And latset version of solargraph added prepareRename. (I implemented in https://github.com/castwide/solargraph/pull/158). So no need to do workaround, I think.

roxma commented 5 years ago

Thanks for the info! @mattn

However, I don't enjoy chaining a prepareRename in the middle of completion request. (EDIT: As described by its name, it is not designed for completion.)

mattn commented 5 years ago

For about completion, afaik, vim-lsp stoped to calculate findstart...

toupeira commented 5 years ago

This issue is fixed in ncm2 ncm2/ncm2@48058b7

@roxma this seems to work great for @foo and $foo, but auto-completing :foo still results in ::foo. I also tried set iskeyword+=: but that didn't help.

roxma commented 5 years ago

@toupeira

but auto-completing :foo still results in ::foo

Fixed in https://github.com/ncm2/ncm2/commit/5549ae88f5496bb6a6108ede83a20d35e1201975

toupeira commented 5 years ago

@roxma thanks a lot, works perfectly now! :+1: