12#include <boost/asio/post.hpp>
14#include <llvm/Support/Error.h>
20using namespace llvm::json;
26class OptionsHoverProvider {
30 OptionsHoverProvider(
AttrSetClient &Client) : Client(Client) {}
31 std::optional<OptionDescription>
33 std::binary_semaphore Ready(0);
34 std::optional<OptionDescription>
Desc;
35 auto OnReply = [&Ready, &
Desc](llvm::Expected<OptionInfoResponse>
Resp) {
39 elog(
"options hover: {0}",
Resp.takeError());
51class NixpkgsHoverProvider {
59 std::ostringstream
OS;
69 OS <<
"[homepage](" << *
Package.Homepage <<
")";
74 OS <<
"## Description"
91 : NixpkgsClient(NixpkgsClient) {}
93 std::optional<std::string>
resolvePackage(std::vector<std::string> Scope,
95 std::binary_semaphore Ready(0);
96 std::optional<AttrPathInfoResponse>
Desc;
97 auto OnReply = [&Ready, &
Desc](llvm::Expected<AttrPathInfoResponse>
Resp) {
101 elog(
"nixpkgs provider: {0}",
Resp.takeError());
104 Scope.emplace_back(std::move(Name));
120 File = std::string(
Params.textDocument.uri.file()),
123 if (std::shared_ptr<nixf::Node> AST = getAST(*
TU,
Reply)) [[
likely]] {
130 std::string Name =
N->name();
135 NixpkgsHoverProvider
NHP(*nixpkgsClient());
137 if (std::optional<std::string>
Doc =
138 NHP.resolvePackage(Scope, Name)) {
142 .
kind = MarkupKind::Markdown,
143 .value = std::move(*
Doc),
151 std::vector<std::string> Scope;
154 std::lock_guard
_(OptionsLock);
155 for (
const auto &[_, Client] : Options) {
157 OptionsHoverProvider
OHP(*
C);
158 std::optional<OptionDescription>
Desc =
OHP.resolveHover(Scope);
163 std::string
TypeDesc =
Desc->Type->Description.value_or(
"");
166 Docs +=
"? (missing type)";
168 if (
Desc->Description) {
169 Docs +=
"\n\n" +
Desc->Description.value_or(
"");
174 .
kind = MarkupKind::Markdown,
175 .value = std::move(
Docs),
190 .
kind = MarkupKind::Markdown,
191 .value =
"`" + Name +
"`",
198 boost::asio::post(Pool, std::move(
Action));
This file declares some common analysis (tree walk) on the AST.
Types used in nixpkgs provider.
Convert between LSP and nixf types.
void optionInfo(const AttrPathInfoParams &Params, lspserver::Callback< OptionInfoResponse > Reply)
void attrpathInfo(const AttrPathInfoParams &Params, lspserver::Callback< AttrPathInfoResponse > Reply)
const Node * descend(PositionRange Range) const
Descendant node that contains the given range.
Whether current platform treats paths case insensitively.
llvm::unique_function< void(llvm::Expected< T >)> Callback
void elog(const char *Fmt, Ts &&...Vals)
bool fromJSON(const llvm::json::Value &Params, Configuration::Diagnostic &R, llvm::json::Path P)
FindAttrPathResult findAttrPath(const nixf::Node &N, const nixf::ParentMapAnalysis &PM, std::vector< std::string > &Path)
Heuristically find attrpath suitable for "attrpath" completion.
bool havePackageScope(const nixf::Node &N, const nixf::VariableLookupAnalysis &VLA, const nixf::ParentMapAnalysis &PM)
Determine whether or not some node has enclosed "with pkgs; [ ]".
lspserver::Range toLSPRange(llvm::StringRef Code, const nixf::LexerCursorRange &R)
std::pair< std::vector< std::string >, std::string > getScopeAndPrefix(const nixf::Node &N, const nixf::ParentMapAnalysis &PM)
get variable scope, and it's prefix name.
MarkupContent contents
The hover's content.