aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2022-06-20 04:15:38 +0200
committerNaïm Favier <n@monade.li>2022-07-11 15:13:51 +0200
commit711b2e1f48316d80853635408c518e3562a1fa37 (patch)
treedcb298bf9a252344e8e7dd947a5d029e4e6e131d /src/libcmd
parentd6d0e781bbade76f6ea3f310cb36973f4013826d (diff)
Fix flake input completion for `InstallablesCommand`s
Defers completion of flake inputs until the whole command line is parsed so that we know what flakes we need to complete the inputs of. Previously, `nix build flake --update-input <Tab>` always behaved like `nix build . --update-input <Tab>`.
Diffstat (limited to 'src/libcmd')
-rw-r--r--src/libcmd/command.hh4
-rw-r--r--src/libcmd/installables.cc34
2 files changed, 24 insertions, 14 deletions
diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh
index cab379b84..ffa8e784f 100644
--- a/src/libcmd/command.hh
+++ b/src/libcmd/command.hh
@@ -77,12 +77,16 @@ struct MixFlakeOptions : virtual Args, EvalCommand
{
flake::LockFlags lockFlags;
+ std::optional<std::string> needsFlakeInputCompletion = {};
+
MixFlakeOptions();
virtual std::vector<std::string> getFlakesForCompletion()
{ return {}; }
void completeFlakeInput(std::string_view prefix);
+
+ void completionHook() override;
};
struct SourceExprCommand : virtual Args, MixFlakeOptions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 1bcef4172..81c8dd062 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -23,18 +23,6 @@
namespace nix {
-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 (hasPrefix(input.first, prefix))
- completions->add(input.first);
- }
-}
-
MixFlakeOptions::MixFlakeOptions()
{
auto category = "Common flake-related options";
@@ -87,7 +75,7 @@ MixFlakeOptions::MixFlakeOptions()
lockFlags.inputUpdates.insert(flake::parseInputPath(s));
}},
.completer = {[&](size_t, std::string_view prefix) {
- completeFlakeInput(prefix);
+ needsFlakeInputCompletion = {std::string(prefix)};
}}
});
@@ -104,7 +92,7 @@ MixFlakeOptions::MixFlakeOptions()
}},
.completer = {[&](size_t n, std::string_view prefix) {
if (n == 0)
- completeFlakeInput(prefix);
+ needsFlakeInputCompletion = {std::string(prefix)};
else if (n == 1)
completeFlakeRef(getEvalState()->store, prefix);
}}
@@ -137,6 +125,24 @@ MixFlakeOptions::MixFlakeOptions()
});
}
+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 (hasPrefix(input.first, prefix))
+ completions->add(input.first);
+ }
+}
+
+void MixFlakeOptions::completionHook()
+{
+ if (auto & prefix = needsFlakeInputCompletion)
+ completeFlakeInput(*prefix);
+}
+
SourceExprCommand::SourceExprCommand(bool supportReadOnlyMode)
{
addFlag({