Merge branch 'main' into polish-project-diagnostics
Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
commit
b2f0c78924
12 changed files with 166 additions and 107 deletions
|
@ -59,14 +59,14 @@ pub struct Collaborator {
|
|||
#[derive(Debug)]
|
||||
pub enum Event {
|
||||
ActiveEntryChanged(Option<ProjectEntry>),
|
||||
WorktreeRemoved(usize),
|
||||
DiskBasedDiagnosticsUpdated { worktree_id: usize },
|
||||
WorktreeRemoved(WorktreeId),
|
||||
DiskBasedDiagnosticsUpdated { worktree_id: WorktreeId },
|
||||
DiagnosticsUpdated(ProjectPath),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct ProjectPath {
|
||||
pub worktree_id: usize,
|
||||
pub worktree_id: WorktreeId,
|
||||
pub path: Arc<Path>,
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ impl DiagnosticSummary {
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ProjectEntry {
|
||||
pub worktree_id: usize,
|
||||
pub worktree_id: WorktreeId,
|
||||
pub entry_id: usize,
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,11 @@ impl Project {
|
|||
&self.worktrees
|
||||
}
|
||||
|
||||
pub fn worktree_for_id(&self, id: usize, cx: &AppContext) -> Option<ModelHandle<Worktree>> {
|
||||
pub fn worktree_for_id(
|
||||
&self,
|
||||
id: WorktreeId,
|
||||
cx: &AppContext,
|
||||
) -> Option<ModelHandle<Worktree>> {
|
||||
self.worktrees
|
||||
.iter()
|
||||
.find(|worktree| worktree.read(cx).id() == id)
|
||||
|
@ -479,13 +483,13 @@ impl Project {
|
|||
cx.subscribe(&worktree, |_, worktree, event, cx| match event {
|
||||
worktree::Event::DiagnosticsUpdated(path) => {
|
||||
cx.emit(Event::DiagnosticsUpdated(ProjectPath {
|
||||
worktree_id: worktree.id(),
|
||||
worktree_id: worktree.read(cx).id(),
|
||||
path: path.clone(),
|
||||
}));
|
||||
}
|
||||
worktree::Event::DiskBasedDiagnosticsUpdated => {
|
||||
cx.emit(Event::DiskBasedDiagnosticsUpdated {
|
||||
worktree_id: worktree.id(),
|
||||
worktree_id: worktree.read(cx).id(),
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -514,9 +518,9 @@ impl Project {
|
|||
cx: &'a AppContext,
|
||||
) -> impl Iterator<Item = (ProjectPath, DiagnosticSummary)> + 'a {
|
||||
self.worktrees.iter().flat_map(move |worktree| {
|
||||
let worktree = worktree.read(cx);
|
||||
let worktree_id = worktree.id();
|
||||
worktree
|
||||
.read(cx)
|
||||
.diagnostic_summaries()
|
||||
.map(move |(path, summary)| (ProjectPath { worktree_id, path }, summary))
|
||||
})
|
||||
|
@ -634,9 +638,9 @@ impl Project {
|
|||
_: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<()> {
|
||||
self.worktrees.retain(|worktree| {
|
||||
worktree.read(cx).as_remote().unwrap().remote_id() != envelope.payload.worktree_id
|
||||
});
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
self.worktrees
|
||||
.retain(|worktree| worktree.read(cx).as_remote().unwrap().id() != worktree_id);
|
||||
cx.notify();
|
||||
Ok(())
|
||||
}
|
||||
|
@ -647,7 +651,8 @@ impl Project {
|
|||
_: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<()> {
|
||||
if let Some(worktree) = self.worktree_for_id(envelope.payload.worktree_id as usize, cx) {
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
if let Some(worktree) = self.worktree_for_id(worktree_id, cx) {
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
let worktree = worktree.as_remote_mut().unwrap();
|
||||
worktree.update_from_remote(envelope, cx)
|
||||
|
@ -662,7 +667,8 @@ impl Project {
|
|||
_: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<()> {
|
||||
if let Some(worktree) = self.worktree_for_id(envelope.payload.worktree_id as usize, cx) {
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
if let Some(worktree) = self.worktree_for_id(worktree_id, cx) {
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
worktree.handle_update_buffer(envelope, cx)
|
||||
})?;
|
||||
|
@ -676,7 +682,8 @@ impl Project {
|
|||
rpc: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<()> {
|
||||
if let Some(worktree) = self.worktree_for_id(envelope.payload.worktree_id as usize, cx) {
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
if let Some(worktree) = self.worktree_for_id(worktree_id, cx) {
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
worktree.handle_save_buffer(envelope, rpc, cx)
|
||||
})?;
|
||||
|
@ -690,7 +697,8 @@ impl Project {
|
|||
rpc: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> anyhow::Result<()> {
|
||||
if let Some(worktree) = self.worktree_for_id(envelope.payload.worktree_id as usize, cx) {
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
if let Some(worktree) = self.worktree_for_id(worktree_id, cx) {
|
||||
return worktree.update(cx, |worktree, cx| {
|
||||
worktree.handle_open_buffer(envelope, rpc, cx)
|
||||
});
|
||||
|
@ -705,7 +713,8 @@ impl Project {
|
|||
rpc: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> anyhow::Result<()> {
|
||||
if let Some(worktree) = self.worktree_for_id(envelope.payload.worktree_id as usize, cx) {
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
if let Some(worktree) = self.worktree_for_id(worktree_id, cx) {
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
worktree.handle_close_buffer(envelope, rpc, cx)
|
||||
})?;
|
||||
|
@ -719,7 +728,8 @@ impl Project {
|
|||
_: Arc<Client>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<()> {
|
||||
if let Some(worktree) = self.worktree_for_id(envelope.payload.worktree_id as usize, cx) {
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
if let Some(worktree) = self.worktree_for_id(worktree_id, cx) {
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
worktree.handle_buffer_saved(envelope, cx)
|
||||
})?;
|
||||
|
@ -772,7 +782,7 @@ impl<'a> PathMatchCandidateSet<'a> for CandidateSet {
|
|||
type Candidates = CandidateSetIter<'a>;
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.snapshot.id()
|
||||
self.snapshot.id().to_usize()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
|
|
|
@ -59,6 +59,9 @@ enum ScanState {
|
|||
Err(Arc<anyhow::Error>),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct WorktreeId(usize);
|
||||
|
||||
pub enum Worktree {
|
||||
Local(LocalWorktree),
|
||||
Remote(RemoteWorktree),
|
||||
|
@ -170,7 +173,7 @@ impl Worktree {
|
|||
let worktree = cx.update(|cx| {
|
||||
cx.add_model(|cx: &mut ModelContext<Worktree>| {
|
||||
let snapshot = Snapshot {
|
||||
id: remote_id as usize,
|
||||
id: WorktreeId(remote_id as usize),
|
||||
scan_id: 0,
|
||||
abs_path: Path::new("").into(),
|
||||
root_name,
|
||||
|
@ -213,7 +216,6 @@ impl Worktree {
|
|||
|
||||
Worktree::Remote(RemoteWorktree {
|
||||
project_id: project_remote_id,
|
||||
remote_id,
|
||||
replica_id,
|
||||
snapshot,
|
||||
snapshot_rx,
|
||||
|
@ -618,9 +620,9 @@ impl Worktree {
|
|||
for (buffer_id, buffer) in open_buffers {
|
||||
if let Some(buffer) = buffer.upgrade(cx) {
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
if let Some(old_file) = buffer.file() {
|
||||
if let Some(old_file) = File::from_dyn(buffer.file()) {
|
||||
let new_file = if let Some(entry) = old_file
|
||||
.entry_id()
|
||||
.entry_id
|
||||
.and_then(|entry_id| self.entry_for_id(entry_id))
|
||||
{
|
||||
File {
|
||||
|
@ -789,16 +791,13 @@ impl Worktree {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
if let Some((project_id, worktree_id, rpc)) = match self {
|
||||
Worktree::Local(worktree) => worktree.share.as_ref().map(|share| {
|
||||
(
|
||||
share.project_id,
|
||||
worktree.id() as u64,
|
||||
worktree.client.clone(),
|
||||
)
|
||||
}),
|
||||
Worktree::Local(worktree) => worktree
|
||||
.share
|
||||
.as_ref()
|
||||
.map(|share| (share.project_id, worktree.id(), worktree.client.clone())),
|
||||
Worktree::Remote(worktree) => Some((
|
||||
worktree.project_id,
|
||||
worktree.remote_id,
|
||||
worktree.snapshot.id(),
|
||||
worktree.client.clone(),
|
||||
)),
|
||||
} {
|
||||
|
@ -806,7 +805,7 @@ impl Worktree {
|
|||
if let Err(error) = rpc
|
||||
.request(proto::UpdateBuffer {
|
||||
project_id,
|
||||
worktree_id,
|
||||
worktree_id: worktree_id.0 as u64,
|
||||
buffer_id,
|
||||
operations: vec![language::proto::serialize_operation(&operation)],
|
||||
})
|
||||
|
@ -827,9 +826,33 @@ impl Worktree {
|
|||
}
|
||||
}
|
||||
|
||||
impl WorktreeId {
|
||||
pub fn from_usize(handle_id: usize) -> Self {
|
||||
Self(handle_id)
|
||||
}
|
||||
|
||||
pub(crate) fn from_proto(id: u64) -> Self {
|
||||
Self(id as usize)
|
||||
}
|
||||
|
||||
pub fn to_proto(&self) -> u64 {
|
||||
self.0 as u64
|
||||
}
|
||||
|
||||
pub fn to_usize(&self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for WorktreeId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Snapshot {
|
||||
id: usize,
|
||||
id: WorktreeId,
|
||||
scan_id: usize,
|
||||
abs_path: Arc<Path>,
|
||||
root_name: String,
|
||||
|
@ -870,7 +893,6 @@ struct ShareState {
|
|||
|
||||
pub struct RemoteWorktree {
|
||||
project_id: u64,
|
||||
remote_id: u64,
|
||||
snapshot: Snapshot,
|
||||
snapshot_rx: watch::Receiver<Snapshot>,
|
||||
client: Arc<Client>,
|
||||
|
@ -926,7 +948,7 @@ impl LocalWorktree {
|
|||
let (mut last_scan_state_tx, last_scan_state_rx) = watch::channel_with(ScanState::Scanning);
|
||||
let tree = cx.add_model(move |cx: &mut ModelContext<Worktree>| {
|
||||
let mut snapshot = Snapshot {
|
||||
id: cx.model_id(),
|
||||
id: WorktreeId::from_usize(cx.model_id()),
|
||||
scan_id: 0,
|
||||
abs_path,
|
||||
root_name: root_name.clone(),
|
||||
|
@ -1114,12 +1136,12 @@ impl LocalWorktree {
|
|||
path: &Path,
|
||||
cx: &mut ModelContext<Worktree>,
|
||||
) -> Option<ModelHandle<Buffer>> {
|
||||
let worktree_id = self.id();
|
||||
let handle = cx.handle();
|
||||
let mut result = None;
|
||||
self.open_buffers.retain(|_buffer_id, buffer| {
|
||||
if let Some(buffer) = buffer.upgrade(cx.as_ref()) {
|
||||
if let Some(file) = buffer.read(cx.as_ref()).file() {
|
||||
if file.worktree_id() == worktree_id && file.path().as_ref() == path {
|
||||
if let Some(buffer) = buffer.upgrade(cx) {
|
||||
if let Some(file) = File::from_dyn(buffer.read(cx).file()) {
|
||||
if file.worktree == handle && file.path().as_ref() == path {
|
||||
result = Some(buffer);
|
||||
}
|
||||
}
|
||||
|
@ -1422,6 +1444,14 @@ impl Deref for LocalWorktree {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deref for RemoteWorktree {
|
||||
type Target = Snapshot;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.snapshot
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for LocalWorktree {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.snapshot.fmt(f)
|
||||
|
@ -1429,10 +1459,6 @@ impl fmt::Debug for LocalWorktree {
|
|||
}
|
||||
|
||||
impl RemoteWorktree {
|
||||
pub fn remote_id(&self) -> u64 {
|
||||
self.remote_id
|
||||
}
|
||||
|
||||
fn get_open_buffer(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
|
@ -1442,8 +1468,8 @@ impl RemoteWorktree {
|
|||
let mut existing_buffer = None;
|
||||
self.open_buffers.retain(|_buffer_id, buffer| {
|
||||
if let Some(buffer) = buffer.upgrade(cx.as_ref()) {
|
||||
if let Some(file) = buffer.read(cx.as_ref()).file() {
|
||||
if file.worktree_id() == handle.id() && file.path().as_ref() == path {
|
||||
if let Some(file) = File::from_dyn(buffer.read(cx).file()) {
|
||||
if file.worktree == handle && file.path().as_ref() == path {
|
||||
existing_buffer = Some(buffer);
|
||||
}
|
||||
}
|
||||
|
@ -1463,7 +1489,7 @@ impl RemoteWorktree {
|
|||
let rpc = self.client.clone();
|
||||
let replica_id = self.replica_id;
|
||||
let project_id = self.project_id;
|
||||
let remote_worktree_id = self.remote_id;
|
||||
let remote_worktree_id = self.id();
|
||||
let root_path = self.snapshot.abs_path.clone();
|
||||
let path: Arc<Path> = Arc::from(path);
|
||||
let path_string = path.to_string_lossy().to_string();
|
||||
|
@ -1476,7 +1502,7 @@ impl RemoteWorktree {
|
|||
let response = rpc
|
||||
.request(proto::OpenBuffer {
|
||||
project_id,
|
||||
worktree_id: remote_worktree_id as u64,
|
||||
worktree_id: remote_worktree_id.to_proto(),
|
||||
path: path_string,
|
||||
})
|
||||
.await?;
|
||||
|
@ -1571,14 +1597,14 @@ impl RemoteBuffer {
|
|||
}
|
||||
|
||||
impl Snapshot {
|
||||
pub fn id(&self) -> usize {
|
||||
pub fn id(&self) -> WorktreeId {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn to_proto(&self) -> proto::Worktree {
|
||||
let root_name = self.root_name.clone();
|
||||
proto::Worktree {
|
||||
id: self.id as u64,
|
||||
id: self.id.0 as u64,
|
||||
root_name,
|
||||
entries: self
|
||||
.entries_by_path
|
||||
|
@ -1954,14 +1980,6 @@ pub struct File {
|
|||
}
|
||||
|
||||
impl language::File for File {
|
||||
fn worktree_id(&self) -> usize {
|
||||
self.worktree.id()
|
||||
}
|
||||
|
||||
fn entry_id(&self) -> Option<usize> {
|
||||
self.entry_id
|
||||
}
|
||||
|
||||
fn mtime(&self) -> SystemTime {
|
||||
self.mtime
|
||||
}
|
||||
|
@ -2007,7 +2025,7 @@ impl language::File for File {
|
|||
version: clock::Global,
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Task<Result<(clock::Global, SystemTime)>> {
|
||||
let worktree_id = self.worktree.read(cx).id() as u64;
|
||||
let worktree_id = self.worktree.read(cx).id().to_proto();
|
||||
self.worktree.update(cx, |worktree, cx| match worktree {
|
||||
Worktree::Local(worktree) => {
|
||||
let rpc = worktree.client.clone();
|
||||
|
@ -2070,7 +2088,7 @@ impl language::File for File {
|
|||
self.worktree.update(cx, |worktree, cx| {
|
||||
if let Worktree::Remote(worktree) = worktree {
|
||||
let project_id = worktree.project_id;
|
||||
let worktree_id = worktree.remote_id;
|
||||
let worktree_id = worktree.id().to_proto();
|
||||
let rpc = worktree.client.clone();
|
||||
cx.background()
|
||||
.spawn(async move {
|
||||
|
@ -2090,15 +2108,21 @@ impl language::File for File {
|
|||
});
|
||||
}
|
||||
|
||||
fn boxed_clone(&self) -> Box<dyn language::File> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl File {
|
||||
pub fn from_dyn(file: Option<&dyn language::File>) -> Option<&Self> {
|
||||
file.and_then(|f| f.as_any().downcast_ref())
|
||||
}
|
||||
|
||||
pub fn worktree_id(&self, cx: &AppContext) -> WorktreeId {
|
||||
self.worktree.read(cx).id()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Entry {
|
||||
pub id: usize,
|
||||
|
@ -4031,7 +4055,7 @@ mod tests {
|
|||
let fs = Arc::new(RealFs);
|
||||
let next_entry_id = Arc::new(AtomicUsize::new(0));
|
||||
let mut initial_snapshot = Snapshot {
|
||||
id: 0,
|
||||
id: WorktreeId::from_usize(0),
|
||||
scan_id: 0,
|
||||
abs_path: root_dir.path().into(),
|
||||
entries_by_path: Default::default(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue