mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-21 23:25:07 +00:00
Report index status via $/progress
Add WorkDoneProgress to represent WorkDoneProgressBegin/WorkDoneProgressReport/WorkDoneProgressEnd.
This commit is contained in:
parent
468258d641
commit
5108cfafcb
11
src/lsp.hh
11
src/lsp.hh
@ -219,6 +219,17 @@ struct TextDocumentDidChangeParam {
|
||||
std::vector<TextDocumentContentChangeEvent> contentChanges;
|
||||
};
|
||||
|
||||
struct WorkDoneProgress {
|
||||
const char *kind;
|
||||
std::optional<std::string> title;
|
||||
std::optional<std::string> message;
|
||||
std::optional<double> percentage;
|
||||
};
|
||||
struct WorkDoneProgressParam {
|
||||
const char *token;
|
||||
WorkDoneProgress value;
|
||||
};
|
||||
|
||||
struct WorkspaceFolder {
|
||||
DocumentUri uri;
|
||||
std::string name;
|
||||
|
@ -191,6 +191,8 @@ REFLECT_UNDERLYING_B(SymbolKind);
|
||||
REFLECT_STRUCT(TextDocumentIdentifier, uri);
|
||||
REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
||||
REFLECT_STRUCT(TextEdit, range, newText);
|
||||
REFLECT_STRUCT(WorkDoneProgress, kind, title, message, percentage);
|
||||
REFLECT_STRUCT(WorkDoneProgressParam, token, value);
|
||||
REFLECT_STRUCT(DiagnosticRelatedInformation, location, message);
|
||||
REFLECT_STRUCT(Diagnostic, range, severity, code, source, message,
|
||||
relatedInformation);
|
||||
|
@ -17,14 +17,14 @@ struct Out_cclsInfo {
|
||||
int files, funcs, types, vars;
|
||||
} db;
|
||||
struct Pipeline {
|
||||
int pendingIndexRequests;
|
||||
int64_t lastIdle, completed, enqueued;
|
||||
} pipeline;
|
||||
struct Project {
|
||||
int entries;
|
||||
} project;
|
||||
};
|
||||
REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars);
|
||||
REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests);
|
||||
REFLECT_STRUCT(Out_cclsInfo::Pipeline, lastIdle, completed, enqueued);
|
||||
REFLECT_STRUCT(Out_cclsInfo::Project, entries);
|
||||
REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project);
|
||||
} // namespace
|
||||
@ -35,7 +35,9 @@ void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) {
|
||||
result.db.funcs = db->funcs.size();
|
||||
result.db.types = db->types.size();
|
||||
result.db.vars = db->vars.size();
|
||||
result.pipeline.pendingIndexRequests = pipeline::pending_index_requests;
|
||||
result.pipeline.lastIdle = pipeline::stats.last_idle;
|
||||
result.pipeline.completed = pipeline::stats.completed;
|
||||
result.pipeline.enqueued = pipeline::stats.enqueued;
|
||||
result.project.entries = 0;
|
||||
for (auto &[_, folder] : project->root2folder)
|
||||
result.project.entries += folder.entries.size();
|
||||
|
@ -44,7 +44,7 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) {
|
||||
// pending index request.
|
||||
auto [lang, header] = lookupExtension(path);
|
||||
if ((lang != LanguageId::Unknown && !header) ||
|
||||
!pipeline::pending_index_requests)
|
||||
pipeline::stats.completed == pipeline::stats.enqueued)
|
||||
pipeline::index(path, {}, IndexMode::Normal, false);
|
||||
if (header)
|
||||
project->indexRelated(path);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <llvm/Support/Threading.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <inttypes.h>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <thread>
|
||||
@ -38,6 +39,12 @@ struct PublishDiagnosticParam {
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
};
|
||||
REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics);
|
||||
|
||||
constexpr char index_progress_token[] = "index";
|
||||
struct WorkDoneProgressCreateParam {
|
||||
const char *token = index_progress_token;
|
||||
};
|
||||
REFLECT_STRUCT(WorkDoneProgressCreateParam, token);
|
||||
} // namespace
|
||||
|
||||
void VFS::clear() {
|
||||
@ -67,7 +74,8 @@ void standaloneInitialize(MessageHandler &, const std::string &root);
|
||||
namespace pipeline {
|
||||
|
||||
std::atomic<bool> g_quit;
|
||||
std::atomic<int64_t> loaded_ts{0}, pending_index_requests{0}, request_id{0};
|
||||
std::atomic<int64_t> loaded_ts{0}, request_id{0};
|
||||
IndexStats stats;
|
||||
int64_t tick = 0;
|
||||
|
||||
namespace {
|
||||
@ -195,9 +203,6 @@ bool indexer_Parse(SemaManager *completion, WorkingFiles *wfiles,
|
||||
return false;
|
||||
auto &request = *opt_request;
|
||||
bool loud = request.mode != IndexMode::OnChange;
|
||||
struct RAII {
|
||||
~RAII() { pending_index_requests--; }
|
||||
} raii;
|
||||
|
||||
// Dummy one to trigger refresh semantic highlight.
|
||||
if (request.path.empty()) {
|
||||
@ -207,6 +212,9 @@ bool indexer_Parse(SemaManager *completion, WorkingFiles *wfiles,
|
||||
return false;
|
||||
}
|
||||
|
||||
struct RAII {
|
||||
~RAII() { stats.completed++; }
|
||||
} raii;
|
||||
if (!matcher.matches(request.path)) {
|
||||
LOG_IF_S(INFO, loud) << "skip " << request.path;
|
||||
return false;
|
||||
@ -643,7 +651,9 @@ void mainLoop() {
|
||||
handler.manager = &manager;
|
||||
handler.include_complete = &include_complete;
|
||||
|
||||
bool work_done_created = false, in_progress = false;
|
||||
bool has_indexed = false;
|
||||
int64_t last_completed = 0;
|
||||
std::deque<InMessage> backlog;
|
||||
StringMap<std::deque<InMessage *>> path2backlog;
|
||||
while (true) {
|
||||
@ -693,6 +703,45 @@ void mainLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
int64_t completed = stats.completed.load(std::memory_order_relaxed);
|
||||
if (completed != last_completed) {
|
||||
if (!work_done_created) {
|
||||
WorkDoneProgressCreateParam param;
|
||||
request("window/workDoneProgress/create", param);
|
||||
work_done_created = true;
|
||||
}
|
||||
|
||||
int64_t enqueued = stats.enqueued.load(std::memory_order_relaxed);
|
||||
if (completed != enqueued) {
|
||||
if (!in_progress) {
|
||||
WorkDoneProgressParam param;
|
||||
param.token = index_progress_token;
|
||||
param.value.kind = "begin";
|
||||
param.value.title = "indexing";
|
||||
notify("$/progress", param);
|
||||
in_progress = true;
|
||||
}
|
||||
int64_t last_idle = stats.last_idle.load(std::memory_order_relaxed);
|
||||
WorkDoneProgressParam param;
|
||||
param.token = index_progress_token;
|
||||
param.value.kind = "report";
|
||||
param.value.message =
|
||||
(Twine(completed - last_idle) + "/" + Twine(enqueued - last_idle))
|
||||
.str();
|
||||
param.value.percentage =
|
||||
100.0 * (completed - last_idle) / (enqueued - last_idle);
|
||||
notify("$/progress", param);
|
||||
} else if (in_progress) {
|
||||
stats.last_idle.store(enqueued, std::memory_order_relaxed);
|
||||
WorkDoneProgressParam param;
|
||||
param.token = index_progress_token;
|
||||
param.value.kind = "end";
|
||||
notify("$/progress", param);
|
||||
in_progress = false;
|
||||
}
|
||||
last_completed = completed;
|
||||
}
|
||||
|
||||
if (did_work) {
|
||||
has_indexed |= indexed;
|
||||
if (g_quit.load(std::memory_order_relaxed))
|
||||
@ -736,16 +785,16 @@ void standalone(const std::string &root) {
|
||||
int entries = 0;
|
||||
for (auto &[_, folder] : project.root2folder)
|
||||
entries += folder.entries.size();
|
||||
printf("entries: %5d\n", entries);
|
||||
printf("entries: %4d\n", entries);
|
||||
}
|
||||
while (1) {
|
||||
(void)on_indexed->dequeueAll();
|
||||
int pending = pending_index_requests;
|
||||
int64_t enqueued = stats.enqueued, completed = stats.completed;
|
||||
if (tty) {
|
||||
printf("\rpending: %5d", pending);
|
||||
printf("\rcompleted: %4" PRId64 "/%" PRId64, completed, enqueued);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (!pending)
|
||||
if (completed == enqueued)
|
||||
break;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
@ -756,7 +805,8 @@ void standalone(const std::string &root) {
|
||||
|
||||
void index(const std::string &path, const std::vector<const char *> &args,
|
||||
IndexMode mode, bool must_exist, RequestId id) {
|
||||
pending_index_requests++;
|
||||
if (!path.empty())
|
||||
stats.enqueued++;
|
||||
index_request->pushBack({path, args, mode, must_exist, std::move(id)},
|
||||
mode != IndexMode::Background);
|
||||
}
|
||||
|
@ -39,9 +39,14 @@ enum class IndexMode {
|
||||
Normal,
|
||||
};
|
||||
|
||||
struct IndexStats {
|
||||
std::atomic<int64_t> last_idle, completed, enqueued;
|
||||
};
|
||||
|
||||
namespace pipeline {
|
||||
extern std::atomic<bool> g_quit;
|
||||
extern std::atomic<int64_t> loaded_ts, pending_index_requests;
|
||||
extern std::atomic<int64_t> loaded_ts;
|
||||
extern IndexStats stats;
|
||||
extern int64_t tick;
|
||||
|
||||
void threadEnter();
|
||||
|
Loading…
Reference in New Issue
Block a user