Compare commits

...

8 Commits

Author SHA1 Message Date
Peter Tripp
9699ceac2f Magical semi-colon 2024-11-22 17:26:01 -05:00
Peter Tripp
6501c46bd6 Remove extra newline 2024-11-22 17:23:23 -05:00
Peter Tripp
bb484333db clippy 2024-11-22 17:19:55 -05:00
Peter Tripp
f5a60d9e06 clippy: replace filter/next with find. 2024-11-22 17:17:42 -05:00
Peter Tripp
c39368ff76 remove dbg 2024-11-22 17:06:15 -05:00
Peter Tripp
b46afa7d2b WIP
Fix for new_path_prompt not working on remote workspaces.

Steps to reproduce:
1. cargo run -- ssh://localhost/~/.zshrc
2. cmd-n, cmd-s enter filename.
2024-11-22 17:00:47 -05:00
Peter Tripp
81f3aa4e42 Fix for the fallback file picker throwing: File exists "os error 17".
This was reproducible when the first worktree is a non-folder worktree (e.g. setting.json) so we were trying to create the new file with a path under ~/.config/zed/settings.json/newfile.ext

Co-Authored-By: Conrad Irwin <conrad@zed.dev>
2024-11-22 16:37:18 -05:00
Peter Tripp
ebff818a18 wip 2024-11-21 13:26:15 -05:00

View File

@@ -1,6 +1,6 @@
use futures::channel::oneshot;
use fuzzy::PathMatch;
use gpui::{HighlightStyle, Model, StyledText};
use gpui::{HighlightStyle, Model, StyledText, Task};
use picker::{Picker, PickerDelegate};
use project::{Entry, PathMatchCandidateSet, Project, ProjectPath, WorktreeId};
use std::{
@@ -68,19 +68,55 @@ impl Match {
}
}
fn project_path(&self, project: &Project, cx: &WindowContext) -> Option<ProjectPath> {
fn project_path(
&self,
project: Model<Project>,
cx: &WindowContext,
) -> Task<anyhow::Result<ProjectPath>> {
let worktree_id = if let Some(path_match) = &self.path_match {
WorktreeId::from_usize(path_match.worktree_id)
} else if let Some(worktree) = project.read(cx).visible_worktrees(cx).find(|worktree| {
worktree
.read(cx)
.root_entry()
.is_some_and(|entry| entry.is_dir())
}) {
worktree.read(cx).id()
} else {
project.worktrees(cx).next()?.read(cx).id()
let path = PathBuf::from(self.relative_path());
return cx.spawn(|mut cx| async move {
let home = project
.update(&mut cx, |project, cx| {
project.resolve_abs_path(
&("~/".to_string() + &path.to_string_lossy().as_ref()),
cx,
)
})?
.await
.ok_or_else(|| anyhow::anyhow!("unable to resolve home"))?;
match home {
project::ResolvedPath::ProjectPath { project_path, .. } => Ok(project_path),
project::ResolvedPath::AbsPath { path, .. } => {
let (worktree, path) = project
.update(&mut cx, |project, cx| {
project.find_or_create_worktree(path, false, cx)
})?
.await?;
Ok(ProjectPath {
worktree_id: worktree.read_with(&cx, |worktree, _| worktree.id())?,
path: Arc::from(path),
})
}
}
});
};
let path = PathBuf::from(self.relative_path());
Some(ProjectPath {
Task::ready(Ok(ProjectPath {
worktree_id,
path: Arc::from(path),
})
}))
}
fn existing_prefix(&self, project: &Project, cx: &WindowContext) -> Option<PathBuf> {
@@ -338,7 +374,7 @@ impl PickerDelegate for NewPathDelegate {
}
fn confirm(&mut self, _: bool, cx: &mut ViewContext<picker::Picker<Self>>) {
let Some(m) = self.matches.get(self.selected_index) else {
let Some(m) = self.matches.get(self.selected_index).cloned() else {
return;
};
@@ -356,31 +392,46 @@ impl PickerDelegate for NewPathDelegate {
let m = m.clone();
cx.spawn(|picker, mut cx| async move {
let answer = answer.await.ok();
picker
.update(&mut cx, |picker, cx| {
picker.delegate.should_dismiss = true;
if answer != Some(0) {
return;
}
if let Some(path) = m.project_path(picker.delegate.project.read(cx), cx) {
if let Some(tx) = picker.delegate.tx.take() {
tx.send(Some(path)).ok();
}
}
cx.emit(gpui::DismissEvent);
})
.ok();
if answer != Some(0) {
return Ok(());
}
let (task, tx) = picker.update(&mut cx, |picker, cx| {
picker.delegate.should_dismiss = true;
(
m.project_path(picker.delegate.project.clone(), cx),
picker.delegate.tx.take(),
)
})?;
let path = task.await?;
if let Some(tx) = tx {
tx.send(Some(path)).ok();
}
picker.update(&mut cx, |_, cx| {
cx.emit(gpui::DismissEvent);
})
})
.detach();
return;
}
cx.spawn(|picker, mut cx| async move {
let (task, tx) = picker.update(&mut cx, |picker, cx| {
(
m.project_path(picker.delegate.project.clone(), cx),
picker.delegate.tx.take(),
)
})?;
let path = task.await?;
if let Some(path) = m.project_path(self.project.read(cx), cx) {
if let Some(tx) = self.tx.take() {
if let Some(tx) = tx {
tx.send(Some(path)).ok();
}
}
cx.emit(gpui::DismissEvent);
picker.update(&mut cx, |_, cx| {
cx.emit(gpui::DismissEvent);
})
})
.detach();
}
fn should_dismiss(&self) -> bool {