Initial version of omnifunc-based omni_completer
Still a work in progress (needs better triggering and bug fixes)
This commit is contained in:
parent
051fc85be4
commit
786e6182ff
@ -191,7 +191,7 @@ function! s:SetCompleteFunc()
|
|||||||
let &completefunc = 'youcompleteme#Complete'
|
let &completefunc = 'youcompleteme#Complete'
|
||||||
let &l:completefunc = 'youcompleteme#Complete'
|
let &l:completefunc = 'youcompleteme#Complete'
|
||||||
|
|
||||||
if pyeval( 'ycm_state.FiletypeCompletionEnabled()' )
|
if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
|
||||||
let &omnifunc = 'youcompleteme#OmniComplete'
|
let &omnifunc = 'youcompleteme#OmniComplete'
|
||||||
let &l:omnifunc = 'youcompleteme#OmniComplete'
|
let &l:omnifunc = 'youcompleteme#OmniComplete'
|
||||||
endif
|
endif
|
||||||
@ -299,7 +299,7 @@ endfunction
|
|||||||
|
|
||||||
function! s:UpdateDiagnosticNotifications()
|
function! s:UpdateDiagnosticNotifications()
|
||||||
if get( g:, 'loaded_syntastic_plugin', 0 ) &&
|
if get( g:, 'loaded_syntastic_plugin', 0 ) &&
|
||||||
\ pyeval( 'ycm_state.FiletypeCompletionEnabled()' ) &&
|
\ pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' ) &&
|
||||||
\ pyeval( 'ycm_state.DiagnosticsForCurrentFileReady()' )
|
\ pyeval( 'ycm_state.DiagnosticsForCurrentFileReady()' )
|
||||||
SyntasticCheck
|
SyntasticCheck
|
||||||
endif
|
endif
|
||||||
@ -408,6 +408,8 @@ function! youcompleteme#Complete( findstart, base )
|
|||||||
return -2
|
return -2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
" TODO: make this a function-local variable instead of a script-local one
|
||||||
let s:completion_start_column = pyeval( 'ycm.CompletionStartColumn()' )
|
let s:completion_start_column = pyeval( 'ycm.CompletionStartColumn()' )
|
||||||
let s:should_use_filetype_completion =
|
let s:should_use_filetype_completion =
|
||||||
\ pyeval( 'ycm_state.ShouldUseFiletypeCompleter(' .
|
\ pyeval( 'ycm_state.ShouldUseFiletypeCompleter(' .
|
||||||
@ -465,7 +467,7 @@ command! YcmDebugInfo call s:DebugInfo()
|
|||||||
|
|
||||||
|
|
||||||
function! s:ForceCompile()
|
function! s:ForceCompile()
|
||||||
if !pyeval( 'ycm_state.FiletypeCompletionEnabled()' )
|
if !pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
|
||||||
echom "Filetype completion not supported for current file, "
|
echom "Filetype completion not supported for current file, "
|
||||||
\ . "cannot force recompilation."
|
\ . "cannot force recompilation."
|
||||||
endif
|
endif
|
||||||
|
@ -55,6 +55,7 @@ extern const unsigned int MIN_ASYNC_THREADS;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// TODO: replace this with ResultAnd from Result.h
|
||||||
struct CompletionDataAndResult {
|
struct CompletionDataAndResult {
|
||||||
CompletionDataAndResult( const CompletionData *completion_data,
|
CompletionDataAndResult( const CompletionData *completion_data,
|
||||||
const Result &result )
|
const Result &result )
|
||||||
@ -419,7 +420,7 @@ std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
|
|||||||
|
|
||||||
if ( result.IsSubsequence() ) {
|
if ( result.IsSubsequence() ) {
|
||||||
CompletionDataAndResult data_and_result( &completion_datas[ i ], result );
|
CompletionDataAndResult data_and_result( &completion_datas[ i ], result );
|
||||||
data_and_results.push_back( data_and_result );
|
data_and_results.push_back( boost::move( data_and_result ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
96
cpp/ycm/PythonSupport.cpp
Normal file
96
cpp/ycm/PythonSupport.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright (C) 2011, 2012, 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/>.
|
||||||
|
|
||||||
|
#include "PythonSupport.h"
|
||||||
|
#include "standard.h"
|
||||||
|
#include "Result.h"
|
||||||
|
#include "Candidate.h"
|
||||||
|
#include "CandidateRepository.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using boost::python::len;
|
||||||
|
using boost::python::extract;
|
||||||
|
using boost::python::object;
|
||||||
|
typedef boost::python::list pylist;
|
||||||
|
|
||||||
|
namespace YouCompleteMe {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::vector< const Candidate * > CandidatesFromObjectList(
|
||||||
|
const pylist &candidates,
|
||||||
|
const std::string &candidate_property ) {
|
||||||
|
int num_candidates = len( candidates );
|
||||||
|
std::vector< std::string > candidate_strings;
|
||||||
|
candidate_strings.reserve( num_candidates );
|
||||||
|
|
||||||
|
for ( int i = 0; i < num_candidates; ++i ) {
|
||||||
|
if ( candidate_property.empty() ) {
|
||||||
|
candidate_strings.push_back( extract< std::string >( candidates[ i ] ) );
|
||||||
|
} else {
|
||||||
|
object holder = extract< object >( candidates[ i ] );
|
||||||
|
candidate_strings.push_back( extract< std::string >(
|
||||||
|
holder[ candidate_property.c_str() ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CandidateRepository::Instance().GetCandidatesForStrings(
|
||||||
|
candidate_strings );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
boost::python::list FilterAndSortCandidates(
|
||||||
|
const boost::python::list &candidates,
|
||||||
|
const std::string &candidate_property,
|
||||||
|
const std::string &query ) {
|
||||||
|
pylist filtered_candidates;
|
||||||
|
if ( query.empty() )
|
||||||
|
return filtered_candidates;
|
||||||
|
|
||||||
|
std::vector< const Candidate * > repository_candidates =
|
||||||
|
CandidatesFromObjectList( candidates, candidate_property );
|
||||||
|
|
||||||
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
|
int num_candidates = len( candidates );
|
||||||
|
std::vector< ResultAnd< int > > object_and_results;
|
||||||
|
|
||||||
|
for ( int i = 0; i < num_candidates; ++i ) {
|
||||||
|
const Candidate *candidate = repository_candidates[ i ];
|
||||||
|
|
||||||
|
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Result result = candidate->QueryMatchResult( query );
|
||||||
|
|
||||||
|
if ( result.IsSubsequence() ) {
|
||||||
|
ResultAnd< int > object_and_result( i, result );
|
||||||
|
object_and_results.push_back( boost::move( object_and_result ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort( object_and_results.begin(), object_and_results.end() );
|
||||||
|
|
||||||
|
foreach ( const ResultAnd< int > &object_and_result,
|
||||||
|
object_and_results ) {
|
||||||
|
filtered_candidates.append( candidates[ object_and_result.extra_object_ ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered_candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace YouCompleteMe
|
37
cpp/ycm/PythonSupport.h
Normal file
37
cpp/ycm/PythonSupport.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (C) 2011, 2012, 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/>.
|
||||||
|
|
||||||
|
#ifndef PYTHONSUPPORT_H_KWGFEX0V
|
||||||
|
#define PYTHONSUPPORT_H_KWGFEX0V
|
||||||
|
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
namespace YouCompleteMe {
|
||||||
|
|
||||||
|
// Given a list of python objects (that represent completion candidates) in a
|
||||||
|
// python list |candidates|, a |candidate_property| on which to filter and sort
|
||||||
|
// the candidates and a user query, returns a new sorted python list with the
|
||||||
|
// original objects that survived the filtering.
|
||||||
|
boost::python::list FilterAndSortCandidates(
|
||||||
|
const boost::python::list &candidates,
|
||||||
|
const std::string &candidate_property,
|
||||||
|
const std::string &query );
|
||||||
|
|
||||||
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
|
#endif /* end of include guard: PYTHONSUPPORT_H_KWGFEX0V */
|
||||||
|
|
@ -86,6 +86,19 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct ResultAnd {
|
||||||
|
ResultAnd( T extra_object, const Result &result )
|
||||||
|
: extra_object_( extra_object ), result_( result ) {}
|
||||||
|
|
||||||
|
bool operator< ( const ResultAnd &other ) const {
|
||||||
|
return result_ < other.result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T extra_object_;
|
||||||
|
Result result_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
#endif /* end of include guard: RESULT_H_CZYD2SGN */
|
#endif /* end of include guard: RESULT_H_CZYD2SGN */
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
// along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
// along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "IdentifierCompleter.h"
|
#include "IdentifierCompleter.h"
|
||||||
|
#include "PythonSupport.h"
|
||||||
#include "Future.h"
|
#include "Future.h"
|
||||||
|
|
||||||
#ifdef USE_CLANG_COMPLETER
|
#ifdef USE_CLANG_COMPLETER
|
||||||
@ -47,6 +48,7 @@ BOOST_PYTHON_MODULE(ycm_core)
|
|||||||
using namespace YouCompleteMe;
|
using namespace YouCompleteMe;
|
||||||
|
|
||||||
def( "HasClangSupport", HasClangSupport );
|
def( "HasClangSupport", HasClangSupport );
|
||||||
|
def( "FilterAndSortCandidates", FilterAndSortCandidates );
|
||||||
|
|
||||||
class_< IdentifierCompleter, boost::noncopyable >( "IdentifierCompleter" )
|
class_< IdentifierCompleter, boost::noncopyable >( "IdentifierCompleter" )
|
||||||
.def( "EnableThreading", &IdentifierCompleter::EnableThreading )
|
.def( "EnableThreading", &IdentifierCompleter::EnableThreading )
|
||||||
|
@ -30,6 +30,7 @@ MIN_NUM_CHARS = int( vimsupport.GetVariableValue(
|
|||||||
|
|
||||||
class IdentifierCompleter( Completer ):
|
class IdentifierCompleter( Completer ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
|
super( IdentifierCompleter, self ).__init__()
|
||||||
self.completer = ycm_core.IdentifierCompleter()
|
self.completer = ycm_core.IdentifierCompleter()
|
||||||
self.completer.EnableThreading()
|
self.completer.EnableThreading()
|
||||||
|
|
||||||
|
76
python/completers/all/omni_completer.py
Normal file
76
python/completers/all/omni_completer.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011, 2012, 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/>.
|
||||||
|
|
||||||
|
import vim
|
||||||
|
import vimsupport
|
||||||
|
from completers.completer import Completer
|
||||||
|
|
||||||
|
class OmniCompleter( Completer ):
|
||||||
|
def __init__( self ):
|
||||||
|
super( OmniCompleter, self ).__init__()
|
||||||
|
self.omnifunc = None
|
||||||
|
self.stored_candidates = None
|
||||||
|
|
||||||
|
|
||||||
|
def SupportedFiletypes( self ):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def ShouldUseNowInner( self, start_column ):
|
||||||
|
line = vim.current.line
|
||||||
|
previous_char_index = start_column - 1
|
||||||
|
if ( not len( line ) or
|
||||||
|
previous_char_index < 0 or
|
||||||
|
previous_char_index >= len( line ) ):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if line[ previous_char_index ] == '.':
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def CandidatesForQueryAsyncInner( self, query ):
|
||||||
|
if not self.omnifunc:
|
||||||
|
self.stored_candidates = None
|
||||||
|
return
|
||||||
|
|
||||||
|
return_value = vim.eval( self.omnifunc + '(1,"")' )
|
||||||
|
if return_value < 0:
|
||||||
|
self.stored_candidates = None
|
||||||
|
return
|
||||||
|
|
||||||
|
omnifunc_call = [ self.omnifunc,
|
||||||
|
"(0,'",
|
||||||
|
vimsupport.EscapeForVim( query ),
|
||||||
|
"')" ]
|
||||||
|
|
||||||
|
self.stored_candidates = vim.eval( ''.join( omnifunc_call ) )
|
||||||
|
|
||||||
|
|
||||||
|
def AsyncCandidateRequestReadyInner( self ):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def OnFileReadyToParse( self ):
|
||||||
|
self.omnifunc = vim.eval( '&omnifunc' )
|
||||||
|
|
||||||
|
|
||||||
|
def CandidatesFromStoredRequestInner( self ):
|
||||||
|
return self.stored_candidates
|
||||||
|
|
@ -18,6 +18,23 @@
|
|||||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
import vim
|
||||||
|
import vimsupport
|
||||||
|
import ycm_core
|
||||||
|
|
||||||
|
|
||||||
|
class CompletionsCache( object ):
|
||||||
|
def __init__( self ):
|
||||||
|
self.line = -1
|
||||||
|
self.column = -1
|
||||||
|
self.raw_completions = []
|
||||||
|
self.filtered_completions = []
|
||||||
|
|
||||||
|
|
||||||
|
def CacheValid( self ):
|
||||||
|
completion_line, _ = vimsupport.CurrentLineAndColumn()
|
||||||
|
completion_column = int( vim.eval( "s:completion_start_column" ) )
|
||||||
|
return completion_line == self.line and completion_column == self.column
|
||||||
|
|
||||||
|
|
||||||
class Completer( object ):
|
class Completer( object ):
|
||||||
@ -26,9 +43,57 @@ class Completer( object ):
|
|||||||
|
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
self.completions_future = None
|
self.completions_future = None
|
||||||
|
self.completions_cache = None
|
||||||
|
|
||||||
|
|
||||||
|
def ShouldUseNow( self, start_column ):
|
||||||
|
inner_says_yes = self.ShouldUseNowInner( start_column )
|
||||||
|
previous_results_were_empty = ( self.completions_cache and
|
||||||
|
not self.completions_cache.raw_completions )
|
||||||
|
return inner_says_yes and not previous_results_were_empty
|
||||||
|
|
||||||
|
|
||||||
|
def ShouldUseNowInner( self, start_column ):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def CandidatesForQueryAsync( self, query ):
|
||||||
|
if query and self.completions_cache and self.completions_cache.CacheValid():
|
||||||
|
self.completions_cache.filtered_completions = (
|
||||||
|
self.FilterAndSortCandidates(
|
||||||
|
self.completions_cache.raw_completions,
|
||||||
|
query ) )
|
||||||
|
else:
|
||||||
|
self.completions_cache = None
|
||||||
|
self.CandidatesForQueryAsyncInner( query )
|
||||||
|
|
||||||
|
|
||||||
|
def FilterAndSortCandidates( self, candidates, query ):
|
||||||
|
if not candidates:
|
||||||
|
return []
|
||||||
|
|
||||||
|
if hasattr( candidates, 'words' ):
|
||||||
|
candidates = candidates.words
|
||||||
|
items_are_objects = 'word' in candidates[ 0 ]
|
||||||
|
|
||||||
|
return ycm_core.FilterAndSortCandidates(
|
||||||
|
candidates,
|
||||||
|
'word' if items_are_objects else '',
|
||||||
|
query )
|
||||||
|
|
||||||
|
|
||||||
|
def CandidatesForQueryAsyncInner( self, query ):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def AsyncCandidateRequestReady( self ):
|
def AsyncCandidateRequestReady( self ):
|
||||||
|
if self.completions_cache:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return self.AsyncCandidateRequestReadyInner()
|
||||||
|
|
||||||
|
|
||||||
|
def AsyncCandidateRequestReadyInner( self ):
|
||||||
if not self.completions_future:
|
if not self.completions_future:
|
||||||
# We return True so that the caller can extract the default value from the
|
# We return True so that the caller can extract the default value from the
|
||||||
# future
|
# future
|
||||||
@ -37,6 +102,18 @@ class Completer( object ):
|
|||||||
|
|
||||||
|
|
||||||
def CandidatesFromStoredRequest( self ):
|
def CandidatesFromStoredRequest( self ):
|
||||||
|
if self.completions_cache:
|
||||||
|
return self.completions_cache.filtered_completions
|
||||||
|
else:
|
||||||
|
self.completions_cache = CompletionsCache()
|
||||||
|
self.completions_cache.raw_completions = self.CandidatesFromStoredRequestInner()
|
||||||
|
self.completions_cache.line, _ = vimsupport.CurrentLineAndColumn()
|
||||||
|
self.completions_cache.column = int(
|
||||||
|
vim.eval( "s:completion_start_column" ) )
|
||||||
|
return self.completions_cache.raw_completions
|
||||||
|
|
||||||
|
|
||||||
|
def CandidatesFromStoredRequestInner( self ):
|
||||||
if not self.completions_future:
|
if not self.completions_future:
|
||||||
return []
|
return []
|
||||||
return self.completions_future.GetResults()
|
return self.completions_future.GetResults()
|
||||||
@ -90,10 +167,5 @@ class Completer( object ):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def ShouldUseNow( self, start_column ):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def DebugInfo( self ):
|
def DebugInfo( self ):
|
||||||
return ''
|
return ''
|
||||||
|
@ -31,6 +31,7 @@ MAX_DIAGNOSTICS_TO_DISPLAY = int( vimsupport.GetVariableValue(
|
|||||||
|
|
||||||
class ClangCompleter( Completer ):
|
class ClangCompleter( Completer ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
|
super( ClangCompleter, self ).__init__()
|
||||||
self.completer = ycm_core.ClangCompleter()
|
self.completer = ycm_core.ClangCompleter()
|
||||||
self.completer.EnableThreading()
|
self.completer.EnableThreading()
|
||||||
self.contents_holder = []
|
self.contents_holder = []
|
||||||
@ -101,6 +102,7 @@ class ClangCompleter( Completer ):
|
|||||||
files = self.GetUnsavedFilesVector()
|
files = self.GetUnsavedFilesVector()
|
||||||
|
|
||||||
line, _ = vim.current.window.cursor
|
line, _ = vim.current.window.cursor
|
||||||
|
# TODO: this should be a function parameter
|
||||||
column = int( vim.eval( "s:completion_start_column" ) ) + 1
|
column = int( vim.eval( "s:completion_start_column" ) ) + 1
|
||||||
self.completions_future = (
|
self.completions_future = (
|
||||||
self.completer.CandidatesForQueryAndLocationInFileAsync(
|
self.completer.CandidatesForQueryAndLocationInFileAsync(
|
||||||
|
@ -55,12 +55,12 @@ def NumLinesInBuffer( buffer ):
|
|||||||
|
|
||||||
|
|
||||||
def PostVimMessage( message ):
|
def PostVimMessage( message ):
|
||||||
vim.command( 'echohl WarningMsg | echomsg "{0}" | echohl None'
|
vim.command( "echohl WarningMsg | echomsg '{0}' | echohl None"
|
||||||
.format( message.replace( '"', '\\"' ) ) )
|
.format( EscapeForVim( message ) ) )
|
||||||
|
|
||||||
|
|
||||||
def EchoText( text ):
|
def EchoText( text ):
|
||||||
vim.command( "echom '{0}'".format( text.replace( "'", r"''") ) )
|
vim.command( "echom '{0}'".format( EscapeForVim( text ) ) )
|
||||||
|
|
||||||
|
|
||||||
def EscapeForVim( text ):
|
def EscapeForVim( text ):
|
||||||
|
@ -34,6 +34,8 @@ except ImportError, e:
|
|||||||
os.path.dirname( os.path.abspath( __file__ ) ), str( e ) ) )
|
os.path.dirname( os.path.abspath( __file__ ) ), str( e ) ) )
|
||||||
|
|
||||||
from completers.all.identifier_completer import IdentifierCompleter
|
from completers.all.identifier_completer import IdentifierCompleter
|
||||||
|
from completers.all.omni_completer import OmniCompleter
|
||||||
|
|
||||||
|
|
||||||
FILETYPE_SPECIFIC_COMPLETION_TO_DISABLE = vim.eval(
|
FILETYPE_SPECIFIC_COMPLETION_TO_DISABLE = vim.eval(
|
||||||
'g:ycm_filetype_specific_completion_to_disable' )
|
'g:ycm_filetype_specific_completion_to_disable' )
|
||||||
@ -42,6 +44,7 @@ FILETYPE_SPECIFIC_COMPLETION_TO_DISABLE = vim.eval(
|
|||||||
class YouCompleteMe( object ):
|
class YouCompleteMe( object ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
self.identcomp = IdentifierCompleter()
|
self.identcomp = IdentifierCompleter()
|
||||||
|
self.omnicomp = OmniCompleter()
|
||||||
self.filetype_completers = {}
|
self.filetype_completers = {}
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +59,6 @@ class YouCompleteMe( object ):
|
|||||||
completer = self.GetFiletypeCompleterForFiletype( filetype )
|
completer = self.GetFiletypeCompleterForFiletype( filetype )
|
||||||
if completer:
|
if completer:
|
||||||
return completer
|
return completer
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +81,8 @@ class YouCompleteMe( object ):
|
|||||||
completer = module.GetCompleter()
|
completer = module.GetCompleter()
|
||||||
if completer:
|
if completer:
|
||||||
supported_filetypes.extend( completer.SupportedFiletypes() )
|
supported_filetypes.extend( completer.SupportedFiletypes() )
|
||||||
|
else:
|
||||||
|
completer = self.omnicomp
|
||||||
|
|
||||||
for supported_filetype in supported_filetypes:
|
for supported_filetype in supported_filetypes:
|
||||||
self.filetype_completers[ supported_filetype ] = completer
|
self.filetype_completers[ supported_filetype ] = completer
|
||||||
@ -90,58 +94,64 @@ class YouCompleteMe( object ):
|
|||||||
|
|
||||||
|
|
||||||
def ShouldUseFiletypeCompleter( self, start_column ):
|
def ShouldUseFiletypeCompleter( self, start_column ):
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
return self.GetFiletypeCompleter().ShouldUseNow(
|
return self.GetFiletypeCompleter().ShouldUseNow(
|
||||||
start_column )
|
start_column )
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def NativeFiletypeCompletionAvailable( self ):
|
||||||
|
completer = self.GetFiletypeCompleter()
|
||||||
|
return bool( completer ) and completer is not self.omnicomp
|
||||||
|
|
||||||
|
|
||||||
def FiletypeCompletionAvailable( self ):
|
def FiletypeCompletionAvailable( self ):
|
||||||
return bool( self.GetFiletypeCompleter() )
|
return bool( self.GetFiletypeCompleter() )
|
||||||
|
|
||||||
|
|
||||||
def FiletypeCompletionEnabled( self ):
|
def NativeFiletypeCompletionUsable( self ):
|
||||||
filetypes = vimsupport.CurrentFiletypes()
|
return ( _CurrentFiletypeCompletionEnabled() and
|
||||||
filetype_disabled = all([ x in FILETYPE_SPECIFIC_COMPLETION_TO_DISABLE
|
self.NativeFiletypeCompletionAvailable() )
|
||||||
for x in filetypes ])
|
|
||||||
|
|
||||||
return ( not filetype_disabled and
|
|
||||||
|
def FiletypeCompletionUsable( self ):
|
||||||
|
return ( _CurrentFiletypeCompletionEnabled() and
|
||||||
self.FiletypeCompletionAvailable() )
|
self.FiletypeCompletionAvailable() )
|
||||||
|
|
||||||
|
|
||||||
def OnFileReadyToParse( self ):
|
def OnFileReadyToParse( self ):
|
||||||
self.identcomp.OnFileReadyToParse()
|
self.identcomp.OnFileReadyToParse()
|
||||||
|
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
self.GetFiletypeCompleter().OnFileReadyToParse()
|
self.GetFiletypeCompleter().OnFileReadyToParse()
|
||||||
|
|
||||||
|
|
||||||
def OnInsertLeave( self ):
|
def OnInsertLeave( self ):
|
||||||
self.identcomp.OnInsertLeave()
|
self.identcomp.OnInsertLeave()
|
||||||
|
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
self.GetFiletypeCompleter().OnInsertLeave()
|
self.GetFiletypeCompleter().OnInsertLeave()
|
||||||
|
|
||||||
|
|
||||||
def DiagnosticsForCurrentFileReady( self ):
|
def DiagnosticsForCurrentFileReady( self ):
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
return self.GetFiletypeCompleter().DiagnosticsForCurrentFileReady()
|
return self.GetFiletypeCompleter().DiagnosticsForCurrentFileReady()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def GetDiagnosticsForCurrentFile( self ):
|
def GetDiagnosticsForCurrentFile( self ):
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
return self.GetFiletypeCompleter().GetDiagnosticsForCurrentFile()
|
return self.GetFiletypeCompleter().GetDiagnosticsForCurrentFile()
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def ShowDetailedDiagnostic( self ):
|
def ShowDetailedDiagnostic( self ):
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
return self.GetFiletypeCompleter().ShowDetailedDiagnostic()
|
return self.GetFiletypeCompleter().ShowDetailedDiagnostic()
|
||||||
|
|
||||||
|
|
||||||
def GettingCompletions( self ):
|
def GettingCompletions( self ):
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
return self.GetFiletypeCompleter().GettingCompletions()
|
return self.GetFiletypeCompleter().GettingCompletions()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -149,7 +159,7 @@ class YouCompleteMe( object ):
|
|||||||
def OnCurrentIdentifierFinished( self ):
|
def OnCurrentIdentifierFinished( self ):
|
||||||
self.identcomp.OnCurrentIdentifierFinished()
|
self.identcomp.OnCurrentIdentifierFinished()
|
||||||
|
|
||||||
if self.FiletypeCompletionEnabled():
|
if self.FiletypeCompletionUsable():
|
||||||
self.GetFiletypeCompleter().OnCurrentIdentifierFinished()
|
self.GetFiletypeCompleter().OnCurrentIdentifierFinished()
|
||||||
|
|
||||||
|
|
||||||
@ -174,6 +184,11 @@ class YouCompleteMe( object ):
|
|||||||
return '\n'.join( output )
|
return '\n'.join( output )
|
||||||
|
|
||||||
|
|
||||||
|
def _CurrentFiletypeCompletionEnabled():
|
||||||
|
filetypes = vimsupport.CurrentFiletypes()
|
||||||
|
return not all([ x in FILETYPE_SPECIFIC_COMPLETION_TO_DISABLE
|
||||||
|
for x in filetypes ])
|
||||||
|
|
||||||
|
|
||||||
def _PathToCompletersFolder():
|
def _PathToCompletersFolder():
|
||||||
dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) )
|
dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) )
|
||||||
|
Loading…
Reference in New Issue
Block a user