diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index b6a15ff0a2..ed81782768 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -250,7 +250,9 @@ impl NuCompleter { working_set.get_span_contents(previous_expr.0).to_vec(); // Completion for .nu files - if prev_expr_str == b"use" || prev_expr_str == b"source-env" + if prev_expr_str == b"use" + || prev_expr_str == b"overlay use" + || prev_expr_str == b"source-env" { let mut completer = DotNuCompletion::new(self.engine_state.clone()); diff --git a/crates/nu-cli/src/completions/dotnu_completions.rs b/crates/nu-cli/src/completions/dotnu_completions.rs index fd5c346d95..d82d5a8913 100644 --- a/crates/nu-cli/src/completions/dotnu_completions.rs +++ b/crates/nu-cli/src/completions/dotnu_completions.rs @@ -5,7 +5,7 @@ use nu_protocol::{ }; use reedline::Suggestion; use std::{ - path::{is_separator, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR}, + path::{is_separator, Path, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR}, sync::Arc, }; @@ -91,16 +91,21 @@ impl Completer for DotNuCompletion { // and transform them into suggestions let output: Vec = search_dirs .into_iter() - .flat_map(|it| { - file_path_completion(span, &partial, &it, options) + .flat_map(|search_dir| { + let completions = file_path_completion(span, &partial, &search_dir, options); + completions .into_iter() - .filter(|it| { + .filter(move |it| { // Different base dir, so we list the .nu files or folders if !is_current_folder { it.1.ends_with(".nu") || it.1.ends_with(SEP) } else { - // Lib dirs, so we filter only the .nu files - it.1.ends_with(".nu") + // Lib dirs, so we filter only the .nu files or directory modules + if it.1.ends_with(SEP) { + Path::new(&search_dir).join(&it.1).join("mod.nu").exists() + } else { + it.1.ends_with(".nu") + } } }) .map(move |x| Suggestion { diff --git a/crates/nu-cli/tests/completions.rs b/crates/nu-cli/tests/completions.rs index e5db82e4ea..e48c1e9ee4 100644 --- a/crates/nu-cli/tests/completions.rs +++ b/crates/nu-cli/tests/completions.rs @@ -91,7 +91,7 @@ fn variables_dollar_sign_with_varialblecompletion() { let target_dir = "$ "; let suggestions = completer.complete(target_dir, target_dir.len()); - assert_eq!(7, suggestions.len()); + assert_eq!(8, suggestions.len()); } #[rstest] @@ -144,15 +144,34 @@ fn dotnu_completions() { let completion_str = "source-env ".to_string(); let suggestions = completer.complete(&completion_str, completion_str.len()); - assert_eq!(1, suggestions.len()); + assert_eq!(2, suggestions.len()); assert_eq!("custom_completion.nu", suggestions.first().unwrap().value); + #[cfg(windows)] + assert_eq!("directory_completion\\", suggestions.get(1).unwrap().value); + #[cfg(not(windows))] + assert_eq!("directory_completion/", suggestions.get(1).unwrap().value); // Test use completion let completion_str = "use ".to_string(); let suggestions = completer.complete(&completion_str, completion_str.len()); - assert_eq!(1, suggestions.len()); + assert_eq!(2, suggestions.len()); assert_eq!("custom_completion.nu", suggestions.first().unwrap().value); + #[cfg(windows)] + assert_eq!("directory_completion\\", suggestions.get(1).unwrap().value); + #[cfg(not(windows))] + assert_eq!("directory_completion/", suggestions.get(1).unwrap().value); + + // Test overlay use completion + let completion_str = "overlay use ".to_string(); + let suggestions = completer.complete(&completion_str, completion_str.len()); + + assert_eq!(2, suggestions.len()); + assert_eq!("custom_completion.nu", suggestions.first().unwrap().value); + #[cfg(windows)] + assert_eq!("directory_completion\\", suggestions.get(1).unwrap().value); + #[cfg(not(windows))] + assert_eq!("directory_completion/", suggestions.get(1).unwrap().value); } #[test] @@ -208,6 +227,7 @@ fn file_completions() { 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")), @@ -323,6 +343,7 @@ fn command_ls_with_filecompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -333,6 +354,7 @@ fn command_ls_with_filecompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -355,6 +377,7 @@ fn command_open_with_filecompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -365,6 +388,7 @@ fn command_open_with_filecompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -388,6 +412,7 @@ fn command_rm_with_globcompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -398,6 +423,7 @@ fn command_rm_with_globcompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -421,6 +447,7 @@ fn command_cp_with_globcompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -431,6 +458,7 @@ fn command_cp_with_globcompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -454,6 +482,7 @@ fn command_save_with_filecompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -464,6 +493,7 @@ fn command_save_with_filecompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -487,6 +517,7 @@ fn command_touch_with_filecompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -497,6 +528,7 @@ fn command_touch_with_filecompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -520,6 +552,7 @@ fn command_watch_with_filecompletion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -530,6 +563,7 @@ fn command_watch_with_filecompletion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -625,6 +659,7 @@ fn folder_with_directorycompletions() { // Create the expected values let expected_paths: Vec = vec![ folder(dir.join("another")), + folder(dir.join("directory_completion")), folder(dir.join("test_a")), folder(dir.join("test_b")), folder(dir.join(".hidden_folder")), @@ -839,6 +874,7 @@ fn unknown_command_completion() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -849,6 +885,7 @@ fn unknown_command_completion() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), @@ -899,6 +936,7 @@ fn filecompletions_triggers_after_cursor() { let expected_paths: Vec = vec![ "another\\".to_string(), "custom_completion.nu".to_string(), + "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), "test_b\\".to_string(), @@ -909,6 +947,7 @@ fn filecompletions_triggers_after_cursor() { let expected_paths: Vec = vec![ "another/".to_string(), "custom_completion.nu".to_string(), + "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), "test_b/".to_string(), diff --git a/tests/fixtures/completions/directory_completion/mod.nu b/tests/fixtures/completions/directory_completion/mod.nu new file mode 100644 index 0000000000..e69de29bb2