Skip to content

Commit

Permalink
nixd: support hover
Browse files Browse the repository at this point in the history
  • Loading branch information
inclyc committed May 25, 2023
1 parent c66938c commit 71194e7
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
8 changes: 7 additions & 1 deletion lib/nixd/include/nixd/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

#include "lspserver/Connection.h"
#include "lspserver/DraftStore.h"
#include "lspserver/Function.h"
#include "lspserver/LSPServer.h"
#include "lspserver/Logger.h"
#include "lspserver/Protocol.h"
#include "lspserver/SourceCode.h"
#include "nixd/EvalDraftStore.h"

#include <llvm/ADT/FunctionExtras.h>
#include <llvm/Support/JSON.h>
Expand All @@ -14,7 +16,8 @@ namespace nixd {
/// The server instance, nix-related language features goes here
class Server : public lspserver::LSPServer {

lspserver::DraftStore DraftMgr;
EvalDraftStore DraftMgr;
boost::asio::thread_pool Pool;

std::shared_ptr<const std::string> getDraft(lspserver::PathRef File) const;

Expand All @@ -37,6 +40,7 @@ class Server : public lspserver::LSPServer {
std::unique_ptr<lspserver::OutboundPort> Out)
: LSPServer(std::move(In), std::move(Out)) {
Registry.addMethod("initialize", this, &Server::onInitialize);
Registry.addMethod("textDocument/hover", this, &Server::onHover);
Registry.addNotification("initialized", this, &Server::onInitialized);

// Text Document Synchronization
Expand All @@ -61,6 +65,8 @@ class Server : public lspserver::LSPServer {
void publishStandaloneDiagnostic(lspserver::URIForFile Uri,
std::string Content,
std::optional<int64_t> LSPVersion);
void onHover(const lspserver::TextDocumentPositionParams &,
lspserver::Callback<llvm::json::Value>);
};

}; // namespace nixd
44 changes: 42 additions & 2 deletions lib/nixd/src/Server.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "nixd/Server.h"
#include "lspserver/Logger.h"
#include "nixd/Diagnostic.h"

#include "lspserver/Path.h"
#include "lspserver/Protocol.h"

#include <exception>
#include <llvm/ADT/StringRef.h>
#include <llvm/Support/Error.h>
#include <llvm/Support/JSON.h>
Expand All @@ -13,6 +15,9 @@
#include <nix/store-api.hh>

#include <filesystem>
#include <sstream>
#include <string>
#include <variant>
namespace fs = std::filesystem;
namespace nixd {

Expand All @@ -25,6 +30,7 @@ void Server::onInitialize(const lspserver::InitializeParams &InitializeParams,
{"change", (int)lspserver::TextDocumentSyncKind::Incremental},
{"save", true},
}},
{"hoverProvider", true},
};

llvm::json::Object Result{
Expand Down Expand Up @@ -89,8 +95,8 @@ void Server::publishStandaloneDiagnostic(lspserver::URIForFile Uri,
auto NixState = std::make_unique<nix::EvalState>(nix::Strings{}, NixStore);
try {
fs::path Path = Uri.file().str();
auto *E =
NixState->parseExprFromString(std::move(Content), Path.remove_filename());
auto *E = NixState->parseExprFromString(std::move(Content),
Path.remove_filename());
nix::Value V;
NixState->eval(E, V);
} catch (const nix::Error &PE) {
Expand All @@ -104,4 +110,38 @@ void Server::publishStandaloneDiagnostic(lspserver::URIForFile Uri,
.uri = Uri, .diagnostics = {}, .version = LSPVersion});
}

void Server::onHover(const lspserver::TextDocumentPositionParams &Paras,
lspserver::Callback<llvm::json::Value> Reply) {
std::string HoverFile = Paras.textDocument.uri.file().str();
DraftMgr.withEvaluation(
Pool, {"--file", HoverFile}, "",
[=, Reply = std::move(Reply)](
std::variant<std::exception *,
nix::ref<EvalDraftStore::EvaluationResult>>
EvalResult) mutable {
nix::ref<EvalDraftStore::EvaluationResult> Result =
std::get<1>(EvalResult);
try {
std::get<1>(EvalResult); // w contains int, not float: will throw
} catch (const std::bad_variant_access &) {
std::exception *Excepts = std::get<0>(EvalResult);
lspserver::log(Excepts->what());
}
auto Forest = Result->EvalASTForest;
auto AST = Forest.at(HoverFile);
auto *Node = AST->lookupPosition(Paras.position);
std::stringstream NodeOut;
Node->show(Result->State->symbols, NodeOut);
auto Value = AST->getValue(Node);
std::stringstream Res{};
Value.print(Result->State->symbols, Res);
Reply(lspserver::Hover{
.contents =
{
.value = Res.str(),
},
});
});
}

} // namespace nixd

0 comments on commit 71194e7

Please sign in to comment.