Fix completion of nested attributes in completeInstallable

Without this, completing `nix eval -f file.nix foo.<Tab>` suggests `bar`
instead of `foo.bar`, which messes up the command
This commit is contained in:
Naïm Favier 2022-02-19 18:51:18 +01:00
parent 7ddcb39206
commit 5f06a91bf7
No known key found for this signature in database
GPG key ID: 49B07322580B7EE2

View file

@ -187,6 +187,8 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
void SourceExprCommand::completeInstallable(std::string_view prefix) void SourceExprCommand::completeInstallable(std::string_view prefix)
{ {
if (file) { if (file) {
completionType = ctAttrs;
evalSettings.pureEval = false; evalSettings.pureEval = false;
auto state = getEvalState(); auto state = getEvalState();
Expr *e = state->parseExprFromFile( Expr *e = state->parseExprFromFile(
@ -215,13 +217,14 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
Value v2; Value v2;
state->autoCallFunction(*autoArgs, v1, v2); state->autoCallFunction(*autoArgs, v1, v2);
completionType = ctAttrs;
if (v2.type() == nAttrs) { if (v2.type() == nAttrs) {
for (auto & i : *v2.attrs) { for (auto & i : *v2.attrs) {
std::string name = i.name; std::string name = i.name;
if (name.find(searchWord) == 0) { if (name.find(searchWord) == 0) {
completions->add(i.name); if (prefix_ == "")
completions->add(name);
else
completions->add(prefix_ + "." + name);
} }
} }
} }
@ -249,6 +252,8 @@ void completeFlakeRefWithFragment(
if (hash == std::string::npos) { if (hash == std::string::npos) {
completeFlakeRef(evalState->store, prefix); completeFlakeRef(evalState->store, prefix);
} else { } else {
completionType = ctAttrs;
auto fragment = prefix.substr(hash + 1); auto fragment = prefix.substr(hash + 1);
auto flakeRefS = std::string(prefix.substr(0, hash)); auto flakeRefS = std::string(prefix.substr(0, hash));
// FIXME: do tilde expansion. // FIXME: do tilde expansion.
@ -264,8 +269,6 @@ void completeFlakeRefWithFragment(
flake. */ flake. */
attrPathPrefixes.push_back(""); attrPathPrefixes.push_back("");
completionType = ctAttrs;
for (auto & attrPathPrefixS : attrPathPrefixes) { for (auto & attrPathPrefixS : attrPathPrefixes) {
auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS); auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS);
auto attrPathS = attrPathPrefixS + std::string(fragment); auto attrPathS = attrPathPrefixS + std::string(fragment);