Add absolute paths to historic elements
This commit is contained in:
parent
128c19875d
commit
364631a155
1 changed files with 94 additions and 42 deletions
|
@ -6,7 +6,7 @@ use gpui::{
|
|||
use picker::{Picker, PickerDelegate};
|
||||
use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId};
|
||||
use std::{
|
||||
path::Path,
|
||||
path::{Path, PathBuf},
|
||||
sync::{
|
||||
atomic::{self, AtomicBool},
|
||||
Arc,
|
||||
|
@ -25,11 +25,17 @@ pub struct FileFinderDelegate {
|
|||
latest_search_id: usize,
|
||||
latest_search_did_cancel: bool,
|
||||
latest_search_query: Option<PathLikeWithPosition<FileSearchQuery>>,
|
||||
currently_opened_path: Option<ProjectPath>,
|
||||
currently_opened_path: Option<FoundPath>,
|
||||
matches: Vec<PathMatch>,
|
||||
selected: Option<(usize, Arc<Path>)>,
|
||||
cancel_flag: Arc<AtomicBool>,
|
||||
history_items: Vec<ProjectPath>,
|
||||
history_items: Vec<FoundPath>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct FoundPath {
|
||||
project: ProjectPath,
|
||||
absolute: Option<PathBuf>,
|
||||
}
|
||||
|
||||
actions!(file_finder, [Toggle]);
|
||||
|
@ -43,10 +49,36 @@ const MAX_RECENT_SELECTIONS: usize = 20;
|
|||
|
||||
fn toggle_file_finder(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
|
||||
workspace.toggle_modal(cx, |workspace, cx| {
|
||||
let history_items = workspace.recent_navigation_history(Some(MAX_RECENT_SELECTIONS), cx);
|
||||
let project = workspace.project().read(cx);
|
||||
let project_to_found_path = |project_path: ProjectPath| FoundPath {
|
||||
absolute: project
|
||||
.worktree_for_id(project_path.worktree_id, cx)
|
||||
.map(|worktree| worktree.read(cx).abs_path().join(&project_path.path)),
|
||||
project: project_path,
|
||||
};
|
||||
|
||||
let currently_opened_path = workspace
|
||||
.active_item(cx)
|
||||
.and_then(|item| item.project_path(cx));
|
||||
.and_then(|item| item.project_path(cx))
|
||||
.map(project_to_found_path);
|
||||
|
||||
// if exists, bubble the currently opened path to the top
|
||||
let history_items = currently_opened_path
|
||||
.clone()
|
||||
.into_iter()
|
||||
.chain(
|
||||
workspace
|
||||
.recent_navigation_history(Some(MAX_RECENT_SELECTIONS), cx)
|
||||
.into_iter()
|
||||
.filter(|history_path| {
|
||||
Some(history_path)
|
||||
!= currently_opened_path
|
||||
.as_ref()
|
||||
.map(|found_path| &found_path.project)
|
||||
})
|
||||
.map(project_to_found_path),
|
||||
)
|
||||
.collect();
|
||||
|
||||
let project = workspace.project().clone();
|
||||
let workspace = cx.handle().downgrade();
|
||||
|
@ -113,11 +145,11 @@ impl FileFinderDelegate {
|
|||
(file_name, file_name_positions, full_path, path_positions)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
fn new(
|
||||
workspace: WeakViewHandle<Workspace>,
|
||||
project: ModelHandle<Project>,
|
||||
currently_opened_path: Option<ProjectPath>,
|
||||
history_items: Vec<ProjectPath>,
|
||||
currently_opened_path: Option<FoundPath>,
|
||||
history_items: Vec<FoundPath>,
|
||||
cx: &mut ViewContext<FileFinder>,
|
||||
) -> Self {
|
||||
cx.observe(&project, |picker, _, cx| {
|
||||
|
@ -147,7 +179,7 @@ impl FileFinderDelegate {
|
|||
let relative_to = self
|
||||
.currently_opened_path
|
||||
.as_ref()
|
||||
.map(|project_path| Arc::clone(&project_path.path));
|
||||
.map(|found_path| Arc::clone(&found_path.project.path));
|
||||
let worktrees = self
|
||||
.project
|
||||
.read(cx)
|
||||
|
@ -255,20 +287,33 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
self.latest_search_id = post_inc(&mut self.search_count);
|
||||
self.matches.clear();
|
||||
|
||||
let project = self.project.read(cx);
|
||||
self.matches = self
|
||||
.currently_opened_path
|
||||
.iter() // if exists, bubble the currently opened path to the top
|
||||
.chain(self.history_items.iter().filter(|history_item| {
|
||||
Some(*history_item) != self.currently_opened_path.as_ref()
|
||||
}))
|
||||
.history_items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, history_item)| PathMatch {
|
||||
score: i as f64,
|
||||
positions: Vec::new(),
|
||||
worktree_id: history_item.worktree_id.to_usize(),
|
||||
path: Arc::clone(&history_item.path),
|
||||
path_prefix: "".into(),
|
||||
distance_to_relative_ancestor: usize::MAX,
|
||||
.map(|(i, found_path)| {
|
||||
let worktree_id = found_path.project.worktree_id;
|
||||
// TODO kb wrong:
|
||||
// * for no worktree, check the project path
|
||||
// * if no project path exists — filter out(?), otherwise take it and open a workspace for it (enum for match kinds?)
|
||||
let path = if project.worktree_for_id(worktree_id, cx).is_some() {
|
||||
Arc::clone(&found_path.project.path)
|
||||
} else {
|
||||
found_path
|
||||
.absolute
|
||||
.as_ref()
|
||||
.map(|abs_path| Arc::from(abs_path.as_path()))
|
||||
.unwrap_or_else(|| Arc::clone(&found_path.project.path))
|
||||
};
|
||||
PathMatch {
|
||||
score: i as f64,
|
||||
positions: Vec::new(),
|
||||
worktree_id: worktree_id.to_usize(),
|
||||
path,
|
||||
path_prefix: "".into(),
|
||||
distance_to_relative_ancestor: usize::MAX,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
cx.notify();
|
||||
|
@ -876,10 +921,10 @@ mod tests {
|
|||
// When workspace has an active item, sort items which are closer to that item
|
||||
// first when they have the same name. In this case, b.txt is closer to dir2's a.txt
|
||||
// so that one should be sorted earlier
|
||||
let b_path = Some(ProjectPath {
|
||||
let b_path = Some(dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("/root/dir2/b.txt")),
|
||||
});
|
||||
}));
|
||||
let (_, finder) = cx.add_window(|cx| {
|
||||
Picker::new(
|
||||
FileFinderDelegate::new(
|
||||
|
@ -1012,10 +1057,10 @@ mod tests {
|
|||
.await;
|
||||
assert_eq!(
|
||||
history_after_first,
|
||||
vec![ProjectPath {
|
||||
vec![dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
}],
|
||||
})],
|
||||
"Should show 1st opened item in the history when opening the 2nd item"
|
||||
);
|
||||
|
||||
|
@ -1032,14 +1077,14 @@ mod tests {
|
|||
assert_eq!(
|
||||
history_after_second,
|
||||
vec![
|
||||
ProjectPath {
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
ProjectPath {
|
||||
}),
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
}),
|
||||
],
|
||||
"Should show 1st and 2nd opened items in the history when opening the 3rd item. \
|
||||
2nd item should be the first in the history, as the last opened."
|
||||
|
@ -1058,18 +1103,18 @@ mod tests {
|
|||
assert_eq!(
|
||||
history_after_third,
|
||||
vec![
|
||||
ProjectPath {
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/third.rs")),
|
||||
},
|
||||
ProjectPath {
|
||||
}),
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
ProjectPath {
|
||||
}),
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
}),
|
||||
],
|
||||
"Should show 1st, 2nd and 3rd opened items in the history when opening the 2nd item again. \
|
||||
3rd item should be the first in the history, as the last opened."
|
||||
|
@ -1088,18 +1133,18 @@ mod tests {
|
|||
assert_eq!(
|
||||
history_after_second_again,
|
||||
vec![
|
||||
ProjectPath {
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
ProjectPath {
|
||||
}),
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/third.rs")),
|
||||
},
|
||||
ProjectPath {
|
||||
}),
|
||||
dummy_found_path(ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
}),
|
||||
],
|
||||
"Should show 1st, 2nd and 3rd opened items in the history when opening the 3rd item again. \
|
||||
2nd item, as the last opened, 3rd item should go next as it was opened right before."
|
||||
|
@ -1114,7 +1159,7 @@ mod tests {
|
|||
workspace: &ViewHandle<Workspace>,
|
||||
deterministic: &gpui::executor::Deterministic,
|
||||
cx: &mut gpui::TestAppContext,
|
||||
) -> Vec<ProjectPath> {
|
||||
) -> Vec<FoundPath> {
|
||||
cx.dispatch_action(window_id, Toggle);
|
||||
let finder = cx.read(|cx| workspace.read(cx).modal::<FileFinder>().unwrap());
|
||||
finder
|
||||
|
@ -1216,4 +1261,11 @@ mod tests {
|
|||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn dummy_found_path(project_path: ProjectPath) -> FoundPath {
|
||||
FoundPath {
|
||||
project: project_path,
|
||||
absolute: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue