From 84af461c1490512b2460f5fe491bd855249d2116 Mon Sep 17 00:00:00 2001 From: ylh Date: Mon, 26 Aug 2024 06:00:37 -0700 Subject: [PATCH] completeFlakeRefWithFragment: handle names with dots --- src/libcmd/installables.cc | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 0fe956ec023b..343cb406cba9 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -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 attrPath; + try { + attrPath = parseAttrPath(*evalState, attrPathS); + } catch (const ParseError&) { + attrPath = parseAttrPath(*evalState, attrPathS + "\""); + incompleteQuote = true; + } std::string lastAttr; + emptyLast: if (!attrPath.empty() && !hasSuffix(attrPathS, ".")) { lastAttr = evalState->symbols[attrPath.back()]; attrPath.pop_back(); + if (incompleteQuote && lastAttr.empty()) { + incompleteQuote = false; + goto emptyLast; + } } 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)); } } }