default to file completion after first command, add command option for completions (#6257)

* remove unnecessary FlatShape

* add test
This commit is contained in:
pwygab 2022-08-25 03:46:00 +08:00 committed by GitHub
parent 5ebfa10495
commit e45b169cba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 3 deletions

View File

@ -11,6 +11,7 @@ pub struct CommandCompletion {
engine_state: Arc<EngineState>,
flattened: Vec<(Span, FlatShape)>,
flat_shape: FlatShape,
force_completion_after_space: bool,
}
impl CommandCompletion {
@ -19,11 +20,13 @@ impl CommandCompletion {
_: &StateWorkingSet,
flattened: Vec<(Span, FlatShape)>,
flat_shape: FlatShape,
force_completion_after_space: bool,
) -> Self {
Self {
engine_state,
flattened,
flat_shape,
force_completion_after_space,
}
}
@ -81,9 +84,6 @@ impl CommandCompletion {
match_algorithm: MatchAlgorithm,
) -> Vec<Suggestion> {
let partial = working_set.get_span_contents(span);
if partial.is_empty() {
return Vec::new();
}
let filter_predicate = |command: &[u8]| match_algorithm.matches_u8(command, partial);
@ -209,6 +209,10 @@ impl Completer for CommandCompletion {
|| ((span.end - span.start) == 0)
{
// we're in a gap or at a command
if working_set.get_span_contents(span).is_empty() && !self.force_completion_after_space
{
return vec![];
}
self.complete_commands(
working_set,
span,

View File

@ -215,6 +215,26 @@ impl NuCompleter {
}
}
// specially check if it is currently empty - always complete commands
if flat_idx == 0 && working_set.get_span_contents(new_span).is_empty() {
let mut completer = CommandCompletion::new(
self.engine_state.clone(),
&working_set,
flattened.clone(),
// flat_idx,
FlatShape::String,
true,
);
return self.process_completion(
&mut completer,
&working_set,
prefix,
new_span,
offset,
pos,
);
}
// Completions that depends on the previous expression (e.g: use, source)
if flat_idx > 0 {
if let Some(previous_expr) = flattened.get(flat_idx - 1) {
@ -302,6 +322,7 @@ impl NuCompleter {
flattened.clone(),
// flat_idx,
flat_shape.clone(),
false,
);
let mut out: Vec<_> = self.process_completion(

View File

@ -625,3 +625,36 @@ fn run_external_completion(block: &str, input: &str) -> Vec<Suggestion> {
completer.complete(&input, input.len())
}
#[test]
fn unknown_command_completion() {
let (_, _, engine, stack) = new_engine();
let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack);
let target_dir = "thiscommanddoesnotexist ";
let suggestions = completer.complete(target_dir, target_dir.len());
#[cfg(windows)]
let expected_paths: Vec<String> = vec![
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
"another\\".to_string(),
"custom_completion.nu".to_string(),
".hidden_file".to_string(),
".hidden_folder\\".to_string(),
];
#[cfg(not(windows))]
let expected_paths: Vec<String> = vec![
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
"another/".to_string(),
"custom_completion.nu".to_string(),
".hidden_file".to_string(),
".hidden_folder/".to_string(),
];
match_suggestions(expected_paths, suggestions)
}