file_finder: Add option to create new file (#31567)
https://github.com/user-attachments/assets/7c8a05a1-8d59-4371-a1d6-a8cb82aa13b9 While implementing this, I noticed that currently when the search panel displays only one result, the box oscillates a bit up and down like so: https://github.com/user-attachments/assets/dd1520e2-fa0b-4307-b27a-984e69b0a644 Not sure how to fix this at the moment, maybe that could be another PR? Release Notes: - Add option to create new file in project search panel.
This commit is contained in:
parent
1bc052d76b
commit
de225fd242
2 changed files with 117 additions and 33 deletions
|
@ -332,6 +332,7 @@ impl FileFinder {
|
||||||
worktree_id: WorktreeId::from_usize(m.0.worktree_id),
|
worktree_id: WorktreeId::from_usize(m.0.worktree_id),
|
||||||
path: m.0.path.clone(),
|
path: m.0.path.clone(),
|
||||||
},
|
},
|
||||||
|
Match::CreateNew(p) => p.clone(),
|
||||||
};
|
};
|
||||||
let open_task = workspace.update(cx, move |workspace, cx| {
|
let open_task = workspace.update(cx, move |workspace, cx| {
|
||||||
workspace.split_path_preview(path, false, Some(split_direction), window, cx)
|
workspace.split_path_preview(path, false, Some(split_direction), window, cx)
|
||||||
|
@ -456,13 +457,15 @@ enum Match {
|
||||||
panel_match: Option<ProjectPanelOrdMatch>,
|
panel_match: Option<ProjectPanelOrdMatch>,
|
||||||
},
|
},
|
||||||
Search(ProjectPanelOrdMatch),
|
Search(ProjectPanelOrdMatch),
|
||||||
|
CreateNew(ProjectPath),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Match {
|
impl Match {
|
||||||
fn path(&self) -> &Arc<Path> {
|
fn path(&self) -> Option<&Arc<Path>> {
|
||||||
match self {
|
match self {
|
||||||
Match::History { path, .. } => &path.project.path,
|
Match::History { path, .. } => Some(&path.project.path),
|
||||||
Match::Search(panel_match) => &panel_match.0.path,
|
Match::Search(panel_match) => Some(&panel_match.0.path),
|
||||||
|
Match::CreateNew(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,6 +473,7 @@ impl Match {
|
||||||
match self {
|
match self {
|
||||||
Match::History { panel_match, .. } => panel_match.as_ref(),
|
Match::History { panel_match, .. } => panel_match.as_ref(),
|
||||||
Match::Search(panel_match) => Some(&panel_match),
|
Match::Search(panel_match) => Some(&panel_match),
|
||||||
|
Match::CreateNew(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,7 +503,10 @@ impl Matches {
|
||||||
// reason for the matches set to change.
|
// reason for the matches set to change.
|
||||||
self.matches
|
self.matches
|
||||||
.iter()
|
.iter()
|
||||||
.position(|m| path.project.path == *m.path())
|
.position(|m| match m.path() {
|
||||||
|
Some(p) => path.project.path == *p,
|
||||||
|
None => false,
|
||||||
|
})
|
||||||
.ok_or(0)
|
.ok_or(0)
|
||||||
} else {
|
} else {
|
||||||
self.matches.binary_search_by(|m| {
|
self.matches.binary_search_by(|m| {
|
||||||
|
@ -576,6 +583,12 @@ impl Matches {
|
||||||
a: &Match,
|
a: &Match,
|
||||||
b: &Match,
|
b: &Match,
|
||||||
) -> cmp::Ordering {
|
) -> cmp::Ordering {
|
||||||
|
// Handle CreateNew variant - always put it at the end
|
||||||
|
match (a, b) {
|
||||||
|
(Match::CreateNew(_), _) => return cmp::Ordering::Less,
|
||||||
|
(_, Match::CreateNew(_)) => return cmp::Ordering::Greater,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
debug_assert!(a.panel_match().is_some() && b.panel_match().is_some());
|
debug_assert!(a.panel_match().is_some() && b.panel_match().is_some());
|
||||||
|
|
||||||
match (&a, &b) {
|
match (&a, &b) {
|
||||||
|
@ -908,6 +921,23 @@ impl FileFinderDelegate {
|
||||||
matches.into_iter(),
|
matches.into_iter(),
|
||||||
extend_old_matches,
|
extend_old_matches,
|
||||||
);
|
);
|
||||||
|
let worktree = self.project.read(cx).visible_worktrees(cx).next();
|
||||||
|
let filename = query.raw_query.to_string();
|
||||||
|
let path = Path::new(&filename);
|
||||||
|
|
||||||
|
// add option of creating new file only if path is relative
|
||||||
|
if let Some(worktree) = worktree {
|
||||||
|
let worktree = worktree.read(cx);
|
||||||
|
if path.is_relative()
|
||||||
|
&& worktree.entry_for_path(&path).is_none()
|
||||||
|
&& !filename.ends_with("/")
|
||||||
|
{
|
||||||
|
self.matches.matches.push(Match::CreateNew(ProjectPath {
|
||||||
|
worktree_id: worktree.id(),
|
||||||
|
path: Arc::from(path),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.selected_index = selected_match.map_or_else(
|
self.selected_index = selected_match.map_or_else(
|
||||||
|| self.calculate_selected_index(cx),
|
|| self.calculate_selected_index(cx),
|
||||||
|
@ -988,6 +1018,12 @@ impl FileFinderDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Match::Search(path_match) => self.labels_for_path_match(&path_match.0),
|
Match::Search(path_match) => self.labels_for_path_match(&path_match.0),
|
||||||
|
Match::CreateNew(project_path) => (
|
||||||
|
format!("Create file: {}", project_path.path.display()),
|
||||||
|
vec![],
|
||||||
|
String::from(""),
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
if file_name_positions.is_empty() {
|
if file_name_positions.is_empty() {
|
||||||
|
@ -1372,6 +1408,29 @@ impl PickerDelegate for FileFinderDelegate {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match &m {
|
match &m {
|
||||||
|
Match::CreateNew(project_path) => {
|
||||||
|
// Create a new file with the given filename
|
||||||
|
if secondary {
|
||||||
|
workspace.split_path_preview(
|
||||||
|
project_path.clone(),
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
workspace.open_path_preview(
|
||||||
|
project_path.clone(),
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Match::History { path, .. } => {
|
Match::History { path, .. } => {
|
||||||
let worktree_id = path.project.worktree_id;
|
let worktree_id = path.project.worktree_id;
|
||||||
if workspace
|
if workspace
|
||||||
|
@ -1502,6 +1561,10 @@ impl PickerDelegate for FileFinderDelegate {
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.size(IconSize::Small.rems())
|
.size(IconSize::Small.rems())
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
|
Match::CreateNew(_) => Icon::new(IconName::Plus)
|
||||||
|
.color(Color::Muted)
|
||||||
|
.size(IconSize::Small)
|
||||||
|
.into_any_element(),
|
||||||
};
|
};
|
||||||
let (file_name_label, full_path_label) = self.labels_for_match(path_match, window, cx, ix);
|
let (file_name_label, full_path_label) = self.labels_for_match(path_match, window, cx, ix);
|
||||||
|
|
||||||
|
@ -1509,7 +1572,7 @@ impl PickerDelegate for FileFinderDelegate {
|
||||||
if !settings.file_icons {
|
if !settings.file_icons {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let file_name = path_match.path().file_name()?;
|
let file_name = path_match.path()?.file_name()?;
|
||||||
let icon = FileIcons::get_icon(file_name.as_ref(), cx)?;
|
let icon = FileIcons::get_icon(file_name.as_ref(), cx)?;
|
||||||
Some(Icon::from_path(icon).color(Color::Muted))
|
Some(Icon::from_path(icon).color(Color::Muted))
|
||||||
});
|
});
|
||||||
|
|
|
@ -196,7 +196,7 @@ async fn test_matching_paths(cx: &mut TestAppContext) {
|
||||||
|
|
||||||
cx.simulate_input("bna");
|
cx.simulate_input("bna");
|
||||||
picker.update(cx, |picker, _| {
|
picker.update(cx, |picker, _| {
|
||||||
assert_eq!(picker.delegate.matches.len(), 2);
|
assert_eq!(picker.delegate.matches.len(), 3);
|
||||||
});
|
});
|
||||||
cx.dispatch_action(SelectNext);
|
cx.dispatch_action(SelectNext);
|
||||||
cx.dispatch_action(Confirm);
|
cx.dispatch_action(Confirm);
|
||||||
|
@ -229,7 +229,12 @@ async fn test_matching_paths(cx: &mut TestAppContext) {
|
||||||
picker.update(cx, |picker, _| {
|
picker.update(cx, |picker, _| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
picker.delegate.matches.len(),
|
picker.delegate.matches.len(),
|
||||||
1,
|
// existence of CreateNew option depends on whether path already exists
|
||||||
|
if bandana_query == util::separator!("a/bandana") {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
},
|
||||||
"Wrong number of matches for bandana query '{bandana_query}'. Matches: {:?}",
|
"Wrong number of matches for bandana query '{bandana_query}'. Matches: {:?}",
|
||||||
picker.delegate.matches
|
picker.delegate.matches
|
||||||
);
|
);
|
||||||
|
@ -269,9 +274,9 @@ async fn test_unicode_paths(cx: &mut TestAppContext) {
|
||||||
|
|
||||||
cx.simulate_input("g");
|
cx.simulate_input("g");
|
||||||
picker.update(cx, |picker, _| {
|
picker.update(cx, |picker, _| {
|
||||||
assert_eq!(picker.delegate.matches.len(), 1);
|
assert_eq!(picker.delegate.matches.len(), 2);
|
||||||
|
assert_match_at_position(picker, 1, "g");
|
||||||
});
|
});
|
||||||
cx.dispatch_action(SelectNext);
|
|
||||||
cx.dispatch_action(Confirm);
|
cx.dispatch_action(Confirm);
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
|
let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
|
||||||
|
@ -365,13 +370,12 @@ async fn test_complex_path(cx: &mut TestAppContext) {
|
||||||
|
|
||||||
cx.simulate_input("t");
|
cx.simulate_input("t");
|
||||||
picker.update(cx, |picker, _| {
|
picker.update(cx, |picker, _| {
|
||||||
assert_eq!(picker.delegate.matches.len(), 1);
|
assert_eq!(picker.delegate.matches.len(), 2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
collect_search_matches(picker).search_paths_only(),
|
collect_search_matches(picker).search_paths_only(),
|
||||||
vec![PathBuf::from("其他/S数据表格/task.xlsx")],
|
vec![PathBuf::from("其他/S数据表格/task.xlsx")],
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
cx.dispatch_action(SelectNext);
|
|
||||||
cx.dispatch_action(Confirm);
|
cx.dispatch_action(Confirm);
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
|
let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
|
||||||
|
@ -416,8 +420,9 @@ async fn test_row_column_numbers_query_inside_file(cx: &mut TestAppContext) {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
|
assert_match_at_position(finder, 1, &query_inside_file.to_string());
|
||||||
let finder = &finder.delegate;
|
let finder = &finder.delegate;
|
||||||
assert_eq!(finder.matches.len(), 1);
|
assert_eq!(finder.matches.len(), 2);
|
||||||
let latest_search_query = finder
|
let latest_search_query = finder
|
||||||
.latest_search_query
|
.latest_search_query
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -431,7 +436,6 @@ async fn test_row_column_numbers_query_inside_file(cx: &mut TestAppContext) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.dispatch_action(SelectNext);
|
|
||||||
cx.dispatch_action(Confirm);
|
cx.dispatch_action(Confirm);
|
||||||
|
|
||||||
let editor = cx.update(|_, cx| workspace.read(cx).active_item_as::<Editor>(cx).unwrap());
|
let editor = cx.update(|_, cx| workspace.read(cx).active_item_as::<Editor>(cx).unwrap());
|
||||||
|
@ -491,8 +495,9 @@ async fn test_row_column_numbers_query_outside_file(cx: &mut TestAppContext) {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
|
assert_match_at_position(finder, 1, &query_outside_file.to_string());
|
||||||
let delegate = &finder.delegate;
|
let delegate = &finder.delegate;
|
||||||
assert_eq!(delegate.matches.len(), 1);
|
assert_eq!(delegate.matches.len(), 2);
|
||||||
let latest_search_query = delegate
|
let latest_search_query = delegate
|
||||||
.latest_search_query
|
.latest_search_query
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -506,7 +511,6 @@ async fn test_row_column_numbers_query_outside_file(cx: &mut TestAppContext) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.dispatch_action(SelectNext);
|
|
||||||
cx.dispatch_action(Confirm);
|
cx.dispatch_action(Confirm);
|
||||||
|
|
||||||
let editor = cx.update(|_, cx| workspace.read(cx).active_item_as::<Editor>(cx).unwrap());
|
let editor = cx.update(|_, cx| workspace.read(cx).active_item_as::<Editor>(cx).unwrap());
|
||||||
|
@ -561,7 +565,8 @@ async fn test_matching_cancellation(cx: &mut TestAppContext) {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
picker.update(cx, |picker, _cx| {
|
picker.update(cx, |picker, _cx| {
|
||||||
assert_eq!(picker.delegate.matches.len(), 5)
|
// CreateNew option not shown in this case since file already exists
|
||||||
|
assert_eq!(picker.delegate.matches.len(), 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
picker.update_in(cx, |picker, window, cx| {
|
picker.update_in(cx, |picker, window, cx| {
|
||||||
|
@ -959,7 +964,8 @@ async fn test_search_worktree_without_files(cx: &mut TestAppContext) {
|
||||||
.await;
|
.await;
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let finder = picker.read(cx);
|
let finder = picker.read(cx);
|
||||||
assert_eq!(finder.delegate.matches.len(), 0);
|
assert_eq!(finder.delegate.matches.len(), 1);
|
||||||
|
assert_match_at_position(finder, 0, "dir");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,12 +1524,13 @@ async fn test_keep_opened_file_on_top_of_search_results_and_select_next_one(
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 5);
|
assert_eq!(finder.delegate.matches.len(), 6);
|
||||||
assert_match_at_position(finder, 0, "main.rs");
|
assert_match_at_position(finder, 0, "main.rs");
|
||||||
assert_match_selection(finder, 1, "bar.rs");
|
assert_match_selection(finder, 1, "bar.rs");
|
||||||
assert_match_at_position(finder, 2, "lib.rs");
|
assert_match_at_position(finder, 2, "lib.rs");
|
||||||
assert_match_at_position(finder, 3, "moo.rs");
|
assert_match_at_position(finder, 3, "moo.rs");
|
||||||
assert_match_at_position(finder, 4, "maaa.rs");
|
assert_match_at_position(finder, 4, "maaa.rs");
|
||||||
|
assert_match_at_position(finder, 5, ".rs");
|
||||||
});
|
});
|
||||||
|
|
||||||
// main.rs is not among matches, select top item
|
// main.rs is not among matches, select top item
|
||||||
|
@ -1533,9 +1540,10 @@ async fn test_keep_opened_file_on_top_of_search_results_and_select_next_one(
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 3);
|
||||||
assert_match_at_position(finder, 0, "bar.rs");
|
assert_match_at_position(finder, 0, "bar.rs");
|
||||||
assert_match_at_position(finder, 1, "lib.rs");
|
assert_match_at_position(finder, 1, "lib.rs");
|
||||||
|
assert_match_at_position(finder, 2, "b");
|
||||||
});
|
});
|
||||||
|
|
||||||
// main.rs is back, put it on top and select next item
|
// main.rs is back, put it on top and select next item
|
||||||
|
@ -1545,10 +1553,11 @@ async fn test_keep_opened_file_on_top_of_search_results_and_select_next_one(
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 3);
|
assert_eq!(finder.delegate.matches.len(), 4);
|
||||||
assert_match_at_position(finder, 0, "main.rs");
|
assert_match_at_position(finder, 0, "main.rs");
|
||||||
assert_match_selection(finder, 1, "moo.rs");
|
assert_match_selection(finder, 1, "moo.rs");
|
||||||
assert_match_at_position(finder, 2, "maaa.rs");
|
assert_match_at_position(finder, 2, "maaa.rs");
|
||||||
|
assert_match_at_position(finder, 3, "m");
|
||||||
});
|
});
|
||||||
|
|
||||||
// get back to the initial state
|
// get back to the initial state
|
||||||
|
@ -1623,12 +1632,13 @@ async fn test_setting_auto_select_first_and_select_active_file(cx: &mut TestAppC
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 5);
|
assert_eq!(finder.delegate.matches.len(), 6);
|
||||||
assert_match_selection(finder, 0, "main.rs");
|
assert_match_selection(finder, 0, "main.rs");
|
||||||
assert_match_at_position(finder, 1, "bar.rs");
|
assert_match_at_position(finder, 1, "bar.rs");
|
||||||
assert_match_at_position(finder, 2, "lib.rs");
|
assert_match_at_position(finder, 2, "lib.rs");
|
||||||
assert_match_at_position(finder, 3, "moo.rs");
|
assert_match_at_position(finder, 3, "moo.rs");
|
||||||
assert_match_at_position(finder, 4, "maaa.rs");
|
assert_match_at_position(finder, 4, "maaa.rs");
|
||||||
|
assert_match_at_position(finder, 5, ".rs");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1679,12 +1689,13 @@ async fn test_non_separate_history_items(cx: &mut TestAppContext) {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 5);
|
assert_eq!(finder.delegate.matches.len(), 6);
|
||||||
assert_match_at_position(finder, 0, "main.rs");
|
assert_match_at_position(finder, 0, "main.rs");
|
||||||
assert_match_selection(finder, 1, "moo.rs");
|
assert_match_selection(finder, 1, "moo.rs");
|
||||||
assert_match_at_position(finder, 2, "bar.rs");
|
assert_match_at_position(finder, 2, "bar.rs");
|
||||||
assert_match_at_position(finder, 3, "lib.rs");
|
assert_match_at_position(finder, 3, "lib.rs");
|
||||||
assert_match_at_position(finder, 4, "maaa.rs");
|
assert_match_at_position(finder, 4, "maaa.rs");
|
||||||
|
assert_match_at_position(finder, 5, ".rs");
|
||||||
});
|
});
|
||||||
|
|
||||||
// main.rs is not among matches, select top item
|
// main.rs is not among matches, select top item
|
||||||
|
@ -1694,9 +1705,10 @@ async fn test_non_separate_history_items(cx: &mut TestAppContext) {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 3);
|
||||||
assert_match_at_position(finder, 0, "bar.rs");
|
assert_match_at_position(finder, 0, "bar.rs");
|
||||||
assert_match_at_position(finder, 1, "lib.rs");
|
assert_match_at_position(finder, 1, "lib.rs");
|
||||||
|
assert_match_at_position(finder, 2, "b");
|
||||||
});
|
});
|
||||||
|
|
||||||
// main.rs is back, put it on top and select next item
|
// main.rs is back, put it on top and select next item
|
||||||
|
@ -1706,10 +1718,11 @@ async fn test_non_separate_history_items(cx: &mut TestAppContext) {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 3);
|
assert_eq!(finder.delegate.matches.len(), 4);
|
||||||
assert_match_at_position(finder, 0, "main.rs");
|
assert_match_at_position(finder, 0, "main.rs");
|
||||||
assert_match_selection(finder, 1, "moo.rs");
|
assert_match_selection(finder, 1, "moo.rs");
|
||||||
assert_match_at_position(finder, 2, "maaa.rs");
|
assert_match_at_position(finder, 2, "maaa.rs");
|
||||||
|
assert_match_at_position(finder, 3, "m");
|
||||||
});
|
});
|
||||||
|
|
||||||
// get back to the initial state
|
// get back to the initial state
|
||||||
|
@ -1965,9 +1978,10 @@ async fn test_search_results_refreshed_on_worktree_updates(cx: &mut gpui::TestAp
|
||||||
let picker = open_file_picker(&workspace, cx);
|
let picker = open_file_picker(&workspace, cx);
|
||||||
cx.simulate_input("rs");
|
cx.simulate_input("rs");
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 3);
|
||||||
assert_match_at_position(finder, 0, "lib.rs");
|
assert_match_at_position(finder, 0, "lib.rs");
|
||||||
assert_match_at_position(finder, 1, "main.rs");
|
assert_match_at_position(finder, 1, "main.rs");
|
||||||
|
assert_match_at_position(finder, 2, "rs");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete main.rs
|
// Delete main.rs
|
||||||
|
@ -1980,8 +1994,9 @@ async fn test_search_results_refreshed_on_worktree_updates(cx: &mut gpui::TestAp
|
||||||
|
|
||||||
// main.rs is in not among search results anymore
|
// main.rs is in not among search results anymore
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 1);
|
assert_eq!(finder.delegate.matches.len(), 2);
|
||||||
assert_match_at_position(finder, 0, "lib.rs");
|
assert_match_at_position(finder, 0, "lib.rs");
|
||||||
|
assert_match_at_position(finder, 1, "rs");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create util.rs
|
// Create util.rs
|
||||||
|
@ -1994,9 +2009,10 @@ async fn test_search_results_refreshed_on_worktree_updates(cx: &mut gpui::TestAp
|
||||||
|
|
||||||
// util.rs is among search results
|
// util.rs is among search results
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 3);
|
||||||
assert_match_at_position(finder, 0, "lib.rs");
|
assert_match_at_position(finder, 0, "lib.rs");
|
||||||
assert_match_at_position(finder, 1, "util.rs");
|
assert_match_at_position(finder, 1, "util.rs");
|
||||||
|
assert_match_at_position(finder, 2, "rs");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2036,9 +2052,10 @@ async fn test_search_results_refreshed_on_adding_and_removing_worktrees(
|
||||||
let picker = open_file_picker(&workspace, cx);
|
let picker = open_file_picker(&workspace, cx);
|
||||||
cx.simulate_input("rs");
|
cx.simulate_input("rs");
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 3);
|
||||||
assert_match_at_position(finder, 0, "bar.rs");
|
assert_match_at_position(finder, 0, "bar.rs");
|
||||||
assert_match_at_position(finder, 1, "lib.rs");
|
assert_match_at_position(finder, 1, "lib.rs");
|
||||||
|
assert_match_at_position(finder, 2, "rs");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add new worktree
|
// Add new worktree
|
||||||
|
@ -2054,10 +2071,11 @@ async fn test_search_results_refreshed_on_adding_and_removing_worktrees(
|
||||||
|
|
||||||
// main.rs is among search results
|
// main.rs is among search results
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 3);
|
assert_eq!(finder.delegate.matches.len(), 4);
|
||||||
assert_match_at_position(finder, 0, "bar.rs");
|
assert_match_at_position(finder, 0, "bar.rs");
|
||||||
assert_match_at_position(finder, 1, "lib.rs");
|
assert_match_at_position(finder, 1, "lib.rs");
|
||||||
assert_match_at_position(finder, 2, "main.rs");
|
assert_match_at_position(finder, 2, "main.rs");
|
||||||
|
assert_match_at_position(finder, 3, "rs");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove the first worktree
|
// Remove the first worktree
|
||||||
|
@ -2068,8 +2086,9 @@ async fn test_search_results_refreshed_on_adding_and_removing_worktrees(
|
||||||
|
|
||||||
// Files from the first worktree are not in the search results anymore
|
// Files from the first worktree are not in the search results anymore
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 1);
|
assert_eq!(finder.delegate.matches.len(), 2);
|
||||||
assert_match_at_position(finder, 0, "main.rs");
|
assert_match_at_position(finder, 0, "main.rs");
|
||||||
|
assert_match_at_position(finder, 1, "rs");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2414,7 +2433,7 @@ async fn test_repeat_toggle_action(cx: &mut gpui::TestAppContext) {
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
|
|
||||||
picker.update(cx, |picker, _| {
|
picker.update(cx, |picker, _| {
|
||||||
assert_eq!(picker.delegate.matches.len(), 6);
|
assert_eq!(picker.delegate.matches.len(), 7);
|
||||||
assert_eq!(picker.delegate.selected_index, 0);
|
assert_eq!(picker.delegate.selected_index, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2426,7 +2445,7 @@ async fn test_repeat_toggle_action(cx: &mut gpui::TestAppContext) {
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
|
|
||||||
picker.update(cx, |picker, _| {
|
picker.update(cx, |picker, _| {
|
||||||
assert_eq!(picker.delegate.matches.len(), 6);
|
assert_eq!(picker.delegate.matches.len(), 7);
|
||||||
assert_eq!(picker.delegate.selected_index, 3);
|
assert_eq!(picker.delegate.selected_index, 3);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2468,7 +2487,7 @@ async fn open_queried_buffer(
|
||||||
let history_items = picker.update(cx, |finder, _| {
|
let history_items = picker.update(cx, |finder, _| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
finder.delegate.matches.len(),
|
finder.delegate.matches.len(),
|
||||||
expected_matches,
|
expected_matches + 1, // +1 from CreateNew option
|
||||||
"Unexpected number of matches found for query `{input}`, matches: {:?}",
|
"Unexpected number of matches found for query `{input}`, matches: {:?}",
|
||||||
finder.delegate.matches
|
finder.delegate.matches
|
||||||
);
|
);
|
||||||
|
@ -2617,6 +2636,7 @@ fn collect_search_matches(picker: &Picker<FileFinderDelegate>) -> SearchEntries
|
||||||
.push(Path::new(path_match.0.path_prefix.as_ref()).join(&path_match.0.path));
|
.push(Path::new(path_match.0.path_prefix.as_ref()).join(&path_match.0.path));
|
||||||
search_entries.search_matches.push(path_match.0.clone());
|
search_entries.search_matches.push(path_match.0.clone());
|
||||||
}
|
}
|
||||||
|
Match::CreateNew(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
search_entries
|
search_entries
|
||||||
|
@ -2650,6 +2670,7 @@ fn assert_match_at_position(
|
||||||
let match_file_name = match &match_item {
|
let match_file_name = match &match_item {
|
||||||
Match::History { path, .. } => path.absolute.as_deref().unwrap().file_name(),
|
Match::History { path, .. } => path.absolute.as_deref().unwrap().file_name(),
|
||||||
Match::Search(path_match) => path_match.0.path.file_name(),
|
Match::Search(path_match) => path_match.0.path.file_name(),
|
||||||
|
Match::CreateNew(project_path) => project_path.path.file_name(),
|
||||||
}
|
}
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string_lossy();
|
.to_string_lossy();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue