WIP
This commit is contained in:
@@ -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>(
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -624,7 +624,8 @@ impl<V> Entity<V> {
|
||||
handle
|
||||
.upgrade()
|
||||
.expect("view dropped with pending condition")
|
||||
.read(cx),
|
||||
.read(cx)
|
||||
.deref(),
|
||||
cx,
|
||||
) {
|
||||
break;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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>> {
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
});
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 })
|
||||
|
||||
Reference in New Issue
Block a user