Do not treat \: or \= as file completion anchor

Partially reapplies f7dac82ed (Escape separators (colon and equals) to
improve completion, 2019-08-23) which has been reverted.
This commit is contained in:
Johannes Altmanninger 2024-04-19 14:09:58 +02:00
parent a046b73ec7
commit db365b5ef8
2 changed files with 24 additions and 7 deletions

View File

@ -9,7 +9,11 @@ use std::{
time::{Duration, Instant},
};
use crate::{common::charptr2wcstring, util::wcsfilecmp};
use crate::{
common::charptr2wcstring,
reader::{get_quote, is_backslashed},
util::wcsfilecmp,
};
use bitflags::bitflags;
use once_cell::sync::Lazy;
use printf_compat::sprintf;
@ -1522,6 +1526,7 @@ impl<'ctx> Completer<'ctx> {
flags -= ExpandFlags::GEN_DESCRIPTIONS;
}
// Expand words separated by '=' separately, unless '=' is escaped or quoted.
// We have the following cases:
//
// --foo=bar => expand just bar
@ -1529,13 +1534,25 @@ impl<'ctx> Completer<'ctx> {
// foo=bar => expand the whole thing, and also just bar
//
// We also support colon separator (#2178). If there's more than one, prefer the last one.
let sep_index = s.chars().rposition(|c| c == '=' || c == ':');
let sep_index = if get_quote(s, s.len()).is_some() {
None
} else {
let mut end = s.len();
loop {
match s[..end].chars().rposition(|c| c == '=' || c == ':') {
Some(pos) => {
if !is_backslashed(s, pos) {
break Some(pos);
}
end = pos;
}
None => break None,
}
}
};
let complete_from_start = sep_index.is_none() || !string_prefixes_string(L!("-"), s);
if let Some(sep_index) = sep_index {
// FIXME: This just cuts the token,
// so any quoting or braces gets lost.
// See #4954.
let sep_string = s.slice_from(sep_index + 1);
let mut local_completions = Vec::new();
if expand_string(

View File

@ -5043,7 +5043,7 @@ fn try_expand_wildcard(
/// Test if the specified character in the specified string is backslashed. pos may be at the end of
/// the string, which indicates if there is a trailing backslash.
fn is_backslashed(s: &wstr, pos: usize) -> bool {
pub(crate) fn is_backslashed(s: &wstr, pos: usize) -> bool {
// note pos == str.size() is OK.
if pos > s.len() {
return false;
@ -5093,7 +5093,7 @@ fn replace_line_at_cursor(
text[..start].to_owned() + replacement + &text[end..]
}
fn get_quote(cmd_str: &wstr, len: usize) -> Option<char> {
pub(crate) fn get_quote(cmd_str: &wstr, len: usize) -> Option<char> {
let cmd = cmd_str.as_char_slice();
let mut i = 0;
while i < cmd.len() {