The UltiSnips completer works again

This commit is contained in:
Strahinja Val Markovic 2013-09-25 10:56:46 -07:00
parent bf5708c422
commit 4c6a69b432
8 changed files with 89 additions and 36 deletions

View File

@ -44,6 +44,7 @@ function! youcompleteme#Enable()
py from ycm import vimsupport py from ycm import vimsupport
py from ycm import user_options_store py from ycm import user_options_store
py user_options_store.SetAll( base.BuildServerConf() ) py user_options_store.SetAll( base.BuildServerConf() )
" TODO: Remove the call to YcmPreload
py from ycm import extra_conf_store py from ycm import extra_conf_store
py extra_conf_store.CallExtraConfYcmCorePreloadIfExists() py extra_conf_store.CallExtraConfYcmCorePreloadIfExists()
@ -549,6 +550,7 @@ endfunction
function! youcompleteme#OmniComplete( findstart, base ) function! youcompleteme#OmniComplete( findstart, base )
if a:findstart if a:findstart
let s:omnifunc_mode = 1 let s:omnifunc_mode = 1
" TODO: Force semantic mode here (<c-space> needs to work)
return pyeval( 'ycm_state.CreateCompletionRequest().CompletionStartColumn()' ) return pyeval( 'ycm_state.CreateCompletionRequest().CompletionStartColumn()' )
else else
return s:CompletionsForQuery( a:base ) return s:CompletionsForQuery( a:base )

View File

@ -88,6 +88,7 @@ private:
template< class T > template< class T >
struct ResultAnd { struct ResultAnd {
// TODO: Swap the order of these parameters
ResultAnd( T extra_object, const Result &result ) ResultAnd( T extra_object, const Result &result )
: extra_object_( extra_object ), result_( result ) {} : extra_object_( extra_object ), result_( result ) {}

View File

@ -55,6 +55,9 @@ class ClangCompleter( Completer ):
# in progress. We use this to trigger the pending request after the previous # in progress. We use this to trigger the pending request after the previous
# one completes (from GetDiagnosticsForCurrentFile because that's the only # one completes (from GetDiagnosticsForCurrentFile because that's the only
# method that knows when the compilation has finished). # method that knows when the compilation has finished).
# TODO: Remove this now that we have multiple threads in the server; the
# subsequent requests that want to parse will just block until the current
# parse is done and will then proceed.
self.extra_parse_desired = False self.extra_parse_desired = False
@ -213,7 +216,6 @@ class ClangCompleter( Completer ):
self.flags.Clear() self.flags.Clear()
def OnFileReadyToParse( self, request_data ): def OnFileReadyToParse( self, request_data ):
filename = request_data[ 'filepath' ] filename = request_data[ 'filepath' ]
contents = request_data[ 'file_data' ][ filename ][ 'contents' ] contents = request_data[ 'file_data' ][ filename ][ 'contents' ]

View File

@ -21,13 +21,7 @@
from ycm.completers.completer import Completer from ycm.completers.completer import Completer
from ycm.completers.all.identifier_completer import IdentifierCompleter from ycm.completers.all.identifier_completer import IdentifierCompleter
from ycm.completers.general.filename_completer import FilenameCompleter from ycm.completers.general.filename_completer import FilenameCompleter
try:
from ycm.completers.general.ultisnips_completer import UltiSnipsCompleter from ycm.completers.general.ultisnips_completer import UltiSnipsCompleter
USE_ULTISNIPS_COMPLETER = True
except ImportError:
USE_ULTISNIPS_COMPLETER = False
class GeneralCompleterStore( Completer ): class GeneralCompleterStore( Completer ):
@ -42,8 +36,7 @@ class GeneralCompleterStore( Completer ):
super( GeneralCompleterStore, self ).__init__( user_options ) super( GeneralCompleterStore, self ).__init__( user_options )
self._identifier_completer = IdentifierCompleter( user_options ) self._identifier_completer = IdentifierCompleter( user_options )
self._filename_completer = FilenameCompleter( user_options ) self._filename_completer = FilenameCompleter( user_options )
self._ultisnips_completer = ( UltiSnipsCompleter( user_options ) self._ultisnips_completer = UltiSnipsCompleter( user_options )
if USE_ULTISNIPS_COMPLETER else None )
self._non_filename_completers = filter( lambda x: x, self._non_filename_completers = filter( lambda x: x,
[ self._ultisnips_completer, [ self._ultisnips_completer,
self._identifier_completer ] ) self._identifier_completer ] )

View File

@ -19,7 +19,6 @@
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>. # along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
from ycm.completers.general_completer import GeneralCompleter from ycm.completers.general_completer import GeneralCompleter
from UltiSnips import UltiSnips_Manager
from ycm.server import responses from ycm.server import responses
@ -52,21 +51,10 @@ class UltiSnipsCompleter( GeneralCompleter ):
def OnBufferVisit( self, request_data ): def OnBufferVisit( self, request_data ):
# TODO: _GetCandidates should be called on the client and it should send raw_candidates = request_data[ 'ultisnips_snippets' ]
# the snippets to the server self._candidates = [
self._candidates = _GetCandidates() responses.BuildCompletionData(
str( snip[ 'trigger' ] ),
str( '<snip> ' + snip[ 'description' ].encode( 'utf-8' ) ) )
for snip in raw_candidates ]
def _GetCandidates():
try:
rawsnips = UltiSnips_Manager._snips( '', 1 )
# UltiSnips_Manager._snips() returns a class instance where:
# class.trigger - name of snippet trigger word ( e.g. defn or testcase )
# class.description - description of the snippet
return [ responses.BuildCompletionData(
str( snip.trigger ),
str( '<snip> ' + snip.description.encode( 'utf-8' ) ) )
for snip in rawsnips ]
except:
return []

View File

@ -20,7 +20,7 @@
from webtest import TestApp from webtest import TestApp
from .. import ycmd from .. import ycmd
from ..responses import BuildCompletionData from ..responses import BuildCompletionData
from nose.tools import ok_, eq_ from nose.tools import ok_, eq_, with_setup
import bottle import bottle
bottle.debug( True ) bottle.debug( True )
@ -40,7 +40,12 @@ def RequestDataForFileWithContents( filename, contents ):
} }
def GetCompletions_IdentifierCompleterWorks_test(): def Setup():
ycmd.SetServerStateToDefaults()
@with_setup( Setup )
def GetCompletions_IdentifierCompleter_Works_test():
app = TestApp( ycmd.app ) app = TestApp( ycmd.app )
event_data = RequestDataForFileWithContents( '/foo/bar', 'foo foogoo ba' ) event_data = RequestDataForFileWithContents( '/foo/bar', 'foo foogoo ba' )
event_data.update( { event_data.update( {
@ -63,6 +68,7 @@ def GetCompletions_IdentifierCompleterWorks_test():
app.post_json( '/get_completions', completion_data ).json ) app.post_json( '/get_completions', completion_data ).json )
@with_setup( Setup )
def GetCompletions_IdentifierCompleter_SyntaxKeywordsAdded_test(): def GetCompletions_IdentifierCompleter_SyntaxKeywordsAdded_test():
app = TestApp( ycmd.app ) app = TestApp( ycmd.app )
event_data = RequestDataForFileWithContents( '/foo/bar', '' ) event_data = RequestDataForFileWithContents( '/foo/bar', '' )
@ -87,6 +93,34 @@ def GetCompletions_IdentifierCompleter_SyntaxKeywordsAdded_test():
app.post_json( '/get_completions', completion_data ).json ) app.post_json( '/get_completions', completion_data ).json )
@with_setup( Setup )
def GetCompletions_UltiSnipsCompleter_Works_test():
app = TestApp( ycmd.app )
event_data = RequestDataForFileWithContents( '/foo/bar', '' )
event_data.update( {
'event_name': 'BufferVisit',
'ultisnips_snippets': [
{'trigger': 'foo', 'description': 'bar'},
{'trigger': 'zoo', 'description': 'goo'},
]
} )
app.post_json( '/event_notification', event_data )
completion_data = RequestDataForFileWithContents( '/foo/bar', 'oo ' )
completion_data.update( {
'query': 'oo',
'line_num': 0,
'column_num': 2,
'start_column': 0,
} )
eq_( [ BuildCompletionData( 'foo', '<snip> bar' ),
BuildCompletionData( 'zoo', '<snip> goo' ) ],
app.post_json( '/get_completions', completion_data ).json )
@with_setup( Setup )
def FiletypeCompletionAvailable_Works_test(): def FiletypeCompletionAvailable_Works_test():
app = TestApp( ycmd.app ) app = TestApp( ycmd.app )
request_data = { request_data = {
@ -97,6 +131,7 @@ def FiletypeCompletionAvailable_Works_test():
request_data ).json ) request_data ).json )
@with_setup( Setup )
def UserOptions_Works_test(): def UserOptions_Works_test():
app = TestApp( ycmd.app ) app = TestApp( ycmd.app )
options = app.get( '/user_options' ).json options = app.get( '/user_options' ).json

View File

@ -43,9 +43,8 @@ import argparse
# size is less than this # size is less than this
bottle.Request.MEMFILE_MAX = 300 * 1024 bottle.Request.MEMFILE_MAX = 300 * 1024
user_options_store.LoadDefaults() SERVER_STATE = None
SERVER_STATE = server_state.ServerState( user_options_store.GetAll() ) # TODO: is init needed here?
LOGGER = logging.getLogger( __name__ ) LOGGER = logging.getLogger( __name__ )
app = bottle.Bottle() app = bottle.Bottle()
@ -132,14 +131,21 @@ def _JsonResponse( data ):
@atexit.register @atexit.register
def _ServerShutdown(): def _ServerShutdown():
if SERVER_STATE:
SERVER_STATE.Shutdown() SERVER_STATE.Shutdown()
def _SetUserOptions( options ): def _SetUserOptions( options ):
global SERVER_STATE global SERVER_STATE
SERVER_STATE = server_state.ServerState( options )
user_options_store.SetAll( options ) user_options_store.SetAll( options )
SERVER_STATE = server_state.ServerState( options )
def SetServerStateToDefaults():
global SERVER_STATE
user_options_store.LoadDefaults()
SERVER_STATE = server_state.ServerState( user_options_store.GetAll() )
def Main(): def Main():

View File

@ -32,6 +32,12 @@ from ycm.client.command_request import SendCommandRequest
from ycm.client.completion_request import CompletionRequest from ycm.client.completion_request import CompletionRequest
from ycm.client.event_notification import SendEventNotificationAsync from ycm.client.event_notification import SendEventNotificationAsync
try:
from UltiSnips import UltiSnips_Manager
USE_ULTISNIPS_DATA = True
except ImportError:
USE_ULTISNIPS_DATA = False
SERVER_PORT_RANGE_START = 10000 SERVER_PORT_RANGE_START = 10000
class YouCompleteMe( object ): class YouCompleteMe( object ):
@ -145,7 +151,9 @@ class YouCompleteMe( object ):
def OnBufferVisit( self ): def OnBufferVisit( self ):
SendEventNotificationAsync( 'BufferVisit' ) extra_data = {}
_AddUltiSnipsDataIfNeeded( extra_data )
SendEventNotificationAsync( 'BufferVisit', extra_data )
def OnInsertLeave( self ): def OnInsertLeave( self ):
@ -237,3 +245,21 @@ def _PathToServerScript():
dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) ) dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) )
return os.path.join( dir_of_current_script, 'server/ycmd.py' ) return os.path.join( dir_of_current_script, 'server/ycmd.py' )
def _AddUltiSnipsDataIfNeeded( extra_data ):
if not USE_ULTISNIPS_DATA:
return
try:
rawsnips = UltiSnips_Manager._snips( '', 1 )
except:
return
# UltiSnips_Manager._snips() returns a class instance where:
# class.trigger - name of snippet trigger word ( e.g. defn or testcase )
# class.description - description of the snippet
extra_data[ 'ultisnips_snippets' ] = [ { 'trigger': x.trigger,
'description': x.description
} for x in rawsnips ]