Skip to content
This repository has been archived by the owner on Jul 27, 2018. It is now read-only.

Doesn't work with LanguageClient-neovim in Vim8 (but works in Neovim) #175

Open
kodemeister opened this issue Jan 13, 2018 · 0 comments
Open

Comments

@kodemeister
Copy link

Hi @roxma,

I'm having issues while trying to get NCM work with LanguageClient-neovim in Vim 8. In Neovim completions from LanguageClient-neovim work perfectly but I can't get them working in Vim 8 at all.

I'm using C++ but the language doesn't really matter. Here is a test C++ file:

#include <iostream>

int main(int argc, char **argv)
{
	std:: // Completions show up in Neovim but not in Vim 8
	return 0;
}

In Vim 8 LanguageClient-neovim issues the following error in /tmp/LanguageClient.log:

2018-01-13T23:17:45.186112346+06:00 ERROR languageclient::languageclient - Error handling message. Message: {"method":"LanguageClient_NCMRefresh","jsonrpc":"2.0","params":[{"scopes":["cpp"],"cm_refresh_patterns":["\\.",">",":"],"early_cache":0,"cm_refresh":"LanguageClient_NCMRefresh","priority":9,"enable":1,"auto_popup":1,"cm_refresh_length":3,"sort":1,"abbreviation":"LC","name":"LanguageClient_cpp"},{"scope_match":"cpp","lnum":5,"bufnr":1,"changedtick":3,"typed":"\tstd::","base":"","filetype":"cpp","curpos":[0,5,7,0,14],"col":7,"early_cache":0,"filepath":"/home/kodemeister/test.cpp","scope":"cpp","force":0,"startcol":7,"match_end":6}]}. Error: ErrorImpl { code: Message("invalid type: integer `0`, expected a boolean"), line: 0, column: 0 }

So basically LanguageClient-neovim tells us that it expects some Boolean value but gets a plain integer 0 instead.

I've tracked the issue down to NCM function cm#_notify_sources_to_refresh, particularly to the code which calls source completion functions:

elseif l:type==1
    "string
    call call(g:_cm_sources[l:name].cm_refresh,[g:_cm_sources[l:name],l:call['context']],g:_cm_sources[l:name])

The problem is that l:call['context'] value differs in Neovim and Vim 8. Here is its value in Neovim:

{'scope_match': 'cpp', 'lnum': 5, 'bufnr': 1, 'changedtick': 3, 'typed': ' std::', 'base' : '', 'filetype': 'cpp', 'curpos': [0, 5, 7, 0, 14], 'col': 7, 'early_cache': v:false, 'filepath': '/home/kodemeister/test.cpp', 'scope': 'cpp', 'force': 0, 'startcol': 7, 'match_end': 6}

And in Vim 8:

{'scope_match': 'cpp', 'lnum': 5, 'bufnr': 1, 'changedtick': 3, 'typed': ' std::', 'base' : '', 'filetype': 'cpp', 'curpos': [0, 5, 7, 0, 14], 'col': 7, 'early_cache': 0, 'filepath': '/home/kodemeister/test.cpp', 'scope': 'cpp', 'force': 0, 'startcol': 7, 'match_end': 6}

Can you see the difference? In Neovim early_cache key is v:false whereas in Vim 8 early_cache is just plain integer 0. That's why LanguageClient-neovim gives us an error in Vim 8! It expects early_cache to be strictly v:true or v:false but not 1 or 0.

Since early_cache is set in Python code I think the difference comes from conversions between Python and VimL types. Neovim converts Python's True and False to VimL's v:true and v:false while Vim 8 bundled with vim-hug-neovim-rpc converts them to 1 and 0.

Nevertheless, I was able to temporarily fix the issue with an ugly hack:

elseif l:type==1
    "string
    let l:context = l:call['context']
    let l:context['early_cache'] = l:context['early_cache'] ? v:true : v:false
    call call(g:_cm_sources[l:name].cm_refresh,[g:_cm_sources[l:name],l:call['context']],g:_cm_sources[l:name])

Could you please suggest a better solution here? I thought about fixing Python code to always set early_cache to 0 or 1 but LanguageClient-neovim should be also adjusted in this case.

Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant