Have lite-parse complete return a complete bare form. (#2389)

Previously, lite parse would stack up opening delimiters in vec, and if we
didn't close everything off, it would simply return an error with a partial form
that didn't include the missing closing delimiters. This commits adds those
delimiters so that `classify_block` can parse correctly.
This commit is contained in:
Jason Gedge 2020-08-21 23:43:40 -04:00 committed by GitHub
parent a951edd0d5
commit eb2ba470c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 9 deletions

View File

@ -270,8 +270,13 @@ mod tests {
registry: &dyn SignatureRegistry,
pos: usize,
) -> Vec<LocationType> {
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, &registry, 8),
vec![LocationType::Command],
);
}
#[test]
fn completes_flags_with_just_a_single_hyphen() {
let registry: VecRegistry = vec![Signature::build("du")

View File

@ -56,12 +56,23 @@ fn skip_whitespace(src: &mut Input) {
}
}
#[derive(Clone, Copy)]
enum BlockKind {
Paren,
CurlyBracket,
SquareBracket,
}
impl From<BlockKind> for char {
fn from(bk: BlockKind) -> char {
match bk {
BlockKind::Paren => ')',
BlockKind::SquareBracket => ']',
BlockKind::CurlyBracket => '}',
}
}
}
fn bare(src: &mut Input, span_offset: usize) -> ParseResult<Spanned<String>> {
skip_whitespace(src);
@ -114,15 +125,15 @@ fn bare(src: &mut Input, span_offset: usize) -> ParseResult<Spanned<String>> {
);
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)),
});
}