From ddd1e56c4dd7d7d91a2b8bda5e3b0fbde9db07ea Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Tue, 16 Apr 2024 02:24:13 +0800 Subject: [PATCH] nixd: basic work-done progress support (#416) --- nixd/include/nixd/Controller/Controller.h | 40 +++++++++++++++++++++ nixd/lib/Controller/LifeTime.cpp | 43 +++++++++++++---------- nixd/lib/Controller/Support.cpp | 21 +++++++++++ 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/nixd/include/nixd/Controller/Controller.h b/nixd/include/nixd/Controller/Controller.h index a11adbc94..3c6f8310f 100644 --- a/nixd/include/nixd/Controller/Controller.h +++ b/nixd/include/nixd/Controller/Controller.h @@ -27,8 +27,48 @@ class Controller : public lspserver::LSPServer { lspserver::DraftStore Store; + lspserver::ClientCapabilities ClientCaps; + llvm::unique_function PublishDiagnostic; + llvm::unique_function)> + CreateWorkDoneProgress; + + void + createWorkDoneProgress(const lspserver::WorkDoneProgressCreateParams &Params); + + llvm::unique_function &)> + BeginWorkDoneProgress; + + void beginWorkDoneProgress( + const lspserver::ProgressParams + &Params) { + if (ClientCaps.WorkDoneProgress) + BeginWorkDoneProgress(Params); + } + + llvm::unique_function &)> + ReportWorkDoneProgress; + + void reportWorkDoneProgress( + const lspserver::ProgressParams + &Params) { + if (ClientCaps.WorkDoneProgress) + ReportWorkDoneProgress(Params); + } + + llvm::unique_function)> + EndWorkDoneProgress; + + void endWorkDoneProgress( + const lspserver::ProgressParams &Params) { + if (ClientCaps.WorkDoneProgress) + EndWorkDoneProgress(Params); + } std::mutex TUsLock; llvm::StringMap> TUs; diff --git a/nixd/lib/Controller/LifeTime.cpp b/nixd/lib/Controller/LifeTime.cpp index 5dd183e09..44f6f177d 100644 --- a/nixd/lib/Controller/LifeTime.cpp +++ b/nixd/lib/Controller/LifeTime.cpp @@ -26,20 +26,6 @@ opt NixpkgsWorkerStderr{ desc("Writable file path for nixpkgs worker stderr (debugging)"), cat(NixdCategory), init("/dev/null")}; -void notifyNixpkgsEval(AttrSetClient &NixpkgsProvider) { - lspserver::log("launched nixd attrs eval for nixpkgs"); - auto Action = [](llvm::Expected Resp) { - if (!Resp) { - lspserver::elog("error on nixpkgs attrs worker eval: {0}", - Resp.takeError()); - return; - } - lspserver::log("evaluated nixpkgs entries"); - }; - // Tell nixpkgs worker to eval - NixpkgsProvider.evalExpr(DefaultNixpkgsExpr, std::move(Action)); -} - void startNixpkgs(std::unique_ptr &NixpkgsEval) { NixpkgsEval = std::make_unique([]() { freopen(NixpkgsWorkerStderr.c_str(), "w", stderr); @@ -129,10 +115,31 @@ void Controller:: Reply(std::move(Result)); - PublishDiagnostic = mkOutNotifiction( - "textDocument/publishDiagnostics"); + ClientCaps = Params.capabilities; startNixpkgs(NixpkgsEval); - if (auto *Provider = nixpkgsEval().client()) - notifyNixpkgsEval(*Provider); + if (nixpkgsClient()) { + auto Token = rand(); + auto Action = [Token, this](llvm::Expected Resp) { + endWorkDoneProgress({ + .token = Token, + .value = WorkDoneProgressEnd{.message = "evaluated nixpkgs entries"}, + }); + if (!Resp) { + lspserver::elog("error on nixpkgs attrs worker eval: {0}", + Resp.takeError()); + return; + } + lspserver::log("evaluated nixpkgs entries"); + }; + createWorkDoneProgress({Token}); + beginWorkDoneProgress({.token = Token, + .value = WorkDoneProgressBegin{ + .title = "evaluating nixipkgs", + .cancellable = false, + .percentage = false, + }}); + // Tell nixpkgs worker to eval + nixpkgsClient()->evalExpr(DefaultNixpkgsExpr, std::move(Action)); + } } diff --git a/nixd/lib/Controller/Support.cpp b/nixd/lib/Controller/Support.cpp index 69e4207e7..746c433f0 100644 --- a/nixd/lib/Controller/Support.cpp +++ b/nixd/lib/Controller/Support.cpp @@ -96,6 +96,15 @@ void Controller::actOnDocumentAdd(PathRef File, Action(); } +void Controller::createWorkDoneProgress( + const lspserver::WorkDoneProgressCreateParams &Params) { + if (ClientCaps.WorkDoneProgress) + CreateWorkDoneProgress(Params, [](llvm::Expected Reply) { + if (!Reply) + elog("create workdone progress error: {0}", Reply.takeError()); + }); +} + Controller::Controller(std::unique_ptr In, std::unique_ptr Out) : LSPServer(std::move(In), std::move(Out)), LitTest(false) { @@ -135,6 +144,18 @@ Controller::Controller(std::unique_ptr In, Registry.addMethod("textDocument/rename", this, &Controller::onRename); Registry.addMethod("textDocument/prepareRename", this, &Controller::onPrepareRename); + + PublishDiagnostic = mkOutNotifiction( + "textDocument/publishDiagnostics"); + CreateWorkDoneProgress = + mkOutMethod( + "window/workDoneProgress/create"); + BeginWorkDoneProgress = + mkOutNotifiction>("$/progress"); + ReportWorkDoneProgress = + mkOutNotifiction>("$/progress"); + EndWorkDoneProgress = + mkOutNotifiction>("$/progress"); } } // namespace nixd