feat: notation to refer to no attribute search prefix

An attrPath prefix of "." indicates no need to try default attrPath prefixes. For example 1nixpkgs#legacyPackages.x86_64-linux.ERROR` searches through

```
trying flake output attribute 'packages.x86_64-linux.legacyPackages.x86_64-linux.ERROR'
using cached attrset attribute ''
trying flake output attribute 'legacyPackages.x86_64-linux.legacyPackages.x86_64-linux.ERROR'
using cached attrset attribute 'legacyPackages.x86_64-linux'
trying flake output attribute 'legacyPackages.x86_64-linux.ERROR'
using cached attrset attribute 'legacyPackages.x86_64-linux'
```

And there is no way to specify that one does not want the automatic
search behavior. Now one can specify
`nixpkgs#.legacyPackages.x86_64-linux.ERROR` to only refer to the rooted
attribute path without any default injection of attribute search path or
system.
This commit is contained in:
Tom Bereknyei 2023-08-19 17:03:31 -04:00
parent 10afcf06aa
commit 52248b1c27
2 changed files with 15 additions and 2 deletions

View file

@ -28,6 +28,11 @@ namespace nix {
std::vector<std::string> InstallableFlake::getActualAttrPaths() std::vector<std::string> InstallableFlake::getActualAttrPaths()
{ {
std::vector<std::string> res; std::vector<std::string> res;
if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")){
attrPaths.front().erase(0,1);
res.push_back(attrPaths.front());
return res;
}
for (auto & prefix : prefixes) for (auto & prefix : prefixes)
res.push_back(prefix + *attrPaths.begin()); res.push_back(prefix + *attrPaths.begin());

View file

@ -301,6 +301,11 @@ void completeFlakeRefWithFragment(
completionType = ctAttrs; completionType = ctAttrs;
auto fragment = prefix.substr(hash + 1); auto fragment = prefix.substr(hash + 1);
std::string prefixRoot = "";
if (fragment.starts_with(".")){
fragment = fragment.substr(1);
prefixRoot = ".";
}
auto flakeRefS = std::string(prefix.substr(0, hash)); auto flakeRefS = std::string(prefix.substr(0, hash));
auto flakeRef = parseFlakeRef(expandTilde(flakeRefS), absPath(".")); auto flakeRef = parseFlakeRef(expandTilde(flakeRefS), absPath("."));
@ -309,6 +314,9 @@ void completeFlakeRefWithFragment(
auto root = evalCache->getRoot(); auto root = evalCache->getRoot();
if (prefixRoot == "."){
attrPathPrefixes.clear();
}
/* Complete 'fragment' relative to all the /* Complete 'fragment' relative to all the
attrpath prefixes as well as the root of the attrpath prefixes as well as the root of the
flake. */ flake. */
@ -333,7 +341,7 @@ void completeFlakeRefWithFragment(
auto attrPath2 = (*attr)->getAttrPath(attr2); auto attrPath2 = (*attr)->getAttrPath(attr2);
/* Strip the attrpath prefix. */ /* Strip the attrpath prefix. */
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size()); attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
completions->add(flakeRefS + "#" + concatStringsSep(".", evalState->symbols.resolve(attrPath2))); completions->add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
} }
} }
} }
@ -344,7 +352,7 @@ void completeFlakeRefWithFragment(
for (auto & attrPath : defaultFlakeAttrPaths) { for (auto & attrPath : defaultFlakeAttrPaths) {
auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath)); auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath));
if (!attr) continue; if (!attr) continue;
completions->add(flakeRefS + "#"); completions->add(flakeRefS + "#" + prefixRoot);
} }
} }
} }