1
0
mirror of https://github.com/nushell/nushell.git synced 2025-04-23 20:58:19 +02:00

fix(completion): quoted cell path completion

This commit is contained in:
blindfs 2025-04-11 08:11:57 +08:00
parent dfca117551
commit 5189e9486c
2 changed files with 48 additions and 9 deletions
crates/nu-cli
src/completions
tests/completions

View File

@ -24,7 +24,10 @@ fn prefix_from_path_member(member: &PathMember, pos: usize) -> (String, Span) {
.get(..pos + 1 - start) .get(..pos + 1 - start)
.map(str::to_string) .map(str::to_string)
.unwrap_or(prefix_str); .unwrap_or(prefix_str);
(prefix_str, Span::new(start, pos + 1)) // strip wrapping quotes
let quotations = ['"', '\'', '`'];
let prefix_str = prefix_str.strip_prefix(quotations).unwrap_or(&prefix_str);
(prefix_str.to_string(), Span::new(start, pos + 1))
} }
impl Completer for CellPathCompletion<'_> { impl Completer for CellPathCompletion<'_> {
@ -108,14 +111,23 @@ fn get_suggestions_by_value(
value: &Value, value: &Value,
current_span: reedline::Span, current_span: reedline::Span,
) -> Vec<SemanticSuggestion> { ) -> Vec<SemanticSuggestion> {
let to_suggestion = |s: String, v: Option<&Value>| SemanticSuggestion { let to_suggestion = |s: String, v: Option<&Value>| {
suggestion: Suggestion { // Check if the string needs quoting (has spaces or punctuation)
value: s, let value = if s.contains(|c: char| c.is_whitespace() || c.is_ascii_punctuation()) {
span: current_span, format!("{:?}", s)
description: v.map(|v| v.get_type().to_string()), } else {
..Suggestion::default() s
}, };
kind: Some(SuggestionKind::CellPath),
SemanticSuggestion {
suggestion: Suggestion {
value,
span: current_span,
description: v.map(|v| v.get_type().to_string()),
..Suggestion::default()
},
kind: Some(SuggestionKind::CellPath),
}
}; };
match value { match value {
Value::Record { val, .. } => val Value::Record { val, .. } => val

View File

@ -2007,6 +2007,33 @@ fn table_cell_path_completions() {
match_suggestions(&expected, &suggestions); match_suggestions(&expected, &suggestions);
} }
#[test]
fn quoted_cell_path_completions() {
let (_, _, mut engine, mut stack) = new_engine();
let command = r#"let foo = {'foo bar':1 'foo\\"bar"': 1 '.': 1 '|': 1}"#;
assert!(support::merge_input(command.as_bytes(), &mut engine, &mut stack).is_ok());
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
let expected: Vec<_> = vec![
"\".\"",
"\"foo bar\"",
"\"foo\\\\\\\\\\\"bar\\\"\"",
"\"|\"",
];
let completion_str = "$foo.";
let suggestions = completer.complete(completion_str, completion_str.len());
match_suggestions(&expected, &suggestions);
let expected: Vec<_> = vec!["\"foo bar\"", "\"foo\\\\\\\\\\\"bar\\\"\""];
let completion_str = "$foo.`foo";
let suggestions = completer.complete(completion_str, completion_str.len());
match_suggestions(&expected, &suggestions);
let completion_str = "$foo.foo";
let suggestions = completer.complete(completion_str, completion_str.len());
match_suggestions(&expected, &suggestions);
}
#[test] #[test]
fn alias_of_command_and_flags() { fn alias_of_command_and_flags() {
let (_, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();