Fix completion of --template
This commit is contained in:
parent
ab54031e04
commit
488ff83e6b
|
@ -38,8 +38,6 @@ struct EvalCommand : virtual StoreCommand, MixEvalArgs
|
|||
ref<EvalState> getEvalState();
|
||||
|
||||
std::shared_ptr<EvalState> evalState;
|
||||
|
||||
void completeFlakeRef(std::string_view prefix);
|
||||
};
|
||||
|
||||
struct MixFlakeOptions : virtual Args
|
||||
|
@ -205,4 +203,13 @@ struct MixEnvironment : virtual Args {
|
|||
void setEnviron();
|
||||
};
|
||||
|
||||
void completeFlakeRef(ref<Store> store, std::string_view prefix);
|
||||
|
||||
void completeFlakeRefWithFragment(
|
||||
ref<EvalState> evalState,
|
||||
flake::LockFlags lockFlags,
|
||||
Strings attrPathPrefixes,
|
||||
const Strings & defaultFlakeAttrPaths,
|
||||
std::string_view prefix);
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
.optional = true,
|
||||
.handler = {&flakeUrl},
|
||||
.completer = {[&](size_t, std::string_view prefix) {
|
||||
completeFlakeRef(prefix);
|
||||
completeFlakeRef(getStore(), prefix);
|
||||
}}
|
||||
});
|
||||
}
|
||||
|
@ -500,6 +500,9 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
|||
std::string templateUrl = "templates";
|
||||
Path destDir;
|
||||
|
||||
const Strings attrsPathPrefixes{"templates."};
|
||||
const LockFlags lockFlags{ .writeLockFile = false };
|
||||
|
||||
CmdFlakeInitCommon()
|
||||
{
|
||||
addFlag({
|
||||
|
@ -509,7 +512,12 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
|||
.labels = {"template"},
|
||||
.handler = {&templateUrl},
|
||||
.completer = {[&](size_t, std::string_view prefix) {
|
||||
completeFlakeRef(prefix);
|
||||
completeFlakeRefWithFragment(
|
||||
getEvalState(),
|
||||
lockFlags,
|
||||
attrsPathPrefixes,
|
||||
{"defaultTemplate"},
|
||||
prefix);
|
||||
}}
|
||||
});
|
||||
}
|
||||
|
@ -525,7 +533,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
|||
auto installable = InstallableFlake(
|
||||
evalState, std::move(templateFlakeRef),
|
||||
Strings{templateName == "" ? "defaultTemplate" : templateName},
|
||||
Strings{"templates."}, { .writeLockFile = false });
|
||||
Strings(attrsPathPrefixes), lockFlags);
|
||||
|
||||
auto cursor = installable.getCursor(*evalState, true);
|
||||
|
||||
|
|
|
@ -111,6 +111,21 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
{
|
||||
if (file) return; // FIXME
|
||||
|
||||
completeFlakeRefWithFragment(
|
||||
getEvalState(),
|
||||
lockFlags,
|
||||
getDefaultFlakeAttrPathPrefixes(),
|
||||
getDefaultFlakeAttrPaths(),
|
||||
prefix);
|
||||
}
|
||||
|
||||
void completeFlakeRefWithFragment(
|
||||
ref<EvalState> evalState,
|
||||
flake::LockFlags lockFlags,
|
||||
Strings attrPathPrefixes,
|
||||
const Strings & defaultFlakeAttrPaths,
|
||||
std::string_view prefix)
|
||||
{
|
||||
/* Look for flake output attributes that match the
|
||||
prefix. */
|
||||
try {
|
||||
|
@ -121,10 +136,8 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
// FIXME: do tilde expansion.
|
||||
auto flakeRef = parseFlakeRef(flakeRefS, absPath("."));
|
||||
|
||||
auto state = getEvalState();
|
||||
|
||||
auto evalCache = openEvalCache(*state,
|
||||
std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlags)),
|
||||
auto evalCache = openEvalCache(*evalState,
|
||||
std::make_shared<flake::LockedFlake>(lockFlake(*evalState, flakeRef, lockFlags)),
|
||||
true);
|
||||
|
||||
auto root = evalCache->getRoot();
|
||||
|
@ -132,13 +145,12 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
/* Complete 'fragment' relative to all the
|
||||
attrpath prefixes as well as the root of the
|
||||
flake. */
|
||||
auto attrPathPrefixes = getDefaultFlakeAttrPathPrefixes();
|
||||
attrPathPrefixes.push_back("");
|
||||
|
||||
for (auto & attrPathPrefixS : attrPathPrefixes) {
|
||||
auto attrPathPrefix = parseAttrPath(*state, attrPathPrefixS);
|
||||
auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS);
|
||||
auto attrPathS = attrPathPrefixS + std::string(fragment);
|
||||
auto attrPath = parseAttrPath(*state, attrPathS);
|
||||
auto attrPath = parseAttrPath(*evalState, attrPathS);
|
||||
|
||||
std::string lastAttr;
|
||||
if (!attrPath.empty() && !hasSuffix(attrPathS, ".")) {
|
||||
|
@ -149,8 +161,7 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
auto attr = root->findAlongAttrPath(attrPath);
|
||||
if (!attr) continue;
|
||||
|
||||
auto attrs = attr->getAttrs();
|
||||
for (auto & attr2 : attrs) {
|
||||
for (auto & attr2 : attr->getAttrs()) {
|
||||
if (hasPrefix(attr2, lastAttr)) {
|
||||
auto attrPath2 = attr->getAttrPath(attr2);
|
||||
/* Strip the attrpath prefix. */
|
||||
|
@ -163,8 +174,8 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
/* And add an empty completion for the default
|
||||
attrpaths. */
|
||||
if (fragment.empty()) {
|
||||
for (auto & attrPath : getDefaultFlakeAttrPaths()) {
|
||||
auto attr = root->findAlongAttrPath(parseAttrPath(*state, attrPath));
|
||||
for (auto & attrPath : defaultFlakeAttrPaths) {
|
||||
auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath));
|
||||
if (!attr) continue;
|
||||
completions->insert(flakeRefS + "#");
|
||||
}
|
||||
|
@ -174,7 +185,7 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
warn(e.msg());
|
||||
}
|
||||
|
||||
completeFlakeRef(prefix);
|
||||
completeFlakeRef(evalState->store, prefix);
|
||||
}
|
||||
|
||||
ref<EvalState> EvalCommand::getEvalState()
|
||||
|
@ -184,7 +195,7 @@ ref<EvalState> EvalCommand::getEvalState()
|
|||
return ref<EvalState>(evalState);
|
||||
}
|
||||
|
||||
void EvalCommand::completeFlakeRef(std::string_view prefix)
|
||||
void completeFlakeRef(ref<Store> store, std::string_view prefix)
|
||||
{
|
||||
if (prefix == "")
|
||||
completions->insert(".");
|
||||
|
@ -192,7 +203,7 @@ void EvalCommand::completeFlakeRef(std::string_view prefix)
|
|||
completeDir(0, prefix);
|
||||
|
||||
/* Look for registry entries that match the prefix. */
|
||||
for (auto & registry : fetchers::getRegistries(getStore())) {
|
||||
for (auto & registry : fetchers::getRegistries(store)) {
|
||||
for (auto & entry : registry->entries) {
|
||||
auto from = entry.from.to_string();
|
||||
if (!hasPrefix(prefix, "flake:") && hasPrefix(from, "flake:")) {
|
||||
|
|
Loading…
Reference in a new issue