mirror of
https://github.com/nushell/nushell.git
synced 2025-03-19 18:16:44 +01:00
Keep forward slash when autocomplete on Windows (#13321)
Related #7044 # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> When autocomplete path with `/` on Windows, paths keep with slash instead of backslash(`\`). If mixed both, path completion uses a last path seperator.    # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. -->  # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
c31291753c
commit
e3f78b8793
@ -10,9 +10,7 @@ use nu_protocol::{
|
|||||||
levenshtein_distance, Span,
|
levenshtein_distance, Span,
|
||||||
};
|
};
|
||||||
use nu_utils::get_ls_colors;
|
use nu_utils::get_ls_colors;
|
||||||
use std::path::{
|
use std::path::{is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP};
|
||||||
is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::SortBy;
|
use super::SortBy;
|
||||||
|
|
||||||
@ -93,16 +91,16 @@ enum OriginalCwd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OriginalCwd {
|
impl OriginalCwd {
|
||||||
fn apply(&self, mut p: PathBuiltFromString) -> String {
|
fn apply(&self, mut p: PathBuiltFromString, path_separator: char) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::None => {}
|
Self::None => {}
|
||||||
Self::Home => p.parts.insert(0, "~".to_string()),
|
Self::Home => p.parts.insert(0, "~".to_string()),
|
||||||
Self::Prefix(s) => p.parts.insert(0, s.clone()),
|
Self::Prefix(s) => p.parts.insert(0, s.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ret = p.parts.join(MAIN_SEPARATOR_STR);
|
let mut ret = p.parts.join(&path_separator.to_string());
|
||||||
if p.isdir {
|
if p.isdir {
|
||||||
ret.push(SEP);
|
ret.push(path_separator);
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@ -133,6 +131,14 @@ pub fn complete_item(
|
|||||||
) -> Vec<(nu_protocol::Span, String, Option<Style>)> {
|
) -> Vec<(nu_protocol::Span, String, Option<Style>)> {
|
||||||
let partial = surround_remove(partial);
|
let partial = surround_remove(partial);
|
||||||
let isdir = partial.ends_with(is_separator);
|
let isdir = partial.ends_with(is_separator);
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
let path_separator = SEP;
|
||||||
|
#[cfg(windows)]
|
||||||
|
let path_separator = partial
|
||||||
|
.chars()
|
||||||
|
.rfind(|c: &char| is_separator(*c))
|
||||||
|
.unwrap_or(SEP);
|
||||||
let cwd_pathbuf = Path::new(cwd).to_path_buf();
|
let cwd_pathbuf = Path::new(cwd).to_path_buf();
|
||||||
let ls_colors = (engine_state.config.use_ls_colors_completions
|
let ls_colors = (engine_state.config.use_ls_colors_completions
|
||||||
&& engine_state.config.use_ansi_coloring)
|
&& engine_state.config.use_ansi_coloring)
|
||||||
@ -195,7 +201,7 @@ pub fn complete_item(
|
|||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
let path = original_cwd.apply(p);
|
let path = original_cwd.apply(p, path_separator);
|
||||||
let style = ls_colors.as_ref().map(|lsc| {
|
let style = ls_colors.as_ref().map(|lsc| {
|
||||||
lsc.style_for_path_with_metadata(
|
lsc.style_for_path_with_metadata(
|
||||||
&path,
|
&path,
|
||||||
|
@ -32,7 +32,6 @@ fn completer() -> NuCompleter {
|
|||||||
fn completer_strings() -> NuCompleter {
|
fn completer_strings() -> NuCompleter {
|
||||||
// Create a new engine
|
// Create a new engine
|
||||||
let (dir, _, mut engine, mut stack) = new_engine();
|
let (dir, _, mut engine, mut stack) = new_engine();
|
||||||
|
|
||||||
// Add record value as example
|
// Add record value as example
|
||||||
let record = r#"def animals [] { ["cat", "dog", "eel" ] }
|
let record = r#"def animals [] { ["cat", "dog", "eel" ] }
|
||||||
def my-command [animal: string@animals] { print $animal }"#;
|
def my-command [animal: string@animals] { print $animal }"#;
|
||||||
@ -123,28 +122,28 @@ fn variables_double_dash_argument_with_flagcompletion(mut completer: NuCompleter
|
|||||||
let suggestions = completer.complete("tst --", 6);
|
let suggestions = completer.complete("tst --", 6);
|
||||||
let expected: Vec<String> = vec!["--help".into(), "--mod".into()];
|
let expected: Vec<String> = vec!["--help".into(), "--mod".into()];
|
||||||
// dbg!(&expected, &suggestions);
|
// dbg!(&expected, &suggestions);
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn variables_single_dash_argument_with_flagcompletion(mut completer: NuCompleter) {
|
fn variables_single_dash_argument_with_flagcompletion(mut completer: NuCompleter) {
|
||||||
let suggestions = completer.complete("tst -", 5);
|
let suggestions = completer.complete("tst -", 5);
|
||||||
let expected: Vec<String> = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()];
|
let expected: Vec<String> = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn variables_command_with_commandcompletion(mut completer_strings: NuCompleter) {
|
fn variables_command_with_commandcompletion(mut completer_strings: NuCompleter) {
|
||||||
let suggestions = completer_strings.complete("my-c ", 4);
|
let suggestions = completer_strings.complete("my-c ", 4);
|
||||||
let expected: Vec<String> = vec!["my-command".into()];
|
let expected: Vec<String> = vec!["my-command".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn variables_subcommands_with_customcompletion(mut completer_strings: NuCompleter) {
|
fn variables_subcommands_with_customcompletion(mut completer_strings: NuCompleter) {
|
||||||
let suggestions = completer_strings.complete("my-command ", 11);
|
let suggestions = completer_strings.complete("my-command ", 11);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
@ -153,7 +152,7 @@ fn variables_customcompletion_subcommands_with_customcompletion_2(
|
|||||||
) {
|
) {
|
||||||
let suggestions = completer_strings.complete("my-command ", 11);
|
let suggestions = completer_strings.complete("my-command ", 11);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -182,19 +181,19 @@ fn dotnu_completions() {
|
|||||||
let completion_str = "source-env ".to_string();
|
let completion_str = "source-env ".to_string();
|
||||||
let suggestions = completer.complete(&completion_str, completion_str.len());
|
let suggestions = completer.complete(&completion_str, completion_str.len());
|
||||||
|
|
||||||
match_suggestions(expected.clone(), suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test use completion
|
// Test use completion
|
||||||
let completion_str = "use ".to_string();
|
let completion_str = "use ".to_string();
|
||||||
let suggestions = completer.complete(&completion_str, completion_str.len());
|
let suggestions = completer.complete(&completion_str, completion_str.len());
|
||||||
|
|
||||||
match_suggestions(expected.clone(), suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test overlay use completion
|
// Test overlay use completion
|
||||||
let completion_str = "overlay use ".to_string();
|
let completion_str = "overlay use ".to_string();
|
||||||
let suggestions = completer.complete(&completion_str, completion_str.len());
|
let suggestions = completer.complete(&completion_str, completion_str.len());
|
||||||
|
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -258,8 +257,22 @@ fn file_completions() {
|
|||||||
folder(dir.join(".hidden_folder")),
|
folder(dir.join(".hidden_folder")),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
let separator = '/';
|
||||||
|
let target_dir = format!("cp {dir_str}{separator}");
|
||||||
|
let slash_suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
let expected_slash_paths: Vec<String> = expected_paths
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.replace('\\', "/"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
match_suggestions(&expected_slash_paths, &slash_suggestions);
|
||||||
|
}
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completions for a file
|
// Test completions for a file
|
||||||
let target_dir = format!("cp {}", folder(dir.join("another")));
|
let target_dir = format!("cp {}", folder(dir.join("another")));
|
||||||
@ -269,17 +282,91 @@ fn file_completions() {
|
|||||||
let expected_paths: Vec<String> = vec![file(dir.join("another").join("newfile"))];
|
let expected_paths: Vec<String> = vec![file(dir.join("another").join("newfile"))];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completions for hidden files
|
// Test completions for hidden files
|
||||||
let target_dir = format!("ls {}/.", folder(dir.join(".hidden_folder")));
|
let target_dir = format!("ls {}{MAIN_SEPARATOR}.", folder(dir.join(".hidden_folder")));
|
||||||
let suggestions = completer.complete(&target_dir, target_dir.len());
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
let expected_paths: Vec<String> =
|
let expected_paths: Vec<String> =
|
||||||
vec![file(dir.join(".hidden_folder").join(".hidden_subfile"))];
|
vec![file(dir.join(".hidden_folder").join(".hidden_subfile"))];
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
let target_dir = format!("ls {}/.", folder(dir.join(".hidden_folder")));
|
||||||
|
let slash_suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
let expected_slash: Vec<String> = expected_paths
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.replace('\\', "/"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
match_suggestions(&expected_slash, &slash_suggestions);
|
||||||
|
}
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
#[test]
|
||||||
|
fn file_completions_with_mixed_separators() {
|
||||||
|
// Create a new engine
|
||||||
|
let (dir, dir_str, engine, stack) = new_dotnu_engine();
|
||||||
|
|
||||||
|
// Instantiate a new completer
|
||||||
|
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
|
||||||
|
|
||||||
|
// Create Expected values
|
||||||
|
let expected_paths: Vec<String> = vec![
|
||||||
|
file(dir.join("lib-dir1").join("bar.nu")),
|
||||||
|
file(dir.join("lib-dir1").join("baz.nu")),
|
||||||
|
file(dir.join("lib-dir1").join("xyzzy.nu")),
|
||||||
|
];
|
||||||
|
let expecetd_slash_paths: Vec<String> = expected_paths
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.replace(MAIN_SEPARATOR, "/"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}/lib-dir1/");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("cp {dir_str}\\lib-dir1/");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}/lib-dir1\\/");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}\\lib-dir1\\/");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}\\lib-dir1\\");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}/lib-dir1\\");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}/lib-dir1/\\");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
|
let target_dir = format!("ls {dir_str}\\lib-dir1/\\");
|
||||||
|
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -303,7 +390,7 @@ fn partial_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completions for the files whose name begin with "h"
|
// Test completions for the files whose name begin with "h"
|
||||||
// and are present under directories whose names begin with "pa"
|
// and are present under directories whose names begin with "pa"
|
||||||
@ -324,7 +411,7 @@ fn partial_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completion for all files under directories whose names begin with "pa"
|
// Test completion for all files under directories whose names begin with "pa"
|
||||||
let dir_str = folder(dir.join("pa"));
|
let dir_str = folder(dir.join("pa"));
|
||||||
@ -345,7 +432,7 @@ fn partial_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completion for a single file
|
// Test completion for a single file
|
||||||
let dir_str = file(dir.join("fi").join("so"));
|
let dir_str = file(dir.join("fi").join("so"));
|
||||||
@ -356,7 +443,7 @@ fn partial_completions() {
|
|||||||
let expected_paths: Vec<String> = vec![file(dir.join("final_partial").join("somefile"))];
|
let expected_paths: Vec<String> = vec![file(dir.join("final_partial").join("somefile"))];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completion where there is a sneaky `..` in the path
|
// Test completion where there is a sneaky `..` in the path
|
||||||
let dir_str = file(dir.join("par").join("..").join("fi").join("so"));
|
let dir_str = file(dir.join("par").join("..").join("fi").join("so"));
|
||||||
@ -392,7 +479,7 @@ fn partial_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completion for all files under directories whose names begin with "pa"
|
// Test completion for all files under directories whose names begin with "pa"
|
||||||
let file_str = file(dir.join("partial-a").join("have"));
|
let file_str = file(dir.join("partial-a").join("have"));
|
||||||
@ -406,7 +493,7 @@ fn partial_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
// Test completion for all files under directories whose names begin with "pa"
|
// Test completion for all files under directories whose names begin with "pa"
|
||||||
let file_str = file(dir.join("partial-a").join("have_ext."));
|
let file_str = file(dir.join("partial-a").join("have_ext."));
|
||||||
@ -420,7 +507,7 @@ fn partial_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -455,15 +542,16 @@ fn command_ls_with_filecompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
let target_dir = "ls custom_completion.";
|
let target_dir = "ls custom_completion.";
|
||||||
let suggestions = completer.complete(target_dir, target_dir.len());
|
let suggestions = completer.complete(target_dir, target_dir.len());
|
||||||
|
|
||||||
let expected_paths: Vec<String> = vec!["custom_completion.nu".to_string()];
|
let expected_paths: Vec<String> = vec!["custom_completion.nu".to_string()];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn command_open_with_filecompletion() {
|
fn command_open_with_filecompletion() {
|
||||||
let (_, _, engine, stack) = new_engine();
|
let (_, _, engine, stack) = new_engine();
|
||||||
@ -496,14 +584,14 @@ fn command_open_with_filecompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
let target_dir = "open custom_completion.";
|
let target_dir = "open custom_completion.";
|
||||||
let suggestions = completer.complete(target_dir, target_dir.len());
|
let suggestions = completer.complete(target_dir, target_dir.len());
|
||||||
|
|
||||||
let expected_paths: Vec<String> = vec!["custom_completion.nu".to_string()];
|
let expected_paths: Vec<String> = vec!["custom_completion.nu".to_string()];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -538,7 +626,7 @@ fn command_rm_with_globcompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -573,7 +661,7 @@ fn command_cp_with_globcompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -608,7 +696,7 @@ fn command_save_with_filecompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -643,7 +731,7 @@ fn command_touch_with_filecompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -678,7 +766,7 @@ fn command_watch_with_filecompletion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
@ -686,19 +774,19 @@ fn subcommand_completions(mut subcommand_completer: NuCompleter) {
|
|||||||
let prefix = "foo br";
|
let prefix = "foo br";
|
||||||
let suggestions = subcommand_completer.complete(prefix, prefix.len());
|
let suggestions = subcommand_completer.complete(prefix, prefix.len());
|
||||||
match_suggestions(
|
match_suggestions(
|
||||||
vec!["foo bar".to_string(), "foo aabrr".to_string()],
|
&vec!["foo bar".to_string(), "foo aabrr".to_string()],
|
||||||
suggestions,
|
&suggestions,
|
||||||
);
|
);
|
||||||
|
|
||||||
let prefix = "foo b";
|
let prefix = "foo b";
|
||||||
let suggestions = subcommand_completer.complete(prefix, prefix.len());
|
let suggestions = subcommand_completer.complete(prefix, prefix.len());
|
||||||
match_suggestions(
|
match_suggestions(
|
||||||
vec![
|
&vec![
|
||||||
"foo bar".to_string(),
|
"foo bar".to_string(),
|
||||||
"foo abaz".to_string(),
|
"foo abaz".to_string(),
|
||||||
"foo aabrr".to_string(),
|
"foo aabrr".to_string(),
|
||||||
],
|
],
|
||||||
suggestions,
|
&suggestions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +812,7 @@ fn file_completion_quoted() {
|
|||||||
format!("`{}`", folder("test dir")),
|
format!("`{}`", folder("test dir")),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
|
|
||||||
let dir: PathBuf = "test dir".into();
|
let dir: PathBuf = "test dir".into();
|
||||||
let target_dir = format!("open '{}'", folder(dir.clone()));
|
let target_dir = format!("open '{}'", folder(dir.clone()));
|
||||||
@ -735,7 +823,7 @@ fn file_completion_quoted() {
|
|||||||
format!("`{}`", file(dir.join("single quote"))),
|
format!("`{}`", file(dir.join("single quote"))),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -770,7 +858,7 @@ fn flag_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -794,8 +882,21 @@ fn folder_with_directorycompletions() {
|
|||||||
folder(dir.join(".hidden_folder")),
|
folder(dir.join(".hidden_folder")),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
let target_dir = format!("cd {dir_str}/");
|
||||||
|
let slash_suggestions = completer.complete(&target_dir, target_dir.len());
|
||||||
|
|
||||||
|
let expected_slash_paths: Vec<String> = expected_paths
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.replace('\\', "/"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
match_suggestions(&expected_slash_paths, &slash_suggestions);
|
||||||
|
}
|
||||||
|
|
||||||
// Match the results
|
// Match the results
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -837,7 +938,7 @@ fn variables_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test completions for $nu.h (filter)
|
// Test completions for $nu.h (filter)
|
||||||
let suggestions = completer.complete("$nu.h", 5);
|
let suggestions = completer.complete("$nu.h", 5);
|
||||||
@ -851,7 +952,7 @@ fn variables_completions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test completions for $nu.os-info
|
// Test completions for $nu.os-info
|
||||||
let suggestions = completer.complete("$nu.os-info.", 12);
|
let suggestions = completer.complete("$nu.os-info.", 12);
|
||||||
@ -863,7 +964,7 @@ fn variables_completions() {
|
|||||||
"name".into(),
|
"name".into(),
|
||||||
];
|
];
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test completions for custom var
|
// Test completions for custom var
|
||||||
let suggestions = completer.complete("$actor.", 7);
|
let suggestions = completer.complete("$actor.", 7);
|
||||||
@ -873,7 +974,7 @@ fn variables_completions() {
|
|||||||
let expected: Vec<String> = vec!["age".into(), "name".into()];
|
let expected: Vec<String> = vec!["age".into(), "name".into()];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test completions for custom var (filtering)
|
// Test completions for custom var (filtering)
|
||||||
let suggestions = completer.complete("$actor.n", 8);
|
let suggestions = completer.complete("$actor.n", 8);
|
||||||
@ -883,7 +984,7 @@ fn variables_completions() {
|
|||||||
let expected: Vec<String> = vec!["name".into()];
|
let expected: Vec<String> = vec!["name".into()];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test completions for $env
|
// Test completions for $env
|
||||||
let suggestions = completer.complete("$env.", 5);
|
let suggestions = completer.complete("$env.", 5);
|
||||||
@ -896,7 +997,7 @@ fn variables_completions() {
|
|||||||
let expected: Vec<String> = vec!["PATH".into(), "PWD".into(), "TEST".into()];
|
let expected: Vec<String> = vec!["PATH".into(), "PWD".into(), "TEST".into()];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
// Test completions for $env
|
// Test completions for $env
|
||||||
let suggestions = completer.complete("$env.T", 6);
|
let suggestions = completer.complete("$env.T", 6);
|
||||||
@ -906,12 +1007,12 @@ fn variables_completions() {
|
|||||||
let expected: Vec<String> = vec!["TEST".into()];
|
let expected: Vec<String> = vec!["TEST".into()];
|
||||||
|
|
||||||
// Match results
|
// Match results
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
|
|
||||||
let suggestions = completer.complete("$", 1);
|
let suggestions = completer.complete("$", 1);
|
||||||
let expected: Vec<String> = vec!["$actor".into(), "$env".into(), "$in".into(), "$nu".into()];
|
let expected: Vec<String> = vec!["$actor".into(), "$env".into(), "$in".into(), "$nu".into()];
|
||||||
|
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -930,7 +1031,7 @@ fn alias_of_command_and_flags() {
|
|||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let expected_paths: Vec<String> = vec!["test_a/".to_string(), "test_b/".to_string()];
|
let expected_paths: Vec<String> = vec!["test_a/".to_string(), "test_b/".to_string()];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -949,7 +1050,7 @@ fn alias_of_basic_command() {
|
|||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let expected_paths: Vec<String> = vec!["test_a/".to_string(), "test_b/".to_string()];
|
let expected_paths: Vec<String> = vec!["test_a/".to_string(), "test_b/".to_string()];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -971,7 +1072,7 @@ fn alias_of_another_alias() {
|
|||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let expected_paths: Vec<String> = vec!["test_a/".to_string(), "test_b/".to_string()];
|
let expected_paths: Vec<String> = vec!["test_a/".to_string(), "test_b/".to_string()];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_external_completion(completer: &str, input: &str) -> Vec<Suggestion> {
|
fn run_external_completion(completer: &str, input: &str) -> Vec<Suggestion> {
|
||||||
@ -1034,35 +1135,35 @@ fn unknown_command_completion() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions)
|
match_suggestions(&expected_paths, &suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn flagcompletion_triggers_after_cursor(mut completer: NuCompleter) {
|
fn flagcompletion_triggers_after_cursor(mut completer: NuCompleter) {
|
||||||
let suggestions = completer.complete("tst -h", 5);
|
let suggestions = completer.complete("tst -h", 5);
|
||||||
let expected: Vec<String> = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()];
|
let expected: Vec<String> = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn customcompletion_triggers_after_cursor(mut completer_strings: NuCompleter) {
|
fn customcompletion_triggers_after_cursor(mut completer_strings: NuCompleter) {
|
||||||
let suggestions = completer_strings.complete("my-command c", 11);
|
let suggestions = completer_strings.complete("my-command c", 11);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn customcompletion_triggers_after_cursor_piped(mut completer_strings: NuCompleter) {
|
fn customcompletion_triggers_after_cursor_piped(mut completer_strings: NuCompleter) {
|
||||||
let suggestions = completer_strings.complete("my-command c | ls", 11);
|
let suggestions = completer_strings.complete("my-command c | ls", 11);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn flagcompletion_triggers_after_cursor_piped(mut completer: NuCompleter) {
|
fn flagcompletion_triggers_after_cursor_piped(mut completer: NuCompleter) {
|
||||||
let suggestions = completer.complete("tst -h | ls", 5);
|
let suggestions = completer.complete("tst -h | ls", 5);
|
||||||
let expected: Vec<String> = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()];
|
let expected: Vec<String> = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1096,77 +1197,77 @@ fn filecompletions_triggers_after_cursor() {
|
|||||||
".hidden_folder/".to_string(),
|
".hidden_folder/".to_string(),
|
||||||
];
|
];
|
||||||
|
|
||||||
match_suggestions(expected_paths, suggestions);
|
match_suggestions(&expected_paths, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn extern_custom_completion_positional(mut extern_completer: NuCompleter) {
|
fn extern_custom_completion_positional(mut extern_completer: NuCompleter) {
|
||||||
let suggestions = extern_completer.complete("spam ", 5);
|
let suggestions = extern_completer.complete("spam ", 5);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn extern_custom_completion_long_flag_1(mut extern_completer: NuCompleter) {
|
fn extern_custom_completion_long_flag_1(mut extern_completer: NuCompleter) {
|
||||||
let suggestions = extern_completer.complete("spam --foo=", 11);
|
let suggestions = extern_completer.complete("spam --foo=", 11);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn extern_custom_completion_long_flag_2(mut extern_completer: NuCompleter) {
|
fn extern_custom_completion_long_flag_2(mut extern_completer: NuCompleter) {
|
||||||
let suggestions = extern_completer.complete("spam --foo ", 11);
|
let suggestions = extern_completer.complete("spam --foo ", 11);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn extern_custom_completion_long_flag_short(mut extern_completer: NuCompleter) {
|
fn extern_custom_completion_long_flag_short(mut extern_completer: NuCompleter) {
|
||||||
let suggestions = extern_completer.complete("spam -f ", 8);
|
let suggestions = extern_completer.complete("spam -f ", 8);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn extern_custom_completion_short_flag(mut extern_completer: NuCompleter) {
|
fn extern_custom_completion_short_flag(mut extern_completer: NuCompleter) {
|
||||||
let suggestions = extern_completer.complete("spam -b ", 8);
|
let suggestions = extern_completer.complete("spam -b ", 8);
|
||||||
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn extern_complete_flags(mut extern_completer: NuCompleter) {
|
fn extern_complete_flags(mut extern_completer: NuCompleter) {
|
||||||
let suggestions = extern_completer.complete("spam -", 6);
|
let suggestions = extern_completer.complete("spam -", 6);
|
||||||
let expected: Vec<String> = vec!["--foo".into(), "-b".into(), "-f".into()];
|
let expected: Vec<String> = vec!["--foo".into(), "-b".into(), "-f".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn custom_completer_triggers_cursor_before_word(mut custom_completer: NuCompleter) {
|
fn custom_completer_triggers_cursor_before_word(mut custom_completer: NuCompleter) {
|
||||||
let suggestions = custom_completer.complete("cmd foo bar", 8);
|
let suggestions = custom_completer.complete("cmd foo bar", 8);
|
||||||
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "".into()];
|
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn custom_completer_triggers_cursor_on_word_left_boundary(mut custom_completer: NuCompleter) {
|
fn custom_completer_triggers_cursor_on_word_left_boundary(mut custom_completer: NuCompleter) {
|
||||||
let suggestions = custom_completer.complete("cmd foo bar", 8);
|
let suggestions = custom_completer.complete("cmd foo bar", 8);
|
||||||
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "".into()];
|
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn custom_completer_triggers_cursor_next_to_word(mut custom_completer: NuCompleter) {
|
fn custom_completer_triggers_cursor_next_to_word(mut custom_completer: NuCompleter) {
|
||||||
let suggestions = custom_completer.complete("cmd foo bar", 11);
|
let suggestions = custom_completer.complete("cmd foo bar", 11);
|
||||||
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "bar".into()];
|
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "bar".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn custom_completer_triggers_cursor_after_word(mut custom_completer: NuCompleter) {
|
fn custom_completer_triggers_cursor_after_word(mut custom_completer: NuCompleter) {
|
||||||
let suggestions = custom_completer.complete("cmd foo bar ", 12);
|
let suggestions = custom_completer.complete("cmd foo bar ", 12);
|
||||||
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "bar".into(), "".into()];
|
let expected: Vec<String> = vec!["cmd".into(), "foo".into(), "bar".into(), "".into()];
|
||||||
match_suggestions(expected, suggestions);
|
match_suggestions(&expected, &suggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ignore = "was reverted, still needs fixing"]
|
#[ignore = "was reverted, still needs fixing"]
|
||||||
|
@ -186,7 +186,7 @@ pub fn new_partial_engine() -> (AbsolutePathBuf, String, EngineState, Stack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// match a list of suggestions with the expected values
|
// match a list of suggestions with the expected values
|
||||||
pub fn match_suggestions(expected: Vec<String>, suggestions: Vec<Suggestion>) {
|
pub fn match_suggestions(expected: &Vec<String>, suggestions: &Vec<Suggestion>) {
|
||||||
let expected_len = expected.len();
|
let expected_len = expected.len();
|
||||||
let suggestions_len = suggestions.len();
|
let suggestions_len = suggestions.len();
|
||||||
if expected_len != suggestions_len {
|
if expected_len != suggestions_len {
|
||||||
@ -196,13 +196,13 @@ pub fn match_suggestions(expected: Vec<String>, suggestions: Vec<Suggestion>) {
|
|||||||
Expected: {expected:#?}\n"
|
Expected: {expected:#?}\n"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
assert_eq!(
|
|
||||||
expected,
|
let suggestoins_str = suggestions
|
||||||
suggestions
|
.iter()
|
||||||
.into_iter()
|
.map(|it| it.value.clone())
|
||||||
.map(|it| it.value)
|
.collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>()
|
|
||||||
);
|
assert_eq!(expected, &suggestoins_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append the separator to the converted path
|
// append the separator to the converted path
|
||||||
|
Loading…
Reference in New Issue
Block a user