From 76bbd41e43f37d4d190f7f45845ffd53505bc90f Mon Sep 17 00:00:00 2001 From: Henry Jetmundsen <32406734+hjetmundsen@users.noreply.github.com> Date: Fri, 27 Dec 2024 06:45:52 -0500 Subject: [PATCH] Remove trailing slash from symlink completion (issue #13275) (#14667) # Description These changes fix #13275 where a slash is appended to completions of symlinks pointing to directories. # User-Facing Changes The `/` character will no longer be appended to completions of symlinks. Co-authored-by: Henry Jetmundsen --- .../src/completions/completion_common.rs | 2 +- crates/nu-cli/tests/completions/mod.rs | 60 ++++++++++++++++--- tests/fixtures/completions/test_a_symlink | 1 + 3 files changed, 55 insertions(+), 8 deletions(-) create mode 120000 tests/fixtures/completions/test_a_symlink diff --git a/crates/nu-cli/src/completions/completion_common.rs b/crates/nu-cli/src/completions/completion_common.rs index 4969cbd51d..4ab0f8f509 100644 --- a/crates/nu-cli/src/completions/completion_common.rs +++ b/crates/nu-cli/src/completions/completion_common.rs @@ -65,7 +65,7 @@ fn complete_rec( for entry in result.filter_map(|e| e.ok()) { let entry_name = entry.file_name().to_string_lossy().into_owned(); - let entry_isdir = entry.path().is_dir(); + let entry_isdir = entry.path().is_dir() && !entry.path().is_symlink(); let mut built = built.clone(); built.parts.push(entry_name.clone()); built.isdir = entry_isdir; diff --git a/crates/nu-cli/tests/completions/mod.rs b/crates/nu-cli/tests/completions/mod.rs index e32ac8c4f2..18390345e4 100644 --- a/crates/nu-cli/tests/completions/mod.rs +++ b/crates/nu-cli/tests/completions/mod.rs @@ -176,7 +176,7 @@ fn variables_dollar_sign_with_variablecompletion() { let target_dir = "$ "; let suggestions = completer.complete(target_dir, target_dir.len()); - assert_eq!(8, suggestions.len()); + assert_eq!(9, suggestions.len()); } #[rstest] @@ -335,6 +335,7 @@ fn file_completions() { folder(dir.join("directory_completion")), file(dir.join("nushell")), folder(dir.join("test_a")), + file(dir.join("test_a_symlink")), folder(dir.join("test_b")), file(dir.join(".hidden_file")), folder(dir.join(".hidden_folder")), @@ -368,6 +369,7 @@ fn file_completions() { folder(dir.join("directory_completion")), file(dir.join("nushell")), folder(dir.join("test_a")), + file(dir.join("test_a_symlink")), folder(dir.join("test_b")), file(dir.join(".hidden_file")), folder(dir.join(".hidden_folder")), @@ -445,6 +447,7 @@ fn custom_command_rest_any_args_file_completions() { folder(dir.join("directory_completion")), file(dir.join("nushell")), folder(dir.join("test_a")), + file(dir.join("test_a_symlink")), folder(dir.join("test_b")), file(dir.join(".hidden_file")), folder(dir.join(".hidden_folder")), @@ -464,6 +467,7 @@ fn custom_command_rest_any_args_file_completions() { folder(dir.join("directory_completion")), file(dir.join("nushell")), folder(dir.join("test_a")), + file(dir.join("test_a_symlink")), folder(dir.join("test_b")), file(dir.join(".hidden_file")), folder(dir.join(".hidden_folder")), @@ -763,6 +767,7 @@ fn command_ls_with_filecompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -774,6 +779,7 @@ fn command_ls_with_filecompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -805,6 +811,7 @@ fn command_open_with_filecompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -816,6 +823,7 @@ fn command_open_with_filecompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -847,6 +855,7 @@ fn command_rm_with_globcompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -858,6 +867,7 @@ fn command_rm_with_globcompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -882,6 +892,7 @@ fn command_cp_with_globcompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -893,6 +904,7 @@ fn command_cp_with_globcompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -917,6 +929,7 @@ fn command_save_with_filecompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -928,6 +941,7 @@ fn command_save_with_filecompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -952,6 +966,7 @@ fn command_touch_with_filecompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -963,6 +978,7 @@ fn command_touch_with_filecompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -987,6 +1003,7 @@ fn command_watch_with_filecompletion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -998,6 +1015,7 @@ fn command_watch_with_filecompletion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -1452,9 +1470,17 @@ fn alias_of_command_and_flags() { let suggestions = completer.complete("ll t", 4); #[cfg(windows)] - let expected_paths: Vec = vec!["test_a\\".to_string(), "test_b\\".to_string()]; + let expected_paths: Vec = vec![ + "test_a\\".to_string(), + "test_a_symlink".to_string(), + "test_b\\".to_string(), + ]; #[cfg(not(windows))] - let expected_paths: Vec = vec!["test_a/".to_string(), "test_b/".to_string()]; + let expected_paths: Vec = vec![ + "test_a/".to_string(), + "test_a_symlink".to_string(), + "test_b/".to_string(), + ]; match_suggestions(&expected_paths, &suggestions) } @@ -1471,9 +1497,17 @@ fn alias_of_basic_command() { let suggestions = completer.complete("ll t", 4); #[cfg(windows)] - let expected_paths: Vec = vec!["test_a\\".to_string(), "test_b\\".to_string()]; + let expected_paths: Vec = vec![ + "test_a\\".to_string(), + "test_a_symlink".to_string(), + "test_b\\".to_string(), + ]; #[cfg(not(windows))] - let expected_paths: Vec = vec!["test_a/".to_string(), "test_b/".to_string()]; + let expected_paths: Vec = vec![ + "test_a/".to_string(), + "test_a_symlink".to_string(), + "test_b/".to_string(), + ]; match_suggestions(&expected_paths, &suggestions) } @@ -1493,9 +1527,17 @@ fn alias_of_another_alias() { let suggestions = completer.complete("lf t", 4); #[cfg(windows)] - let expected_paths: Vec = vec!["test_a\\".to_string(), "test_b\\".to_string()]; + let expected_paths: Vec = vec![ + "test_a\\".to_string(), + "test_a_symlink".to_string(), + "test_b\\".to_string(), + ]; #[cfg(not(windows))] - let expected_paths: Vec = vec!["test_a/".to_string(), "test_b/".to_string()]; + let expected_paths: Vec = vec![ + "test_a/".to_string(), + "test_a_symlink".to_string(), + "test_b/".to_string(), + ]; match_suggestions(&expected_paths, &suggestions) } @@ -1544,6 +1586,7 @@ fn unknown_command_completion() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -1555,6 +1598,7 @@ fn unknown_command_completion() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), @@ -1606,6 +1650,7 @@ fn filecompletions_triggers_after_cursor() { "directory_completion\\".to_string(), "nushell".to_string(), "test_a\\".to_string(), + "test_a_symlink".to_string(), "test_b\\".to_string(), ".hidden_file".to_string(), ".hidden_folder\\".to_string(), @@ -1617,6 +1662,7 @@ fn filecompletions_triggers_after_cursor() { "directory_completion/".to_string(), "nushell".to_string(), "test_a/".to_string(), + "test_a_symlink".to_string(), "test_b/".to_string(), ".hidden_file".to_string(), ".hidden_folder/".to_string(), diff --git a/tests/fixtures/completions/test_a_symlink b/tests/fixtures/completions/test_a_symlink new file mode 120000 index 0000000000..a4bcb06a3d --- /dev/null +++ b/tests/fixtures/completions/test_a_symlink @@ -0,0 +1 @@ +test_a \ No newline at end of file