Ensure command name available for Argument completion locations (#2443)

This commit is contained in:
Jason Gedge 2020-08-28 19:50:46 -04:00 committed by GitHub
parent ee71a35786
commit e3c4d82798
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 17 deletions

View File

@ -184,6 +184,7 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
if locations.is_empty() {
vec![LocationType::Command.spanned(Span::unknown())]
} else {
let mut command = None;
let mut prev = None;
for loc in locations {
// We don't use span.contains because we want to include the end. This handles the case
@ -210,6 +211,10 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
break;
}
if let LocationType::Command = loc.item {
command = Some(String::from(loc.span.slice(line)));
}
prev = Some(loc);
}
@ -221,7 +226,7 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
vec![LocationType::Command.spanned(Span::unknown())]
} else {
// TODO this should be able to be mapped to a command
vec![LocationType::Argument(None, None).spanned(Span::unknown())]
vec![LocationType::Argument(command, None).spanned(Span::unknown())]
}
} else {
// Cursor is before any possible completion location, so must be a command
@ -354,6 +359,17 @@ mod tests {
);
}
#[test]
fn has_correct_command_name_for_argument() {
let registry: VecRegistry = vec![Signature::build("cd")].into();
let line = "cd ";
assert_eq!(
completion_location(line, &registry, 3),
vec![LocationType::Argument(Some("cd".to_string()), None)],
);
}
#[test]
fn completes_flags_with_just_a_single_hyphen() {
let registry: VecRegistry = vec![Signature::build("du")

View File

@ -45,14 +45,12 @@ impl NuCompleter {
flag_completer.complete(context, cmd, partial)
}
LocationType::Argument(_cmd, _arg_name) => {
// TODO use cmd and arg_name to narrow things down further
LocationType::Argument(cmd, _arg_name) => {
let path_completer = crate::completion::path::Completer::new();
let completed_paths = path_completer.complete(context, partial);
if &line[..2] == "cd" {
autocomplete_only_folders(completed_paths)
} else {
completed_paths
match cmd.as_deref().unwrap_or("") {
"cd" => select_directory_suggestions(completed_paths),
_ => completed_paths,
}
}
@ -68,16 +66,15 @@ impl NuCompleter {
}
}
fn autocomplete_only_folders(completed_paths: Vec<Suggestion>) -> Vec<Suggestion> {
let mut result = Vec::new();
for path in completed_paths {
let filepath = path.replacement.clone();
let md = metadata(filepath).expect("Expect filepath");
if md.is_dir() {
result.push(path);
}
}
result
fn select_directory_suggestions(completed_paths: Vec<Suggestion>) -> Vec<Suggestion> {
completed_paths
.into_iter()
.filter(|suggestion| {
metadata(&suggestion.replacement)
.map(|md| md.is_dir())
.unwrap_or(false)
})
.collect()
}
fn requote(item: Suggestion) -> Suggestion {