From 2659ea3dbd9ba1d4670139e75eeac537f5c1af9a Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Fri, 29 Apr 2022 13:11:41 -0500 Subject: [PATCH] Revert "nu-cli/completions: better fix for files with special characters (#5254)" (#5372) This reverts commit 3cf3329e4928a835c0b823604758b968aa5ab6b4. --- Cargo.lock | 2 +- .../src/completions/file_completions.rs | 92 ++----------------- crates/nu-cli/src/completions/mod.rs | 2 +- crates/nu-cli/tests/test_completions.rs | 36 ++------ tests/fixtures/completions/nushell | 0 5 files changed, 19 insertions(+), 113 deletions(-) create mode 100644 tests/fixtures/completions/nushell diff --git a/Cargo.lock b/Cargo.lock index 83cac125ee..263db17c26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3716,7 +3716,7 @@ dependencies = [ [[package]] name = "reedline" version = "0.4.0" -source = "git+https://github.com/nushell/reedline?branch=main#229c729898ef91bf9cb83a5420a6fe7b4c8d1045" +source = "git+https://github.com/nushell/reedline?branch=main#2e2bdc54621643e7bee5ba2e2d9bf28e757074e0" dependencies = [ "chrono", "crossterm", diff --git a/crates/nu-cli/src/completions/file_completions.rs b/crates/nu-cli/src/completions/file_completions.rs index e09b684c80..4c146060fd 100644 --- a/crates/nu-cli/src/completions/file_completions.rs +++ b/crates/nu-cli/src/completions/file_completions.rs @@ -134,8 +134,14 @@ pub fn file_path_completion( file_name.push(SEP); } - // Escape path string if necessary - path = escape_path_str(path); + if path.contains(' ') { + path = format!("\'{}\'", path); + } + + // Fix files or folders with quotes + if path.contains('\'') || path.contains('"') { + path = format!("`{}`", path); + } Some((span, path)) } else { @@ -152,85 +158,3 @@ pub fn file_path_completion( pub fn matches(partial: &str, from: &str, match_algorithm: MatchAlgorithm) -> bool { match_algorithm.matches_str(&from.to_ascii_lowercase(), &partial.to_ascii_lowercase()) } - -// escape paths that contains some special characters -pub fn escape_path_str(path: String) -> String { - let mut path = path; - - // List of special characters that need to be escaped - let special_characters = b"\\\'\""; - let replacements = [b"\\\\", b"\\\'", b"\\\""]; - - // Check if path needs to be escaped - let needs_escape = path.bytes().fold(false, |acc, x| { - acc - || x == b'\\' // 0x5c - || x == b'`' // 0x60 - || x == b'"' - || x == b' ' - || x == b'\'' - }); - - if needs_escape { - let mut result: Vec = vec![b'\"']; - - // Walk through the path characters - for b in path.bytes() { - // Basically the equivalent of str.find(), but expanded - if let Some(idx) = special_characters.iter().enumerate().fold(None, |idx, c| { - if *c.1 == b { - Some(c.0) - } else { - idx - } - }) { - for rb in replacements[idx] { - result.push(*rb); - } - } else { - result.push(b); - } - } - - // Final quote - result.push(b'\"'); - - // Update path - path = String::from_utf8(result).unwrap_or(path); - } - - path -} - -mod test { - #[test] - fn escape_path() { - // Vec of (path, expected escape) - let cases: Vec<(&str, &str)> = vec![ - ("/home/nushell/filewith`", "\"/home/nushell/filewith`\""), - ( - "/home/nushell/folder with spaces", - "\"/home/nushell/folder with spaces\"", - ), - ( - "/home/nushell/folder\"withquotes", - "\"/home/nushell/folder\\\"withquotes\"", - ), - ( - "C:\\windows\\system32\\escape path", - "\"C:\\\\windows\\\\system32\\\\escape path\"", - ), - ( - "/home/nushell/shouldnt/be/escaped", - "/home/nushell/shouldnt/be/escaped", - ), - ]; - - for item in cases.into_iter() { - assert_eq!( - crate::completions::escape_path_str(item.0.to_string()), - item.1.to_string() - ) - } - } -} diff --git a/crates/nu-cli/src/completions/mod.rs b/crates/nu-cli/src/completions/mod.rs index 7a97437ce5..9e7a1d8379 100644 --- a/crates/nu-cli/src/completions/mod.rs +++ b/crates/nu-cli/src/completions/mod.rs @@ -16,6 +16,6 @@ pub use completion_options::{CompletionOptions, MatchAlgorithm, SortBy}; pub use custom_completions::CustomCompletion; pub use directory_completions::DirectoryCompletion; pub use dotnu_completions::DotNuCompletion; -pub use file_completions::{escape_path_str, file_path_completion, partial_from, FileCompletion}; +pub use file_completions::{file_path_completion, partial_from, FileCompletion}; pub use flag_completions::FlagCompletion; pub use variable_completions::VariableCompletion; diff --git a/crates/nu-cli/tests/test_completions.rs b/crates/nu-cli/tests/test_completions.rs index 5ca6ad07ce..7ea7b1c93a 100644 --- a/crates/nu-cli/tests/test_completions.rs +++ b/crates/nu-cli/tests/test_completions.rs @@ -8,7 +8,6 @@ use reedline::{Completer, Suggestion}; const SEP: char = std::path::MAIN_SEPARATOR; #[test] -#[cfg(not(target_os = "windows"))] fn file_completions() { // Create a new engine let (dir, dir_str, engine) = new_engine(); @@ -24,11 +23,12 @@ fn file_completions() { // Create the expected values let expected_paths: Vec = vec![ - folder(dir.clone().join("test_a")), - folder(dir.clone().join("test_b")), - folder(dir.clone().join("another")), - file(dir.clone().join(".hidden_file")), - folder(dir.clone().join(".hidden_folder")), + file(dir.join("nushell")), + folder(dir.join("test_a")), + folder(dir.join("test_b")), + folder(dir.join("another")), + file(dir.join(".hidden_file")), + folder(dir.join(".hidden_folder")), ]; // Match the results @@ -46,7 +46,6 @@ fn file_completions() { } #[test] -#[cfg(not(target_os = "windows"))] fn folder_completions() { // Create a new engine let (dir, dir_str, engine) = new_engine(); @@ -88,26 +87,9 @@ pub fn new_engine() -> (PathBuf, String, EngineState) { } // match a list of suggestions with the expected values -// skipping the order (for now) due to some issue with sorting behaving -// differently for each OS -fn match_suggestions(expected: Vec, suggestions: Vec) { - suggestions.into_iter().for_each(|it| { - let items = expected.clone(); - let result = items.into_iter().find(|x| { - let mut current_item = x.clone(); - - // For windows the expected should also escape "\" - if cfg!(windows) { - current_item = current_item.replace("\\", "\\\\"); - } - - ¤t_item == &it.value - }); - - match result { - Some(val) => assert_eq!(val, it.value), - None => panic!("the path {} is not expected", it.value), - } +pub fn match_suggestions(expected: Vec, suggestions: Vec) { + expected.iter().zip(suggestions).for_each(|it| { + assert_eq!(it.0, &it.1.value); }); } diff --git a/tests/fixtures/completions/nushell b/tests/fixtures/completions/nushell new file mode 100644 index 0000000000..e69de29bb2