Identifier completer now fully decoupled from Vim
This commit is contained in:
parent
a7c609efd7
commit
6acc381262
@ -18,12 +18,10 @@
|
|||||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import vim
|
|
||||||
import ycm_core
|
import ycm_core
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from ycm.completers.general_completer import GeneralCompleter
|
from ycm.completers.general_completer import GeneralCompleter
|
||||||
from ycm.completers.general import syntax_parse
|
# from ycm.completers.general import syntax_parse
|
||||||
from ycm import vimsupport
|
|
||||||
from ycm import utils
|
from ycm import utils
|
||||||
from ycm import server_responses
|
from ycm import server_responses
|
||||||
|
|
||||||
@ -50,9 +48,9 @@ class IdentifierCompleter( GeneralCompleter ):
|
|||||||
request_data[ 'filetypes' ][ 0 ] )
|
request_data[ 'filetypes' ][ 0 ] )
|
||||||
|
|
||||||
|
|
||||||
def AddIdentifier( self, identifier ):
|
def AddIdentifier( self, identifier, request_data ):
|
||||||
filetype = vim.eval( "&filetype" )
|
filetype = request_data[ 'filetypes' ][ 0 ]
|
||||||
filepath = vim.eval( "expand('%:p')" )
|
filepath = request_data[ 'filepath' ]
|
||||||
|
|
||||||
if not filetype or not filepath or not identifier:
|
if not filetype or not filepath or not identifier:
|
||||||
return
|
return
|
||||||
@ -64,23 +62,20 @@ class IdentifierCompleter( GeneralCompleter ):
|
|||||||
filepath )
|
filepath )
|
||||||
|
|
||||||
|
|
||||||
def AddPreviousIdentifier( self ):
|
def AddPreviousIdentifier( self, request_data ):
|
||||||
self.AddIdentifier( _PreviousIdentifier( self.user_options[
|
self.AddIdentifier(
|
||||||
'min_num_of_chars_for_completion' ] ) )
|
_PreviousIdentifier(
|
||||||
|
self.user_options[ 'min_num_of_chars_for_completion' ],
|
||||||
|
request_data ),
|
||||||
|
request_data )
|
||||||
|
|
||||||
|
|
||||||
def AddIdentifierUnderCursor( self ):
|
def AddIdentifierUnderCursor( self, request_data ):
|
||||||
cursor_identifier = vim.eval( 'expand("<cword>")' )
|
cursor_identifier = _GetCursorIdentifier( request_data )
|
||||||
if not cursor_identifier:
|
if not cursor_identifier:
|
||||||
return
|
return
|
||||||
|
|
||||||
stripped_cursor_identifier = ''.join( ( x for x in
|
self.AddIdentifier( cursor_identifier, request_data )
|
||||||
cursor_identifier if
|
|
||||||
utils.IsIdentifierChar( x ) ) )
|
|
||||||
if not stripped_cursor_identifier:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.AddIdentifier( stripped_cursor_identifier )
|
|
||||||
|
|
||||||
|
|
||||||
def AddBufferIdentifiers( self, request_data ):
|
def AddBufferIdentifiers( self, request_data ):
|
||||||
@ -100,26 +95,22 @@ class IdentifierCompleter( GeneralCompleter ):
|
|||||||
collect_from_comments_and_strings )
|
collect_from_comments_and_strings )
|
||||||
|
|
||||||
|
|
||||||
def AddIdentifiersFromTagFiles( self ):
|
def AddIdentifiersFromTagFiles( self, tag_files ):
|
||||||
tag_files = vim.eval( 'tagfiles()' )
|
|
||||||
current_working_directory = os.getcwd()
|
|
||||||
absolute_paths_to_tag_files = ycm_core.StringVec()
|
absolute_paths_to_tag_files = ycm_core.StringVec()
|
||||||
for tag_file in tag_files:
|
for tag_file in tag_files:
|
||||||
absolute_tag_file = os.path.join( current_working_directory,
|
|
||||||
tag_file )
|
|
||||||
try:
|
try:
|
||||||
current_mtime = os.path.getmtime( absolute_tag_file )
|
current_mtime = os.path.getmtime( tag_file )
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
last_mtime = self.tags_file_last_mtime[ absolute_tag_file ]
|
last_mtime = self.tags_file_last_mtime[ tag_file ]
|
||||||
|
|
||||||
# We don't want to repeatedly process the same file over and over; we only
|
# We don't want to repeatedly process the same file over and over; we only
|
||||||
# process if it's changed since the last time we looked at it
|
# process if it's changed since the last time we looked at it
|
||||||
if current_mtime <= last_mtime:
|
if current_mtime <= last_mtime:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.tags_file_last_mtime[ absolute_tag_file ] = current_mtime
|
self.tags_file_last_mtime[ tag_file ] = current_mtime
|
||||||
absolute_paths_to_tag_files.append( absolute_tag_file )
|
absolute_paths_to_tag_files.append( tag_file )
|
||||||
|
|
||||||
if not absolute_paths_to_tag_files:
|
if not absolute_paths_to_tag_files:
|
||||||
return
|
return
|
||||||
@ -128,41 +119,37 @@ class IdentifierCompleter( GeneralCompleter ):
|
|||||||
absolute_paths_to_tag_files )
|
absolute_paths_to_tag_files )
|
||||||
|
|
||||||
|
|
||||||
def AddIdentifiersFromSyntax( self ):
|
# def AddIdentifiersFromSyntax( self ):
|
||||||
filetype = vim.eval( "&filetype" )
|
# filetype = vim.eval( "&filetype" )
|
||||||
if filetype in self.filetypes_with_keywords_loaded:
|
# if filetype in self.filetypes_with_keywords_loaded:
|
||||||
return
|
# return
|
||||||
|
|
||||||
self.filetypes_with_keywords_loaded.add( filetype )
|
# self.filetypes_with_keywords_loaded.add( filetype )
|
||||||
|
|
||||||
keyword_set = syntax_parse.SyntaxKeywordsForCurrentBuffer()
|
# keyword_set = syntax_parse.SyntaxKeywordsForCurrentBuffer()
|
||||||
keywords = ycm_core.StringVec()
|
# keywords = ycm_core.StringVec()
|
||||||
for keyword in keyword_set:
|
# for keyword in keyword_set:
|
||||||
keywords.append( keyword )
|
# keywords.append( keyword )
|
||||||
|
|
||||||
filepath = SYNTAX_FILENAME + filetype
|
# filepath = SYNTAX_FILENAME + filetype
|
||||||
self.completer.AddIdentifiersToDatabase( keywords,
|
# self.completer.AddIdentifiersToDatabase( keywords,
|
||||||
filetype,
|
# filetype,
|
||||||
filepath )
|
# filepath )
|
||||||
|
|
||||||
|
|
||||||
def OnFileReadyToParse( self, request_data ):
|
def OnFileReadyToParse( self, request_data ):
|
||||||
self.AddBufferIdentifiers( request_data )
|
self.AddBufferIdentifiers( request_data )
|
||||||
|
if 'tag_files' in request_data:
|
||||||
# TODO: make these work again
|
self.AddIdentifiersFromTagFiles( request_data[ 'tag_files' ] )
|
||||||
# if self.user_options[ 'collect_identifiers_from_tags_files' ]:
|
|
||||||
# self.AddIdentifiersFromTagFiles()
|
|
||||||
|
|
||||||
# if self.user_options[ 'seed_identifiers_with_syntax' ]:
|
|
||||||
#self.AddIdentifiersFromSyntax()
|
#self.AddIdentifiersFromSyntax()
|
||||||
|
|
||||||
|
|
||||||
def OnInsertLeave( self ):
|
def OnInsertLeave( self, request_data ):
|
||||||
self.AddIdentifierUnderCursor()
|
self.AddIdentifierUnderCursor( request_data )
|
||||||
|
|
||||||
|
|
||||||
def OnCurrentIdentifierFinished( self ):
|
def OnCurrentIdentifierFinished( self, request_data ):
|
||||||
self.AddPreviousIdentifier()
|
self.AddPreviousIdentifier( request_data )
|
||||||
|
|
||||||
|
|
||||||
def CandidatesFromStoredRequest( self ):
|
def CandidatesFromStoredRequest( self ):
|
||||||
@ -177,10 +164,13 @@ class IdentifierCompleter( GeneralCompleter ):
|
|||||||
return [ server_responses.BuildCompletionData( x ) for x in completions ]
|
return [ server_responses.BuildCompletionData( x ) for x in completions ]
|
||||||
|
|
||||||
|
|
||||||
def _PreviousIdentifier( min_num_completion_start_chars ):
|
def _PreviousIdentifier( min_num_completion_start_chars, request_data ):
|
||||||
line_num, column_num = vimsupport.CurrentLineAndColumn()
|
line_num = request_data[ 'line_num' ]
|
||||||
buffer = vim.current.buffer
|
column_num = request_data[ 'column_num' ]
|
||||||
line = buffer[ line_num ]
|
filepath = request_data[ 'filepath' ]
|
||||||
|
contents_per_line = (
|
||||||
|
request_data[ 'file_data' ][ filepath ][ 'contents' ].split( '\n' ) )
|
||||||
|
line = contents_per_line[ line_num ]
|
||||||
|
|
||||||
end_column = column_num
|
end_column = column_num
|
||||||
|
|
||||||
@ -190,7 +180,7 @@ def _PreviousIdentifier( min_num_completion_start_chars ):
|
|||||||
# Look at the previous line if we reached the end of the current one
|
# Look at the previous line if we reached the end of the current one
|
||||||
if end_column == 0:
|
if end_column == 0:
|
||||||
try:
|
try:
|
||||||
line = buffer[ line_num - 1]
|
line = contents_per_line[ line_num - 1 ]
|
||||||
except:
|
except:
|
||||||
return ""
|
return ""
|
||||||
end_column = len( line )
|
end_column = len( line )
|
||||||
@ -214,3 +204,40 @@ def _RemoveSmallCandidates( candidates, min_num_candidate_size_chars ):
|
|||||||
|
|
||||||
return [ x for x in candidates if len( x ) >= min_num_candidate_size_chars ]
|
return [ x for x in candidates if len( x ) >= min_num_candidate_size_chars ]
|
||||||
|
|
||||||
|
|
||||||
|
# This is meant to behave like 'expand("<cword")' in Vim, thus starting at the
|
||||||
|
# cursor column and returning the "cursor word". If the cursor is not on a valid
|
||||||
|
# character, it searches forward until a valid identifier is found.
|
||||||
|
def _GetCursorIdentifier( request_data ):
|
||||||
|
def FindFirstValidChar( line, column ):
|
||||||
|
current_column = column
|
||||||
|
while not utils.IsIdentifierChar( line[ current_column ] ):
|
||||||
|
current_column += 1
|
||||||
|
return current_column
|
||||||
|
|
||||||
|
|
||||||
|
def FindIdentifierStart( line, valid_char_column ):
|
||||||
|
identifier_start = valid_char_column
|
||||||
|
while identifier_start > 0 and utils.IsIdentifierChar( line[
|
||||||
|
identifier_start - 1 ] ):
|
||||||
|
identifier_start -= 1
|
||||||
|
return identifier_start
|
||||||
|
|
||||||
|
|
||||||
|
def FindIdentifierEnd( line, valid_char_column ):
|
||||||
|
identifier_end = valid_char_column
|
||||||
|
while identifier_end < len( line ) - 1 and utils.IsIdentifierChar( line[
|
||||||
|
identifier_end + 1 ] ):
|
||||||
|
identifier_end += 1
|
||||||
|
return identifier_end + 1
|
||||||
|
|
||||||
|
column_num = request_data[ 'column_num' ]
|
||||||
|
line = request_data[ 'line_value' ]
|
||||||
|
|
||||||
|
try:
|
||||||
|
valid_char_column = FindFirstValidChar( line, column_num )
|
||||||
|
return line[ FindIdentifierStart( line, valid_char_column ) :
|
||||||
|
FindIdentifierEnd( line, valid_char_column ) ]
|
||||||
|
except:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
127
python/ycm/completers/all/tests/identifier_completer_test.py
Normal file
127
python/ycm/completers/all/tests/identifier_completer_test.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Strahinja Val Markovic <val@markovic.io>
|
||||||
|
#
|
||||||
|
# This file is part of YouCompleteMe.
|
||||||
|
#
|
||||||
|
# YouCompleteMe is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# YouCompleteMe is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from nose.tools import eq_
|
||||||
|
from ycm.completers.all import identifier_completer
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_StartOfLine_test():
|
||||||
|
eq_( 'foo',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 0,
|
||||||
|
'line_value': 'foo'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
eq_( 'fooBar',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 0,
|
||||||
|
'line_value': 'fooBar'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_EndOfLine_test():
|
||||||
|
eq_( 'foo',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 2,
|
||||||
|
'line_value': 'foo'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_PastEndOfLine_test():
|
||||||
|
eq_( '',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 10,
|
||||||
|
'line_value': 'foo'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_NegativeColumn_test():
|
||||||
|
eq_( '',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': -10,
|
||||||
|
'line_value': 'foo'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_StartOfLine_StopsAtNonIdentifierChar_test():
|
||||||
|
eq_( 'foo',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 0,
|
||||||
|
'line_value': 'foo(goo)'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_AtNonIdentifier_test():
|
||||||
|
eq_( 'goo',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 3,
|
||||||
|
'line_value': 'foo(goo)'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_WalksForwardForIdentifier_test():
|
||||||
|
eq_( 'foo',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 0,
|
||||||
|
'line_value': ' foo'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_FindsNothingForward_test():
|
||||||
|
eq_( '',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 4,
|
||||||
|
'line_value': 'foo ()***()'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_SingleCharIdentifier_test():
|
||||||
|
eq_( 'f',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 0,
|
||||||
|
'line_value': ' f '
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_StartsInMiddleOfIdentifier_test():
|
||||||
|
eq_( 'foobar',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 3,
|
||||||
|
'line_value': 'foobar'
|
||||||
|
} ) )
|
||||||
|
|
||||||
|
|
||||||
|
def GetCursorIdentifier_LineEmpty_test():
|
||||||
|
eq_( '',
|
||||||
|
identifier_completer._GetCursorIdentifier(
|
||||||
|
{
|
||||||
|
'column_num': 11,
|
||||||
|
'line_value': ''
|
||||||
|
} ) )
|
@ -265,19 +265,19 @@ class Completer( object ):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def OnBufferVisit( self ):
|
def OnBufferVisit( self, request_data ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def OnBufferUnload( self, deleted_buffer_file ):
|
def OnBufferUnload( self, request_data ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def OnInsertLeave( self ):
|
def OnInsertLeave( self, request_data ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def OnVimLeave( self ):
|
def OnVimLeave( self, request_data ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ class Completer( object ):
|
|||||||
raise NotImplementedError( NO_USER_COMMANDS )
|
raise NotImplementedError( NO_USER_COMMANDS )
|
||||||
|
|
||||||
|
|
||||||
def OnCurrentIdentifierFinished( self ):
|
def OnCurrentIdentifierFinished( self, request_data ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,8 +245,8 @@ class ClangCompleter( Completer ):
|
|||||||
self.extra_parse_desired = False
|
self.extra_parse_desired = False
|
||||||
|
|
||||||
|
|
||||||
def OnBufferUnload( self, deleted_buffer_file ):
|
def OnBufferUnload( self, request_data ):
|
||||||
self.completer.DeleteCachesForFileAsync( deleted_buffer_file )
|
self.completer.DeleteCachesForFileAsync( request_data[ 'unloaded_buffer' ] )
|
||||||
|
|
||||||
|
|
||||||
def DiagnosticsForCurrentFileReady( self ):
|
def DiagnosticsForCurrentFileReady( self ):
|
||||||
@ -271,7 +271,7 @@ class ClangCompleter( Completer ):
|
|||||||
self.parse_future = None
|
self.parse_future = None
|
||||||
|
|
||||||
if self.extra_parse_desired:
|
if self.extra_parse_desired:
|
||||||
self.OnFileReadyToParse()
|
self.OnFileReadyToParse( request_data )
|
||||||
|
|
||||||
return self.last_prepared_diagnostics
|
return self.last_prepared_diagnostics
|
||||||
|
|
||||||
|
@ -100,29 +100,29 @@ class GeneralCompleterStore( Completer ):
|
|||||||
completer.OnFileReadyToParse( request_data )
|
completer.OnFileReadyToParse( request_data )
|
||||||
|
|
||||||
|
|
||||||
def OnBufferVisit( self ):
|
def OnBufferVisit( self, request_data ):
|
||||||
for completer in self._all_completers:
|
for completer in self._all_completers:
|
||||||
completer.OnBufferVisit()
|
completer.OnBufferVisit( request_data )
|
||||||
|
|
||||||
|
|
||||||
def OnBufferUnload( self, deleted_buffer_file ):
|
def OnBufferUnload( self, request_data ):
|
||||||
for completer in self._all_completers:
|
for completer in self._all_completers:
|
||||||
completer.OnBufferUnload( deleted_buffer_file )
|
completer.OnBufferUnload( request_data )
|
||||||
|
|
||||||
|
|
||||||
def OnInsertLeave( self ):
|
def OnInsertLeave( self, request_data ):
|
||||||
for completer in self._all_completers:
|
for completer in self._all_completers:
|
||||||
completer.OnInsertLeave()
|
completer.OnInsertLeave( request_data )
|
||||||
|
|
||||||
|
|
||||||
def OnVimLeave( self ):
|
def OnVimLeave( self, request_data ):
|
||||||
for completer in self._all_completers:
|
for completer in self._all_completers:
|
||||||
completer.OnVimLeave()
|
completer.OnVimLeave( request_data )
|
||||||
|
|
||||||
|
|
||||||
def OnCurrentIdentifierFinished( self ):
|
def OnCurrentIdentifierFinished( self, request_data ):
|
||||||
for completer in self._all_completers:
|
for completer in self._all_completers:
|
||||||
completer.OnCurrentIdentifierFinished()
|
completer.OnCurrentIdentifierFinished( request_data )
|
||||||
|
|
||||||
|
|
||||||
def GettingCompletions( self ):
|
def GettingCompletions( self ):
|
||||||
|
@ -51,7 +51,9 @@ class UltiSnipsCompleter( GeneralCompleter ):
|
|||||||
return self._filtered_candidates if self._filtered_candidates else []
|
return self._filtered_candidates if self._filtered_candidates else []
|
||||||
|
|
||||||
|
|
||||||
def OnBufferVisit( self ):
|
def OnBufferVisit( self, request_data ):
|
||||||
|
# TODO: _GetCandidates should be called on the client and it should send
|
||||||
|
# the snippets to the server
|
||||||
self._candidates = _GetCandidates()
|
self._candidates = _GetCandidates()
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,8 +31,27 @@ from ycm.completers.general.general_completer_store import GeneralCompleterStore
|
|||||||
|
|
||||||
|
|
||||||
# TODO: Put the Request classes in separate files
|
# TODO: Put the Request classes in separate files
|
||||||
class CompletionRequest( object ):
|
class BaseRequest( object ):
|
||||||
|
def __init__( self ):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def Start( self ):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def Done( self ):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def Response( self ):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
class CompletionRequest( BaseRequest ):
|
||||||
def __init__( self, ycm_state ):
|
def __init__( self, ycm_state ):
|
||||||
|
super( CompletionRequest, self ).__init__()
|
||||||
|
|
||||||
self._completion_start_column = base.CompletionStartColumn()
|
self._completion_start_column = base.CompletionStartColumn()
|
||||||
self._ycm_state = ycm_state
|
self._ycm_state = ycm_state
|
||||||
self._request_data = _BuildRequestData( self._completion_start_column )
|
self._request_data = _BuildRequestData( self._completion_start_column )
|
||||||
@ -70,7 +89,7 @@ class CompletionRequest( object ):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CommandRequest( object ):
|
class CommandRequest( BaseRequest ):
|
||||||
class ServerResponse( object ):
|
class ServerResponse( object ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
pass
|
pass
|
||||||
@ -79,6 +98,8 @@ class CommandRequest( object ):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def __init__( self, ycm_state, arguments, completer_target = None ):
|
def __init__( self, ycm_state, arguments, completer_target = None ):
|
||||||
|
super( CommandRequest, self ).__init__()
|
||||||
|
|
||||||
if not completer_target:
|
if not completer_target:
|
||||||
completer_target = 'filetpe_default'
|
completer_target = 'filetpe_default'
|
||||||
|
|
||||||
@ -95,9 +116,6 @@ class CommandRequest( object ):
|
|||||||
self._completer.OnUserCommand( self._arguments,
|
self._completer.OnUserCommand( self._arguments,
|
||||||
_BuildRequestData() )
|
_BuildRequestData() )
|
||||||
|
|
||||||
def Done( self ):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def Response( self ):
|
def Response( self ):
|
||||||
# TODO: Call vimsupport.JumpToLocation if the user called a GoTo command...
|
# TODO: Call vimsupport.JumpToLocation if the user called a GoTo command...
|
||||||
@ -117,6 +135,31 @@ class CommandRequest( object ):
|
|||||||
return self.ServerResponse()
|
return self.ServerResponse()
|
||||||
|
|
||||||
|
|
||||||
|
class EventNotification( BaseRequest ):
|
||||||
|
def __init__( self, event_name, ycm_state, extra_data = None ):
|
||||||
|
super( EventNotification, self ).__init__()
|
||||||
|
|
||||||
|
self._ycm_state = ycm_state
|
||||||
|
self._event_name = event_name
|
||||||
|
self._request_data = _BuildRequestData()
|
||||||
|
if extra_data:
|
||||||
|
self._request_data.update( extra_data )
|
||||||
|
|
||||||
|
|
||||||
|
def Start( self ):
|
||||||
|
getattr( self._ycm_state.GetGeneralCompleter(),
|
||||||
|
'On' + self._event_name )( self._request_data )
|
||||||
|
|
||||||
|
if self._ycm_state.FiletypeCompletionUsable():
|
||||||
|
getattr( self._ycm_state.GetFiletypeCompleter(),
|
||||||
|
'On' + self._event_name )( self._request_data )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def SendEventNotificationAsync( event_name, ycm_state, extra_data = None ):
|
||||||
|
event = EventNotification( event_name, ycm_state, extra_data )
|
||||||
|
event.Start()
|
||||||
|
|
||||||
|
|
||||||
class YouCompleteMe( object ):
|
class YouCompleteMe( object ):
|
||||||
def __init__( self, user_options ):
|
def __init__( self, user_options ):
|
||||||
@ -235,38 +278,36 @@ class YouCompleteMe( object ):
|
|||||||
|
|
||||||
|
|
||||||
def OnFileReadyToParse( self ):
|
def OnFileReadyToParse( self ):
|
||||||
self._gencomp.OnFileReadyToParse( _BuildRequestData() )
|
extra_data = {}
|
||||||
|
if self._user_options[ 'collect_identifiers_from_tags_files' ]:
|
||||||
|
extra_data[ 'tag_files' ] = _GetTagFiles()
|
||||||
|
|
||||||
if self.FiletypeCompletionUsable():
|
# TODO: make this work again
|
||||||
self.GetFiletypeCompleter().OnFileReadyToParse( _BuildRequestData() )
|
# if self._user_options[ 'seed_identifiers_with_syntax' ]:
|
||||||
|
|
||||||
|
SendEventNotificationAsync( 'FileReadyToParse', self, extra_data )
|
||||||
|
|
||||||
|
|
||||||
def OnBufferUnload( self, deleted_buffer_file ):
|
def OnBufferUnload( self, deleted_buffer_file ):
|
||||||
self._gencomp.OnBufferUnload( deleted_buffer_file )
|
SendEventNotificationAsync( 'BufferUnload',
|
||||||
|
self,
|
||||||
if self.FiletypeCompletionUsable():
|
{ 'unloaded_buffer': deleted_buffer_file } )
|
||||||
self.GetFiletypeCompleter().OnBufferUnload( deleted_buffer_file )
|
|
||||||
|
|
||||||
|
|
||||||
def OnBufferVisit( self ):
|
def OnBufferVisit( self ):
|
||||||
self._gencomp.OnBufferVisit()
|
SendEventNotificationAsync( 'BufferVisit', self )
|
||||||
|
|
||||||
if self.FiletypeCompletionUsable():
|
|
||||||
self.GetFiletypeCompleter().OnBufferVisit()
|
|
||||||
|
|
||||||
|
|
||||||
def OnInsertLeave( self ):
|
def OnInsertLeave( self ):
|
||||||
self._gencomp.OnInsertLeave()
|
SendEventNotificationAsync( 'InsertLeave', self )
|
||||||
|
|
||||||
if self.FiletypeCompletionUsable():
|
|
||||||
self.GetFiletypeCompleter().OnInsertLeave()
|
|
||||||
|
|
||||||
|
|
||||||
def OnVimLeave( self ):
|
def OnVimLeave( self ):
|
||||||
self._gencomp.OnVimLeave()
|
SendEventNotificationAsync( 'VimLeave', self )
|
||||||
|
|
||||||
if self.FiletypeCompletionUsable():
|
|
||||||
self.GetFiletypeCompleter().OnVimLeave()
|
def OnCurrentIdentifierFinished( self ):
|
||||||
|
SendEventNotificationAsync( 'CurrentIdentifierFinished', self )
|
||||||
|
|
||||||
|
|
||||||
def DiagnosticsForCurrentFileReady( self ):
|
def DiagnosticsForCurrentFileReady( self ):
|
||||||
@ -292,13 +333,6 @@ class YouCompleteMe( object ):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def OnCurrentIdentifierFinished( self ):
|
|
||||||
self._gencomp.OnCurrentIdentifierFinished()
|
|
||||||
|
|
||||||
if self.FiletypeCompletionUsable():
|
|
||||||
self.GetFiletypeCompleter().OnCurrentIdentifierFinished()
|
|
||||||
|
|
||||||
|
|
||||||
def DebugInfo( self ):
|
def DebugInfo( self ):
|
||||||
completers = set( self._filetype_completers.values() )
|
completers = set( self._filetype_completers.values() )
|
||||||
completers.add( self._gencomp )
|
completers.add( self._gencomp )
|
||||||
@ -370,3 +404,8 @@ def _ConvertCompletionDataToVimData( completion_data ):
|
|||||||
vim_data[ 'info' ] = completion_data[ 'detailed_info' ]
|
vim_data[ 'info' ] = completion_data[ 'detailed_info' ]
|
||||||
|
|
||||||
return vim_data
|
return vim_data
|
||||||
|
|
||||||
|
def _GetTagFiles():
|
||||||
|
tag_files = vim.eval( 'tagfiles()' )
|
||||||
|
current_working_directory = os.getcwd()
|
||||||
|
return [ os.path.join( current_working_directory, x ) for x in tag_files ]
|
||||||
|
Loading…
Reference in New Issue
Block a user