@@ -225,7 +225,8 @@ impl OpenPathPrompt {
cx: &mut Context<Workspace>,
) {
workspace.toggle_modal(window, cx, |window, cx| {
- let delegate = OpenPathDelegate::new(tx, lister.clone(), creating_path, cx);
+ let delegate =
+ OpenPathDelegate::new(tx, lister.clone(), creating_path, cx).show_hidden();
let picker = Picker::uniform_list(delegate, window, cx).width(rems(34.));
let mut query = lister.default_query(cx);
if let Some(suggested_name) = suggested_name {
@@ -402,14 +403,15 @@ impl PickerDelegate for OpenPathDelegate {
return;
};
+ if !hidden_entries {
+ new_entries.retain(|entry| !entry.path.string.starts_with('.'));
+ }
+
let max_id = new_entries
.iter()
.map(|entry| entry.path.id)
.max()
.unwrap_or(0);
- if !suffix.starts_with('.') && !hidden_entries {
- new_entries.retain(|entry| !entry.path.string.starts_with('.'));
- }
if suffix.is_empty() {
let should_prepend_with_current_dir = this
@@ -489,6 +491,8 @@ impl PickerDelegate for OpenPathDelegate {
if is_create_state && !entry.is_dir && Some(&suffix) == Some(&entry.path.string)
{
None
+ } else if !suffix.is_empty() && entry.path.string == current_dir {
+ None
} else {
Some(&entry.path)
}
@@ -892,33 +896,6 @@ fn path_candidates(
.collect()
}
-#[cfg(target_os = "windows")]
-fn get_dir_and_suffix(query: String, path_style: PathStyle) -> (String, String) {
- let last_item = Path::new(&query)
- .file_name()
- .unwrap_or_default()
- .to_string_lossy();
- let (mut dir, suffix) = if let Some(dir) = query.strip_suffix(last_item.as_ref()) {
- (dir.to_string(), last_item.into_owned())
- } else {
- (query.to_string(), String::new())
- };
- match path_style {
- PathStyle::Posix => {
- if dir.is_empty() {
- dir = "/".to_string();
- }
- }
- PathStyle::Windows => {
- if dir.len() < 3 {
- dir = "C:\\".to_string();
- }
- }
- }
- (dir, suffix)
-}
-
-#[cfg(not(target_os = "windows"))]
fn get_dir_and_suffix(query: String, path_style: PathStyle) -> (String, String) {
match path_style {
PathStyle::Posix => {
@@ -933,17 +910,18 @@ fn get_dir_and_suffix(query: String, path_style: PathStyle) -> (String, String)
(dir, suffix)
}
PathStyle::Windows => {
- let (mut dir, suffix) = if let Some(index) = query.rfind('\\') {
- (query[..index].to_string(), query[index + 1..].to_string())
+ let last_sep = query.rfind('\\').into_iter().chain(query.rfind('/')).max();
+ let (mut dir, suffix) = if let Some(index) = last_sep {
+ (
+ query[..index + 1].to_string(),
+ query[index + 1..].to_string(),
+ )
} else {
(query, String::new())
};
if dir.len() < 3 {
dir = "C:\\".to_string();
}
- if !dir.ends_with('\\') {
- dir.push('\\');
- }
(dir, suffix)
}
}
@@ -987,6 +965,34 @@ mod tests {
get_dir_and_suffix("C:\\Users\\Junkui\\Documents\\".into(), PathStyle::Windows);
assert_eq!(dir, "C:\\Users\\Junkui\\Documents\\");
assert_eq!(suffix, "");
+
+ let (dir, suffix) = get_dir_and_suffix("C:\\root\\.".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:\\root\\");
+ assert_eq!(suffix, ".");
+
+ let (dir, suffix) = get_dir_and_suffix("C:\\root\\..".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:\\root\\");
+ assert_eq!(suffix, "..");
+
+ let (dir, suffix) = get_dir_and_suffix("C:\\root\\.hidden".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:\\root\\");
+ assert_eq!(suffix, ".hidden");
+
+ let (dir, suffix) = get_dir_and_suffix("C:/root/".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:/root/");
+ assert_eq!(suffix, "");
+
+ let (dir, suffix) = get_dir_and_suffix("C:/root/Use".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:/root/");
+ assert_eq!(suffix, "Use");
+
+ let (dir, suffix) = get_dir_and_suffix("C:\\root/Use".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:\\root/");
+ assert_eq!(suffix, "Use");
+
+ let (dir, suffix) = get_dir_and_suffix("C:/root\\.hidden".into(), PathStyle::Windows);
+ assert_eq!(dir, "C:/root\\");
+ assert_eq!(suffix, ".hidden");
}
#[test]
@@ -1014,5 +1020,17 @@ mod tests {
let (dir, suffix) = get_dir_and_suffix("/Users/Junkui/Documents/".into(), PathStyle::Posix);
assert_eq!(dir, "/Users/Junkui/Documents/");
assert_eq!(suffix, "");
+
+ let (dir, suffix) = get_dir_and_suffix("/root/.".into(), PathStyle::Posix);
+ assert_eq!(dir, "/root/");
+ assert_eq!(suffix, ".");
+
+ let (dir, suffix) = get_dir_and_suffix("/root/..".into(), PathStyle::Posix);
+ assert_eq!(dir, "/root/");
+ assert_eq!(suffix, "..");
+
+ let (dir, suffix) = get_dir_and_suffix("/root/.hidden".into(), PathStyle::Posix);
+ assert_eq!(dir, "/root/");
+ assert_eq!(suffix, ".hidden");
}
}
@@ -19,6 +19,8 @@ async fn test_open_path_prompt(cx: &mut TestAppContext) {
.insert_tree(
path!("/root"),
json!({
+ ".a1": ".A1",
+ ".b1": ".B1",
"a1": "A1",
"a2": "A2",
"a3": "A3",
@@ -51,7 +53,7 @@ async fn test_open_path_prompt(cx: &mut TestAppContext) {
#[cfg(windows)]
let expected_separator = ".\\";
- // If the query ends with a slash, the picker should show the contents of the directory.
+ // If the query ends with a slash, the picker should show the contents of the directory and not show any of the hidden entries.
let query = path!("/root/");
insert_query(query, &picker, cx).await;
assert_eq!(
@@ -94,6 +96,33 @@ async fn test_open_path_prompt(cx: &mut TestAppContext) {
let query = path!("/root/dir2/di");
insert_query(query, &picker, cx).await;
assert_eq!(collect_match_candidates(&picker, cx), vec!["dir3", "dir4"]);
+
+ // Don't show candidates for the query ".".
+ let query = path!("/root/.");
+ insert_query(query, &picker, cx).await;
+ assert_eq!(collect_match_candidates(&picker, cx), Vec::<String>::new());
+
+ // Don't show any candidates for the query ".a".
+ let query = path!("/root/.a");
+ insert_query(query, &picker, cx).await;
+ assert_eq!(collect_match_candidates(&picker, cx), Vec::<String>::new());
+
+ // Show candidates for the query "./".
+ // Should show current directory and contents.
+ let query = path!("/root/./");
+ insert_query(query, &picker, cx).await;
+ assert_eq!(
+ collect_match_candidates(&picker, cx),
+ vec![expected_separator, "a1", "a2", "a3", "dir1", "dir2"]
+ );
+
+ // Show candidates for the query "../". Show parent contents.
+ let query = path!("/root/dir1/../");
+ insert_query(query, &picker, cx).await;
+ assert_eq!(
+ collect_match_candidates(&picker, cx),
+ vec![expected_separator, "a1", "a2", "a3", "dir1", "dir2"]
+ );
}
#[gpui::test]
@@ -369,11 +398,13 @@ async fn test_open_path_prompt_with_show_hidden(cx: &mut TestAppContext) {
let expected_separator = ".\\";
insert_query(path!("/root/"), &picker, cx).await;
-
assert_eq!(
collect_match_candidates(&picker, cx),
vec![expected_separator, ".hidden", "directory_1", "directory_2"]
);
+
+ insert_query(path!("/root/."), &picker, cx).await;
+ assert_eq!(collect_match_candidates(&picker, cx), vec![".hidden"]);
}
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {