This commit is contained in:
Nathan Sobo
2025-07-09 06:31:23 -06:00
parent 1eea7400e5
commit 47713d1edb
14 changed files with 118 additions and 89 deletions

View File

@@ -4,6 +4,7 @@ use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task,
use language::{Language, LanguageRegistry};
use rope::Rope;
use std::{
cell::Ref,
cmp::Ordering,
future::Future,
iter,
@@ -1109,9 +1110,11 @@ impl BufferDiff {
let unstaged_counterpart = self
.secondary_diff
.as_ref()
.map(|diff| &diff.read(cx).inner);
self.inner
.hunks_intersecting_range(range, buffer_snapshot, unstaged_counterpart)
.map(|diff| Ref::map(diff.read(cx), |d| &d.inner));
// self.inner
// .hunks_intersecting_range(range, buffer_snapshot, unstaged_counterpart)
// todo! Figure out what to do here
None.into_iter()
}
pub fn hunks_intersecting_range_rev<'a>(

View File

@@ -976,7 +976,8 @@ impl ChannelStore {
if let OpenEntityHandle::Open(buffer) = buffer {
if let Some(buffer) = buffer.upgrade() {
let channel_buffer = buffer.read(cx);
let buffer = channel_buffer.buffer().read(cx);
let buffer = channel_buffer.buffer();
let buffer = buffer.read(cx);
buffer_versions.push(proto::ChannelBufferVersion {
channel_id: channel_buffer.channel_id.0,
epoch: channel_buffer.epoch(),

View File

@@ -6,7 +6,7 @@ use parking_lot::{RwLock, RwLockUpgradableReadGuard};
use slotmap::{KeyData, SecondaryMap, SlotMap};
use std::{
any::{Any, TypeId, type_name},
cell::RefCell,
cell::{Ref, RefCell},
cmp::Ordering,
fmt::{self, Display},
hash::{Hash, Hasher},
@@ -371,8 +371,11 @@ impl<T: 'static> Entity<T> {
}
/// Grab a reference to this entity from the context.
pub fn read<'a>(&self, cx: &'a App) -> &'a T {
cx.entities.read(self)
/// todo! remove the cx param
pub fn read(&self, _cx: &App) -> Ref<T> {
Ref::map(self.any_entity.entity_data.borrow(), |data| {
data.downcast_ref().unwrap()
})
}
/// Read the entity referenced by this handle with the given function.

View File

@@ -624,7 +624,8 @@ impl<V> Entity<V> {
handle
.upgrade()
.expect("view dropped with pending condition")
.read(cx),
.read(cx)
.deref(),
cx,
) {
break;

View File

@@ -31,6 +31,8 @@ use raw_window_handle::{HandleError, HasDisplayHandle, HasWindowHandle};
use refineable::Refineable;
use slotmap::SlotMap;
use smallvec::SmallVec;
use std::cell::Ref;
use std::ops::Deref;
use std::{
any::{Any, TypeId},
borrow::Cow,
@@ -4139,7 +4141,8 @@ impl Window {
if let Some(inspector_id) = _inspector_id {
if let Some(inspector) = &self.inspector {
let inspector = inspector.clone();
let active_element_id = inspector.read(cx).active_element_id();
let inspector_ref = inspector.read(cx);
let active_element_id = inspector_ref.active_element_id();
if Some(inspector_id) == active_element_id {
return inspector.update(cx, |inspector, _cx| {
inspector.with_active_element_state(self, f)
@@ -4213,9 +4216,9 @@ impl Window {
#[cfg(any(feature = "inspector", debug_assertions))]
fn paint_inspector_hitbox(&mut self, cx: &App) {
if let Some(inspector) = self.inspector.as_ref() {
let inspector = inspector.read(cx);
if let Some((hitbox_id, _)) = self.hovered_inspector_hitbox(inspector, &self.next_frame)
if let Some(inspector) = self.inspector.clone() {
if let Some((hitbox_id, _)) =
self.hovered_inspector_hitbox(inspector.read(cx).deref(), &self.next_frame)
{
if let Some(hitbox) = self
.next_frame
@@ -4379,7 +4382,7 @@ impl<V: 'static + Render> WindowHandle<V> {
/// Read the root view out of this window.
///
/// This will fail if the window is closed or if the root view's type does not match `V`.
pub fn read<'a>(&self, cx: &'a App) -> Result<&'a V> {
pub fn read(&self, cx: &App) -> Result<Ref<V>> {
let x = cx
.windows
.get(self.id)
@@ -4392,7 +4395,7 @@ impl<V: 'static + Render> WindowHandle<V> {
.context("window not found")?
.map_err(|_| anyhow!("the type of the window's root view has changed"))?;
Ok(x.read(cx))
todo!()
}
/// Read the root view out of this window, with a callback
@@ -4402,7 +4405,9 @@ impl<V: 'static + Render> WindowHandle<V> {
where
C: AppContext,
{
cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
cx.read_window(self, |root_view, cx| {
read_with(root_view.read(cx).deref(), cx)
})
}
/// Read the root view pointer off of this window.

View File

@@ -41,7 +41,7 @@ use std::{
cell::Cell,
cmp::{self, Ordering, Reverse},
collections::{BTreeMap, BTreeSet},
ffi::OsStr,
ffi::{OsStr, OsString},
future::Future,
iter::{self, Iterator, Peekable},
mem,
@@ -343,7 +343,7 @@ pub trait File: Send + Sync + Any {
/// Returns the last component of this handle's absolute path. If this handle refers to the root
/// of its worktree, then this method will return the name of the worktree itself.
fn file_name<'a>(&'a self, cx: &'a App) -> &'a OsStr;
fn file_name<'a>(&'a self, cx: &'a App) -> OsString;
/// Returns the id of the worktree to which this file belongs.
///
@@ -4895,8 +4895,11 @@ impl File for TestFile {
unimplemented!()
}
fn file_name<'a>(&'a self, _: &'a gpui::App) -> &'a std::ffi::OsStr {
self.path().file_name().unwrap_or(self.root_name.as_ref())
fn file_name<'a>(&'a self, _: &'a gpui::App) -> OsString {
self.path()
.file_name()
.unwrap_or(self.root_name.as_ref())
.into()
}
fn worktree_id(&self, _: &App) -> WorktreeId {

View File

@@ -4,7 +4,7 @@ use crate::{
};
use collections::BTreeMap;
use gpui::{App, Context, Entity, EventEmitter, Global, prelude::*};
use std::{str::FromStr, sync::Arc};
use std::{cell::Ref, str::FromStr, sync::Arc};
use thiserror::Error;
use util::maybe;
@@ -119,7 +119,7 @@ impl LanguageModelRegistry {
cx.global::<GlobalLanguageModelRegistry>().0.clone()
}
pub fn read_global(cx: &App) -> &Self {
pub fn read_global(cx: &App) -> Ref<Self> {
cx.global::<GlobalLanguageModelRegistry>().0.read(cx)
}

View File

@@ -1215,8 +1215,9 @@ impl MultiBuffer {
if let Some(excerpt) = cursor.item() {
if excerpt.locator == *excerpt_id {
let excerpt_buffer_start =
excerpt.range.context.start.summary::<D>(buffer);
let excerpt_buffer_end = excerpt.range.context.end.summary::<D>(buffer);
excerpt.range.context.start.summary::<D>(&buffer);
let excerpt_buffer_end =
excerpt.range.context.end.summary::<D>(&buffer);
let excerpt_range = excerpt_buffer_start..excerpt_buffer_end;
if excerpt_range.contains(&range.start)
&& excerpt_range.contains(&range.end)
@@ -2477,7 +2478,7 @@ impl MultiBuffer {
};
let buffer = buffer_state.buffer.read(cx);
let diff_change_range = range.to_offset(buffer);
let diff_change_range = range.to_offset(&buffer);
let new_diff = diff.snapshot(cx);
let mut snapshot = self.snapshot.borrow_mut();
@@ -2558,19 +2559,20 @@ impl MultiBuffer {
}
pub fn language_settings<'a>(&'a self, cx: &'a App) -> Cow<'a, LanguageSettings> {
let buffer_id = self
.snapshot
.borrow()
.excerpts
.first()
.map(|excerpt| excerpt.buffer.remote_id());
buffer_id
.and_then(|buffer_id| self.buffer(buffer_id))
.map(|buffer| {
let buffer = buffer.read(cx);
language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
})
.unwrap_or_else(move || self.language_settings_at(0, cx))
// let buffer_id = self
// .snapshot
// .borrow()
// .excerpts
// .first()
// .map(|excerpt| excerpt.buffer.remote_id());
// buffer_id
// .and_then(|buffer_id| self.buffer(buffer_id))
// .map(|buffer| {
// let buffer = buffer.read(cx);
// language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
// })
// .unwrap_or_else(move || self.language_settings_at(0, cx))
todo!()
}
pub fn language_settings_at<'a, T: ToOffset>(
@@ -2585,7 +2587,8 @@ impl MultiBuffer {
language = buffer.language_at(offset);
file = buffer.file();
}
language_settings(language.map(|l| l.name()), file, cx)
// language_settings(language.map(|l| l.name()), file, cx)
todo!()
}
pub fn for_each_buffer(&self, mut f: impl FnMut(&Entity<Buffer>)) {
@@ -2596,23 +2599,24 @@ impl MultiBuffer {
}
pub fn title<'a>(&'a self, cx: &'a App) -> Cow<'a, str> {
if let Some(title) = self.title.as_ref() {
return title.into();
}
// if let Some(title) = self.title.as_ref() {
// return title.into();
// }
if let Some(buffer) = self.as_singleton() {
let buffer = buffer.read(cx);
// if let Some(buffer) = self.as_singleton() {
// let buffer = buffer.read(cx);
if let Some(file) = buffer.file() {
return file.file_name(cx).to_string_lossy();
}
// if let Some(file) = buffer.file() {
// return file.file_name(cx).to_string_lossy();
// }
if let Some(title) = self.buffer_content_title(buffer) {
return title;
}
};
// if let Some(title) = self.buffer_content_title(&buffer) {
// return title;
// }
// };
"untitled".into()
// "untitled".into()
todo!()
}
fn buffer_content_title(&self, buffer: &Buffer) -> Option<Cow<'_, str>> {

View File

@@ -126,6 +126,7 @@ impl RemoteBufferStore {
let version = buffer.version();
let rpc = self.upstream_client.clone();
let project_id = self.project_id;
drop(buffer);
cx.spawn(async move |_, cx| {
let response = rpc
.request(proto::SaveBuffer {
@@ -373,6 +374,7 @@ impl LocalBufferStore {
let save = worktree.update(cx, |worktree, cx| {
worktree.write_file(path.as_ref(), text, line_ending, cx)
});
drop(buffer);
cx.spawn(async move |this, cx| {
let new_file = save.await?;
@@ -574,7 +576,8 @@ impl LocalBufferStore {
buffer: Entity<Buffer>,
cx: &mut Context<BufferStore>,
) -> Task<Result<()>> {
let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
let buffer_ref = buffer.read(cx);
let Some(file) = File::from_dyn(buffer_ref.file()) else {
return Task::ready(Err(anyhow!("buffer doesn't have a file")));
};
let worktree = file.worktree.clone();
@@ -922,6 +925,7 @@ impl BufferStore {
self.path_to_buffer_id.insert(path, remote_id);
}
drop(buffer);
cx.subscribe(&buffer_entity, Self::on_buffer_event).detach();
cx.emit(BufferStoreEvent::BufferAdded(buffer_entity));
Ok(())

View File

@@ -1740,7 +1740,8 @@ impl Project {
}
pub fn active_debug_session(&self, cx: &App) -> Option<(Entity<Session>, ActiveStackFrame)> {
let active_position = self.breakpoint_store.read(cx).active_position()?;
let store = self.breakpoint_store.read(cx);
let active_position = store.active_position()?;
let session = self
.dap_store
.read(cx)

View File

@@ -8162,8 +8162,8 @@ async fn test_update_gitignore(cx: &mut gpui::TestAppContext) {
// One file is unmodified, the other is ignored.
cx.read(|cx| {
assert_entry_git_state(tree.read(cx), repository.read(cx), "a.xml", None, false);
assert_entry_git_state(tree.read(cx), repository.read(cx), "b.txt", None, true);
assert_entry_git_state(&tree.read(cx), &repository.read(cx), "a.xml", None, false);
assert_entry_git_state(&tree.read(cx), &repository.read(cx), "b.txt", None, true);
});
// Change the gitignore, and stage the newly non-ignored file.
@@ -8181,10 +8181,10 @@ async fn test_update_gitignore(cx: &mut gpui::TestAppContext) {
cx.executor().run_until_parked();
cx.read(|cx| {
assert_entry_git_state(tree.read(cx), repository.read(cx), "a.xml", None, true);
assert_entry_git_state(&tree.read(cx), &repository.read(cx), "a.xml", None, true);
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"b.txt",
Some(StatusCode::Added),
false,
@@ -8597,22 +8597,22 @@ async fn test_rescan_with_gitignore(cx: &mut gpui::TestAppContext) {
cx.read(|cx| {
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"tracked-dir/tracked-file1",
None,
false,
);
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"tracked-dir/ancestor-ignored-file1",
None,
false,
);
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"ignored-dir/ignored-file1",
None,
true,
@@ -8649,22 +8649,22 @@ async fn test_rescan_with_gitignore(cx: &mut gpui::TestAppContext) {
cx.executor().run_until_parked();
cx.read(|cx| {
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"tracked-dir/tracked-file2",
Some(StatusCode::Added),
false,
);
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"tracked-dir/ancestor-ignored-file2",
None,
false,
);
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
&tree.read(cx),
&repository.read(cx),
"ignored-dir/ignored-file2",
None,
true,

View File

@@ -435,7 +435,7 @@ impl Inventory {
let fs = self.fs.clone();
let worktree = task_contexts.worktree();
let location = task_contexts.location();
let language = location.and_then(|location| location.buffer.read(cx).language());
let language = location.and_then(|location| location.buffer.read(cx).language().clone());
let task_source_kind = language.as_ref().map(|language| TaskSourceKind::Language {
name: language.name().into(),
});

View File

@@ -1,7 +1,7 @@
use anyhow::Result;
use collections::HashMap;
use gpui::{App, AppContext as _, Context, Entity, Global, SharedString, Task};
use std::sync::Arc;
use std::{cell::Ref, sync::Arc};
use zed_llm_client::WebSearchResponse;
pub fn init(cx: &mut App) {
@@ -32,7 +32,7 @@ impl WebSearchRegistry {
cx.global::<GlobalWebSearchRegistry>().0.clone()
}
pub fn read_global(cx: &App) -> &Self {
pub fn read_global(cx: &App) -> Ref<Self> {
cx.global::<GlobalWebSearchRegistry>().0.read(cx)
}

View File

@@ -49,7 +49,7 @@ use std::{
cmp::Ordering,
collections::hash_map,
convert::TryFrom,
ffi::OsStr,
ffi::{OsStr, OsString},
fmt,
future::Future,
mem::{self},
@@ -2667,17 +2667,18 @@ impl Snapshot {
}
pub fn entry_for_path(&self, path: impl AsRef<Path>) -> Option<&Entry> {
let path = path.as_ref();
debug_assert!(path.is_relative());
self.traverse_from_path(true, true, true, path)
.entry()
.and_then(|entry| {
if entry.path.as_ref() == path {
Some(entry)
} else {
None
}
})
// let path = path.as_ref();
// debug_assert!(path.is_relative());
// self.traverse_from_path(true, true, true, path)
// .entry()
// .and_then(|entry| {
// if entry.path.as_ref() == path {
// Some(entry)
// } else {
// None
// }
// })
todo!()
}
pub fn entry_for_id(&self, id: ProjectEntryId) -> Option<&Entry> {
@@ -3321,10 +3322,11 @@ impl language::File for File {
/// Returns the last component of this handle's absolute path. If this handle refers to the root
/// of its worktree, then this method will return the name of the worktree itself.
fn file_name<'a>(&'a self, cx: &'a App) -> &'a OsStr {
fn file_name<'a>(&'a self, cx: &'a App) -> OsString {
self.path
.file_name()
.unwrap_or_else(|| OsStr::new(&self.worktree.read(cx).root_name))
.map(Into::into)
.unwrap_or_else(|| OsStr::new(&self.worktree.read(cx).root_name).into())
}
fn worktree_id(&self, cx: &App) -> WorktreeId {
@@ -3357,14 +3359,16 @@ impl language::LocalFile for File {
}
fn load(&self, cx: &App) -> Task<Result<String>> {
let worktree = self.worktree.read(cx).as_local().unwrap();
let worktree = self.worktree.read(cx);
let worktree = worktree.as_local().unwrap();
let abs_path = worktree.absolutize(&self.path);
let fs = worktree.fs.clone();
cx.background_spawn(async move { fs.load(&abs_path?).await })
}
fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>> {
let worktree = self.worktree.read(cx).as_local().unwrap();
let worktree = self.worktree.read(cx);
let worktree = worktree.as_local().unwrap();
let abs_path = worktree.absolutize(&self.path);
let fs = worktree.fs.clone();
cx.background_spawn(async move { fs.load_bytes(&abs_path?).await })