diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index 555d14ff27..16b1673a4f 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -297,7 +297,7 @@ impl NuCompleter { let mut completer = OperatorCompletion::new(pipeline_element.expr.clone()); - return self.process_completion( + let operator_suggestion = self.process_completion( &mut completer, &working_set, prefix, @@ -305,6 +305,9 @@ impl NuCompleter { fake_offset, pos, ); + if !operator_suggestion.is_empty() { + return operator_suggestion; + } } } } diff --git a/crates/nu-cli/tests/completions/mod.rs b/crates/nu-cli/tests/completions/mod.rs index 7f6fe30430..78c36cad7e 100644 --- a/crates/nu-cli/tests/completions/mod.rs +++ b/crates/nu-cli/tests/completions/mod.rs @@ -357,6 +357,39 @@ fn file_completions() { // Match the results match_suggestions(&expected_paths, &suggestions); + // Test completions for the current folder even with parts before the autocomplet + let target_dir = format!("cp somefile.txt {dir_str}{MAIN_SEPARATOR}"); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![ + folder(dir.join("another")), + file(dir.join("custom_completion.nu")), + folder(dir.join("directory_completion")), + file(dir.join("nushell")), + folder(dir.join("test_a")), + folder(dir.join("test_b")), + file(dir.join(".hidden_file")), + folder(dir.join(".hidden_folder")), + ]; + + #[cfg(windows)] + { + let separator = '/'; + let target_dir = format!("cp somefile.txt {dir_str}{separator}"); + let slash_suggestions = completer.complete(&target_dir, target_dir.len()); + + let expected_slash_paths: Vec = expected_paths + .iter() + .map(|s| s.replace('\\', "/")) + .collect(); + + match_suggestions(&expected_slash_paths, &slash_suggestions); + } + + // Match the results + match_suggestions(&expected_paths, &suggestions); + // Test completions for a file let target_dir = format!("cp {}", folder(dir.join("another"))); let suggestions = completer.complete(&target_dir, target_dir.len()); @@ -391,6 +424,75 @@ fn file_completions() { match_suggestions(&expected_paths, &suggestions); } +#[test] +fn custom_command_rest_any_args_file_completions() { + // Create a new engine + let (dir, dir_str, mut engine, mut stack) = new_engine(); + let command = r#"def list [ ...args: any ] {}"#; + assert!(support::merge_input(command.as_bytes(), &mut engine, &mut stack).is_ok()); + + // Instantiate a new completer + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); + + // Test completions for the current folder + let target_dir = format!("list {dir_str}{MAIN_SEPARATOR}"); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![ + folder(dir.join("another")), + file(dir.join("custom_completion.nu")), + folder(dir.join("directory_completion")), + file(dir.join("nushell")), + folder(dir.join("test_a")), + folder(dir.join("test_b")), + file(dir.join(".hidden_file")), + folder(dir.join(".hidden_folder")), + ]; + + // Match the results + match_suggestions(&expected_paths, &suggestions); + + // Test completions for the current folder even with parts before the autocomplet + let target_dir = format!("list somefile.txt {dir_str}{MAIN_SEPARATOR}"); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![ + folder(dir.join("another")), + file(dir.join("custom_completion.nu")), + folder(dir.join("directory_completion")), + file(dir.join("nushell")), + folder(dir.join("test_a")), + folder(dir.join("test_b")), + file(dir.join(".hidden_file")), + folder(dir.join(".hidden_folder")), + ]; + + // Match the results + match_suggestions(&expected_paths, &suggestions); + + // Test completions for a file + let target_dir = format!("list {}", folder(dir.join("another"))); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![file(dir.join("another").join("newfile"))]; + + // Match the results + match_suggestions(&expected_paths, &suggestions); + + // Test completions for hidden files + let target_dir = format!("list {}", file(dir.join(".hidden_folder").join("."))); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + let expected_paths: Vec = + vec![file(dir.join(".hidden_folder").join(".hidden_subfile"))]; + + // Match the results + match_suggestions(&expected_paths, &suggestions); +} + #[cfg(windows)] #[test] fn file_completions_with_mixed_separators() {