diff --git a/autoload/youcompleteme.vim b/autoload/youcompleteme.vim index deb3248b..506d7bb6 100644 --- a/autoload/youcompleteme.vim +++ b/autoload/youcompleteme.vim @@ -195,6 +195,7 @@ endfunction function! s:ClangCompletion( query ) + " TODO: don't trigger on a dot inside a string constant py vim.command( 'let l:results = ' + \ str( clangcomp.CandidatesForQuery( vim.eval( 'a:query' ) ) ) ) diff --git a/cpp/ycm/ClangCompleter.cpp b/cpp/ycm/ClangCompleter.cpp index 8af6f145..a5a988c3 100644 --- a/cpp/ycm/ClangCompleter.cpp +++ b/cpp/ycm/ClangCompleter.cpp @@ -16,7 +16,10 @@ // along with YouCompleteMe. If not, see . #include "ClangCompleter.h" +#include "Candidate.h" #include "standard.h" +#include "CandidateRepository.h" + #include namespace YouCompleteMe @@ -88,6 +91,7 @@ std::vector< std::string > ToStringVector( CXCodeCompleteResults *results ) ClangCompleter::ClangCompleter() + : candidate_repository_( CandidateRepository::Instance() ) { clang_index_ = clang_createIndex( 0, 0 ); } @@ -148,6 +152,7 @@ void ClangCompleter::UpdateTranslationUnit( std::vector< std::string > ClangCompleter::CandidatesForLocationInFile( + const std::string &query, const std::string &filename, int line, int column, @@ -176,6 +181,9 @@ std::vector< std::string > ClangCompleter::CandidatesForLocationInFile( clang_defaultCodeCompleteOptions()); std::vector< std::string > completions = ToStringVector( results ); + if ( !query.empty() ) + completions = SortCandidatesForQuery( query, completions ); + clang_disposeCodeCompleteResults( results ); return completions; } @@ -237,4 +245,40 @@ CXTranslationUnit ClangCompleter::GetTranslationUnitForFile( return unit; } + +std::vector< std::string > ClangCompleter::SortCandidatesForQuery( + const std::string &query, + const std::vector< std::string > &candidates ) +{ + Bitset query_bitset = LetterBitsetFromString( query ); + + std::vector< const Candidate* > repository_candidates = + candidate_repository_.GetCandidatesForStrings( candidates ); + + std::vector< Result > results; + + // This loop needs to be a separate function + foreach ( const Candidate* candidate, repository_candidates ) + { + if ( !candidate->MatchesQueryBitset( query_bitset ) ) + continue; + + Result result = candidate->QueryMatchResult( query ); + 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() ); + } + + return sorted_candidates; +} + } // namespace YouCompleteMe diff --git a/cpp/ycm/ClangCompleter.h b/cpp/ycm/ClangCompleter.h index ed0e40a0..983b89f1 100644 --- a/cpp/ycm/ClangCompleter.h +++ b/cpp/ycm/ClangCompleter.h @@ -29,6 +29,8 @@ typedef struct CXTranslationUnitImpl *CXTranslationUnit; namespace YouCompleteMe { +class CandidateRepository; + struct UnsavedFile { UnsavedFile() : filename_( NULL ), contents_( NULL ), length_( 0 ) {} @@ -68,7 +70,9 @@ public: void UpdateTranslationUnit( const std::string &filename, const std::vector< UnsavedFile > &unsaved_files ); + // TODO: rename this std::vector< std::string > CandidatesForLocationInFile( + const std::string &query, const std::string &filename, int line, int column, @@ -88,10 +92,20 @@ private: const std::string &filename, const std::vector< UnsavedFile > &unsaved_files ); + std::vector< std::string > SortCandidatesForQuery( + const std::string &query, + const std::vector< std::string > &candidates ); + + + ///////////////////////////// + // PRIVATE MEMBER VARIABLES + ///////////////////////////// + CXIndex clang_index_; FlagsForFile flags_for_file_; TranslationUnitForFilename filename_to_translation_unit_; std::vector< std::string > global_flags_; + CandidateRepository &candidate_repository_; }; diff --git a/cpp/ycm/IdentifierCompleter.cpp b/cpp/ycm/IdentifierCompleter.cpp index a1ad4a81..0d78753d 100644 --- a/cpp/ycm/IdentifierCompleter.cpp +++ b/cpp/ycm/IdentifierCompleter.cpp @@ -127,6 +127,8 @@ std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType( ResultsForQueryAndType( query, filetype, results ); std::vector< std::string > candidates; + candidates.reserve( results.size() ); + foreach ( const Result& result, results ) { candidates.push_back( *result.Text() ); diff --git a/python/ycm.py b/python/ycm.py index 4b46d42f..f6aac053 100644 --- a/python/ycm.py +++ b/python/ycm.py @@ -119,7 +119,8 @@ class ClangCompleter( object ): line, _ = vim.current.window.cursor column = int( vim.eval( "s:completion_start_column" ) ) + 1 current_buffer = vim.current.buffer - results = self.completer.CandidatesForLocationInFile( current_buffer.name, + results = self.completer.CandidatesForLocationInFile( query, + current_buffer.name, line, column, files )