Merge pull request #7134 from yorickvP/disable-dbg-on-complete

Temporarily disable the debugger during completion evaluation
This commit is contained in:
Théophane Hufschmitt 2022-11-16 11:28:40 +01:00 committed by GitHub
commit 62960f3291
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 40 deletions

View file

@ -207,55 +207,59 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
void SourceExprCommand::completeInstallable(std::string_view prefix) void SourceExprCommand::completeInstallable(std::string_view prefix)
{ {
if (file) { try {
completionType = ctAttrs; if (file) {
completionType = ctAttrs;
evalSettings.pureEval = false; evalSettings.pureEval = false;
auto state = getEvalState(); auto state = getEvalState();
Expr *e = state->parseExprFromFile( Expr *e = state->parseExprFromFile(
resolveExprPath(state->checkSourcePath(lookupFileArg(*state, *file))) resolveExprPath(state->checkSourcePath(lookupFileArg(*state, *file)))
); );
Value root; Value root;
state->eval(e, root); state->eval(e, root);
auto autoArgs = getAutoArgs(*state); auto autoArgs = getAutoArgs(*state);
std::string prefix_ = std::string(prefix); std::string prefix_ = std::string(prefix);
auto sep = prefix_.rfind('.'); auto sep = prefix_.rfind('.');
std::string searchWord; std::string searchWord;
if (sep != std::string::npos) { if (sep != std::string::npos) {
searchWord = prefix_.substr(sep + 1, std::string::npos); searchWord = prefix_.substr(sep + 1, std::string::npos);
prefix_ = prefix_.substr(0, sep); prefix_ = prefix_.substr(0, sep);
} else { } else {
searchWord = prefix_; searchWord = prefix_;
prefix_ = ""; prefix_ = "";
} }
auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root); auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root);
Value &v1(*v); Value &v1(*v);
state->forceValue(v1, pos); state->forceValue(v1, pos);
Value v2; Value v2;
state->autoCallFunction(*autoArgs, v1, v2); state->autoCallFunction(*autoArgs, v1, v2);
if (v2.type() == nAttrs) { if (v2.type() == nAttrs) {
for (auto & i : *v2.attrs) { for (auto & i : *v2.attrs) {
std::string name = state->symbols[i.name]; std::string name = state->symbols[i.name];
if (name.find(searchWord) == 0) { if (name.find(searchWord) == 0) {
if (prefix_ == "") if (prefix_ == "")
completions->add(name); completions->add(name);
else else
completions->add(prefix_ + "." + name); completions->add(prefix_ + "." + name);
}
} }
} }
} else {
completeFlakeRefWithFragment(
getEvalState(),
lockFlags,
getDefaultFlakeAttrPathPrefixes(),
getDefaultFlakeAttrPaths(),
prefix);
} }
} else { } catch (EvalError&) {
completeFlakeRefWithFragment( // Don't want eval errors to mess-up with the completion engine, so let's just swallow them
getEvalState(),
lockFlags,
getDefaultFlakeAttrPathPrefixes(),
getDefaultFlakeAttrPaths(),
prefix);
} }
} }

View file

@ -384,6 +384,10 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
i++; i++;
} }
} else { } else {
/* Temporarily disable the debugger, to avoid re-entering readline. */
auto debug_repl = state->debugRepl;
state->debugRepl = nullptr;
Finally restoreDebug([&]() { state->debugRepl = debug_repl; });
try { try {
/* This is an expression that should evaluate to an /* This is an expression that should evaluate to an
attribute set. Evaluate it to get the names of the attribute set. Evaluate it to get the names of the

View file

@ -28,6 +28,10 @@ cat <<EOF > bar/flake.nix
}; };
} }
EOF EOF
mkdir -p err
cat <<EOF > err/flake.nix
throw "error"
EOF
# Test the completion of a subcommand # Test the completion of a subcommand
[[ "$(NIX_GET_COMPLETIONS=1 nix buil)" == $'normal\nbuild\t' ]] [[ "$(NIX_GET_COMPLETIONS=1 nix buil)" == $'normal\nbuild\t' ]]
@ -60,3 +64,5 @@ NIX_GET_COMPLETIONS=3 nix build --option allow-import-from | grep -- "allow-impo
# Attr path completions # Attr path completions
[[ "$(NIX_GET_COMPLETIONS=2 nix eval ./foo\#sam)" == $'attrs\n./foo#sampleOutput\t' ]] [[ "$(NIX_GET_COMPLETIONS=2 nix eval ./foo\#sam)" == $'attrs\n./foo#sampleOutput\t' ]]
[[ "$(NIX_GET_COMPLETIONS=4 nix eval --file ./foo/flake.nix outp)" == $'attrs\noutputs\t' ]] [[ "$(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' ]]