From a17ffdfe5674d87b9a43d7d1c0ed616fd42174df Mon Sep 17 00:00:00 2001 From: Yash Thakur <45539777+ysthakur@users.noreply.github.com> Date: Wed, 12 Mar 2025 09:13:41 -0400 Subject: [PATCH] Include symlinks in directory completions (#15268) Fixes #15077 # Description Symlinks are currently not shown in directory completions. #14667 modified completions so that symlinks wouldn't be suggested with trailing slashes, but it did this by treating symlinks as files. This PR includes symlinks to directories when completing directories, but still suggests them without trailing slashes. # User-Facing Changes Directory completions will once again include symlinks. # Tests + Formatting # After Submitting --- .../src/completions/completion_common.rs | 5 +++-- crates/nu-cli/tests/completions/mod.rs | 21 ++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/crates/nu-cli/src/completions/completion_common.rs b/crates/nu-cli/src/completions/completion_common.rs index f5adb6aecdd..31a4bdd75b2 100644 --- a/crates/nu-cli/src/completions/completion_common.rs +++ b/crates/nu-cli/src/completions/completion_common.rs @@ -65,10 +65,11 @@ 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() && !entry.path().is_symlink(); + let entry_isdir = entry.path().is_dir(); let mut built = built.clone(); built.parts.push(entry_name.clone()); - built.isdir = entry_isdir; + // Symlinks to directories shouldn't have a trailing slash (#13275) + built.isdir = entry_isdir && !entry.path().is_symlink(); if !want_directory || entry_isdir { matcher.add(entry_name.clone(), (entry_name, built)); diff --git a/crates/nu-cli/tests/completions/mod.rs b/crates/nu-cli/tests/completions/mod.rs index 8c29c83ebc8..5890aa21da4 100644 --- a/crates/nu-cli/tests/completions/mod.rs +++ b/crates/nu-cli/tests/completions/mod.rs @@ -307,7 +307,12 @@ fn custom_arguments_and_subcommands() { let completion_str = "foo test"; let suggestions = completer.complete(completion_str, completion_str.len()); // including both subcommand and directory completions - let expected = ["foo test bar".into(), folder("test_a"), folder("test_b")]; + let expected = [ + "foo test bar".into(), + folder("test_a"), + file("test_a_symlink"), + folder("test_b"), + ]; match_suggestions_by_string(&expected, &suggestions); } @@ -1492,6 +1497,7 @@ fn folder_with_directorycompletions() { folder(dir.join("another")), folder(dir.join("directory_completion")), folder(dir.join("test_a")), + file(dir.join("test_a_symlink")), folder(dir.join("test_b")), folder(dir.join(".hidden_folder")), ]; @@ -1594,6 +1600,12 @@ fn folder_with_directorycompletions_with_three_trailing_dots() { .join("...") .join("test_a"), ), + file( + dir.join("directory_completion") + .join("folder_inside_folder") + .join("...") + .join("test_a_symlink"), + ), folder( dir.join("directory_completion") .join("folder_inside_folder") @@ -1666,6 +1678,13 @@ fn folder_with_directorycompletions_do_not_collapse_dots() { .join("..") .join("test_a"), ), + file( + dir.join("directory_completion") + .join("folder_inside_folder") + .join("..") + .join("..") + .join("test_a_symlink"), + ), folder( dir.join("directory_completion") .join("folder_inside_folder")