Improve Zed prompts for file path selection (#32014)
Part of https://github.com/zed-industries/zed/discussions/31653 `"use_system_path_prompts": false` is needed in settings for these to appear as modals for new file save and file open. Fixed a very subpar experience of the "save new file" Zed modal, compared to a similar "open file path" Zed modal by uniting their code. Before: https://github.com/user-attachments/assets/c4082b70-6cdc-4598-a416-d491011c8ac4 After: https://github.com/user-attachments/assets/21ca672a-ae40-426c-b68f-9efee4f93c8c Also * alters both prompts to start in the current worktree directory, with the fallback to home directory. * adjusts the code to handle Windows paths better Release Notes: - Improved Zed prompts for file path selection --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This commit is contained in:
parent
8c46a4f594
commit
4aabba6cf6
10 changed files with 721 additions and 792 deletions
|
@ -770,13 +770,26 @@ pub struct DirectoryItem {
|
|||
#[derive(Clone)]
|
||||
pub enum DirectoryLister {
|
||||
Project(Entity<Project>),
|
||||
Local(Arc<dyn Fs>),
|
||||
Local(Entity<Project>, Arc<dyn Fs>),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for DirectoryLister {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
DirectoryLister::Project(project) => {
|
||||
write!(f, "DirectoryLister::Project({project:?})")
|
||||
}
|
||||
DirectoryLister::Local(project, _) => {
|
||||
write!(f, "DirectoryLister::Local({project:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DirectoryLister {
|
||||
pub fn is_local(&self, cx: &App) -> bool {
|
||||
match self {
|
||||
DirectoryLister::Local(_) => true,
|
||||
DirectoryLister::Local(..) => true,
|
||||
DirectoryLister::Project(project) => project.read(cx).is_local(),
|
||||
}
|
||||
}
|
||||
|
@ -790,12 +803,28 @@ impl DirectoryLister {
|
|||
}
|
||||
|
||||
pub fn default_query(&self, cx: &mut App) -> String {
|
||||
if let DirectoryLister::Project(project) = self {
|
||||
if let Some(worktree) = project.read(cx).visible_worktrees(cx).next() {
|
||||
return worktree.read(cx).abs_path().to_string_lossy().to_string();
|
||||
let separator = std::path::MAIN_SEPARATOR_STR;
|
||||
match self {
|
||||
DirectoryLister::Project(project) => project,
|
||||
DirectoryLister::Local(project, _) => project,
|
||||
}
|
||||
.read(cx)
|
||||
.visible_worktrees(cx)
|
||||
.next()
|
||||
.map(|worktree| worktree.read(cx).abs_path())
|
||||
.map(|dir| dir.to_string_lossy().to_string())
|
||||
.or_else(|| std::env::home_dir().map(|dir| dir.to_string_lossy().to_string()))
|
||||
.map(|mut s| {
|
||||
s.push_str(separator);
|
||||
s
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
if cfg!(target_os = "windows") {
|
||||
format!("C:{separator}")
|
||||
} else {
|
||||
format!("~{separator}")
|
||||
}
|
||||
};
|
||||
format!("~{}", std::path::MAIN_SEPARATOR_STR)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn list_directory(&self, path: String, cx: &mut App) -> Task<Result<Vec<DirectoryItem>>> {
|
||||
|
@ -803,7 +832,7 @@ impl DirectoryLister {
|
|||
DirectoryLister::Project(project) => {
|
||||
project.update(cx, |project, cx| project.list_directory(path, cx))
|
||||
}
|
||||
DirectoryLister::Local(fs) => {
|
||||
DirectoryLister::Local(_, fs) => {
|
||||
let fs = fs.clone();
|
||||
cx.background_spawn(async move {
|
||||
let mut results = vec![];
|
||||
|
@ -4049,7 +4078,7 @@ impl Project {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Vec<DirectoryItem>>> {
|
||||
if self.is_local() {
|
||||
DirectoryLister::Local(self.fs.clone()).list_directory(query, cx)
|
||||
DirectoryLister::Local(cx.entity(), self.fs.clone()).list_directory(query, cx)
|
||||
} else if let Some(session) = self.ssh_client.as_ref() {
|
||||
let path_buf = PathBuf::from(query);
|
||||
let request = proto::ListRemoteDirectory {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue