Complete flake inputs for all given flakes

Allow `nix build flake1 flake2 --update-input <Tab>` to complete the
inputs of both flakes.

Also do tilde expansion so that `nix build ~/flake --update-input <Tab>`
works.
This commit is contained in:
Naïm Favier 2022-06-19 17:54:27 +02:00
parent 7e301fd74e
commit d6d0e781bb
No known key found for this signature in database
GPG key ID: 95AFCE8211908325
3 changed files with 24 additions and 24 deletions

View file

@ -79,8 +79,10 @@ struct MixFlakeOptions : virtual Args, EvalCommand
MixFlakeOptions(); MixFlakeOptions();
virtual std::optional<FlakeRef> getFlakeRefForCompletion() virtual std::vector<std::string> getFlakesForCompletion()
{ return {}; } { return {}; }
void completeFlakeInput(std::string_view prefix);
}; };
struct SourceExprCommand : virtual Args, MixFlakeOptions struct SourceExprCommand : virtual Args, MixFlakeOptions
@ -119,7 +121,7 @@ struct InstallablesCommand : virtual Args, SourceExprCommand
virtual bool useDefaultInstallables() { return true; } virtual bool useDefaultInstallables() { return true; }
std::optional<FlakeRef> getFlakeRefForCompletion() override; std::vector<std::string> getFlakesForCompletion() override;
private: private:
@ -135,9 +137,9 @@ struct InstallableCommand : virtual Args, SourceExprCommand
void prepare() override; void prepare() override;
std::optional<FlakeRef> getFlakeRefForCompletion() override std::vector<std::string> getFlakesForCompletion() override
{ {
return parseFlakeRefWithFragment(_installable, absPath(".")).first; return {_installable};
} }
private: private:

View file

@ -23,16 +23,17 @@
namespace nix { namespace nix {
void completeFlakeInputPath( void MixFlakeOptions::completeFlakeInput(std::string_view prefix)
ref<EvalState> evalState,
const FlakeRef & flakeRef,
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); auto flake = flake::getFlake(*evalState, flakeRef, true);
for (auto & input : flake.inputs) for (auto & input : flake.inputs)
if (hasPrefix(input.first, prefix)) if (hasPrefix(input.first, prefix))
completions->add(input.first); completions->add(input.first);
} }
}
MixFlakeOptions::MixFlakeOptions() MixFlakeOptions::MixFlakeOptions()
{ {
@ -86,8 +87,7 @@ MixFlakeOptions::MixFlakeOptions()
lockFlags.inputUpdates.insert(flake::parseInputPath(s)); lockFlags.inputUpdates.insert(flake::parseInputPath(s));
}}, }},
.completer = {[&](size_t, std::string_view prefix) { .completer = {[&](size_t, std::string_view prefix) {
if (auto flakeRef = getFlakeRefForCompletion()) completeFlakeInput(prefix);
completeFlakeInputPath(getEvalState(), *flakeRef, prefix);
}} }}
}); });
@ -103,12 +103,10 @@ MixFlakeOptions::MixFlakeOptions()
parseFlakeRef(flakeRef, absPath("."), true)); parseFlakeRef(flakeRef, absPath("."), true));
}}, }},
.completer = {[&](size_t n, std::string_view prefix) { .completer = {[&](size_t n, std::string_view prefix) {
if (n == 0) { if (n == 0)
if (auto flakeRef = getFlakeRefForCompletion()) completeFlakeInput(prefix);
completeFlakeInputPath(getEvalState(), *flakeRef, prefix); else if (n == 1)
} else if (n == 1) {
completeFlakeRef(getEvalState()->store, prefix); completeFlakeRef(getEvalState()->store, prefix);
}
}} }}
}); });
@ -1043,14 +1041,14 @@ void InstallablesCommand::prepare()
installables = parseInstallables(getStore(), _installables); installables = parseInstallables(getStore(), _installables);
} }
std::optional<FlakeRef> InstallablesCommand::getFlakeRefForCompletion() std::vector<std::string> InstallablesCommand::getFlakesForCompletion()
{ {
if (_installables.empty()) { if (_installables.empty()) {
if (useDefaultInstallables()) if (useDefaultInstallables())
return parseFlakeRefWithFragment(".", absPath(".")).first; return {"."};
return {}; return {};
} }
return parseFlakeRefWithFragment(_installables.front(), absPath(".")).first; return _installables;
} }
InstallableCommand::InstallableCommand(bool supportReadOnlyMode) InstallableCommand::InstallableCommand(bool supportReadOnlyMode)

View file

@ -50,9 +50,9 @@ public:
return flake::lockFlake(*getEvalState(), getFlakeRef(), lockFlags); return flake::lockFlake(*getEvalState(), getFlakeRef(), lockFlags);
} }
std::optional<FlakeRef> getFlakeRefForCompletion() override std::vector<std::string> getFlakesForCompletion() override
{ {
return getFlakeRef(); return {flakeUrl};
} }
}; };