nixd
Loading...
Searching...
No Matches
DocumentLink.cpp
Go to the documentation of this file.
1/// \file
2/// \brief Implementation of [Document Link].
3/// [Document Link]:
4/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentLink
5///
6/// In Nix language, there are a few interesting constructs worth highlighting:
7///
8/// 1. URL literal. Writing URls directly without quotes, supported by vscode.
9/// 2. Path. (Append "default.nix", perhaps)
10/// 3. Search Path <>
11/// FIXME: support search path.
12/// 4. Home Path: (begins with ~)
13/// FIXME: support home path.
14/// 5. Flake Reference
15/// FIXME: support flake ref
16///
17
18#include "CheckReturn.h"
19#include "Convert.h"
20#include "PathResolve.h"
21
23
24#include <boost/asio/post.hpp>
25
26using namespace nixd;
27using namespace lspserver;
28using namespace nixf;
29
30namespace {
31
32void dfs(const Node *N, const std::string &BasePath,
33 std::vector<DocumentLink> &Links, llvm::StringRef Src) {
34 if (!N)
35 return;
36
37 switch (N->kind()) {
38 case Node::NK_ExprPath: {
39 // Resolve the path.
40 const auto &Path = static_cast<const ExprPath &>(*N);
41 if (Path.parts().isLiteral()) {
42 // Provide literal path linking.
43 if (auto Link = resolveExprPath(BasePath, Path.parts().literal())) {
44 Links.emplace_back(
45 DocumentLink{.range = toLSPRange(Src, N->range()),
46 .target = URIForFile::canonicalize(*Link, *Link)});
47 }
48 }
49 return;
50 }
51 default:
52 break;
53 }
54
55 // Traverse on all children
56 for (const Node *Ch : N->children()) {
57 dfs(Ch, BasePath, Links, Src);
58 }
59}
60
61} // namespace
62
63void Controller::onDocumentLink(
64 const DocumentLinkParams &Params,
65 lspserver::Callback<std::vector<DocumentLink>> Reply) {
66 using CheckTy = std::vector<DocumentLink>;
67 auto Action = [File = Params.textDocument.uri.file().str(),
68 Reply = std::move(Reply), this]() mutable {
69 return Reply([&]() -> llvm::Expected<CheckTy> {
70 const auto TU = CheckDefault(getTU(File));
71 const auto AST = CheckDefault(getAST(*TU));
72
73 // Traverse the AST, provide the links
74 std::vector<DocumentLink> Links;
75 dfs(AST.get(), File, Links, TU->src());
76 return Links;
77 }());
78 };
79 boost::asio::post(Pool, std::move(Action));
80}
#define CheckDefault(x)
Variant of CheckReturn, but returns default constructed CheckTy.
Definition CheckReturn.h:16
Convert between LSP and nixf types.
Shared path resolution utilities for Nix path literals.
NodeKind kind() const
Definition Basic.h:34
LexerCursorRange range() const
Definition Basic.h:35
virtual ChildVector children() const =0
Whether current platform treats paths case insensitively.
Definition Connection.h:11
llvm::unique_function< void(llvm::Expected< T >)> Callback
Definition Function.h:14
std::string Path
Definition Path.h:24
std::optional< std::string > resolveExprPath(const std::string &BasePath, const std::string &ExprPath)
Resolve a Nix expression path to a real filesystem path.
Definition PathResolve.h:28
lspserver::Range toLSPRange(llvm::StringRef Code, const nixf::LexerCursorRange &R)
Definition Convert.cpp:40
Parameters for the document link request.
TextDocumentIdentifier textDocument
The document to provide document links for.
static URIForFile canonicalize(llvm::StringRef AbsPath, llvm::StringRef TUPath)
llvm::StringRef file() const
Retrieves absolute path to the file.