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
@ -240,8 +246,8 @@ notify you to recompile it. You should then rerun the install process.
Now we need to generate the makefiles. If you DON'T care about semantic Now we need to generate the makefiles. If you DON'T care about semantic
support for C-family languages, run the following command in the `ycm_build` support for C-family languages, run the following command in the `ycm_build`
directory: directory:
cmake -G "Unix Makefiles" . ~/.vim/bundle/YouCompleteMe/cpp cmake -G "Unix Makefiles" . ~/.vim/bundle/YouCompleteMe/cpp
If you DO care about semantic support for C-family languages, then your If you DO care about semantic support for C-family languages, then your
@ -250,11 +256,11 @@ notify you to recompile it. You should then rerun the install process.
extracted the archive file to folder `~/ycm_temp/llvm_root_dir` (with `bin`, extracted the archive file to folder `~/ycm_temp/llvm_root_dir` (with `bin`,
`lib`, `include` etc. folders right inside that folder). With that in mind, `lib`, `include` etc. folders right inside that folder). With that in mind,
run the following command in the `ycm_build` directory: run the following command in the `ycm_build` directory:
cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir . ~/.vim/bundle/YouCompleteMe/cpp cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir . ~/.vim/bundle/YouCompleteMe/cpp
Now that makefiles have been generated, simply run: Now that makefiles have been generated, simply run:
make ycm_core make ycm_core
For those who want to use the system version of libclang, you would pass For those who want to use the system version of libclang, you would pass
@ -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,68 +87,78 @@ 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
if len( solutionfiles ) == 0: solutionfiles, folder = _FindSolutionFiles()
vimsupport.PostVimMessage(
'Error starting OmniSharp server: no solutionfile found' ) if len( solutionfiles ) == 0:
vimsupport.PostVimMessage(
'Error starting OmniSharp server: no solutionfile found' )
return
elif len( solutionfiles ) == 1:
solutionfile = solutionfiles[ 0 ]
else:
choice = vimsupport.PresentDialog(
"Which solutionfile should be loaded?",
[ str( i ) + " " + solution for i, solution in
enumerate( solutionfiles ) ] )
if choice == -1:
vimsupport.PostVimMessage( 'OmniSharp not started' )
return return
elif len( solutionfiles ) == 1:
solutionfile = solutionfiles[0]
else: else:
choice = vimsupport.PresentDialog( #>>>MERGED
"Which solutionfile should be loaded?", solutionfile = solutionfiles[ choice ]
[ str(i) + " " + s for i, s in enumerate( solutionfiles ) ] )
if choice == -1:
vimsupport.PostVimMessage( 'OmniSharp not started' )
return
else:
solutionfile = solutionfiles[ choice ]
omnisharp = os.path.join( os.path.abspath( os.path.dirname( __file__ ) ), omnisharp = os.path.join(
'OmniSharpServer/OmniSharp/bin/Debug/OmniSharp.exe' ) os.path.abspath( os.path.dirname( __file__ ) ),
solutionfile = os.path.join ( folder, solutionfile ) 'OmniSharpServer/OmniSharp/bin/Debug/OmniSharp.exe' )
# command has to be provided as one string for some reason
command = [ omnisharp + ' -p ' + str( self.OmniSharpPort )
+ ' -s ' + solutionfile ]
stderrLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stderr_logfile_format" ) if not os.path.isfile( omnisharp ):
if stderrLogFormat: vimsupport.PostVimMessage( SERVER_NOT_FOUND_MSG.format( omnisharp ) )
filename_stderr = os.path.expanduser( stderrLogFormat.format( port=self.OmniSharpPort ) ) return
else:
filename_stderr = os.devnull
stdoutLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stdout_logfile_format" ) if not platform.startswith( 'win' ):
if stdoutLogFormat: omnisharp = "mono " + omnisharp
filename_stdout = os.path.expanduser( stdoutLogFormat.format( port=self.OmniSharpPort ) )
else:
filename_stdout = os.devnull
with open( filename_stderr, "w" ) as fstderr: solutionfile = os.path.join( folder, solutionfile )
with open( filename_stdout, "w" ) as fstdout: # command has to be provided as one string for some reason
subprocess.Popen( command, stdout=fstdout, stderr=fstderr, shell=True ) command = [ omnisharp + ' -p ' + str( self._omnisharp_port ) + ' -s ' +
solutionfile ]
stderrLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stderr_logfile_format" )
if stderrLogFormat:
filename_stderr = os.path.expanduser( stderrLogFormat.format( port=self._omnisharp_port ) )
else:
filename_stderr = os.devnull
stdoutLogFormat = vimsupport.GetVariableValue( "g:ycm_csharp_server_stdout_logfile_format" )
if stdoutLogFormat:
filename_stdout = os.path.expanduser( stdoutLogFormat.format( port=self._omnisharp_port ) )
else:
filename_stdout = os.devnull
with open( filename_stderr, "w" ) as fstderr:
with open( filename_stdout, "w" ) as fstdout:
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