mirror of
https://github.com/nushell/nushell
synced 2024-12-28 05:53:09 +00:00
Add support for subcommand completions (#3571)
* Add support for subcommand completions * Update test * WIP * Fix prepend for completions * Fix test
This commit is contained in:
parent
31a5de973d
commit
7eadbd938d
2 changed files with 50 additions and 10 deletions
|
@ -203,7 +203,8 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
|
|||
} else {
|
||||
let mut command = None;
|
||||
let mut prev = None;
|
||||
for loc in locations {
|
||||
|
||||
for loc in &locations {
|
||||
// We don't use span.contains because we want to include the end. This handles the case
|
||||
// where the cursor is just after the text (i.e., no space between cursor and text)
|
||||
if loc.span.start() <= pos && pos <= loc.span.end() {
|
||||
|
@ -215,14 +216,31 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
|
|||
let cmd = cmd.clone();
|
||||
let span = loc.span;
|
||||
vec![
|
||||
loc,
|
||||
loc.clone(),
|
||||
LocationType::Flag(cmd.unwrap_or_default()).spanned(span),
|
||||
]
|
||||
} else {
|
||||
vec![loc]
|
||||
let mut output = vec![];
|
||||
|
||||
for rloc in locations.iter().rev() {
|
||||
if let Spanned {
|
||||
span,
|
||||
item: LocationType::Command,
|
||||
} = &rloc
|
||||
{
|
||||
output.push(LocationType::Command.spanned(Span::new(
|
||||
span.start(),
|
||||
locations[locations.len() - 1].span.end(),
|
||||
)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output.push(loc.clone());
|
||||
output
|
||||
}
|
||||
}
|
||||
_ => vec![loc],
|
||||
_ => vec![loc.clone()],
|
||||
};
|
||||
} else if pos < loc.span.start() {
|
||||
break;
|
||||
|
@ -236,14 +254,25 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
|
|||
}
|
||||
|
||||
if let Some(prev) = prev {
|
||||
let mut locations = vec![];
|
||||
// Cursor is between locations (or at the end). Look at the line to see if the cursor
|
||||
// is after some character that would imply we're in the command position.
|
||||
let start = prev.span.end();
|
||||
|
||||
if let Spanned {
|
||||
item: LocationType::Command,
|
||||
span,
|
||||
} = &prev
|
||||
{
|
||||
locations.push(LocationType::Command.spanned(Span::new(span.start(), pos)));
|
||||
}
|
||||
if line[start..pos].contains(BEFORE_COMMAND_CHARS) {
|
||||
vec![LocationType::Command.spanned(Span::new(pos, pos))]
|
||||
locations.push(LocationType::Command.spanned(Span::new(pos, pos)));
|
||||
locations
|
||||
} else {
|
||||
// TODO this should be able to be mapped to a command
|
||||
vec![LocationType::Argument(command, None).spanned(Span::new(pos, pos))]
|
||||
locations.push(LocationType::Argument(command, None).spanned(Span::new(pos, pos)));
|
||||
locations
|
||||
}
|
||||
} else {
|
||||
// Cursor is before any possible completion location, so must be a command
|
||||
|
@ -399,7 +428,10 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
completion_location(line, ®istry, 3),
|
||||
vec![LocationType::Argument(Some("cd".to_string()), None)],
|
||||
vec![
|
||||
LocationType::Command,
|
||||
LocationType::Argument(Some("cd".to_string()), None)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -429,7 +461,10 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
completion_location(line, ®istry, 6),
|
||||
vec![LocationType::Argument(Some("echo".to_string()), None)],
|
||||
vec![
|
||||
LocationType::Command,
|
||||
LocationType::Argument(Some("echo".to_string()), None)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::completion::path::{PathCompleter, PathSuggestion};
|
|||
use crate::completion::{self, Completer, Suggestion};
|
||||
use nu_engine::EvaluationContext;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_source::Tag;
|
||||
use nu_source::{Span, Tag};
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
@ -72,6 +72,7 @@ impl NuCompleter {
|
|||
|
||||
LocationType::Argument(cmd, _arg_name) => {
|
||||
let path_completer = PathCompleter;
|
||||
let prepend = Span::new(pos, location.span.start()).slice(line);
|
||||
|
||||
const QUOTE_CHARS: &[char] = &['\'', '"', '`'];
|
||||
|
||||
|
@ -103,7 +104,11 @@ impl NuCompleter {
|
|||
}
|
||||
.into_iter()
|
||||
.map(|s| Suggestion {
|
||||
replacement: requote(s.suggestion.replacement),
|
||||
replacement: format!(
|
||||
"{}{}",
|
||||
prepend,
|
||||
requote(s.suggestion.replacement)
|
||||
),
|
||||
display: s.suggestion.display,
|
||||
})
|
||||
.collect()
|
||||
|
|
Loading…
Reference in a new issue