ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.44k stars 2.81k forks source link

meta: Integrate external completers into YCM? #207

Closed chtenb closed 11 years ago

chtenb commented 11 years ago

I'm eager to get strong C# autocompletion for vim, which is as powerful as the engine in visual-studio or mono-develop. The engine that is used by sharpdevelop and monodevelop is available as open source: https://github.com/icsharpcode/NRefactory/.

This made me think. Is it good to write a completer for every language specifically for YCM? Or is it better to integrate powerful engines that already exist? If they exist, of course.

I don't know if the latter is reasonably possible though. But if it's possible, it might open up a door to other languages with external completers as well.

Valloric commented 11 years ago

There is already a robust Completer API in YCM. All that is needed is for someone to start writing those custom completers for YCM. The clang_completer uses libclang as the completion source; it's certainly possible to call an external executable to do the same thing.

So yes, it's already possible to integrate external completers into YCM.

chtenb commented 11 years ago

That's good to know. I will have a look how tough it is to connect NRefactory to YCM.

chtenb commented 11 years ago

One more question one this.

Although the clang_completer is using an external executable, it can be built when YCM is installed, since it is written in C++. (same as YCM, as far as I'm aware) The NRefactory library containing tools for C# completion is written in C# however. That means that a user should compile C# code using mono or .NET to be able to use C# completion. I don't know if that's desirable. Would this affect the likeliness of the external completer being merged?

Valloric commented 11 years ago

The NRefactory library containing tools for C# completion is written in C# however. That means that a user should compile C# code using mono or .NET to be able to use C# completion. I don't know if that's desirable. Would this affect the likeliness of the external completer being merged?

No, it wouldn't affect the chances of that being merged in as long as users who don't want C# completion are not burdened by this. For instance, YCM can be compiled with and without clang support and the install script does not compile it by default. Something similar should be available for the C# completion; the user should have to provide a flag to install.sh so that the C# system builds and by default it doesn't.

chtenb commented 11 years ago

I have been investigating Omnisharp (https://github.com/nosami/Omnisharp), a plugin that also tries to utilize the NRefactory library. It basically runs a server which is listening for requests from vim.

What is the best approach? Creating a binary that is executed for every request, or create a server like with Omnisharp. Or is there an even better approach? I can't seem to figure out which jedi and clang use.

Valloric commented 11 years ago

I'm not sure you'd be able to get the performance you want if you make it a binary you have to call every time you want semantic completions. The process set-up costs would eat your latency budget (I'm guessing, I could be wrong; you could try it and see).

A server that your Completer class would talk to sounds like a sensible idea. May I suggest Apache Thrift as the communication mechanism between the Completer Python code and your C# code.

The jedi_completer runs Jedi's Python code in-process. Vim runs an embedded Python interpreter and this is what YCM uses for its Python code. The jedi_completer just imports the Jedi library like any Python library and then uses it.

The clang_completer is a bit special. The whole Clang compiler can be accessed from the libclang (native-code) shared library. YCM build process builds ycm_core which is a shared library that uses the API in libclang (and depends on the libclang library). ycm_core is compiled as a native-code Python plugin that is then loaded into the YCM Python code in Vim's Python interpreter. So all of this again runs inside the Vim process (although this may change in the future).

chtenb commented 11 years ago

I have been playing around with the Omnisharp server, and I got it to work with YCM. It works pretty well.

The Omnisharp server listens on some port and does the communication in json objects. You suggested Apache thrift as communication mechanism. What are the benefits of this, and is it worth rewriting the communication part of the server?

Valloric commented 11 years ago

It was just a suggestion; if JSON is good enough, than I'm fine with that.

chtenb commented 11 years ago

Currently, the Omnisharp server needs to be started manually and pointed to the solution file (.sln) of the project you are working on. Of course it's desirable if this could be done automatically as far as possible. However, is some cases it may be unclear where the solution file is, and the user should be prompted within vim. Would YCM come with a feature which enables this? Or do you think this must be solved differently?

Valloric commented 11 years ago

I recommend using the ycm_extra_conf.py file for this. Require the user to have a function in it that returns the full, absolute path to the .sln file. See the YCM docs for details on how the ycm_extra_conf file works.

chtenb commented 11 years ago

Isn't there a way that wouldn't require the user to do anything? You basically want vim to recognize the right .sln file automatically, as far as possible.

I was thinking of just scanning upwards through the folders from the the current source file until the solution was found and just start that one (assuming that there is only one solution file). If more than one was found, then we'd have to prompt the user.

Valloric commented 11 years ago

That sounds fine.