aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd/installables.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r--src/libcmd/installables.cc114
1 files changed, 65 insertions, 49 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 4ffc9af24..8afbbd51a 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -28,6 +28,20 @@
namespace nix {
+static void completeFlakeInputPath(
+ AddCompletions & completions,
+ ref<EvalState> evalState,
+ const std::vector<FlakeRef> & flakeRefs,
+ std::string_view prefix)
+{
+ for (auto & flakeRef : flakeRefs) {
+ auto flake = flake::getFlake(*evalState, flakeRef, true);
+ for (auto & input : flake.inputs)
+ if (input.first.starts_with(prefix))
+ completions.add(input.first);
+ }
+}
+
MixFlakeOptions::MixFlakeOptions()
{
auto category = "Common flake-related options";
@@ -79,8 +93,8 @@ MixFlakeOptions::MixFlakeOptions()
.handler = {[&](std::string s) {
lockFlags.inputUpdates.insert(flake::parseInputPath(s));
}},
- .completer = {[&](size_t, std::string_view prefix) {
- needsFlakeInputCompletion = {std::string(prefix)};
+ .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
+ completeFlakeInputPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix);
}}
});
@@ -95,11 +109,12 @@ MixFlakeOptions::MixFlakeOptions()
flake::parseInputPath(inputPath),
parseFlakeRef(flakeRef, absPath("."), true));
}},
- .completer = {[&](size_t n, std::string_view prefix) {
- if (n == 0)
- needsFlakeInputCompletion = {std::string(prefix)};
- else if (n == 1)
- completeFlakeRef(getEvalState()->store, prefix);
+ .completer = {[&](AddCompletions & completions, size_t n, std::string_view prefix) {
+ if (n == 0) {
+ completeFlakeInputPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix);
+ } else if (n == 1) {
+ completeFlakeRef(completions, getEvalState()->store, prefix);
+ }
}}
});
@@ -146,30 +161,12 @@ MixFlakeOptions::MixFlakeOptions()
}
}
}},
- .completer = {[&](size_t, std::string_view prefix) {
- completeFlakeRef(getEvalState()->store, prefix);
+ .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
+ completeFlakeRef(completions, getEvalState()->store, prefix);
}}
});
}
-void MixFlakeOptions::completeFlakeInput(std::string_view prefix)
-{
- auto evalState = getEvalState();
- for (auto & flakeRefS : getFlakesForCompletion()) {
- auto flakeRef = parseFlakeRefWithFragment(expandTilde(flakeRefS), absPath(".")).first;
- auto flake = flake::getFlake(*evalState, flakeRef, true);
- for (auto & input : flake.inputs)
- if (input.first.starts_with(prefix))
- completions->add(input.first);
- }
-}
-
-void MixFlakeOptions::completionHook()
-{
- if (auto & prefix = needsFlakeInputCompletion)
- completeFlakeInput(*prefix);
-}
-
SourceExprCommand::SourceExprCommand()
{
addFlag({
@@ -227,11 +224,18 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
};
}
-void SourceExprCommand::completeInstallable(std::string_view prefix)
+Args::CompleterClosure SourceExprCommand::getCompleteInstallable()
+{
+ return [this](AddCompletions & completions, size_t, std::string_view prefix) {
+ completeInstallable(completions, prefix);
+ };
+}
+
+void SourceExprCommand::completeInstallable(AddCompletions & completions, std::string_view prefix)
{
try {
if (file) {
- completionType = ctAttrs;
+ completions.setType(AddCompletions::Type::Attrs);
evalSettings.pureEval = false;
auto state = getEvalState();
@@ -266,14 +270,15 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
std::string name = state->symbols[i.name];
if (name.find(searchWord) == 0) {
if (prefix_ == "")
- completions->add(name);
+ completions.add(name);
else
- completions->add(prefix_ + "." + name);
+ completions.add(prefix_ + "." + name);
}
}
}
} else {
completeFlakeRefWithFragment(
+ completions,
getEvalState(),
lockFlags,
getDefaultFlakeAttrPathPrefixes(),
@@ -286,6 +291,7 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
}
void completeFlakeRefWithFragment(
+ AddCompletions & completions,
ref<EvalState> evalState,
flake::LockFlags lockFlags,
Strings attrPathPrefixes,
@@ -297,9 +303,9 @@ void completeFlakeRefWithFragment(
try {
auto hash = prefix.find('#');
if (hash == std::string::npos) {
- completeFlakeRef(evalState->store, prefix);
+ completeFlakeRef(completions, evalState->store, prefix);
} else {
- completionType = ctAttrs;
+ completions.setType(AddCompletions::Type::Attrs);
auto fragment = prefix.substr(hash + 1);
std::string prefixRoot = "";
@@ -342,7 +348,7 @@ void completeFlakeRefWithFragment(
auto attrPath2 = (*attr)->getAttrPath(attr2);
/* Strip the attrpath prefix. */
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
- completions->add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
+ completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
}
}
}
@@ -353,7 +359,7 @@ void completeFlakeRefWithFragment(
for (auto & attrPath : defaultFlakeAttrPaths) {
auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath));
if (!attr) continue;
- completions->add(flakeRefS + "#" + prefixRoot);
+ completions.add(flakeRefS + "#" + prefixRoot);
}
}
}
@@ -362,15 +368,15 @@ void completeFlakeRefWithFragment(
}
}
-void completeFlakeRef(ref<Store> store, std::string_view prefix)
+void completeFlakeRef(AddCompletions & completions, ref<Store> store, std::string_view prefix)
{
if (!experimentalFeatureSettings.isEnabled(Xp::Flakes))
return;
if (prefix == "")
- completions->add(".");
+ completions.add(".");
- completeDir(0, prefix);
+ Args::completeDir(completions, 0, prefix);
/* Look for registry entries that match the prefix. */
for (auto & registry : fetchers::getRegistries(store)) {
@@ -379,10 +385,10 @@ void completeFlakeRef(ref<Store> store, std::string_view prefix)
if (!prefix.starts_with("flake:") && from.starts_with("flake:")) {
std::string from2(from, 6);
if (from2.starts_with(prefix))
- completions->add(from2);
+ completions.add(from2);
} else {
if (from.starts_with(prefix))
- completions->add(from);
+ completions.add(from);
}
}
}
@@ -762,9 +768,7 @@ RawInstallablesCommand::RawInstallablesCommand()
expectArgs({
.label = "installables",
.handler = {&rawInstallables},
- .completer = {[&](size_t, std::string_view prefix) {
- completeInstallable(prefix);
- }}
+ .completer = getCompleteInstallable(),
});
}
@@ -777,6 +781,17 @@ void RawInstallablesCommand::applyDefaultInstallables(std::vector<std::string> &
}
}
+std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
+{
+ applyDefaultInstallables(rawInstallables);
+ std::vector<FlakeRef> res;
+ for (auto i : rawInstallables)
+ res.push_back(parseFlakeRefWithFragment(
+ expandTilde(i),
+ absPath(".")).first);
+ return res;
+}
+
void RawInstallablesCommand::run(ref<Store> store)
{
if (readFromStdIn && !isatty(STDIN_FILENO)) {
@@ -790,10 +805,13 @@ void RawInstallablesCommand::run(ref<Store> store)
run(store, std::move(rawInstallables));
}
-std::vector<std::string> RawInstallablesCommand::getFlakesForCompletion()
+std::vector<FlakeRef> InstallableCommand::getFlakeRefsForCompletion()
{
- applyDefaultInstallables(rawInstallables);
- return rawInstallables;
+ return {
+ parseFlakeRefWithFragment(
+ expandTilde(_installable),
+ absPath(".")).first
+ };
}
void InstallablesCommand::run(ref<Store> store, std::vector<std::string> && rawInstallables)
@@ -809,9 +827,7 @@ InstallableCommand::InstallableCommand()
.label = "installable",
.optional = true,
.handler = {&_installable},
- .completer = {[&](size_t, std::string_view prefix) {
- completeInstallable(prefix);
- }}
+ .completer = getCompleteInstallable(),
});
}