mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
Cache code completion results for backspace character.
This commit is contained in:
parent
9ae526089a
commit
29845cc1e3
@ -75,7 +75,14 @@ std::string FormatMicroseconds(long long microseconds) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Cached completion information, so we can give fast completion results when
|
||||||
|
// the user erases a character. vscode will resend the completion request if
|
||||||
|
// that happens.
|
||||||
|
struct CodeCompleteCache {
|
||||||
|
optional<lsPosition> cached_completion_position;
|
||||||
|
NonElidedVector<lsCompletionItem> cached_results;
|
||||||
|
NonElidedVector<lsDiagnostic> cached_diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -146,7 +153,15 @@ IpcManager* IpcManager::instance_ = nullptr;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This function returns true if e2e timing should be displayed for the given IpcId.
|
||||||
|
bool ShouldDisplayIpcTiming(IpcId id) {
|
||||||
|
switch (id) {
|
||||||
|
case IpcId::TextDocumentPublishDiagnostics:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1364,7 +1379,8 @@ bool QueryDbMainLoop(
|
|||||||
Project* project,
|
Project* project,
|
||||||
FileConsumer::SharedState* file_consumer_shared,
|
FileConsumer::SharedState* file_consumer_shared,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
CompletionManager* completion_manager) {
|
CompletionManager* completion_manager,
|
||||||
|
CodeCompleteCache* code_complete_cache) {
|
||||||
IpcManager* ipc = IpcManager::instance();
|
IpcManager* ipc = IpcManager::instance();
|
||||||
|
|
||||||
bool did_work = false;
|
bool did_work = false;
|
||||||
@ -1689,9 +1705,13 @@ bool QueryDbMainLoop(
|
|||||||
|
|
||||||
case IpcId::TextDocumentCompletion: {
|
case IpcId::TextDocumentCompletion: {
|
||||||
auto msg = static_cast<Ipc_TextDocumentComplete*>(message.get());
|
auto msg = static_cast<Ipc_TextDocumentComplete*>(message.get());
|
||||||
lsTextDocumentPositionParams params = msg->params;
|
lsTextDocumentPositionParams& params = msg->params;
|
||||||
|
|
||||||
CompletionManager::OnComplete callback = std::bind([working_files](BaseIpcMessage* message, NonElidedVector<lsCompletionItem> results, NonElidedVector<lsDiagnostic> diagnostics) {
|
WorkingFile* file = working_files->GetFileByFilename(params.textDocument.uri.GetPath());
|
||||||
|
if (file)
|
||||||
|
params.position = file->FindStableCompletionSource(params.position);
|
||||||
|
|
||||||
|
CompletionManager::OnComplete callback = std::bind([working_files, code_complete_cache](BaseIpcMessage* message, NonElidedVector<lsCompletionItem> results, NonElidedVector<lsDiagnostic> diagnostics) {
|
||||||
auto msg = static_cast<Ipc_TextDocumentComplete*>(message);
|
auto msg = static_cast<Ipc_TextDocumentComplete*>(message);
|
||||||
auto ipc = IpcManager::instance();
|
auto ipc = IpcManager::instance();
|
||||||
|
|
||||||
@ -1707,14 +1727,21 @@ bool QueryDbMainLoop(
|
|||||||
diagnostic_response.params.diagnostics = diagnostics;
|
diagnostic_response.params.diagnostics = diagnostics;
|
||||||
ipc->SendOutMessageToClient(IpcId::TextDocumentPublishDiagnostics, diagnostic_response);
|
ipc->SendOutMessageToClient(IpcId::TextDocumentPublishDiagnostics, diagnostic_response);
|
||||||
|
|
||||||
WorkingFile* working_file = working_files->GetFileByFilename(msg->params.textDocument.uri.GetPath());
|
code_complete_cache->cached_completion_position = msg->params.position;
|
||||||
if (working_file)
|
code_complete_cache->cached_results = results;
|
||||||
working_file->has_diagnostics = !diagnostics.empty();
|
code_complete_cache->cached_diagnostics = diagnostics;
|
||||||
|
|
||||||
delete message;
|
delete message;
|
||||||
}, message.release(), std::placeholders::_1, std::placeholders::_2);
|
}, message.release(), std::placeholders::_1, std::placeholders::_2);
|
||||||
|
|
||||||
completion_manager->CodeComplete(params, std::move(callback));
|
if (code_complete_cache->cached_completion_position &&
|
||||||
|
code_complete_cache->cached_completion_position == params.position) {
|
||||||
|
std::cerr << "[complete] Using cached completion results at " << params.position.ToString() << std::endl;
|
||||||
|
callback(code_complete_cache->cached_results, code_complete_cache->cached_diagnostics);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completion_manager->CodeComplete(params, std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2206,13 +2233,14 @@ void QueryDbMain(IndexerConfig* config, MultiQueueWaiter* waiter) {
|
|||||||
Project project;
|
Project project;
|
||||||
WorkingFiles working_files;
|
WorkingFiles working_files;
|
||||||
CompletionManager completion_manager(config, &project, &working_files);
|
CompletionManager completion_manager(config, &project, &working_files);
|
||||||
|
CodeCompleteCache code_complete_cache;
|
||||||
FileConsumer::SharedState file_consumer_shared;
|
FileConsumer::SharedState file_consumer_shared;
|
||||||
|
|
||||||
// Run query db main loop.
|
// Run query db main loop.
|
||||||
SetCurrentThreadName("querydb");
|
SetCurrentThreadName("querydb");
|
||||||
QueryDatabase db;
|
QueryDatabase db;
|
||||||
while (true) {
|
while (true) {
|
||||||
bool did_work = QueryDbMainLoop(config, &db, waiter, &queue_do_index, &queue_do_id_map, &queue_on_id_mapped, &queue_on_indexed, &project, &file_consumer_shared, &working_files, &completion_manager);
|
bool did_work = QueryDbMainLoop(config, &db, waiter, &queue_do_index, &queue_do_id_map, &queue_on_id_mapped, &queue_on_indexed, &project, &file_consumer_shared, &working_files, &completion_manager, &code_complete_cache);
|
||||||
if (!did_work) {
|
if (!did_work) {
|
||||||
IpcManager* ipc = IpcManager::instance();
|
IpcManager* ipc = IpcManager::instance();
|
||||||
waiter->Wait({
|
waiter->Wait({
|
||||||
@ -2416,8 +2444,10 @@ void StdoutMain(std::unordered_map<IpcId, Timer>* request_times, MultiQueueWaite
|
|||||||
case IpcId::Cout: {
|
case IpcId::Cout: {
|
||||||
auto msg = static_cast<Ipc_Cout*>(message.get());
|
auto msg = static_cast<Ipc_Cout*>(message.get());
|
||||||
|
|
||||||
Timer time = (*request_times)[msg->original_ipc_id];
|
if (ShouldDisplayIpcTiming(message->method_id)) {
|
||||||
time.ResetAndPrint("[e2e] Running " + std::string(IpcIdToString(msg->original_ipc_id)));
|
Timer time = (*request_times)[msg->original_ipc_id];
|
||||||
|
time.ResetAndPrint("[e2e] Running " + std::string(IpcIdToString(msg->original_ipc_id)));
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << msg->content;
|
std::cout << msg->content;
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
@ -208,6 +208,21 @@ std::string WorkingFile::FindClosestCallNameInBuffer(lsPosition position, int* a
|
|||||||
return buffer_content.substr(offset, start_offset - offset + 1);
|
return buffer_content.substr(offset, start_offset - offset + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a position which contains the most recent ., ->, :, or ( for code
|
||||||
|
// completion purposes.
|
||||||
|
lsPosition WorkingFile::FindStableCompletionSource(lsPosition position) const {
|
||||||
|
int offset = GetOffsetForPosition(position, buffer_content);
|
||||||
|
|
||||||
|
while (offset > 0) {
|
||||||
|
char c = buffer_content[offset - 1];
|
||||||
|
if (!isalnum(c))
|
||||||
|
break;
|
||||||
|
--offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetPositionForOffset(buffer_content, offset);
|
||||||
|
}
|
||||||
|
|
||||||
CXUnsavedFile WorkingFile::AsUnsavedFile() const {
|
CXUnsavedFile WorkingFile::AsUnsavedFile() const {
|
||||||
CXUnsavedFile result;
|
CXUnsavedFile result;
|
||||||
result.Filename = filename.c_str();
|
result.Filename = filename.c_str();
|
||||||
|
@ -51,6 +51,10 @@ struct WorkingFile {
|
|||||||
// for fetching signatures.
|
// for fetching signatures.
|
||||||
std::string FindClosestCallNameInBuffer(lsPosition position, int* active_parameter, lsPosition* completion_position = nullptr) const;
|
std::string FindClosestCallNameInBuffer(lsPosition position, int* active_parameter, lsPosition* completion_position = nullptr) const;
|
||||||
|
|
||||||
|
// Returns a relatively stable completion position (it jumps back until there
|
||||||
|
// is a non-alphanumeric character).
|
||||||
|
lsPosition FindStableCompletionSource(lsPosition position) const;
|
||||||
|
|
||||||
CXUnsavedFile AsUnsavedFile() const;
|
CXUnsavedFile AsUnsavedFile() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user