diff --git a/crates/nu-completion/src/engine.rs b/crates/nu-completion/src/engine.rs index 8f5e648b0..67158548e 100644 --- a/crates/nu-completion/src/engine.rs +++ b/crates/nu-completion/src/engine.rs @@ -238,11 +238,19 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec vec![loc.clone()], + _ => vec![{ + let mut partial_loc = loc.clone(); + partial_loc.span = Span::new(loc.span.start(), pos); + partial_loc + }], }; } else if pos < loc.span.start() { break; @@ -339,7 +347,7 @@ mod tests { line: &str, scope: &dyn ParserScope, pos: usize, - ) -> Vec { + ) -> Vec { let (tokens, _) = lex(line, 0, nu_parser::NewlineMode::Normal); let (lite_block, _) = parse_block(tokens); @@ -348,9 +356,6 @@ mod tests { scope.exit_scope(); super::completion_location(line, &block, pos) - .into_iter() - .map(|v| v.item) - .collect() } #[test] @@ -362,7 +367,7 @@ mod tests { assert_eq!( completion_location(line, ®istry, 10), - vec![LocationType::Command], + vec![LocationType::Command.spanned(Span::new(9, 10)),], ); } @@ -373,7 +378,7 @@ mod tests { assert_eq!( completion_location(line, ®istry, 10), - vec![LocationType::Command], + vec![LocationType::Command.spanned(Span::new(9, 10)),], ); } @@ -384,7 +389,7 @@ mod tests { assert_eq!( completion_location(line, ®istry, 4), - vec![LocationType::Command], + vec![LocationType::Command.spanned(Span::new(0, 4)),], ); } @@ -395,7 +400,7 @@ mod tests { assert_eq!( completion_location(line, ®istry, 13), - vec![LocationType::Variable], + vec![LocationType::Variable.spanned(Span::new(5, 13)),], ); } @@ -410,7 +415,7 @@ mod tests { assert_eq!( completion_location(line, ®istry, 7), - vec![LocationType::Flag("du".to_string())], + vec![LocationType::Flag("du".to_string()).spanned(Span::new(3, 7)),], ); } @@ -421,7 +426,7 @@ mod tests { assert_eq!( completion_location(line, ®istry, 8), - vec![LocationType::Command], + vec![LocationType::Command.spanned(Span::new(6, 8)),], ); } @@ -433,8 +438,8 @@ mod tests { assert_eq!( completion_location(line, ®istry, 3), vec![ - LocationType::Command, - LocationType::Argument(Some("cd".to_string()), None) + LocationType::Command.spanned(Span::new(0, 3)), + LocationType::Argument(Some("cd".to_string()), None).spanned(Span::new(3, 3)), ], ); } @@ -451,8 +456,8 @@ mod tests { assert_eq!( completion_location(line, ®istry, 3), vec![ - LocationType::Argument(Some("du".to_string()), None), - LocationType::Flag("du".to_string()), + LocationType::Argument(Some("du".to_string()), None).spanned(Span::new(3, 4)), + LocationType::Flag("du".to_string()).spanned(Span::new(3, 4)), ], ); } @@ -467,8 +472,24 @@ mod tests { assert_eq!( completion_location(line, ®istry, 6), vec![ - LocationType::Command, - LocationType::Argument(Some("echo".to_string()), None) + LocationType::Command.spanned(Span::new(0, 6)), + LocationType::Argument(Some("echo".to_string()), None).spanned(Span::new(5, 6)), + ], + ); + } + + #[test] + fn completes_argument_when_cursor_inside_argument() { + let registry: VecRegistry = + vec![Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")] + .into(); + let line = "echo 123"; + + assert_eq!( + completion_location(line, ®istry, 6), + vec![ + LocationType::Command.spanned(Span::new(0, 6)), + LocationType::Argument(Some("echo".to_string()), None).spanned(Span::new(5, 6)), ], ); }