Merge branch 'master' of https://github.com/Chiel92/YouCompleteMe into multiple_sln

Conflicts:
	python/ycm/completers/cs/cs_completer.py
This commit is contained in:
Chiel92 2013-07-19 11:31:52 +02:00
commit 3f23893576
4 changed files with 391 additions and 250 deletions

View File

@ -7,10 +7,10 @@ YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for
[Vim][]. It has several completion engines: an identifier-based engine that [Vim][]. It has several completion engines: an identifier-based engine that
works with every programming language, a semantic, [Clang][]-based engine that works with every programming language, a semantic, [Clang][]-based engine that
provides native semantic code completion for C/C++/Objective-C/Objective-C++ provides native semantic code completion for C/C++/Objective-C/Objective-C++
(from now on referred to as "the C-family languages"), a [Jedi][]-based completion (from now on referred to as "the C-family languages"), a [Jedi][]-based
engine for Python and an omnifunc-based completer that uses data from Vim's completion engine for Python, an [OmniSharp][]-based completion engine for C#
omnicomplete system to provide semantic completions for many other languages and an omnifunc-based completer that uses data from Vim's omnicomplete system to
(Ruby, PHP etc.). provide semantic completions for many other languages (Ruby, PHP etc.).
![YouCompleteMe GIF demo](http://i.imgur.com/0OP4ood.gif) ![YouCompleteMe GIF demo](http://i.imgur.com/0OP4ood.gif)
@ -111,6 +111,9 @@ Compiling YCM **without** semantic support for C-family languages:
cd ~/.vim/bundle/YouCompleteMe cd ~/.vim/bundle/YouCompleteMe
./install.sh ./install.sh
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM. That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work, Don't forget that if you want the C-family semantic completion engine to work,
you will need to provide the compilation flags for your project to YCM. It's all you will need to provide the compilation flags for your project to YCM. It's all
@ -150,6 +153,9 @@ Compiling YCM **without** semantic support for C-family languages:
cd ~/.vim/bundle/YouCompleteMe cd ~/.vim/bundle/YouCompleteMe
./install.sh ./install.sh
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM. That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work, Don't forget that if you want the C-family semantic completion engine to work,
you will need to provide the compilation flags for your project to YCM. It's all you will need to provide the compilation flags for your project to YCM. It's all
@ -391,15 +397,15 @@ In the future expect to see features like go-to-definition for Python as well.
### C# semantic completion ### C# semantic completion
YCM uses [omnisharp][] to provide semantic completion for C#. YCM uses [OmniSharp][] to provide semantic completion for C#. It's used as a git
YCM uses it as a git subrepo. If you're installing YCM with Vundle subrepo. If you're installing YCM with Vundle (which is the recommended way)
(which is the recommended way) then Vundle will make sure that the subrepo is then Vundle will make sure that the subrepo is checked out when you do
checked out when you do `:BundleInstall`. If you're installing YCM by hand, then `:BundleInstall`. If you're installing YCM by hand, then you need to run `git
you need to run `git submodule update --init --recursive` when you're checking submodule update --init --recursive` when you're checking out the YCM
out the YCM repository. repository.
OmniSharp is written in C# and has to be compiled. The install script takes care of this OmniSharp is written in C# and has to be compiled. The `install.sh` script takes
if you pass `--omnisharp-completer` as an argument. care of this if you pass `--omnisharp-completer` as an argument.
### Semantic completion for other languages ### Semantic completion for other languages

File diff suppressed because it is too large Load Diff

View File

@ -150,7 +150,7 @@ let g:ycm_cache_omnifunc =
\ get( g:, 'ycm_cache_omnifunc', 1 ) \ get( g:, 'ycm_cache_omnifunc', 1 )
let g:ycm_auto_start_csharp_server = let g:ycm_auto_start_csharp_server =
\ get( g:, 'ycm_auto_start_csharp_server', 0 ) \ get( g:, 'ycm_auto_start_csharp_server', 1 )
let g:ycm_csharp_server_port = let g:ycm_csharp_server_port =
\ get( g:, 'ycm_csharp_server_port', 2000 ) \ get( g:, 'ycm_csharp_server_port', 2000 )

View File

@ -20,6 +20,7 @@
import vim import vim
import os import os
from sys import platform
import glob import glob
from ycm.completers.threaded_completer import ThreadedCompleter from ycm.completers.threaded_completer import ThreadedCompleter
from ycm import vimsupport from ycm import vimsupport
@ -30,6 +31,10 @@ import json
import subprocess import subprocess
SERVER_NOT_FOUND_MSG = ( 'OmniSharp server binary not found at {0}. ' +
'Did you compile it? You can do so by running ' +
'"./install.sh --omnisharp_completer".' )
class CsharpCompleter( ThreadedCompleter ): class CsharpCompleter( ThreadedCompleter ):
""" """
A Completer that uses the Omnisharp server as completion engine. A Completer that uses the Omnisharp server as completion engine.
@ -37,31 +42,36 @@ class CsharpCompleter( ThreadedCompleter ):
def __init__( self ): def __init__( self ):
super( CsharpCompleter, self ).__init__() super( CsharpCompleter, self ).__init__()
self.OmniSharpPort = int( vimsupport.GetVariableValue( self._omnisharp_port = int( vimsupport.GetVariableValue(
"g:ycm_csharp_server_port" ) ) 'g:ycm_csharp_server_port' ) )
self.OmniSharpHost = 'http://localhost:' + str( self.OmniSharpPort ) self._omnisharp_host = 'http://localhost:' + str( self._omnisharp_port )
if vimsupport.GetBoolValue( "g:ycm_auto_start_csharp_server" ): if vimsupport.GetBoolValue( 'g:ycm_auto_start_csharp_server' ):
self._StartServer() self._StartServer()
def OnVimLeave( self ): def OnVimLeave( self ):
if self._ServerIsRunning(): if self._ServerIsRunning():
self._StopServer() self._StopServer()
def SupportedFiletypes( self ): def SupportedFiletypes( self ):
""" Just csharp """ """ Just csharp """
return [ 'cs' ] return [ 'cs' ]
def ComputeCandidates( self, unused_query, unused_start_column ): def ComputeCandidates( self, unused_query, unused_start_column ):
return [ { 'word': str( completion['CompletionText'] ), return [ { 'word': str( completion[ 'CompletionText' ] ),
'menu': str( completion['DisplayText'] ), 'menu': str( completion[ 'DisplayText' ] ),
'info': str( completion['Description'] ) } 'info': str( completion[ 'Description' ] ) }
for completion in self._GetCompletions() ] for completion in self._GetCompletions() ]
def DefinedSubcommands( self ): def DefinedSubcommands( self ):
return [ 'StartServer', return [ 'StartServer',
'StopServer', 'StopServer',
'RestartServer' ] 'RestartServer' ]
def OnUserCommand( self, arguments ): def OnUserCommand( self, arguments ):
if not arguments: if not arguments:
self.EchoUserCommandsHelpMessage() self.EchoUserCommandsHelpMessage()
@ -77,43 +87,59 @@ class CsharpCompleter( ThreadedCompleter ):
self._StopServer() self._StopServer()
self._StartServer() self._StartServer()
def _StartServer( self ): def _StartServer( self ):
""" Start the OmniSharp server """ """ Start the OmniSharp server """
if not self._ServerIsRunning(): if self._ServerIsRunning():
solutionfiles, folder = self._FindSolutionFiles() vimsupport.PostVimMessage(
'Server already running, not starting it again.' )
return
solutionfiles, folder = _FindSolutionFiles()
if len( solutionfiles ) == 0: if len( solutionfiles ) == 0:
vimsupport.PostVimMessage( vimsupport.PostVimMessage(
'Error starting OmniSharp server: no solutionfile found' ) 'Error starting OmniSharp server: no solutionfile found' )
return return
elif len( solutionfiles ) == 1: elif len( solutionfiles ) == 1:
solutionfile = solutionfiles[0] solutionfile = solutionfiles[ 0 ]
else: else:
choice = vimsupport.PresentDialog( choice = vimsupport.PresentDialog(
"Which solutionfile should be loaded?", "Which solutionfile should be loaded?",
[ str(i) + " " + s for i, s in enumerate( solutionfiles ) ] ) [ str( i ) + " " + solution for i, solution in
enumerate( solutionfiles ) ] )
if choice == -1: if choice == -1:
vimsupport.PostVimMessage( 'OmniSharp not started' ) vimsupport.PostVimMessage( 'OmniSharp not started' )
return return
else: else:
#>>>MERGED
solutionfile = solutionfiles[ choice ] solutionfile = solutionfiles[ choice ]
omnisharp = os.path.join( os.path.abspath( os.path.dirname( __file__ ) ), omnisharp = os.path.join(
os.path.abspath( os.path.dirname( __file__ ) ),
'OmniSharpServer/OmniSharp/bin/Debug/OmniSharp.exe' ) 'OmniSharpServer/OmniSharp/bin/Debug/OmniSharp.exe' )
solutionfile = os.path.join ( folder, solutionfile )
if not os.path.isfile( omnisharp ):
vimsupport.PostVimMessage( SERVER_NOT_FOUND_MSG.format( omnisharp ) )
return
if not platform.startswith( 'win' ):
omnisharp = "mono " + omnisharp
solutionfile = os.path.join( folder, solutionfile )
# command has to be provided as one string for some reason # command has to be provided as one string for some reason
command = [ omnisharp + ' -p ' + str( self.OmniSharpPort ) command = [ omnisharp + ' -p ' + str( self._omnisharp_port ) + ' -s ' +
+ ' -s ' + solutionfile ] solutionfile ]
stderrLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stderr_logfile_format" ) stderrLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stderr_logfile_format" )
if stderrLogFormat: if stderrLogFormat:
filename_stderr = os.path.expanduser( stderrLogFormat.format( port=self.OmniSharpPort ) ) filename_stderr = os.path.expanduser( stderrLogFormat.format( port=self._omnisharp_port ) )
else: else:
filename_stderr = os.devnull filename_stderr = os.devnull
stdoutLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stdout_logfile_format" ) stdoutLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stdout_logfile_format" )
if stdoutLogFormat: if stdoutLogFormat:
filename_stdout = os.path.expanduser( stdoutLogFormat.format( port=self.OmniSharpPort ) ) filename_stdout = os.path.expanduser( stdoutLogFormat.format( port=self._omnisharp_port ) )
else: else:
filename_stdout = os.devnull filename_stdout = os.devnull
@ -121,24 +147,18 @@ class CsharpCompleter( ThreadedCompleter ):
with open( filename_stdout, "w" ) as fstdout: with open( filename_stdout, "w" ) as fstdout:
subprocess.Popen( command, stdout=fstdout, stderr=fstderr, shell=True ) subprocess.Popen( command, stdout=fstdout, stderr=fstderr, shell=True )
vimsupport.PostVimMessage( 'Starting OmniSharp server')
def _StopServer( self ): def _StopServer( self ):
""" Stop the OmniSharp server """ """ Stop the OmniSharp server """
self._GetResponse( '/stopserver' ) self._GetResponse( '/stopserver' )
vimsupport.PostVimMessage( 'Stopping OmniSharp server')
def _ServerIsRunning( self ): def _ServerIsRunning( self ):
""" Check if the OmniSharp server is running """ """ Check if the OmniSharp server is running """
return self._GetResponse( '/checkalivestatus', silent=True ) != None return self._GetResponse( '/checkalivestatus', silent=True ) != None
def _FindSolutionFiles( self ):
folder = os.path.dirname( vim.current.buffer.name )
solutionfiles = glob.glob1( folder, '*.sln' )
while not solutionfiles:
lastfolder = folder
folder = os.path.dirname( folder )
if folder == lastfolder:
break
solutionfiles = glob.glob1( folder, '*.sln' )
return solutionfiles, folder
def _GetCompletions( self ): def _GetCompletions( self ):
""" Ask server for completions """ """ Ask server for completions """
@ -152,15 +172,29 @@ class CsharpCompleter( ThreadedCompleter ):
completions = self._GetResponse( '/autocomplete', parameters ) completions = self._GetResponse( '/autocomplete', parameters )
return completions if completions != None else [] return completions if completions != None else []
def _GetResponse( self, endPoint, parameters={}, silent = False ): def _GetResponse( self, endPoint, parameters={}, silent = False ):
""" Handle communication with server """ """ Handle communication with server """
target = urlparse.urljoin( self.OmniSharpHost, endPoint ) target = urlparse.urljoin( self._omnisharp_host, endPoint )
parameters = urllib.urlencode( parameters ) parameters = urllib.urlencode( parameters )
try: try:
response = urllib2.urlopen( target, parameters ) response = urllib2.urlopen( target, parameters )
return json.loads( response.read() ) return json.loads( response.read() )
except Exception as e: except Exception as e:
if not silent: if not silent:
vimsupport.PostVimMessage('OmniSharp : Could not connect to ' vimsupport.PostVimMessage(
+ target + ': ' + str(e)) 'OmniSharp : Could not connect to ' + target + ': ' + str( e ) )
return None return None
def _FindSolutionFiles():
folder = os.path.dirname( vim.current.buffer.name )
solutionfiles = glob.glob1( folder, '*.sln' )
while not solutionfiles:
lastfolder = folder
folder = os.path.dirname( folder )
if folder == lastfolder:
break
solutionfiles = glob.glob1( folder, '*.sln' )
return solutionfiles, folder