ClangCompleter now returs extra data
This data is used to show more information about the completions in the completion menu.
This commit is contained in:
parent
e56080ea56
commit
44b671c2c0
@ -217,7 +217,7 @@ EOF
|
|||||||
let l:results = []
|
let l:results = []
|
||||||
py << EOF
|
py << EOF
|
||||||
results = clangcomp.CandidatesFromStoredRequest()
|
results = clangcomp.CandidatesFromStoredRequest()
|
||||||
result_string = ycm.StringVectorToString( results )
|
result_string = ycm.CompletionDataVectorToString( results )
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
vim.command( 'let l:results = ' + result_string )
|
vim.command( 'let l:results = ' + result_string )
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "CandidateRepository.h"
|
#include "CandidateRepository.h"
|
||||||
#include "Candidate.h"
|
#include "Candidate.h"
|
||||||
|
#include "CompletionData.h"
|
||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ CandidateRepository& CandidateRepository::Instance()
|
|||||||
|
|
||||||
|
|
||||||
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
||||||
const std::vector< std::string > &strings)
|
const std::vector< std::string > &strings )
|
||||||
{
|
{
|
||||||
std::vector< const Candidate* > candidates;
|
std::vector< const Candidate* > candidates;
|
||||||
candidates.reserve( strings.size() );
|
candidates.reserve( strings.size() );
|
||||||
@ -67,6 +68,31 @@ std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
||||||
|
const std::vector< CompletionData > &datas )
|
||||||
|
{
|
||||||
|
std::vector< const Candidate* > candidates;
|
||||||
|
candidates.reserve( datas.size() );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
||||||
|
|
||||||
|
foreach ( const CompletionData &data, datas )
|
||||||
|
{
|
||||||
|
const Candidate *&candidate = GetValueElseInsert( candidate_holder_,
|
||||||
|
data.original_string_,
|
||||||
|
NULL );
|
||||||
|
if ( !candidate )
|
||||||
|
candidate = new Candidate( data.original_string_ );
|
||||||
|
|
||||||
|
candidates.push_back( candidate );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CandidateRepository::~CandidateRepository()
|
CandidateRepository::~CandidateRepository()
|
||||||
{
|
{
|
||||||
foreach ( const CandidateHolder::value_type &pair,
|
foreach ( const CandidateHolder::value_type &pair,
|
||||||
|
@ -29,6 +29,7 @@ namespace YouCompleteMe
|
|||||||
{
|
{
|
||||||
|
|
||||||
class Candidate;
|
class Candidate;
|
||||||
|
struct CompletionData;
|
||||||
|
|
||||||
typedef boost::unordered_map< std::string, const Candidate* >
|
typedef boost::unordered_map< std::string, const Candidate* >
|
||||||
CandidateHolder;
|
CandidateHolder;
|
||||||
@ -41,6 +42,9 @@ public:
|
|||||||
std::vector< const Candidate* > GetCandidatesForStrings(
|
std::vector< const Candidate* > GetCandidatesForStrings(
|
||||||
const std::vector< std::string > &strings );
|
const std::vector< std::string > &strings );
|
||||||
|
|
||||||
|
std::vector< const Candidate* > GetCandidatesForStrings(
|
||||||
|
const std::vector< CompletionData > &datas );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CandidateRepository() {};
|
CandidateRepository() {};
|
||||||
~CandidateRepository();
|
~CandidateRepository();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "ClangCompleter.h"
|
#include "ClangCompleter.h"
|
||||||
#include "Candidate.h"
|
#include "Candidate.h"
|
||||||
|
#include "CompletionData.h"
|
||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
#include "CandidateRepository.h"
|
#include "CandidateRepository.h"
|
||||||
#include "ConcurrentLatestValue.h"
|
#include "ConcurrentLatestValue.h"
|
||||||
@ -35,12 +36,30 @@ using boost::thread;
|
|||||||
namespace YouCompleteMe
|
namespace YouCompleteMe
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef boost::function< std::vector< CompletionData >() >
|
||||||
|
FunctionReturnsCompletionDataVector;
|
||||||
|
|
||||||
extern const unsigned int MAX_ASYNC_THREADS;
|
extern const unsigned int MAX_ASYNC_THREADS;
|
||||||
extern const unsigned int MIN_ASYNC_THREADS;
|
extern const unsigned int MIN_ASYNC_THREADS;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct CompletionDataAndResult
|
||||||
|
{
|
||||||
|
CompletionDataAndResult( const CompletionData *completion_data,
|
||||||
|
const Result &result )
|
||||||
|
: completion_data_( completion_data ), result_( result ) {}
|
||||||
|
|
||||||
|
bool operator< ( const CompletionDataAndResult &other ) const
|
||||||
|
{
|
||||||
|
return result_ < other.result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CompletionData *completion_data_;
|
||||||
|
Result result_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
||||||
const std::vector< UnsavedFile > &unsaved_files )
|
const std::vector< UnsavedFile > &unsaved_files )
|
||||||
@ -83,18 +102,67 @@ bool CompletionStringAvailable( CXCompletionString completion_string )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > ToStringVector( CXCodeCompleteResults *results )
|
bool IsChunkKindForExtraMenuInfo( CXCompletionChunkKind kind )
|
||||||
{
|
{
|
||||||
std::vector< std::string > completions;
|
return
|
||||||
completions.reserve( results->NumResults );
|
kind == CXCompletionChunk_Optional ||
|
||||||
|
kind == CXCompletionChunk_TypedText ||
|
||||||
|
kind == CXCompletionChunk_Placeholder ||
|
||||||
|
kind == CXCompletionChunk_LeftParen ||
|
||||||
|
kind == CXCompletionChunk_RightParen ||
|
||||||
|
kind == CXCompletionChunk_RightBracket ||
|
||||||
|
kind == CXCompletionChunk_LeftBracket ||
|
||||||
|
kind == CXCompletionChunk_LeftBrace ||
|
||||||
|
kind == CXCompletionChunk_RightBrace ||
|
||||||
|
kind == CXCompletionChunk_RightAngle ||
|
||||||
|
kind == CXCompletionChunk_LeftAngle ||
|
||||||
|
kind == CXCompletionChunk_Comma ||
|
||||||
|
kind == CXCompletionChunk_ResultType ||
|
||||||
|
kind == CXCompletionChunk_Colon ||
|
||||||
|
kind == CXCompletionChunk_SemiColon ||
|
||||||
|
kind == CXCompletionChunk_Equal ||
|
||||||
|
kind == CXCompletionChunk_HorizontalSpace;
|
||||||
|
|
||||||
for ( uint i = 0; i < results->NumResults; ++i )
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char CursorKindToVimKind( CXCursorKind kind )
|
||||||
|
{
|
||||||
|
switch ( kind )
|
||||||
{
|
{
|
||||||
CXCompletionString completion_string =
|
case CXCursor_UnexposedDecl:
|
||||||
results->Results[ i ].CompletionString;
|
case CXCursor_StructDecl:
|
||||||
|
case CXCursor_UnionDecl:
|
||||||
|
case CXCursor_ClassDecl:
|
||||||
|
case CXCursor_EnumDecl:
|
||||||
|
case CXCursor_TypedefDecl:
|
||||||
|
return 't';
|
||||||
|
|
||||||
if ( !CompletionStringAvailable( completion_string ) )
|
case CXCursor_FieldDecl:
|
||||||
continue;
|
return 'm';
|
||||||
|
|
||||||
|
case CXCursor_FunctionDecl:
|
||||||
|
case CXCursor_CXXMethod:
|
||||||
|
case CXCursor_FunctionTemplate:
|
||||||
|
return 'f';
|
||||||
|
|
||||||
|
case CXCursor_VarDecl:
|
||||||
|
return 'v';
|
||||||
|
|
||||||
|
case CXCursor_MacroDefinition:
|
||||||
|
return 'd';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 'u'; // for 'unknown', 'unsupported'... whatever you like
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CompletionData CompletionResultToCompletionData(
|
||||||
|
const CXCompletionResult &completion_result )
|
||||||
|
{
|
||||||
|
CompletionData data;
|
||||||
|
CXCompletionString completion_string = completion_result.CompletionString;
|
||||||
|
|
||||||
uint num_chunks = clang_getNumCompletionChunks( completion_string );
|
uint num_chunks = clang_getNumCompletionChunks( completion_string );
|
||||||
for ( uint j = 0; j < num_chunks; ++j )
|
for ( uint j = 0; j < num_chunks; ++j )
|
||||||
@ -102,12 +170,42 @@ std::vector< std::string > ToStringVector( CXCodeCompleteResults *results )
|
|||||||
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
||||||
completion_string, j );
|
completion_string, j );
|
||||||
|
|
||||||
if ( kind == CXCompletionChunk_TypedText )
|
if ( IsChunkKindForExtraMenuInfo( kind ) )
|
||||||
{
|
{
|
||||||
completions.push_back( ChunkToString( completion_string, j ) );
|
data.extra_menu_info_.append( ChunkToString( completion_string, j ) );
|
||||||
break;
|
|
||||||
|
// by default, there's no space after the return type
|
||||||
|
if ( kind == CXCompletionChunk_ResultType )
|
||||||
|
data.extra_menu_info_.append( " " );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( kind == CXCompletionChunk_TypedText )
|
||||||
|
data.original_string_ = ChunkToString( completion_string, j );
|
||||||
|
|
||||||
|
if ( kind == CXCompletionChunk_Informative )
|
||||||
|
data.detailed_info_ = ChunkToString( completion_string, j );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.kind_ = CursorKindToVimKind( completion_result.CursorKind );
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector< CompletionData > ToCompletionDataVector(
|
||||||
|
CXCodeCompleteResults *results )
|
||||||
|
{
|
||||||
|
std::vector< CompletionData > completions;
|
||||||
|
completions.reserve( results->NumResults );
|
||||||
|
|
||||||
|
for ( uint i = 0; i < results->NumResults; ++i )
|
||||||
|
{
|
||||||
|
CXCompletionResult completion_result = results->Results[ i ];
|
||||||
|
|
||||||
|
if ( !CompletionStringAvailable( completion_result.CompletionString ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
completions.push_back(
|
||||||
|
CompletionResultToCompletionData( completion_result ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return completions;
|
return completions;
|
||||||
@ -189,7 +287,7 @@ void ClangCompleter::UpdateTranslationUnit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > ClangCompleter::CandidatesForLocationInFile(
|
std::vector< CompletionData > ClangCompleter::CandidatesForLocationInFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
@ -217,13 +315,14 @@ std::vector< std::string > ClangCompleter::CandidatesForLocationInFile(
|
|||||||
cxunsaved_files.size(),
|
cxunsaved_files.size(),
|
||||||
clang_defaultCodeCompleteOptions());
|
clang_defaultCodeCompleteOptions());
|
||||||
|
|
||||||
std::vector< std::string > candidates = ToStringVector( results );
|
std::vector< CompletionData > candidates = ToCompletionDataVector( results );
|
||||||
clang_disposeCodeCompleteResults( results );
|
clang_disposeCodeCompleteResults( results );
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future< AsyncResults > ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
Future< AsyncCompletions >
|
||||||
|
ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
@ -232,7 +331,7 @@ Future< AsyncResults > ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
|||||||
{
|
{
|
||||||
// TODO: throw exception when threading is not enabled and this is called
|
// TODO: throw exception when threading is not enabled and this is called
|
||||||
if ( !threading_enabled_ )
|
if ( !threading_enabled_ )
|
||||||
return Future< AsyncResults >();
|
return Future< AsyncCompletions >();
|
||||||
|
|
||||||
if ( query.empty() )
|
if ( query.empty() )
|
||||||
{
|
{
|
||||||
@ -251,23 +350,24 @@ Future< AsyncResults > ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
|||||||
// case the clang task finishes (and therefore notifies a sorting thread to
|
// case the clang task finishes (and therefore notifies a sorting thread to
|
||||||
// consume a sorting task) before the sorting task is set
|
// consume a sorting task) before the sorting task is set
|
||||||
|
|
||||||
FunctionReturnsStringVector sort_candidates_for_query_functor =
|
FunctionReturnsCompletionDataVector sort_candidates_for_query_functor =
|
||||||
bind( &ClangCompleter::SortCandidatesForQuery,
|
bind( &ClangCompleter::SortCandidatesForQuery,
|
||||||
boost::ref( *this ),
|
boost::ref( *this ),
|
||||||
query,
|
query,
|
||||||
boost::cref( latest_clang_results_ ) );
|
boost::cref( latest_clang_results_ ) );
|
||||||
|
|
||||||
shared_ptr< packaged_task< AsyncResults > > task =
|
shared_ptr< packaged_task< AsyncCompletions > > task =
|
||||||
make_shared< packaged_task< AsyncResults > >(
|
make_shared< packaged_task< AsyncCompletions > >(
|
||||||
bind( ReturnValueAsShared< std::vector< std::string > >,
|
bind( ReturnValueAsShared< std::vector< CompletionData > >,
|
||||||
sort_candidates_for_query_functor ) );
|
sort_candidates_for_query_functor ) );
|
||||||
|
|
||||||
unique_future< AsyncResults > future = task->get_future();
|
unique_future< AsyncCompletions > future = task->get_future();
|
||||||
sorting_task_.Set( task );
|
sorting_task_.Set( task );
|
||||||
|
|
||||||
if ( query.empty() )
|
if ( query.empty() )
|
||||||
{
|
{
|
||||||
FunctionReturnsStringVector candidates_for_location_in_file_functor =
|
FunctionReturnsCompletionDataVector
|
||||||
|
candidates_for_location_in_file_functor =
|
||||||
bind( &ClangCompleter::CandidatesForLocationInFile,
|
bind( &ClangCompleter::CandidatesForLocationInFile,
|
||||||
boost::ref( *this ),
|
boost::ref( *this ),
|
||||||
filename,
|
filename,
|
||||||
@ -275,15 +375,15 @@ Future< AsyncResults > ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
|||||||
column,
|
column,
|
||||||
unsaved_files );
|
unsaved_files );
|
||||||
|
|
||||||
shared_ptr< packaged_task< AsyncResults > > task =
|
shared_ptr< packaged_task< AsyncCompletions > > task =
|
||||||
make_shared< packaged_task< AsyncResults > >(
|
make_shared< packaged_task< AsyncCompletions > >(
|
||||||
bind( ReturnValueAsShared< std::vector< std::string > >,
|
bind( ReturnValueAsShared< std::vector< CompletionData > >,
|
||||||
candidates_for_location_in_file_functor ) );
|
candidates_for_location_in_file_functor ) );
|
||||||
|
|
||||||
clang_task_.Set( task );
|
clang_task_.Set( task );
|
||||||
}
|
}
|
||||||
|
|
||||||
return Future< AsyncResults >( move( future ) );
|
return Future< AsyncCompletions >( boost::move( future ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -344,39 +444,42 @@ CXTranslationUnit ClangCompleter::GetTranslationUnitForFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > ClangCompleter::SortCandidatesForQuery(
|
std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::vector< std::string > &candidates )
|
const std::vector< CompletionData > &completion_datas )
|
||||||
{
|
{
|
||||||
Bitset query_bitset = LetterBitsetFromString( query );
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
|
|
||||||
std::vector< const Candidate* > repository_candidates =
|
std::vector< const Candidate* > repository_candidates =
|
||||||
candidate_repository_.GetCandidatesForStrings( candidates );
|
candidate_repository_.GetCandidatesForStrings( completion_datas );
|
||||||
|
|
||||||
std::vector< Result > results;
|
std::vector< CompletionDataAndResult > data_and_results;
|
||||||
|
|
||||||
// This loop needs to be a separate function
|
for ( uint i = 0; i < repository_candidates.size(); ++i )
|
||||||
foreach ( const Candidate* candidate, repository_candidates )
|
|
||||||
{
|
{
|
||||||
|
const Candidate* candidate = repository_candidates[ i ];
|
||||||
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Result result = candidate->QueryMatchResult( query );
|
Result result = candidate->QueryMatchResult( query );
|
||||||
if ( result.IsSubsequence() )
|
if ( result.IsSubsequence() )
|
||||||
results.push_back( result );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort( results.begin(), results.end() );
|
|
||||||
|
|
||||||
std::vector< std::string > sorted_candidates;
|
|
||||||
sorted_candidates.reserve( results.size() );
|
|
||||||
|
|
||||||
foreach ( const Result& result, results )
|
|
||||||
{
|
{
|
||||||
sorted_candidates.push_back( *result.Text() );
|
CompletionDataAndResult data_and_result( &completion_datas[ i ], result );
|
||||||
|
data_and_results.push_back( data_and_result );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sorted_candidates;
|
std::sort( data_and_results.begin(), data_and_results.end() );
|
||||||
|
|
||||||
|
std::vector< CompletionData > sorted_completion_datas;
|
||||||
|
sorted_completion_datas.reserve( data_and_results.size() );
|
||||||
|
|
||||||
|
foreach ( const CompletionDataAndResult& data_and_result, data_and_results )
|
||||||
|
{
|
||||||
|
sorted_completion_datas.push_back( *data_and_result.completion_data_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
return sorted_completion_datas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -404,9 +507,9 @@ void ClangCompleter::ClangThreadMain( LatestTask &clang_task )
|
|||||||
{
|
{
|
||||||
while ( true )
|
while ( true )
|
||||||
{
|
{
|
||||||
shared_ptr< packaged_task< AsyncResults > > task = clang_task.Get();
|
shared_ptr< packaged_task< AsyncCompletions > > task = clang_task.Get();
|
||||||
( *task )();
|
( *task )();
|
||||||
unique_future< AsyncResults > future = task->get_future();
|
unique_future< AsyncCompletions > future = task->get_future();
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::unique_lock< boost::shared_mutex > writer_lock(
|
boost::unique_lock< boost::shared_mutex > writer_lock(
|
||||||
@ -439,7 +542,7 @@ void ClangCompleter::SortingThreadMain( LatestTask &sorting_task )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr< packaged_task< AsyncResults > > task = sorting_task.Get();
|
shared_ptr< packaged_task< AsyncCompletions > > task = sorting_task.Get();
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::shared_lock< boost::shared_mutex > reader_lock(
|
boost::shared_lock< boost::shared_mutex > reader_lock(
|
||||||
|
@ -33,7 +33,9 @@ namespace YouCompleteMe
|
|||||||
{
|
{
|
||||||
|
|
||||||
class CandidateRepository;
|
class CandidateRepository;
|
||||||
|
struct CompletionData;
|
||||||
|
|
||||||
|
// TODO: put this in a separated header file
|
||||||
struct UnsavedFile
|
struct UnsavedFile
|
||||||
{
|
{
|
||||||
UnsavedFile() : filename_( NULL ), contents_( NULL ), length_( 0 ) {}
|
UnsavedFile() : filename_( NULL ), contents_( NULL ), length_( 0 ) {}
|
||||||
@ -55,6 +57,7 @@ struct UnsavedFile
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef boost::shared_ptr< std::vector< CompletionData > > AsyncCompletions;
|
||||||
|
|
||||||
typedef boost::unordered_map< std::string, std::vector< std::string > >
|
typedef boost::unordered_map< std::string, std::vector< std::string > >
|
||||||
FlagsForFile;
|
FlagsForFile;
|
||||||
@ -79,13 +82,13 @@ public:
|
|||||||
void UpdateTranslationUnit( const std::string &filename,
|
void UpdateTranslationUnit( const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files );
|
const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
std::vector< std::string > CandidatesForLocationInFile(
|
std::vector< CompletionData > CandidatesForLocationInFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files );
|
const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
Future< AsyncResults > CandidatesForQueryAndLocationInFileAsync(
|
Future< AsyncCompletions > CandidatesForQueryAndLocationInFileAsync(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
@ -95,7 +98,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
typedef ConcurrentLatestValue<
|
typedef ConcurrentLatestValue<
|
||||||
boost::shared_ptr<
|
boost::shared_ptr<
|
||||||
boost::packaged_task< AsyncResults > > > LatestTask;
|
boost::packaged_task< AsyncCompletions > > > LatestTask;
|
||||||
|
|
||||||
// caller takes ownership of translation unit
|
// caller takes ownership of translation unit
|
||||||
CXTranslationUnit CreateTranslationUnit(
|
CXTranslationUnit CreateTranslationUnit(
|
||||||
@ -109,9 +112,9 @@ private:
|
|||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files );
|
const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
std::vector< std::string > SortCandidatesForQuery(
|
std::vector< CompletionData > SortCandidatesForQuery(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::vector< std::string > &candidates );
|
const std::vector< CompletionData > &completion_datas );
|
||||||
|
|
||||||
void InitThreads();
|
void InitThreads();
|
||||||
|
|
||||||
@ -145,7 +148,7 @@ private:
|
|||||||
boost::mutex clang_data_ready_mutex_;
|
boost::mutex clang_data_ready_mutex_;
|
||||||
boost::condition_variable clang_data_ready_condition_variable_;
|
boost::condition_variable clang_data_ready_condition_variable_;
|
||||||
|
|
||||||
std::vector< std::string > latest_clang_results_;
|
std::vector< CompletionData > latest_clang_results_;
|
||||||
boost::shared_mutex latest_clang_results_shared_mutex_;
|
boost::shared_mutex latest_clang_results_shared_mutex_;
|
||||||
|
|
||||||
// Unfortunately clang is not thread-safe so we can only ever use one thread
|
// Unfortunately clang is not thread-safe so we can only ever use one thread
|
||||||
|
69
cpp/ycm/CompletionData.h
Normal file
69
cpp/ycm/CompletionData.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (C) 2011, 2012 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 COMPLETIONDATA_H_2JCTF1NU
|
||||||
|
#define COMPLETIONDATA_H_2JCTF1NU
|
||||||
|
|
||||||
|
namespace YouCompleteMe
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CompletionData
|
||||||
|
{
|
||||||
|
// What should actually be inserted into the buffer. For functions, this
|
||||||
|
// should be the original string plus "("
|
||||||
|
std::string TextToInsertInBuffer()
|
||||||
|
{
|
||||||
|
if ( kind_ == 'f' )
|
||||||
|
return original_string_ + "(";
|
||||||
|
return original_string_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator== ( const CompletionData &other ) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
kind_ == other.kind_ &&
|
||||||
|
original_string_ == other.original_string_ &&
|
||||||
|
extra_menu_info_ == other.extra_menu_info_;
|
||||||
|
// detailed_info_ doesn't matter
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used to show extra information in vim's preview window
|
||||||
|
std::string detailed_info_;
|
||||||
|
|
||||||
|
// This is extra info shown in the pop-up completion menu, after the
|
||||||
|
// completion text and the kind
|
||||||
|
std::string extra_menu_info_;
|
||||||
|
|
||||||
|
// Vim's completion string "kind"
|
||||||
|
// 'v' -> variable
|
||||||
|
// 'f' -> function or method
|
||||||
|
// 'm' -> member of struct/class (data member)
|
||||||
|
// 't' -> typedef (but we're going to use it for types in general)
|
||||||
|
// 'd' -> #define or macro
|
||||||
|
char kind_;
|
||||||
|
|
||||||
|
// The original, raw completion string. For a function like "int foo(int x)",
|
||||||
|
// the original string is "foo". This corresponds to clang's TypedText chunk
|
||||||
|
// of the completion string.
|
||||||
|
std::string original_string_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* end of include guard: COMPLETIONDATA_H_2JCTF1NU */
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/python.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
@ -30,12 +29,6 @@ namespace YouCompleteMe
|
|||||||
class Result;
|
class Result;
|
||||||
template< typename T > class ConcurrentLatestValue;
|
template< typename T > class ConcurrentLatestValue;
|
||||||
|
|
||||||
typedef boost::python::list Pylist;
|
|
||||||
typedef boost::shared_ptr< std::vector< std::string > > AsyncResults;
|
|
||||||
|
|
||||||
typedef boost::function< std::vector< std::string >() >
|
|
||||||
FunctionReturnsStringVector;
|
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
boost::shared_ptr< T > ReturnValueAsShared(
|
boost::shared_ptr< T > ReturnValueAsShared(
|
||||||
boost::function< T() > func )
|
boost::function< T() > func )
|
||||||
|
@ -158,7 +158,7 @@ Future< AsyncResults > IdentifierCompleter::CandidatesForQueryAndTypeAsync(
|
|||||||
unique_future< AsyncResults > future = task->get_future();
|
unique_future< AsyncResults > future = task->get_future();
|
||||||
|
|
||||||
latest_task_.Set( task );
|
latest_task_.Set( task );
|
||||||
return Future< AsyncResults >( move( future ) );
|
return Future< AsyncResults >( boost::move( future ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +35,13 @@ namespace YouCompleteMe
|
|||||||
class Candidate;
|
class Candidate;
|
||||||
class CandidateRepository;
|
class CandidateRepository;
|
||||||
|
|
||||||
|
typedef boost::shared_ptr< std::vector< std::string > > AsyncResults;
|
||||||
|
|
||||||
|
// TODO: cpp?
|
||||||
|
typedef boost::function< std::vector< std::string >() >
|
||||||
|
FunctionReturnsStringVector;
|
||||||
|
|
||||||
|
|
||||||
// TODO: move to private
|
// TODO: move to private
|
||||||
// filepath -> *( *candidate )
|
// filepath -> *( *candidate )
|
||||||
typedef boost::unordered_map< std::string,
|
typedef boost::unordered_map< std::string,
|
||||||
|
@ -69,6 +69,20 @@ int NumWordBoundaryCharMatches( const std::string &query,
|
|||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
|
Result::Result()
|
||||||
|
:
|
||||||
|
query_is_empty_( true ),
|
||||||
|
is_subsequence_( false ),
|
||||||
|
first_char_same_in_query_and_text_( false ),
|
||||||
|
ratio_of_word_boundary_chars_in_query_( 0 ),
|
||||||
|
word_boundary_char_utilization_( 0 ),
|
||||||
|
query_is_candidate_prefix_( false ),
|
||||||
|
text_is_lowercase_( false ),
|
||||||
|
char_match_index_sum_( 0 ),
|
||||||
|
text_( NULL )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Result::Result( bool is_subsequence )
|
Result::Result( bool is_subsequence )
|
||||||
:
|
:
|
||||||
@ -84,6 +98,7 @@ Result::Result( bool is_subsequence )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result::Result( bool is_subsequence,
|
Result::Result( bool is_subsequence,
|
||||||
const std::string *text,
|
const std::string *text,
|
||||||
bool text_is_lowercase,
|
bool text_is_lowercase,
|
||||||
|
@ -26,6 +26,7 @@ namespace YouCompleteMe
|
|||||||
class Result
|
class Result
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Result();
|
||||||
explicit Result( bool is_subsequence );
|
explicit Result( bool is_subsequence );
|
||||||
|
|
||||||
Result( bool is_subsequence,
|
Result( bool is_subsequence,
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "IdentifierCompleter.h"
|
#include "IdentifierCompleter.h"
|
||||||
#include "ClangCompleter.h"
|
#include "ClangCompleter.h"
|
||||||
#include "Future.h"
|
#include "Future.h"
|
||||||
|
#include "CompletionData.h"
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
@ -28,14 +29,31 @@ BOOST_PYTHON_MODULE(indexer)
|
|||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using namespace YouCompleteMe;
|
using namespace YouCompleteMe;
|
||||||
|
|
||||||
|
// TODO: rename these *Vec classes to *Vector; don't forget the python file
|
||||||
class_< std::vector< std::string >,
|
class_< std::vector< std::string >,
|
||||||
boost::shared_ptr< std::vector< std::string > > >( "StringVec" )
|
boost::shared_ptr< std::vector< std::string > > >( "StringVec" )
|
||||||
.def( vector_indexing_suite< std::vector< std::string > >() );
|
.def( vector_indexing_suite< std::vector< std::string > >() );
|
||||||
|
|
||||||
|
class_< CompletionData >( "CompletionData" )
|
||||||
|
.def( "TextToInsertInBuffer", &CompletionData::TextToInsertInBuffer )
|
||||||
|
.def_readonly( "detailed_info_", &CompletionData::detailed_info_ )
|
||||||
|
.def_readonly( "extra_menu_info_", &CompletionData::extra_menu_info_ )
|
||||||
|
.def_readonly( "kind_", &CompletionData::kind_ )
|
||||||
|
.def_readonly( "original_string_", &CompletionData::original_string_ );
|
||||||
|
|
||||||
|
class_< std::vector< CompletionData >,
|
||||||
|
boost::shared_ptr< std::vector< CompletionData > > >(
|
||||||
|
"CompletionVec" )
|
||||||
|
.def( vector_indexing_suite< std::vector< CompletionData > >() );
|
||||||
|
|
||||||
class_< Future< AsyncResults > >( "Future" )
|
class_< Future< AsyncResults > >( "Future" )
|
||||||
.def( "ResultsReady", &Future< AsyncResults >::ResultsReady )
|
.def( "ResultsReady", &Future< AsyncResults >::ResultsReady )
|
||||||
.def( "GetResults", &Future< AsyncResults >::GetResults );
|
.def( "GetResults", &Future< AsyncResults >::GetResults );
|
||||||
|
|
||||||
|
class_< Future< AsyncCompletions > >( "Future" )
|
||||||
|
.def( "ResultsReady", &Future< AsyncCompletions >::ResultsReady )
|
||||||
|
.def( "GetResults", &Future< AsyncCompletions >::GetResults );
|
||||||
|
|
||||||
class_< IdentifierCompleter, boost::noncopyable >( "IdentifierCompleter" )
|
class_< IdentifierCompleter, boost::noncopyable >( "IdentifierCompleter" )
|
||||||
.def( "EnableThreading", &IdentifierCompleter::EnableThreading )
|
.def( "EnableThreading", &IdentifierCompleter::EnableThreading )
|
||||||
.def( "AddCandidatesToDatabase",
|
.def( "AddCandidatesToDatabase",
|
||||||
|
@ -151,6 +151,21 @@ def StringVectorToString( stringvec ):
|
|||||||
return ''.join( result )
|
return ''.join( result )
|
||||||
|
|
||||||
|
|
||||||
|
def CompletionDataToDict( completion_data ):
|
||||||
|
# see :h complete-items for a description of the dictionary fields
|
||||||
|
return {
|
||||||
|
'word' : completion_data.TextToInsertInBuffer(),
|
||||||
|
'abbr' : completion_data.original_string_,
|
||||||
|
'menu' : completion_data.extra_menu_info_,
|
||||||
|
'kind' : completion_data.kind_,
|
||||||
|
# TODO: add detailed_info_ as 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def CompletionDataVectorToString( datavec ):
|
||||||
|
return str( [ CompletionDataToDict( x ) for x in datavec ] )
|
||||||
|
|
||||||
|
|
||||||
def CurrentColumn():
|
def CurrentColumn():
|
||||||
"""Do NOT access the CurrentColumn in vim.current.line. It doesn't exist yet.
|
"""Do NOT access the CurrentColumn in vim.current.line. It doesn't exist yet.
|
||||||
Only the chars before the current column exist in vim.current.line."""
|
Only the chars before the current column exist in vim.current.line."""
|
||||||
|
Loading…
Reference in New Issue
Block a user