Improving IdentifierCompleter performance
We limit the number of candidates returned to Vim to 20 and also make sure that we are not returning any duplicate candidates. This provides a noticeable improvement in latency.
This commit is contained in:
parent
0f7f32d96f
commit
7bf18c7c5c
@ -43,6 +43,13 @@ CandidateRepository& CandidateRepository::Instance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CandidateRepository::NumStoredCandidates()
|
||||||
|
{
|
||||||
|
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
||||||
|
return candidate_holder_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
||||||
const std::vector< std::string > &strings )
|
const std::vector< std::string > &strings )
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,8 @@ class CandidateRepository : boost::noncopyable
|
|||||||
public:
|
public:
|
||||||
static CandidateRepository& Instance();
|
static CandidateRepository& Instance();
|
||||||
|
|
||||||
|
int NumStoredCandidates();
|
||||||
|
|
||||||
std::vector< const Candidate* > GetCandidatesForStrings(
|
std::vector< const Candidate* > GetCandidatesForStrings(
|
||||||
const std::vector< std::string > &strings );
|
const std::vector< std::string > &strings );
|
||||||
|
|
||||||
|
@ -128,6 +128,8 @@ bool IsChunkKindForExtraMenuInfo( CXCompletionChunkKind kind )
|
|||||||
|
|
||||||
char CursorKindToVimKind( CXCursorKind kind )
|
char CursorKindToVimKind( CXCursorKind kind )
|
||||||
{
|
{
|
||||||
|
// TODO: actually it appears that Vim will show returned kinds even when they
|
||||||
|
// do not match the "approved" list, so let's use that
|
||||||
switch ( kind )
|
switch ( kind )
|
||||||
{
|
{
|
||||||
case CXCursor_UnexposedDecl:
|
case CXCursor_UnexposedDecl:
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "Candidate.h"
|
#include "Candidate.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -173,11 +174,19 @@ void IdentifierCompleter::ResultsForQueryAndType(
|
|||||||
|
|
||||||
Bitset query_bitset = LetterBitsetFromString( query );
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
|
|
||||||
|
boost::unordered_set< const Candidate* > seen_candidates;
|
||||||
|
seen_candidates.reserve( candidate_repository_.NumStoredCandidates() );
|
||||||
|
|
||||||
foreach ( const FilepathToCandidates::value_type &path_and_candidates,
|
foreach ( const FilepathToCandidates::value_type &path_and_candidates,
|
||||||
*it->second )
|
*it->second )
|
||||||
{
|
{
|
||||||
foreach ( const Candidate* candidate, *path_and_candidates.second )
|
foreach ( const Candidate* candidate, *path_and_candidates.second )
|
||||||
{
|
{
|
||||||
|
if ( ContainsKey( seen_candidates, candidate ) )
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
seen_candidates.insert( candidate );
|
||||||
|
|
||||||
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -73,6 +73,15 @@ TEST( IdentifierCompleterTest, EmptyQueryNoResults )
|
|||||||
ElementsAre() );
|
ElementsAre() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST( IdentifierCompleterTest, NoDuplicatesReturned )
|
||||||
|
{
|
||||||
|
EXPECT_THAT( IdentifierCompleter( Candidates(
|
||||||
|
"foobar",
|
||||||
|
"foobar",
|
||||||
|
"foobar" ) ).CandidatesForQuery( "foo" ),
|
||||||
|
ElementsAre( "foobar" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST( IdentifierCompleterTest, OneCandidate )
|
TEST( IdentifierCompleterTest, OneCandidate )
|
||||||
{
|
{
|
||||||
|
@ -21,8 +21,10 @@ import re
|
|||||||
import vim
|
import vim
|
||||||
import indexer
|
import indexer
|
||||||
|
|
||||||
min_num_chars = int( vim.eval( "g:ycm_min_num_of_chars_for_completion" ) )
|
MIN_NUM_CHARS = int( vim.eval( "g:ycm_min_num_of_chars_for_completion" ) )
|
||||||
clang_filetypes = set( [ 'c', 'cpp', 'objc', 'objcpp' ] )
|
CLANG_FILETYPES = set( [ 'c', 'cpp', 'objc', 'objcpp' ] )
|
||||||
|
MAX_IDENTIFIER_COMPLETIONS_RETURNED = 20
|
||||||
|
|
||||||
|
|
||||||
class Completer( object ):
|
class Completer( object ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
@ -89,6 +91,11 @@ class IdentifierCompleter( Completer ):
|
|||||||
filepath,
|
filepath,
|
||||||
True )
|
True )
|
||||||
|
|
||||||
|
def CandidatesFromStoredRequest( self ):
|
||||||
|
if not self.future:
|
||||||
|
return []
|
||||||
|
return self.future.GetResults()[ : MAX_IDENTIFIER_COMPLETIONS_RETURNED ]
|
||||||
|
|
||||||
|
|
||||||
class ClangCompleter( Completer ):
|
class ClangCompleter( Completer ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
@ -181,7 +188,7 @@ def CurrentLineAndColumn():
|
|||||||
|
|
||||||
def ShouldUseClang( start_column ):
|
def ShouldUseClang( start_column ):
|
||||||
filetype = vim.eval( "&filetype" )
|
filetype = vim.eval( "&filetype" )
|
||||||
if filetype not in clang_filetypes:
|
if filetype not in CLANG_FILETYPES:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
line = vim.current.line
|
line = vim.current.line
|
||||||
@ -253,7 +260,7 @@ def PreviousIdentifier():
|
|||||||
while start_column > 0 and IsIdentifierChar( line[ start_column - 1 ] ):
|
while start_column > 0 and IsIdentifierChar( line[ start_column - 1 ] ):
|
||||||
start_column -= 1
|
start_column -= 1
|
||||||
|
|
||||||
if end_column - start_column < min_num_chars:
|
if end_column - start_column < MIN_NUM_CHARS:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
return line[ start_column : end_column ]
|
return line[ start_column : end_column ]
|
||||||
|
Loading…
Reference in New Issue
Block a user