From b39d797c1f40071f35d51c9940f7c0de16e4053a Mon Sep 17 00:00:00 2001 From: pwygab <88221256+merelymyself@users.noreply.github.com> Date: Fri, 9 Dec 2022 04:37:10 +0800 Subject: [PATCH] Add quotes to hash file autocomplete (#7398) # Description Fixes #6741. Autocompleting a dir/file named something like foo#bar will now complete to \`foo#bar\` --- .../src/completions/directory_completions.rs | 8 +++- .../src/completions/file_completions.rs | 8 +++- crates/nu-cli/tests/completions.rs | 20 +++++++++- .../tests/support/completions_helpers.rs | 39 +++++++++++++++++++ tests/fixtures/quoted_completions/te st.txt | 0 tests/fixtures/quoted_completions/te#st.txt | 0 tests/fixtures/quoted_completions/te'st.txt | 0 7 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 tests/fixtures/quoted_completions/te st.txt create mode 100644 tests/fixtures/quoted_completions/te#st.txt create mode 100644 tests/fixtures/quoted_completions/te'st.txt diff --git a/crates/nu-cli/src/completions/directory_completions.rs b/crates/nu-cli/src/completions/directory_completions.rs index e413d45e0c..27a6f80d1c 100644 --- a/crates/nu-cli/src/completions/directory_completions.rs +++ b/crates/nu-cli/src/completions/directory_completions.rs @@ -136,8 +136,12 @@ pub fn directory_completion( file_name.push(SEP); } - // Fix files or folders with quotes - if path.contains('\'') || path.contains('"') || path.contains(' ') { + // Fix files or folders with quotes or hash + if path.contains('\'') + || path.contains('"') + || path.contains(' ') + || path.contains('#') + { path = format!("`{}`", path); } diff --git a/crates/nu-cli/src/completions/file_completions.rs b/crates/nu-cli/src/completions/file_completions.rs index de0040e84a..d589799d1b 100644 --- a/crates/nu-cli/src/completions/file_completions.rs +++ b/crates/nu-cli/src/completions/file_completions.rs @@ -141,8 +141,12 @@ pub fn file_path_completion( file_name.push(SEP); } - // Fix files or folders with quotes - if path.contains('\'') || path.contains('"') || path.contains(' ') { + // Fix files or folders with quotes or hashes + if path.contains('\'') + || path.contains('"') + || path.contains(' ') + || path.contains('#') + { path = format!("`{}`", path); } diff --git a/crates/nu-cli/tests/completions.rs b/crates/nu-cli/tests/completions.rs index 2ecf053ac6..098434d6f8 100644 --- a/crates/nu-cli/tests/completions.rs +++ b/crates/nu-cli/tests/completions.rs @@ -5,7 +5,7 @@ use nu_parser::parse; use nu_protocol::engine::StateWorkingSet; use reedline::{Completer, Suggestion}; use rstest::{fixture, rstest}; -use support::{file, folder, match_suggestions, new_engine}; +use support::{completions_helpers::new_quote_engine, file, folder, match_suggestions, new_engine}; #[fixture] fn completer() -> NuCompleter { @@ -411,6 +411,24 @@ fn command_watch_with_filecompletion() { match_suggestions(expected_paths, suggestions) } +#[test] +fn file_completion_quoted() { + let (_, _, engine, stack) = new_quote_engine(); + + let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + + let target_dir = "open "; + let suggestions = completer.complete(target_dir, target_dir.len()); + + let expected_paths: Vec = vec![ + "`te st.txt`".to_string(), + "`te#st.txt`".to_string(), + "`te'st.txt`".to_string(), + ]; + + match_suggestions(expected_paths, suggestions) +} + #[test] fn flag_completions() { // Create a new engine diff --git a/crates/nu-cli/tests/support/completions_helpers.rs b/crates/nu-cli/tests/support/completions_helpers.rs index 2ef7b648ac..7b50edf7a5 100644 --- a/crates/nu-cli/tests/support/completions_helpers.rs +++ b/crates/nu-cli/tests/support/completions_helpers.rs @@ -51,6 +51,45 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { (dir, dir_str, engine_state, stack) } +pub fn new_quote_engine() -> (PathBuf, String, EngineState, Stack) { + // Target folder inside assets + let dir = fs::fixtures().join("quoted_completions"); + let mut dir_str = dir + .clone() + .into_os_string() + .into_string() + .unwrap_or_default(); + dir_str.push(SEP); + + // Create a new engine with default context + let mut engine_state = create_default_context(); + + // New stack + let mut stack = Stack::new(); + + // Add pwd as env var + stack.add_env_var( + "PWD".to_string(), + Value::String { + val: dir_str.clone(), + span: nu_protocol::Span::new(0, dir_str.len()), + }, + ); + stack.add_env_var( + "TEST".to_string(), + Value::String { + val: "NUSHELL".to_string(), + span: nu_protocol::Span::new(0, dir_str.len()), + }, + ); + + // Merge environment into the permanent state + let merge_result = engine_state.merge_env(&mut stack, &dir); + assert!(merge_result.is_ok()); + + (dir, dir_str, engine_state, stack) +} + // match a list of suggestions with the expected values pub fn match_suggestions(expected: Vec, suggestions: Vec) { let expected_len = expected.len(); diff --git a/tests/fixtures/quoted_completions/te st.txt b/tests/fixtures/quoted_completions/te st.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/fixtures/quoted_completions/te#st.txt b/tests/fixtures/quoted_completions/te#st.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/fixtures/quoted_completions/te'st.txt b/tests/fixtures/quoted_completions/te'st.txt new file mode 100644 index 0000000000..e69de29bb2