Quote only unique completions, use backslashes for ambiguous ones

Commit 29dc307111 (Insert some completions with quotes instead of backslashes,
2024-04-13) breaks some workflows. Given

	touch '[test] file1'
	touch '[test] file2'
	ls tes<Tab>

we insert completions quoted, which is inconvenient when using globs.

This implicit quoting feature is somewhat minor. But quotes look nicer,
so let's try to keep them.  Either way, users can ask for it by starting a
token with «"».

Use quoting only when we insert unique completions.

Closes #11271

(cherry picked from commit 9f79fe17fc)
This commit is contained in:
Johannes Altmanninger
2025-03-13 07:32:37 +01:00
parent ae3532e9ec
commit ffbf957fa3
5 changed files with 31 additions and 7 deletions

View File

@@ -517,7 +517,8 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
next.flags,
faux_cmdline,
&mut tmp_cursor,
false,
/*append_only=*/ false,
/*is_unique=*/ false,
);
// completion_apply_to_command_line will append a space unless COMPLETE_NO_SPACE

View File

@@ -3777,6 +3777,7 @@ fn pager_selection_changed(&mut self) {
&self.cycle_command_line,
&mut cursor_pos,
false,
/*is_unique=*/ false, // don't care
),
};
@@ -4414,6 +4415,7 @@ fn get_autosuggestion_performer(
&search_string,
&mut cursor,
/*append_only=*/ true,
/*is_unique=*/ false,
);
}
result
@@ -5597,6 +5599,7 @@ pub fn completion_apply_to_command_line(
command_line: &wstr,
inout_cursor_pos: &mut usize,
append_only: bool,
is_unique: bool,
) -> WString {
let add_space = !flags.contains(CompleteFlags::NO_SPACE);
let do_replace_token = flags.contains(CompleteFlags::REPLACES_TOKEN);
@@ -5621,7 +5624,7 @@ pub fn completion_apply_to_command_line(
}
let mut escape_flags = EscapeFlags::empty();
if append_only || !add_space {
if append_only || !is_unique || !add_space {
escape_flags.insert(EscapeFlags::NO_QUOTED);
}
if no_tilde {
@@ -5869,7 +5872,12 @@ fn try_insert(&mut self, c: Completion, tok: &wstr, token_range: Range<usize>) {
// If this is a replacement completion, check that we know how to replace it, e.g. that
// the token doesn't contain evil operators like {}.
if !c.flags.contains(CompleteFlags::REPLACES_TOKEN) || reader_can_replace(tok, c.flags) {
self.completion_insert(&c.completion, token_range.end, c.flags);
self.completion_insert(
&c.completion,
token_range.end,
c.flags,
/*is_unique=*/ true,
);
}
}
@@ -6005,7 +6013,12 @@ fn handle_completions(&mut self, token_range: Range<usize>) -> bool {
if prefix_is_partial_completion {
flags |= CompleteFlags::NO_SPACE;
}
self.completion_insert(&common_prefix, token_range.end, flags);
self.completion_insert(
&common_prefix,
token_range.end,
flags,
/*is_unique=*/ false,
);
self.cycle_command_line = self.command_line.text().to_owned();
self.cycle_cursor_pos = self.command_line.position();
}
@@ -6049,7 +6062,13 @@ fn handle_completions(&mut self, token_range: Range<usize>) -> bool {
/// \param token_end the position after the token to complete
/// \param flags A union of all flags describing the completion to insert. See the completion_t
/// struct for more information on possible values.
fn completion_insert(&mut self, val: &wstr, token_end: usize, flags: CompleteFlags) {
fn completion_insert(
&mut self,
val: &wstr,
token_end: usize,
flags: CompleteFlags,
is_unique: bool,
) {
let (elt, el) = self.active_edit_line();
// Move the cursor to the end of the token.
@@ -6065,6 +6084,7 @@ fn completion_insert(&mut self, val: &wstr, token_end: usize, flags: CompleteFla
el.text(),
&mut cursor,
/*append_only=*/ false,
is_unique,
);
self.set_buffer_maintaining_pager(&new_command_line, cursor, false);
}

View File

@@ -160,7 +160,8 @@ macro_rules! unique_completion_applies_as {
completions[0].flags,
cmdline,
&mut cursor,
false,
/*append_only=*/ false,
/*is_unique=*/ true,
);
assert_eq!(newcmdline, L!($applied), "apply result mismatch");
};
@@ -224,6 +225,7 @@ macro_rules! unique_completion_applies_as {
L!("mv debug debug"),
&mut cursor_pos,
true,
/*is_unique=*/ false,
);
assert_eq!(newcmdline, L!("mv debug Debug/"));

View File

@@ -57,6 +57,7 @@ macro_rules! validate {
&line,
&mut cursor_pos,
$append_only,
/*is_unique=*/ false,
);
assert_eq!(result, expected);
assert_eq!(cursor_pos, out_cursor_pos);