Fix completion failing on unclosed brace with wildcard

Completion on ": {*," used to work but nowadays our attempt to wildcard-expand
it fails with a syntax error and we do nothing.  This behavior probably only
makes sense for the overflow case, so do that.
This commit is contained in:
Johannes Altmanninger
2024-10-19 12:26:44 +02:00
parent f4ff312265
commit cd541575b4
8 changed files with 57 additions and 35 deletions

View File

@@ -151,8 +151,10 @@ fn write_part(
)
.result
{
ExpandResultCode::error | ExpandResultCode::wildcard_no_match => {
// Hit expansion limit, forward the unexpanded string.
ExpandResultCode::error
| ExpandResultCode::overflow
| ExpandResultCode::wildcard_no_match => {
// Maybe hit expansion limit, forward the unexpanded string.
args.push(Completion::from_completion(token_text.to_owned()));
}
ExpandResultCode::cancel => {

View File

@@ -1566,16 +1566,17 @@ fn complete_param_expand(
if let Some(sep_index) = sep_index {
let sep_string = s.slice_from(sep_index + 1);
let mut local_completions = Vec::new();
if expand_string(
sep_string.to_owned(),
&mut local_completions,
flags,
self.ctx,
None,
)
.result
== ExpandResultCode::error
{
if matches!(
expand_string(
sep_string.to_owned(),
&mut local_completions,
flags,
self.ctx,
None,
)
.result,
ExpandResultCode::error | ExpandResultCode::overflow
) {
FLOGF!(complete, "Error while expanding string '%ls'", sep_string);
}
@@ -1606,9 +1607,11 @@ fn complete_param_expand(
}
let first = self.completions.len();
if expand_to_receiver(s.to_owned(), &mut self.completions, flags, self.ctx, None).result
== ExpandResultCode::error
{
if matches!(
expand_to_receiver(s.to_owned(), &mut self.completions, flags, self.ctx, None)
.result,
ExpandResultCode::error | ExpandResultCode::overflow,
) {
FLOGF!(complete, "Error while expanding string '%ls'", s);
}
Self::escape_opening_brackets(&mut self.completions[first..], s);

View File

@@ -1275,14 +1275,20 @@ fn expand_string(
}
let this_result = (stage)(&mut expand, comp.completion, &mut output_storage);
total_result = this_result;
if total_result == ExpandResultCode::error {
if matches!(
total_result.result,
ExpandResultCode::error | ExpandResultCode::overflow
) {
break;
}
}
// Output becomes our next stage's input.
completions = output_storage.take();
if total_result == ExpandResultCode::error {
if matches!(
total_result.result,
ExpandResultCode::error | ExpandResultCode::overflow
) {
break;
}
}
@@ -1487,7 +1493,7 @@ fn stage_wildcards(
let mut expanded = expanded_recv.take();
expanded.sort_by(|a, b| wcsfilecmp_glob(&a.completion, &b.completion));
if !out.extend(expanded) {
result = ExpandResult::new(ExpandResultCode::error);
result = ExpandResult::new(ExpandResultCode::overflow);
}
} else {
// Can't fully justify this check. I think it's that SKIP_WILDCARDS is used when completing
@@ -1558,6 +1564,8 @@ fn unexpand_tildes(&self, input: &wstr, completions: &mut CompletionList) {
pub enum ExpandResultCode {
/// There was an error, for example, unmatched braces.
error,
/// Expansion would exceed the maximum number of elements.
overflow,
/// Expansion succeeded.
ok,
/// Expansion was cancelled (e.g. control-C).

View File

@@ -498,7 +498,7 @@ fn expand_command(
false,
);
match expand_err.result {
ExpandResultCode::error => {
ExpandResultCode::error | ExpandResultCode::overflow => {
// Issue #5812 - the expansions were done on the command token,
// excluding prefixes such as " " or "if ".
// This means that the error positions are relative to the beginning
@@ -630,7 +630,7 @@ fn apply_variable_assignments(
variable_assignment.range().unwrap().start() + equals_pos + 1,
);
match expand_ret.result {
ExpandResultCode::error => {
ExpandResultCode::error|ExpandResultCode::overflow => {
return self.report_errors(ctx, expand_ret.status, &errors);
}
ExpandResultCode::cancel => {
@@ -1103,7 +1103,7 @@ fn run_switch_statement(
parse_error_offset_source_start(&mut errors, statement.argument.range().unwrap().start());
match expand_ret.result {
ExpandResultCode::error => {
ExpandResultCode::error | ExpandResultCode::overflow => {
return self.report_errors(ctx, expand_ret.status, &errors);
}
ExpandResultCode::cancel => {
@@ -1386,7 +1386,7 @@ fn expand_arguments_from_nodes(
);
parse_error_offset_source_start(&mut errors, arg_node.range().unwrap().start());
match expand_ret.result {
ExpandResultCode::error => {
ExpandResultCode::error | ExpandResultCode::overflow => {
return self.report_errors(ctx, expand_ret.status, &errors);
}
ExpandResultCode::cancel => {

View File

@@ -1669,15 +1669,18 @@ fn detect_errors_in_decorated_statement(
// Make a new error list so we can fix the offset for just those, then append later.
let mut new_errors = ParseErrorList::new();
let mut command = WString::new();
if expand_to_command_and_args(
unexp_command,
&OperationContext::empty(),
&mut command,
None,
Some(&mut new_errors),
true, /* skip wildcards */
) == ExpandResultCode::error
{
if matches!(
expand_to_command_and_args(
unexp_command,
&OperationContext::empty(),
&mut command,
None,
Some(&mut new_errors),
true, /* skip wildcards */
)
.result,
ExpandResultCode::error | ExpandResultCode::overflow
) {
errored = true;
}

View File

@@ -652,9 +652,10 @@ pub fn expand_argument_list(
let list = ast.top().as_freestanding_argument_list().unwrap();
for arg in &list.arguments {
let arg_src = arg.source(arg_list_src);
if expand_string(arg_src.to_owned(), &mut result, flags, ctx, None)
== ExpandResultCode::error
{
if matches!(
expand_string(arg_src.to_owned(), &mut result, flags, ctx, None).result,
ExpandResultCode::error | ExpandResultCode::overflow
) {
break; // failed to expand a string
}
}

View File

@@ -5648,7 +5648,8 @@ fn compute_and_apply_completions(&mut self, c: ReadlineCmd) {
position_in_token,
&mut wc_expanded,
) {
ExpandResultCode::error => {
ExpandResultCode::error => {}
ExpandResultCode::overflow => {
// This may come about if we exceeded the max number of matches.
// Return "success" to suppress normal completions.
self.flash();

View File

@@ -112,3 +112,7 @@ tmux-sleep
isolated-tmux send-keys C-s C-s C-s 'x'
isolated-tmux capture-pane -p
# CHECK: prompt 10> echo do not accept thix
isolated-tmux send-keys C-u C-l ': {*,' Tab Tab Space ,
tmux-sleep
isolated-tmux capture-pane -p
# CHECK: prompt 10> : {*,cmake/ ,{{.*}}