completeFlakeRefWithFragment: handle names with dots

This commit is contained in:
ylh 2024-08-26 06:00:37 -07:00
parent a30eb6de1b
commit 6fbd189ae1
2 changed files with 37 additions and 5 deletions

View File

@ -359,13 +359,28 @@ void completeFlakeRefWithFragment(
for (auto & attrPathPrefixS : attrPathPrefixes) {
auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS);
auto attrPathS = attrPathPrefixS + std::string(fragment);
auto attrPath = parseAttrPath(*evalState, attrPathS);
// we receive backslashes as typed; left alone, they get into attr names.
auto fragmentUnshell = replaceStrings(std::string(fragment), "\\\"", "\"");
auto attrPathS = attrPathPrefixS + fragmentUnshell;
auto incompleteQuote = false;
std::vector<Symbol> attrPath;
try {
attrPath = parseAttrPath(*evalState, attrPathS);
} catch (const ParseError&) {
attrPath = parseAttrPath(*evalState, attrPathS + "\"");
incompleteQuote = true;
}
std::string lastAttr;
if (!attrPath.empty() && !hasSuffix(attrPathS, ".")) {
while (!attrPath.empty() && !hasSuffix(attrPathS, ".")) {
lastAttr = evalState->symbols[attrPath.back()];
attrPath.pop_back();
if (incompleteQuote && lastAttr.empty()) {
incompleteQuote = false;
continue;
}
break;
}
auto attr = root->findAlongAttrPath(attrPath);
@ -376,8 +391,13 @@ void completeFlakeRefWithFragment(
auto attrPath2 = (*attr)->getAttrPath(attr2);
/* Strip the attrpath prefix. */
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
// FIXME: handle names with dots
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
Strings escs;
for (auto sym : evalState->symbols.resolve(attrPath2)) {
std::stringstream ss;
ss << sym;
escs.push_back(replaceStrings(ss.str(), "\"", "\\\""));
}
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", escs));
}
}
}

View File

@ -34,6 +34,16 @@ mkdir -p err
cat <<EOF > err/flake.nix
throw "error"
EOF
mkdir -p hasdots
cat <<EOF > hasdots/flake.nix
{
outputs = i: {
"sample.dotted.output" = {
subAttr = 1;
};
};
}
EOF
# Test the completion of a subcommand
[[ "$(NIX_GET_COMPLETIONS=1 nix buil)" == $'normal\nbuild\t' ]]
@ -73,3 +83,5 @@ NIX_GET_COMPLETIONS=3 nix build --option allow-import-from | grep -- "allow-impo
[[ "$(NIX_GET_COMPLETIONS=4 nix eval --file ./foo/flake.nix outp)" == $'attrs\noutputs\t' ]]
[[ "$(NIX_GET_COMPLETIONS=4 nix eval --file ./err/flake.nix outp 2>&1)" == $'attrs' ]]
[[ "$(NIX_GET_COMPLETIONS=2 nix eval ./err\# 2>&1)" == $'attrs' ]]
[[ "$(NIX_GET_COMPLETIONS=2 nix eval './hasdots#s')" == $'attrs\n./hasdots#\\"sample.dotted.output\\"\t' ]]
[[ "$(NIX_GET_COMPLETIONS=2 nix eval './hasdots#\"sample.dotted.output\".s')" == $'attrs\n./hasdots#\\"sample.dotted.output\\".subAttr\t' ]]