From e640a01ea5a1789e8ea69110e93073dabd786622 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 22 Jan 2020 11:58:10 -0800 Subject: [PATCH] Express cancellation as a possible result of expand_string This allows us to properly thread control-C signals from command substitutions into the expanding string. --- src/complete.cpp | 3 +++ src/expand.cpp | 6 +++++- src/expand.h | 2 ++ src/parse_execution.cpp | 9 +++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/complete.cpp b/src/complete.cpp index 67d1522d2..088c0ec47 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -680,6 +680,9 @@ void completer_t::complete_cmd(const wcstring &str_cmd) { this->expand_flags() | expand_flag::special_for_command | expand_flag::for_completions | expand_flag::executables_only, ctx); + if (result == expand_result_t::cancel) { + return; + } if (result != expand_result_t::error && this->wants_descriptions()) { this->complete_cmd_desc(str_cmd); } diff --git a/src/expand.cpp b/src/expand.cpp index 3cb203e6e..990295037 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -1012,7 +1012,7 @@ expand_result_t expander_t::stage_wildcards(wcstring path_to_expand, completion_ case wildcard_expand_result_t::no_match: break; case wildcard_expand_result_t::cancel: - result = expand_result_t::error; + result = expand_result_t::cancel; break; } } @@ -1055,6 +1055,10 @@ expand_result_t expander_t::expand_string(wcstring input, completion_list_t *out expand_result_t total_result = expand_result_t::ok; for (stage_t stage : stages) { for (completion_t &comp : completions) { + if (ctx.check_cancel()) { + total_result = expand_result_t::cancel; + break; + } expand_result_t this_result = (expand.*stage)(std::move(comp.completion), &output_storage); total_result = this_result; diff --git a/src/expand.h b/src/expand.h index 5b396c711..8aa2915cc 100644 --- a/src/expand.h +++ b/src/expand.h @@ -105,6 +105,8 @@ enum class expand_result_t { error, /// Expansion succeeded. ok, + /// Expansion was cancelled (e.g. control-C). + cancel, /// Expansion succeeded, but a wildcard in the string matched no files, /// so the output is empty. wildcard_no_match, diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 5f0de0765..f60d9d61f 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -465,6 +465,9 @@ eval_result_t parse_execution_context_t::run_switch_statement( case expand_result_t::error: return report_errors(errors); + case expand_result_t::cancel: + return eval_result_t::cancelled; + case expand_result_t::wildcard_no_match: return report_unmatched_wildcard_error(switch_value_n); @@ -874,6 +877,9 @@ eval_result_t parse_execution_context_t::expand_arguments_from_nodes( case expand_result_t::error: { return this->report_errors(errors); } + case expand_result_t::cancel: { + return eval_result_t::cancelled; + } case expand_result_t::wildcard_no_match: { if (glob_behavior == failglob) { // Report the unmatched wildcard error and stop processing. @@ -1023,6 +1029,9 @@ eval_result_t parse_execution_context_t::apply_variable_assignments( this->report_errors(errors); return eval_result_t::error; } + case expand_result_t::cancel: { + return eval_result_t::cancelled; + } case expand_result_t::wildcard_no_match: // nullglob (equivalent to set) case expand_result_t::ok: { break;