diff --git a/crates/nu-cli/src/completion/engine.rs b/crates/nu-cli/src/completion/engine.rs index eb9a77713..0f4b1b8dc 100644 --- a/crates/nu-cli/src/completion/engine.rs +++ b/crates/nu-cli/src/completion/engine.rs @@ -270,8 +270,13 @@ mod tests { registry: &dyn SignatureRegistry, pos: usize, ) -> Vec { - let lite_block = lite_parse(line, 0).expect("lite_parse"); + let lite_block = match lite_parse(line, 0) { + Ok(v) => v, + Err(e) => e.partial.expect("lite_parse result"), + }; + let block = classify_block(&lite_block, registry); + super::completion_location(line, &block.block, pos) .into_iter() .map(|v| v.item) @@ -338,6 +343,17 @@ mod tests { ); } + #[test] + fn completes_incomplete_nested_structure() { + let registry: VecRegistry = vec![Signature::build("sys")].into(); + let line = "echo $(sy"; + + assert_eq!( + completion_location(line, ®istry, 8), + vec![LocationType::Command], + ); + } + #[test] fn completes_flags_with_just_a_single_hyphen() { let registry: VecRegistry = vec![Signature::build("du") diff --git a/crates/nu-parser/src/lite_parse.rs b/crates/nu-parser/src/lite_parse.rs index 4c7e4c4cb..58145d884 100644 --- a/crates/nu-parser/src/lite_parse.rs +++ b/crates/nu-parser/src/lite_parse.rs @@ -56,12 +56,23 @@ fn skip_whitespace(src: &mut Input) { } } +#[derive(Clone, Copy)] enum BlockKind { Paren, CurlyBracket, SquareBracket, } +impl From for char { + fn from(bk: BlockKind) -> char { + match bk { + BlockKind::Paren => ')', + BlockKind::SquareBracket => ']', + BlockKind::CurlyBracket => '}', + } + } +} + fn bare(src: &mut Input, span_offset: usize) -> ParseResult> { skip_whitespace(src); @@ -114,15 +125,15 @@ fn bare(src: &mut Input, span_offset: usize) -> ParseResult> { ); if let Some(block) = block_level.last() { + let delim: char = (*block).into(); + let cause = nu_errors::ParseError::unexpected_eof(delim.to_string(), span); + + while let Some(bk) = block_level.pop() { + bare.push(bk.into()); + } + return Err(ParseError { - cause: nu_errors::ParseError::unexpected_eof( - match block { - BlockKind::Paren => ")", - BlockKind::SquareBracket => "]", - BlockKind::CurlyBracket => "}", - }, - span, - ), + cause, partial: Some(bare.spanned(span)), }); }