From 713d4c44704dd694b37bece89ef70a8854c9c5cb Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Sun, 13 Aug 2023 14:14:58 +0800 Subject: [PATCH 1/2] nixd/Sema: filter item prefix for completion builder Fixes: #110 --- nixd/include/nixd/Sema/CompletionBuilder.h | 6 +++ nixd/lib/Sema/CompletionBuilder.cpp | 53 ++++++++++------------ nixd/lib/Server/EvalWorker.cpp | 6 +++ 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/nixd/include/nixd/Sema/CompletionBuilder.h b/nixd/include/nixd/Sema/CompletionBuilder.h index 55ec1c28a..5d9a54bc8 100644 --- a/nixd/include/nixd/Sema/CompletionBuilder.h +++ b/nixd/include/nixd/Sema/CompletionBuilder.h @@ -5,6 +5,7 @@ #include "lspserver/Protocol.h" +#include #include namespace nixd { @@ -14,6 +15,9 @@ using CompletionResult = lspserver::CompletionList; class CompletionBuilder { CompletionResult Result; size_t Limit = 1000; + std::string Prefix; + + void addItem(lspserver::CompletionItem Item); public: /// { a = 1; b = 2; }.| @@ -44,6 +48,8 @@ class CompletionBuilder { CompletionResult &getResult() { return Result; } void setLimit(size_t Limit) { this->Limit = Limit; } + + void setPrefix(std::string Prefix) { this->Prefix = std::move(Prefix); } }; } // namespace nixd diff --git a/nixd/lib/Sema/CompletionBuilder.cpp b/nixd/lib/Sema/CompletionBuilder.cpp index 63db6e752..8aeb16eb4 100644 --- a/nixd/lib/Sema/CompletionBuilder.cpp +++ b/nixd/lib/Sema/CompletionBuilder.cpp @@ -11,6 +11,18 @@ namespace nixd { using lspserver::CompletionItem; using lspserver::CompletionItemKind; +void CompletionBuilder::addItem(lspserver::CompletionItem Item) { + if (!Item.label.starts_with(Prefix)) + return; + + if (Result.items.size() >= Limit) { + Result.isIncomplete = true; + return; + } + + Result.items.emplace_back(std::move(Item)); +} + void CompletionBuilder::addAttrFields(const EvalAST &AST, const lspserver::Position &Pos, nix::EvalState &State) { @@ -25,16 +37,10 @@ void CompletionBuilder::addAttrFields(const EvalAST &AST, return; for (const auto &Attr : *OpV->attrs) { - CompletionItem R; R.label = State.symbols[Attr.name]; R.kind = CompletionItemKind::Field; - Result.items.emplace_back(std::move(R)); - - if (Result.items.size() > Limit) { - Result.isIncomplete = true; - break; - } + addItem(std::move(R)); } } @@ -42,13 +48,12 @@ void CompletionBuilder::addSymbols(const ParseAST &AST, const nix::Expr *Node) { std::vector Symbols; AST.collectSymbols(Node, Symbols); // Insert symbols to our completion list. - std::transform(Symbols.begin(), Symbols.end(), - std::back_inserter(Result.items), [&](const nix::Symbol &V) { - lspserver::CompletionItem R; - R.kind = CompletionItemKind::Interface; - R.label = AST.symbols()[V]; - return R; - }); + for (const auto &Symbol : Symbols) { + lspserver::CompletionItem R; + R.kind = CompletionItemKind::Interface; + R.label = AST.symbols()[Symbol]; + addItem(std::move(R)); + } } void CompletionBuilder::addLambdaFormals(const EvalAST &AST, @@ -81,7 +86,7 @@ void CompletionBuilder::addLambdaFormals(const EvalAST &AST, CompletionItem R; R.label = State.symbols[Formal.name]; R.kind = CompletionItemKind::Constructor; - Result.items.emplace_back(std::move(R)); + addItem(std::move(R)); } } @@ -95,16 +100,10 @@ void CompletionBuilder::addEnv(nix::EvalState &State, nix::Env &NixEnv) { } if (NixEnv.type == nix::Env::HasWithAttrs) { for (const auto &SomeAttr : *NixEnv.values[0]->attrs) { - std::string Name = State.symbols[SomeAttr.name]; lspserver::CompletionItem R; - R.label = Name; + R.label = State.symbols[SomeAttr.name]; R.kind = lspserver::CompletionItemKind::Variable; - Result.items.emplace_back(std::move(R)); - - if (Result.items.size() > Limit) { - Result.isIncomplete = true; - break; - } + addItem(std::move(R)); } } if (NixEnv.up) @@ -122,14 +121,10 @@ void CompletionBuilder::addEnv(const EvalAST &AST, nix::EvalState &State, void CompletionBuilder::addStaticEnv(const nix::SymbolTable &STable, const nix::StaticEnv &SEnv) { for (auto [Symbol, Displ] : SEnv.vars) { - std::string Name = STable[Symbol]; - if (Name.starts_with("__")) - continue; - CompletionItem R; - R.label = Name; + R.label = STable[Symbol]; R.kind = CompletionItemKind::Constant; - Result.items.emplace_back(std::move(R)); + addItem(std::move(R)); } if (SEnv.up) diff --git a/nixd/lib/Server/EvalWorker.cpp b/nixd/lib/Server/EvalWorker.cpp index 380c9dd34..894074821 100644 --- a/nixd/lib/Server/EvalWorker.cpp +++ b/nixd/lib/Server/EvalWorker.cpp @@ -7,6 +7,7 @@ #include "nixd/Support/String.h" #include "lspserver/LSPServer.h" +#include "nixexpr.hh" #include @@ -171,6 +172,11 @@ void EvalWorker::onCompletion(const lspserver::CompletionParams &Params, Builder.addAttrFields(*AST, Params.position, *State); } else { const auto *Node = AST->lookupContainMin(Params.position); + + if (const auto *EVar = dynamic_cast(Node)) { + Builder.setPrefix(State->symbols[EVar->name]); + } + Builder.addSymbols(*AST, Node); Builder.addLambdaFormals(*AST, *State, Node); Builder.addEnv(*AST, *State, Node); From 21f040885ae241c338ec9b4e14d9ddc1de97d651 Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Sun, 13 Aug 2023 15:22:56 +0800 Subject: [PATCH 2/2] nixd/Sema: address comments in #242 Link: https://github.com/nix-community/nixd/pull/242 --- nixd/lib/Sema/CompletionBuilder.cpp | 7 ++++++- nixd/lib/Server/EvalWorker.cpp | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nixd/lib/Sema/CompletionBuilder.cpp b/nixd/lib/Sema/CompletionBuilder.cpp index 8aeb16eb4..f016a51aa 100644 --- a/nixd/lib/Sema/CompletionBuilder.cpp +++ b/nixd/lib/Sema/CompletionBuilder.cpp @@ -121,8 +121,13 @@ void CompletionBuilder::addEnv(const EvalAST &AST, nix::EvalState &State, void CompletionBuilder::addStaticEnv(const nix::SymbolTable &STable, const nix::StaticEnv &SEnv) { for (auto [Symbol, Displ] : SEnv.vars) { + std::string Name = STable[Symbol]; + + if (Name.starts_with("__")) + continue; + CompletionItem R; - R.label = STable[Symbol]; + R.label = std::move(Name); R.kind = CompletionItemKind::Constant; addItem(std::move(R)); } diff --git a/nixd/lib/Server/EvalWorker.cpp b/nixd/lib/Server/EvalWorker.cpp index 894074821..e7d8eea26 100644 --- a/nixd/lib/Server/EvalWorker.cpp +++ b/nixd/lib/Server/EvalWorker.cpp @@ -7,10 +7,11 @@ #include "nixd/Support/String.h" #include "lspserver/LSPServer.h" -#include "nixexpr.hh" #include +#include + namespace nixd { EvalWorker::EvalWorker(std::unique_ptr In,