Completion suggestions are now fetched async
This commit is contained in:
parent
7468a5a21c
commit
7cf580a447
@ -102,13 +102,27 @@ function! youcompleteme#Complete(findstart, base)
|
|||||||
return start_column
|
return start_column
|
||||||
else
|
else
|
||||||
let s:old_cursor_text = a:base
|
let s:old_cursor_text = a:base
|
||||||
let results = []
|
|
||||||
if strlen( a:base ) < g:ycm_min_num_of_chars_for_completion
|
if strlen( a:base ) < g:ycm_min_num_of_chars_for_completion
|
||||||
return results
|
return []
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
py csystem.CandidatesForQueryAsync( vim.eval('a:base') )
|
||||||
|
|
||||||
|
let l:results_ready = 0
|
||||||
|
while !l:results_ready
|
||||||
py << EOF
|
py << EOF
|
||||||
results = csystem.CompletionCandidatesForQuery( vim.eval('a:base') )
|
results_ready = csystem.AsyncCandidateRequestReady()
|
||||||
|
if results_ready:
|
||||||
|
vim.command( 'let l:results_ready = 1' )
|
||||||
|
EOF
|
||||||
|
if complete_check()
|
||||||
|
return { 'words' : [], 'refresh' : 'always'}
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let l:results = []
|
||||||
|
py << EOF
|
||||||
|
results = csystem.CandidatesFromStoredRequest()
|
||||||
if results:
|
if results:
|
||||||
vim.command( 'let l:results = ' + str( results ) )
|
vim.command( 'let l:results = ' + str( results ) )
|
||||||
EOF
|
EOF
|
||||||
@ -117,10 +131,8 @@ EOF
|
|||||||
" keystroke. The problem is still present in vim 7.3.390 but is fixed in
|
" keystroke. The problem is still present in vim 7.3.390 but is fixed in
|
||||||
" 7.3.475. It's possible that patch 404 was the one that fixed this issue,
|
" 7.3.475. It's possible that patch 404 was the one that fixed this issue,
|
||||||
" but I haven't tested this assumption.
|
" but I haven't tested this assumption.
|
||||||
let dict = { 'words' : results }
|
|
||||||
" A bug in vim causes the '.' register to break when we use set this... sigh
|
" A bug in vim causes the '.' register to break when we use set this... sigh
|
||||||
let dict.refresh = 'always'
|
return { 'words' : l:results, 'refresh' : 'always'}
|
||||||
return dict
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ endif()
|
|||||||
|
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG )
|
if( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG )
|
||||||
# We want all warnings, and warnings should be treated as errors
|
# We want all warnings, and warnings should be treated as errors
|
||||||
#add_definitions( -Wall -pedantic -Werror )
|
# TODO: -Wextra?
|
||||||
add_definitions( -Wall -Werror )
|
add_definitions( -Wall -Werror )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -19,14 +19,42 @@
|
|||||||
#include "Completer.h"
|
#include "Completer.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using boost::python::len;
|
using boost::python::len;
|
||||||
using boost::python::extract;
|
using boost::python::extract;
|
||||||
|
using boost::packaged_task;
|
||||||
|
using boost::bind;
|
||||||
|
using boost::unique_future;
|
||||||
|
using boost::make_shared;
|
||||||
|
using boost::shared_ptr;
|
||||||
|
using boost::bind;
|
||||||
|
using boost::thread;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
const unsigned int MAX_ASYNC_THREADS = 4;
|
||||||
|
const unsigned int MIN_ASYNC_THREADS = 2;
|
||||||
|
|
||||||
|
void ThreadMain( TaskStack &task_stack )
|
||||||
|
{
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
( *task_stack.Pop() )();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
Completer::Completer( const Pylist &candidates )
|
Completer::Completer( const Pylist &candidates )
|
||||||
|
: threading_enabled_( false )
|
||||||
{
|
{
|
||||||
AddCandidatesToDatabase( candidates, "", "" );
|
AddCandidatesToDatabase( candidates, "", "" );
|
||||||
}
|
}
|
||||||
@ -34,7 +62,8 @@ Completer::Completer( const Pylist &candidates )
|
|||||||
|
|
||||||
Completer::Completer( const Pylist &candidates,
|
Completer::Completer( const Pylist &candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath)
|
const std::string &filepath )
|
||||||
|
: threading_enabled_( false )
|
||||||
{
|
{
|
||||||
AddCandidatesToDatabase( candidates, filetype, filepath );
|
AddCandidatesToDatabase( candidates, filetype, filepath );
|
||||||
}
|
}
|
||||||
@ -50,6 +79,15 @@ Completer::~Completer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We need this mostly so that we can not use it in tests. Apparently the
|
||||||
|
// GoogleTest framework goes apeshit on us if we enable threads by default.
|
||||||
|
void Completer::EnableThreading()
|
||||||
|
{
|
||||||
|
threading_enabled_ = true;
|
||||||
|
InitThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Completer::AddCandidatesToDatabase( const Pylist &new_candidates,
|
void Completer::AddCandidatesToDatabase( const Pylist &new_candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath )
|
const std::string &filepath )
|
||||||
@ -85,13 +123,57 @@ void Completer::CandidatesForQuery( const std::string &query,
|
|||||||
void Completer::CandidatesForQueryAndType( const std::string &query,
|
void Completer::CandidatesForQueryAndType( const std::string &query,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
Pylist &candidates ) const
|
Pylist &candidates ) const
|
||||||
|
{
|
||||||
|
std::vector< Result > results;
|
||||||
|
ResultsForQueryAndType( query, filetype, results );
|
||||||
|
|
||||||
|
foreach ( const Result& result, results )
|
||||||
|
{
|
||||||
|
candidates.append( *result.Text() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future Completer::CandidatesForQueryAndTypeAsync(
|
||||||
|
const std::string &query,
|
||||||
|
const std::string &filetype ) const
|
||||||
|
{
|
||||||
|
// TODO: throw exception when threading is not enabled and this is called
|
||||||
|
if (!threading_enabled_)
|
||||||
|
return Future();
|
||||||
|
|
||||||
|
// Try not to look at this too hard, it may burn your eyes.
|
||||||
|
shared_ptr< packaged_task< AsyncResults > > task =
|
||||||
|
make_shared< packaged_task< AsyncResults > >(
|
||||||
|
bind( &Completer::ResultsForQueryAndType,
|
||||||
|
boost::cref( *this ),
|
||||||
|
query,
|
||||||
|
filetype ) );
|
||||||
|
|
||||||
|
unique_future< AsyncResults > future = task->get_future();
|
||||||
|
|
||||||
|
task_stack_.Push( task );
|
||||||
|
return Future( move( future ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncResults Completer::ResultsForQueryAndType(
|
||||||
|
const std::string &query,
|
||||||
|
const std::string &filetype ) const
|
||||||
|
{
|
||||||
|
AsyncResults results = boost::make_shared< std::vector< Result > >();
|
||||||
|
ResultsForQueryAndType( query, filetype, *results );
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Completer::ResultsForQueryAndType( const std::string &query,
|
||||||
|
const std::string &filetype,
|
||||||
|
std::vector< Result > &results ) const
|
||||||
{
|
{
|
||||||
FiletypeMap::const_iterator it = filetype_map_.find( filetype );
|
FiletypeMap::const_iterator it = filetype_map_.find( filetype );
|
||||||
if ( it == filetype_map_.end() )
|
if ( it == filetype_map_.end() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Bitset query_bitset = LetterBitsetFromString( query );
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
std::vector< Result > results;
|
|
||||||
|
|
||||||
foreach ( const FilepathToCandidates::value_type &path_and_candidates,
|
foreach ( const FilepathToCandidates::value_type &path_and_candidates,
|
||||||
*it->second )
|
*it->second )
|
||||||
@ -108,11 +190,6 @@ void Completer::CandidatesForQueryAndType( const std::string &query,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::sort( results.begin(), results.end() );
|
std::sort( results.begin(), results.end() );
|
||||||
|
|
||||||
foreach ( const Result& result, results )
|
|
||||||
{
|
|
||||||
candidates.append( *result.Text() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -136,4 +213,17 @@ std::vector< Candidate* >& Completer::GetCandidateVector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Completer::InitThreads()
|
||||||
|
{
|
||||||
|
int threads_to_create =
|
||||||
|
std::max( MIN_ASYNC_THREADS,
|
||||||
|
std::min( MAX_ASYNC_THREADS, thread::hardware_concurrency() ) );
|
||||||
|
|
||||||
|
for ( int i = 0; i < threads_to_create; ++i )
|
||||||
|
{
|
||||||
|
threads_.create_thread( bind( ThreadMain, boost::ref( task_stack_ ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#define COMPLETER_H_7AR4UGXE
|
#define COMPLETER_H_7AR4UGXE
|
||||||
|
|
||||||
#include "Candidate.h"
|
#include "Candidate.h"
|
||||||
|
#include "ConcurrentStack.h"
|
||||||
|
#include "Future.h"
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
@ -28,6 +30,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -44,10 +47,12 @@ typedef boost::unordered_map< std::string,
|
|||||||
typedef boost::unordered_map< std::string,
|
typedef boost::unordered_map< std::string,
|
||||||
boost::shared_ptr< FilepathToCandidates > > FiletypeMap;
|
boost::shared_ptr< FilepathToCandidates > > FiletypeMap;
|
||||||
|
|
||||||
|
typedef ConcurrentStack<
|
||||||
|
boost::shared_ptr<
|
||||||
|
boost::packaged_task< AsyncResults > > > TaskStack;
|
||||||
|
|
||||||
// TODO: resolve problems with noncopyable
|
|
||||||
// class Completer : boost::noncopyable
|
class Completer : boost::noncopyable
|
||||||
class Completer
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Completer() {}
|
Completer() {}
|
||||||
@ -57,6 +62,8 @@ public:
|
|||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
~Completer();
|
~Completer();
|
||||||
|
|
||||||
|
void EnableThreading();
|
||||||
|
|
||||||
void AddCandidatesToDatabase( const Pylist &new_candidates,
|
void AddCandidatesToDatabase( const Pylist &new_candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
@ -69,27 +76,41 @@ public:
|
|||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
Pylist &candidates ) const;
|
Pylist &candidates ) const;
|
||||||
|
|
||||||
|
Future CandidatesForQueryAndTypeAsync( const std::string &query,
|
||||||
|
const std::string &filetype ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
AsyncResults ResultsForQueryAndType( const std::string &query,
|
||||||
|
const std::string &filetype ) const;
|
||||||
|
|
||||||
|
void ResultsForQueryAndType( const std::string &query,
|
||||||
|
const std::string &filetype,
|
||||||
|
std::vector< Result > &results ) const;
|
||||||
|
|
||||||
std::vector< Candidate* >& GetCandidateVector(
|
std::vector< Candidate* >& GetCandidateVector(
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
|
|
||||||
struct CandidatePointerLess
|
void InitThreads();
|
||||||
{
|
|
||||||
bool operator() ( const Candidate *first, const Candidate *second )
|
|
||||||
{
|
/////////////////////////////
|
||||||
return first->Text() < second->Text();
|
// PRIVATE MEMBER VARIABLES
|
||||||
}
|
/////////////////////////////
|
||||||
};
|
|
||||||
|
|
||||||
// This data structure owns all the Candidate pointers
|
// This data structure owns all the Candidate pointers
|
||||||
CandidateRepository candidate_repository_;
|
CandidateRepository candidate_repository_;
|
||||||
|
|
||||||
FiletypeMap filetype_map_;
|
FiletypeMap filetype_map_;
|
||||||
|
|
||||||
|
mutable TaskStack task_stack_;
|
||||||
|
|
||||||
|
bool threading_enabled_;
|
||||||
|
|
||||||
|
boost::thread_group threads_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
#endif /* end of include guard: COMPLETER_H_7AR4UGXE */
|
#endif /* end of include guard: COMPLETER_H_7AR4UGXE */
|
||||||
|
|
||||||
|
66
cpp/ConcurrentStack.h
Normal file
66
cpp/ConcurrentStack.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// 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 CONCURRENTSTACK_H_SYF1JPPG
|
||||||
|
#define CONCURRENTSTACK_H_SYF1JPPG
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
|
namespace YouCompleteMe
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ConcurrentStack : boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Push( const T& data )
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
|
stack_.push( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
condition_variable_.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
T Pop()
|
||||||
|
{
|
||||||
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
|
|
||||||
|
while ( stack_.empty() )
|
||||||
|
{
|
||||||
|
condition_variable_.wait( lock );
|
||||||
|
}
|
||||||
|
|
||||||
|
T result = stack_.top();
|
||||||
|
stack_.pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::stack<T> stack_;
|
||||||
|
boost::mutex mutex_;
|
||||||
|
boost::condition_variable condition_variable_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
|
#endif /* end of include guard: CONCURRENTSTACK_H_SYF1JPPG */
|
55
cpp/Future.cpp
Normal file
55
cpp/Future.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
#include "standard.h"
|
||||||
|
#include "Future.h"
|
||||||
|
#include "Result.h"
|
||||||
|
|
||||||
|
namespace YouCompleteMe
|
||||||
|
{
|
||||||
|
|
||||||
|
Future::Future( boost::shared_future< AsyncResults > future )
|
||||||
|
: future_( boost::move( future ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Future::ResultsReady()
|
||||||
|
{
|
||||||
|
return future_.is_ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Future::GetResults( Pylist &candidates )
|
||||||
|
{
|
||||||
|
AsyncResults results;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = future_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( boost::future_uninitialized & )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( const Result& result, *results )
|
||||||
|
{
|
||||||
|
candidates.append( *result.Text() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace YouCompleteMe
|
47
cpp/Future.h
Normal file
47
cpp/Future.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// 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 FUTURE_H_NR1U6MZS
|
||||||
|
#define FUTURE_H_NR1U6MZS
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
namespace YouCompleteMe
|
||||||
|
{
|
||||||
|
|
||||||
|
class Result;
|
||||||
|
|
||||||
|
typedef boost::python::list Pylist;
|
||||||
|
typedef boost::shared_ptr< std::vector< Result > > AsyncResults;
|
||||||
|
|
||||||
|
class Future
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Future() {}
|
||||||
|
Future( boost::shared_future< AsyncResults > future );
|
||||||
|
bool ResultsReady();
|
||||||
|
void GetResults( Pylist &candidates );
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::shared_future< AsyncResults > future_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
|
#endif /* end of include guard: FUTURE_H_NR1U6MZS */
|
@ -16,15 +16,23 @@
|
|||||||
// along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
// along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "Completer.h"
|
#include "Completer.h"
|
||||||
|
#include "Future.h"
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(indexer)
|
BOOST_PYTHON_MODULE(indexer)
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using namespace YouCompleteMe;
|
using namespace YouCompleteMe;
|
||||||
|
|
||||||
class_<Completer>( "Completer" )
|
class_< Future >( "Future" )
|
||||||
|
.def( "ResultsReady", &Future::ResultsReady )
|
||||||
|
.def( "GetResults", &Future::GetResults );
|
||||||
|
|
||||||
|
class_< Completer, boost::noncopyable >( "Completer" )
|
||||||
|
.def( "EnableThreading", &Completer::EnableThreading )
|
||||||
.def( "AddCandidatesToDatabase", &Completer::AddCandidatesToDatabase )
|
.def( "AddCandidatesToDatabase", &Completer::AddCandidatesToDatabase )
|
||||||
.def( "CandidatesForQueryAndType", &Completer::CandidatesForQueryAndType );
|
.def( "CandidatesForQueryAndTypeAsync",
|
||||||
|
&Completer::CandidatesForQueryAndTypeAsync );
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,26 @@ min_num_chars = int( vim.eval( "g:ycm_min_num_of_chars_for_completion" ) )
|
|||||||
class CompletionSystem( object ):
|
class CompletionSystem( object ):
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
self.completer = indexer.Completer()
|
self.completer = indexer.Completer()
|
||||||
|
self.completer.EnableThreading()
|
||||||
self.pattern = re.compile( r"[_a-zA-Z]\w*" )
|
self.pattern = re.compile( r"[_a-zA-Z]\w*" )
|
||||||
|
self.future = None
|
||||||
|
|
||||||
def CompletionCandidatesForQuery( self, query ):
|
def CandidatesForQueryAsync( self, query ):
|
||||||
candidates = []
|
|
||||||
filetype = vim.eval( "&filetype" )
|
filetype = vim.eval( "&filetype" )
|
||||||
self.completer.CandidatesForQueryAndType( SanitizeQuery( query ),
|
self.future = self.completer.CandidatesForQueryAndTypeAsync(
|
||||||
filetype,
|
SanitizeQuery( query ),
|
||||||
candidates )
|
filetype )
|
||||||
return candidates
|
|
||||||
|
def AsyncCandidateRequestReady( self ):
|
||||||
|
return self.future.ResultsReady()
|
||||||
|
|
||||||
|
def CandidatesFromStoredRequest( self ):
|
||||||
|
if not self.future:
|
||||||
|
return []
|
||||||
|
|
||||||
|
results = []
|
||||||
|
self.future.GetResults( results )
|
||||||
|
return results
|
||||||
|
|
||||||
def AddBufferIdentifiers( self ):
|
def AddBufferIdentifiers( self ):
|
||||||
text = "\n".join( vim.current.buffer )
|
text = "\n".join( vim.current.buffer )
|
||||||
|
Loading…
Reference in New Issue
Block a user