Eliminate GPUI View, ViewContext, and WindowContext types (#22632)
There's still a bit more work to do on this, but this PR is compiling (with warnings) after eliminating the key types. When the tasks below are complete, this will be the new narrative for GPUI: - `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit of state, and if `T` implements `Render`, then `Entity<T>` implements `Element`. - `&mut App` This replaces `AppContext` and represents the app. - `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It is provided by the framework when updating an entity. - `&mut Window` Broken out of `&mut WindowContext` which no longer exists. Every method that once took `&mut WindowContext` now takes `&mut Window, &mut App` and every method that took `&mut ViewContext<T>` now takes `&mut Window, &mut Context<T>` Not pictured here are the two other failed attempts. It's been quite a month! Tasks: - [x] Remove `View`, `ViewContext`, `WindowContext` and thread through `Window` - [x] [@cole-miller @mikayla-maki] Redraw window when entities change - [x] [@cole-miller @mikayla-maki] Get examples and Zed running - [x] [@cole-miller @mikayla-maki] Fix Zed rendering - [x] [@mikayla-maki] Fix todo! macros and comments - [x] Fix a bug where the editor would not be redrawn because of view caching - [x] remove publicness window.notify() and replace with `AppContext::notify` - [x] remove `observe_new_window_models`, replace with `observe_new_models` with an optional window - [x] Fix a bug where the project panel would not be redrawn because of the wrong refresh() call being used - [x] Fix the tests - [x] Fix warnings by eliminating `Window` params or using `_` - [x] Fix conflicts - [x] Simplify generic code where possible - [x] Rename types - [ ] Update docs ### issues post merge - [x] Issues switching between normal and insert mode - [x] Assistant re-rendering failure - [x] Vim test failures - [x] Mac build issue Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev> Co-authored-by: Joseph <joseph@zed.dev> Co-authored-by: max <max@zed.dev> Co-authored-by: Michael Sloan <michael@zed.dev> Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local> Co-authored-by: Mikayla <mikayla.c.maki@gmail.com> Co-authored-by: joão <joao@zed.dev>
This commit is contained in:
parent
21b4a0d50e
commit
6fca1d2b0b
648 changed files with 36248 additions and 28208 deletions
|
@ -12,8 +12,8 @@ use fs::Fs;
|
|||
use futures::{channel::oneshot, future::Shared, Future, FutureExt as _, StreamExt};
|
||||
use git::{blame::Blame, diff::BufferDiff, repository::RepoPath};
|
||||
use gpui::{
|
||||
AppContext, AsyncAppContext, Context as _, EventEmitter, Model, ModelContext, Subscription,
|
||||
Task, WeakModel,
|
||||
App, AppContext as _, AsyncAppContext, Context, Entity, EventEmitter, Subscription, Task,
|
||||
WeakEntity,
|
||||
};
|
||||
use http_client::Url;
|
||||
use language::{
|
||||
|
@ -43,11 +43,11 @@ use worktree::{File, PathChange, ProjectEntryId, UpdatedGitRepositoriesSet, Work
|
|||
pub struct BufferStore {
|
||||
state: BufferStoreState,
|
||||
#[allow(clippy::type_complexity)]
|
||||
loading_buffers: HashMap<ProjectPath, Shared<Task<Result<Model<Buffer>, Arc<anyhow::Error>>>>>,
|
||||
loading_buffers: HashMap<ProjectPath, Shared<Task<Result<Entity<Buffer>, Arc<anyhow::Error>>>>>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
loading_change_sets:
|
||||
HashMap<BufferId, Shared<Task<Result<Model<BufferChangeSet>, Arc<anyhow::Error>>>>>,
|
||||
worktree_store: Model<WorktreeStore>,
|
||||
HashMap<BufferId, Shared<Task<Result<Entity<BufferChangeSet>, Arc<anyhow::Error>>>>>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
opened_buffers: HashMap<BufferId, OpenBuffer>,
|
||||
downstream_client: Option<(AnyProtoClient, u64)>,
|
||||
shared_buffers: HashMap<proto::PeerId, HashMap<BufferId, SharedBuffer>>,
|
||||
|
@ -55,8 +55,8 @@ pub struct BufferStore {
|
|||
|
||||
#[derive(Hash, Eq, PartialEq, Clone)]
|
||||
struct SharedBuffer {
|
||||
buffer: Model<Buffer>,
|
||||
unstaged_changes: Option<Model<BufferChangeSet>>,
|
||||
buffer: Entity<Buffer>,
|
||||
unstaged_changes: Option<Entity<BufferChangeSet>>,
|
||||
lsp_handle: Option<OpenLspBufferHandle>,
|
||||
}
|
||||
|
||||
|
@ -76,50 +76,46 @@ enum BufferStoreState {
|
|||
}
|
||||
|
||||
struct RemoteBufferStore {
|
||||
shared_with_me: HashSet<Model<Buffer>>,
|
||||
shared_with_me: HashSet<Entity<Buffer>>,
|
||||
upstream_client: AnyProtoClient,
|
||||
project_id: u64,
|
||||
loading_remote_buffers_by_id: HashMap<BufferId, Model<Buffer>>,
|
||||
loading_remote_buffers_by_id: HashMap<BufferId, Entity<Buffer>>,
|
||||
remote_buffer_listeners:
|
||||
HashMap<BufferId, Vec<oneshot::Sender<Result<Model<Buffer>, anyhow::Error>>>>,
|
||||
worktree_store: Model<WorktreeStore>,
|
||||
HashMap<BufferId, Vec<oneshot::Sender<Result<Entity<Buffer>, anyhow::Error>>>>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
}
|
||||
|
||||
struct LocalBufferStore {
|
||||
local_buffer_ids_by_path: HashMap<ProjectPath, BufferId>,
|
||||
local_buffer_ids_by_entry_id: HashMap<ProjectEntryId, BufferId>,
|
||||
worktree_store: Model<WorktreeStore>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
||||
enum OpenBuffer {
|
||||
Complete {
|
||||
buffer: WeakModel<Buffer>,
|
||||
unstaged_changes: Option<WeakModel<BufferChangeSet>>,
|
||||
buffer: WeakEntity<Buffer>,
|
||||
unstaged_changes: Option<WeakEntity<BufferChangeSet>>,
|
||||
},
|
||||
Operations(Vec<Operation>),
|
||||
}
|
||||
|
||||
pub enum BufferStoreEvent {
|
||||
BufferAdded(Model<Buffer>),
|
||||
BufferAdded(Entity<Buffer>),
|
||||
BufferDropped(BufferId),
|
||||
BufferChangedFilePath {
|
||||
buffer: Model<Buffer>,
|
||||
buffer: Entity<Buffer>,
|
||||
old_file: Option<Arc<dyn language::File>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ProjectTransaction(pub HashMap<Model<Buffer>, language::Transaction>);
|
||||
pub struct ProjectTransaction(pub HashMap<Entity<Buffer>, language::Transaction>);
|
||||
|
||||
impl EventEmitter<BufferStoreEvent> for BufferStore {}
|
||||
|
||||
impl RemoteBufferStore {
|
||||
fn load_staged_text(
|
||||
&self,
|
||||
buffer_id: BufferId,
|
||||
cx: &AppContext,
|
||||
) -> Task<Result<Option<String>>> {
|
||||
fn load_staged_text(&self, buffer_id: BufferId, cx: &App) -> Task<Result<Option<String>>> {
|
||||
let project_id = self.project_id;
|
||||
let client = self.upstream_client.clone();
|
||||
cx.background_executor().spawn(async move {
|
||||
|
@ -135,8 +131,8 @@ impl RemoteBufferStore {
|
|||
pub fn wait_for_remote_buffer(
|
||||
&mut self,
|
||||
id: BufferId,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.remote_buffer_listeners.entry(id).or_default().push(tx);
|
||||
|
||||
|
@ -157,9 +153,9 @@ impl RemoteBufferStore {
|
|||
|
||||
fn save_remote_buffer(
|
||||
&self,
|
||||
buffer_handle: Model<Buffer>,
|
||||
buffer_handle: Entity<Buffer>,
|
||||
new_path: Option<proto::ProjectPath>,
|
||||
cx: &ModelContext<BufferStore>,
|
||||
cx: &Context<BufferStore>,
|
||||
) -> Task<Result<()>> {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
let buffer_id = buffer.remote_id().into();
|
||||
|
@ -191,8 +187,8 @@ impl RemoteBufferStore {
|
|||
envelope: TypedEnvelope<proto::CreateBufferForPeer>,
|
||||
replica_id: u16,
|
||||
capability: Capability,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
) -> Result<Option<Model<Buffer>>> {
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Result<Option<Entity<Buffer>>> {
|
||||
match envelope
|
||||
.payload
|
||||
.variant
|
||||
|
@ -220,7 +216,7 @@ impl RemoteBufferStore {
|
|||
|
||||
match buffer_result {
|
||||
Ok(buffer) => {
|
||||
let buffer = cx.new_model(|_| buffer);
|
||||
let buffer = cx.new(|_| buffer);
|
||||
self.loading_remote_buffers_by_id.insert(buffer_id, buffer);
|
||||
}
|
||||
Err(error) => {
|
||||
|
@ -292,7 +288,7 @@ impl RemoteBufferStore {
|
|||
&self,
|
||||
message: proto::ProjectTransaction,
|
||||
push_to_history: bool,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<ProjectTransaction>> {
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let mut project_transaction = ProjectTransaction::default();
|
||||
|
@ -329,9 +325,9 @@ impl RemoteBufferStore {
|
|||
fn open_buffer(
|
||||
&self,
|
||||
path: Arc<Path>,
|
||||
worktree: Model<Worktree>,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
worktree: Entity<Worktree>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
let worktree_id = worktree.read(cx).id().to_proto();
|
||||
let project_id = self.project_id;
|
||||
let client = self.upstream_client.clone();
|
||||
|
@ -356,7 +352,7 @@ impl RemoteBufferStore {
|
|||
})
|
||||
}
|
||||
|
||||
fn create_buffer(&self, cx: &mut ModelContext<BufferStore>) -> Task<Result<Model<Buffer>>> {
|
||||
fn create_buffer(&self, cx: &mut Context<BufferStore>) -> Task<Result<Entity<Buffer>>> {
|
||||
let create = self.upstream_client.request(proto::OpenNewBuffer {
|
||||
project_id: self.project_id,
|
||||
});
|
||||
|
@ -373,9 +369,9 @@ impl RemoteBufferStore {
|
|||
|
||||
fn reload_buffers(
|
||||
&self,
|
||||
buffers: HashSet<Model<Buffer>>,
|
||||
buffers: HashSet<Entity<Buffer>>,
|
||||
push_to_history: bool,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<ProjectTransaction>> {
|
||||
let request = self.upstream_client.request(proto::ReloadBuffers {
|
||||
project_id: self.project_id,
|
||||
|
@ -399,11 +395,7 @@ impl RemoteBufferStore {
|
|||
}
|
||||
|
||||
impl LocalBufferStore {
|
||||
fn load_staged_text(
|
||||
&self,
|
||||
buffer: &Model<Buffer>,
|
||||
cx: &AppContext,
|
||||
) -> Task<Result<Option<String>>> {
|
||||
fn load_staged_text(&self, buffer: &Entity<Buffer>, cx: &App) -> Task<Result<Option<String>>> {
|
||||
let Some(file) = buffer.read(cx).file() else {
|
||||
return Task::ready(Ok(None));
|
||||
};
|
||||
|
@ -422,11 +414,11 @@ impl LocalBufferStore {
|
|||
|
||||
fn save_local_buffer(
|
||||
&self,
|
||||
buffer_handle: Model<Buffer>,
|
||||
worktree: Model<Worktree>,
|
||||
buffer_handle: Entity<Buffer>,
|
||||
worktree: Entity<Worktree>,
|
||||
path: Arc<Path>,
|
||||
mut has_changed_file: bool,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<()>> {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
|
||||
|
@ -480,8 +472,8 @@ impl LocalBufferStore {
|
|||
|
||||
fn subscribe_to_worktree(
|
||||
&mut self,
|
||||
worktree: &Model<Worktree>,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
worktree: &Entity<Worktree>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) {
|
||||
cx.subscribe(worktree, |this, worktree, event, cx| {
|
||||
if worktree.read(cx).is_local() {
|
||||
|
@ -506,9 +498,9 @@ impl LocalBufferStore {
|
|||
|
||||
fn local_worktree_entries_changed(
|
||||
this: &mut BufferStore,
|
||||
worktree_handle: &Model<Worktree>,
|
||||
worktree_handle: &Entity<Worktree>,
|
||||
changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) {
|
||||
let snapshot = worktree_handle.read(cx).snapshot();
|
||||
for (path, entry_id, _) in changes {
|
||||
|
@ -525,9 +517,9 @@ impl LocalBufferStore {
|
|||
|
||||
fn local_worktree_git_repos_changed(
|
||||
this: &mut BufferStore,
|
||||
worktree_handle: Model<Worktree>,
|
||||
worktree_handle: Entity<Worktree>,
|
||||
changed_repos: &UpdatedGitRepositoriesSet,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) {
|
||||
debug_assert!(worktree_handle.read(cx).is_local());
|
||||
|
||||
|
@ -609,9 +601,9 @@ impl LocalBufferStore {
|
|||
this: &mut BufferStore,
|
||||
entry_id: ProjectEntryId,
|
||||
path: &Arc<Path>,
|
||||
worktree: &Model<worktree::Worktree>,
|
||||
worktree: &Entity<worktree::Worktree>,
|
||||
snapshot: &worktree::Snapshot,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Option<()> {
|
||||
let project_path = ProjectPath {
|
||||
worktree_id: snapshot.id(),
|
||||
|
@ -696,7 +688,7 @@ impl LocalBufferStore {
|
|||
buffer_id,
|
||||
);
|
||||
events.push(BufferStoreEvent::BufferChangedFilePath {
|
||||
buffer: cx.handle(),
|
||||
buffer: cx.model(),
|
||||
old_file: buffer.file().cloned(),
|
||||
});
|
||||
}
|
||||
|
@ -733,7 +725,7 @@ impl LocalBufferStore {
|
|||
None
|
||||
}
|
||||
|
||||
fn buffer_changed_file(&mut self, buffer: Model<Buffer>, cx: &mut AppContext) -> Option<()> {
|
||||
fn buffer_changed_file(&mut self, buffer: Entity<Buffer>, cx: &mut App) -> Option<()> {
|
||||
let file = File::from_dyn(buffer.read(cx).file())?;
|
||||
|
||||
let remote_id = buffer.read(cx).remote_id();
|
||||
|
@ -761,8 +753,8 @@ impl LocalBufferStore {
|
|||
|
||||
fn save_buffer(
|
||||
&self,
|
||||
buffer: Model<Buffer>,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
buffer: Entity<Buffer>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<()>> {
|
||||
let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
|
||||
return Task::ready(Err(anyhow!("buffer doesn't have a file")));
|
||||
|
@ -773,9 +765,9 @@ impl LocalBufferStore {
|
|||
|
||||
fn save_buffer_as(
|
||||
&self,
|
||||
buffer: Model<Buffer>,
|
||||
buffer: Entity<Buffer>,
|
||||
path: ProjectPath,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<()>> {
|
||||
let Some(worktree) = self
|
||||
.worktree_store
|
||||
|
@ -790,9 +782,9 @@ impl LocalBufferStore {
|
|||
fn open_buffer(
|
||||
&self,
|
||||
path: Arc<Path>,
|
||||
worktree: Model<Worktree>,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
worktree: Entity<Worktree>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
let load_buffer = worktree.update(cx, |worktree, cx| {
|
||||
let load_file = worktree.load_file(path.as_ref(), cx);
|
||||
let reservation = cx.reserve_model();
|
||||
|
@ -812,7 +804,7 @@ impl LocalBufferStore {
|
|||
cx.spawn(move |this, mut cx| async move {
|
||||
let buffer = match load_buffer.await {
|
||||
Ok(buffer) => Ok(buffer),
|
||||
Err(error) if is_not_found_error(&error) => cx.new_model(|cx| {
|
||||
Err(error) if is_not_found_error(&error) => cx.new(|cx| {
|
||||
let buffer_id = BufferId::from(cx.entity_id().as_non_zero_u64());
|
||||
let text_buffer = text::Buffer::new(0, buffer_id, "".into());
|
||||
Buffer::build(
|
||||
|
@ -856,11 +848,10 @@ impl LocalBufferStore {
|
|||
})
|
||||
}
|
||||
|
||||
fn create_buffer(&self, cx: &mut ModelContext<BufferStore>) -> Task<Result<Model<Buffer>>> {
|
||||
fn create_buffer(&self, cx: &mut Context<BufferStore>) -> Task<Result<Entity<Buffer>>> {
|
||||
cx.spawn(|buffer_store, mut cx| async move {
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::local("", cx).with_language(language::PLAIN_TEXT.clone(), cx)
|
||||
})?;
|
||||
let buffer =
|
||||
cx.new(|cx| Buffer::local("", cx).with_language(language::PLAIN_TEXT.clone(), cx))?;
|
||||
buffer_store.update(&mut cx, |buffer_store, cx| {
|
||||
buffer_store.add_buffer(buffer.clone(), cx).log_err();
|
||||
})?;
|
||||
|
@ -870,9 +861,9 @@ impl LocalBufferStore {
|
|||
|
||||
fn reload_buffers(
|
||||
&self,
|
||||
buffers: HashSet<Model<Buffer>>,
|
||||
buffers: HashSet<Entity<Buffer>>,
|
||||
push_to_history: bool,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<ProjectTransaction>> {
|
||||
cx.spawn(move |_, mut cx| async move {
|
||||
let mut project_transaction = ProjectTransaction::default();
|
||||
|
@ -885,7 +876,7 @@ impl LocalBufferStore {
|
|||
if !push_to_history {
|
||||
buffer.forget_transaction(transaction.id);
|
||||
}
|
||||
project_transaction.0.insert(cx.handle(), transaction);
|
||||
project_transaction.0.insert(cx.model(), transaction);
|
||||
}
|
||||
})?;
|
||||
}
|
||||
|
@ -909,7 +900,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
/// Creates a buffer store, optionally retaining its buffers.
|
||||
pub fn local(worktree_store: Model<WorktreeStore>, cx: &mut ModelContext<Self>) -> Self {
|
||||
pub fn local(worktree_store: Entity<WorktreeStore>, cx: &mut Context<Self>) -> Self {
|
||||
Self {
|
||||
state: BufferStoreState::Local(LocalBufferStore {
|
||||
local_buffer_ids_by_path: Default::default(),
|
||||
|
@ -932,10 +923,10 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub fn remote(
|
||||
worktree_store: Model<WorktreeStore>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
upstream_client: AnyProtoClient,
|
||||
remote_id: u64,
|
||||
_cx: &mut ModelContext<Self>,
|
||||
_cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
Self {
|
||||
state: BufferStoreState::Remote(RemoteBufferStore {
|
||||
|
@ -979,8 +970,8 @@ impl BufferStore {
|
|||
pub fn open_buffer(
|
||||
&mut self,
|
||||
project_path: ProjectPath,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
if let Some(buffer) = self.get_by_path(&project_path, cx) {
|
||||
return Task::ready(Ok(buffer));
|
||||
}
|
||||
|
@ -1024,9 +1015,9 @@ impl BufferStore {
|
|||
|
||||
pub fn open_unstaged_changes(
|
||||
&mut self,
|
||||
buffer: Model<Buffer>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<BufferChangeSet>>> {
|
||||
buffer: Entity<Buffer>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Entity<BufferChangeSet>>> {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
if let Some(change_set) = self.get_unstaged_changes(buffer_id) {
|
||||
return Task::ready(Ok(change_set));
|
||||
|
@ -1058,17 +1049,17 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn set_change_set(&mut self, buffer_id: BufferId, change_set: Model<BufferChangeSet>) {
|
||||
pub fn set_change_set(&mut self, buffer_id: BufferId, change_set: Entity<BufferChangeSet>) {
|
||||
self.loading_change_sets
|
||||
.insert(buffer_id, Task::ready(Ok(change_set)).shared());
|
||||
}
|
||||
|
||||
pub async fn open_unstaged_changes_internal(
|
||||
this: WeakModel<Self>,
|
||||
this: WeakEntity<Self>,
|
||||
text: Result<Option<String>>,
|
||||
buffer: Model<Buffer>,
|
||||
buffer: Entity<Buffer>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<Model<BufferChangeSet>> {
|
||||
) -> Result<Entity<BufferChangeSet>> {
|
||||
let text = match text {
|
||||
Err(e) => {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
|
@ -1080,9 +1071,7 @@ impl BufferStore {
|
|||
Ok(text) => text,
|
||||
};
|
||||
|
||||
let change_set = cx
|
||||
.new_model(|cx| BufferChangeSet::new(&buffer, cx))
|
||||
.unwrap();
|
||||
let change_set = cx.new(|cx| BufferChangeSet::new(&buffer, cx)).unwrap();
|
||||
|
||||
if let Some(text) = text {
|
||||
change_set
|
||||
|
@ -1108,7 +1097,7 @@ impl BufferStore {
|
|||
Ok(change_set)
|
||||
}
|
||||
|
||||
pub fn create_buffer(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<Model<Buffer>>> {
|
||||
pub fn create_buffer(&mut self, cx: &mut Context<Self>) -> Task<Result<Entity<Buffer>>> {
|
||||
match &self.state {
|
||||
BufferStoreState::Local(this) => this.create_buffer(cx),
|
||||
BufferStoreState::Remote(this) => this.create_buffer(cx),
|
||||
|
@ -1117,8 +1106,8 @@ impl BufferStore {
|
|||
|
||||
pub fn save_buffer(
|
||||
&mut self,
|
||||
buffer: Model<Buffer>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
buffer: Entity<Buffer>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
match &mut self.state {
|
||||
BufferStoreState::Local(this) => this.save_buffer(buffer, cx),
|
||||
|
@ -1128,9 +1117,9 @@ impl BufferStore {
|
|||
|
||||
pub fn save_buffer_as(
|
||||
&mut self,
|
||||
buffer: Model<Buffer>,
|
||||
buffer: Entity<Buffer>,
|
||||
path: ProjectPath,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
let old_file = buffer.read(cx).file().cloned();
|
||||
let task = match &self.state {
|
||||
|
@ -1149,9 +1138,9 @@ impl BufferStore {
|
|||
|
||||
pub fn blame_buffer(
|
||||
&self,
|
||||
buffer: &Model<Buffer>,
|
||||
buffer: &Entity<Buffer>,
|
||||
version: Option<clock::Global>,
|
||||
cx: &AppContext,
|
||||
cx: &App,
|
||||
) -> Task<Result<Option<Blame>>> {
|
||||
let buffer = buffer.read(cx);
|
||||
let Some(file) = File::from_dyn(buffer.file()) else {
|
||||
|
@ -1211,9 +1200,9 @@ impl BufferStore {
|
|||
|
||||
pub fn get_permalink_to_line(
|
||||
&self,
|
||||
buffer: &Model<Buffer>,
|
||||
buffer: &Entity<Buffer>,
|
||||
selection: Range<u32>,
|
||||
cx: &AppContext,
|
||||
cx: &App,
|
||||
) -> Task<Result<url::Url>> {
|
||||
let buffer = buffer.read(cx);
|
||||
let Some(file) = File::from_dyn(buffer.file()) else {
|
||||
|
@ -1306,7 +1295,7 @@ impl BufferStore {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_buffer(&mut self, buffer: Model<Buffer>, cx: &mut ModelContext<Self>) -> Result<()> {
|
||||
fn add_buffer(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
|
||||
let remote_id = buffer.read(cx).remote_id();
|
||||
let is_remote = buffer.read(cx).replica_id() != 0;
|
||||
let open_buffer = OpenBuffer::Complete {
|
||||
|
@ -1314,7 +1303,7 @@ impl BufferStore {
|
|||
unstaged_changes: None,
|
||||
};
|
||||
|
||||
let handle = cx.handle().downgrade();
|
||||
let handle = cx.model().downgrade();
|
||||
buffer.update(cx, move |_, cx| {
|
||||
cx.on_release(move |buffer, cx| {
|
||||
handle
|
||||
|
@ -1350,7 +1339,7 @@ impl BufferStore {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn buffers(&self) -> impl '_ + Iterator<Item = Model<Buffer>> {
|
||||
pub fn buffers(&self) -> impl '_ + Iterator<Item = Entity<Buffer>> {
|
||||
self.opened_buffers
|
||||
.values()
|
||||
.filter_map(|buffer| buffer.upgrade())
|
||||
|
@ -1358,14 +1347,14 @@ impl BufferStore {
|
|||
|
||||
pub fn loading_buffers(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&ProjectPath, impl Future<Output = Result<Model<Buffer>>>)> {
|
||||
) -> impl Iterator<Item = (&ProjectPath, impl Future<Output = Result<Entity<Buffer>>>)> {
|
||||
self.loading_buffers.iter().map(|(path, task)| {
|
||||
let task = task.clone();
|
||||
(path, async move { task.await.map_err(|e| anyhow!("{e}")) })
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_by_path(&self, path: &ProjectPath, cx: &AppContext) -> Option<Model<Buffer>> {
|
||||
pub fn get_by_path(&self, path: &ProjectPath, cx: &App) -> Option<Entity<Buffer>> {
|
||||
self.buffers().find_map(|buffer| {
|
||||
let file = File::from_dyn(buffer.read(cx).file())?;
|
||||
if file.worktree_id(cx) == path.worktree_id && file.path == path.path {
|
||||
|
@ -1376,23 +1365,23 @@ impl BufferStore {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get(&self, buffer_id: BufferId) -> Option<Model<Buffer>> {
|
||||
pub fn get(&self, buffer_id: BufferId) -> Option<Entity<Buffer>> {
|
||||
self.opened_buffers.get(&buffer_id)?.upgrade()
|
||||
}
|
||||
|
||||
pub fn get_existing(&self, buffer_id: BufferId) -> Result<Model<Buffer>> {
|
||||
pub fn get_existing(&self, buffer_id: BufferId) -> Result<Entity<Buffer>> {
|
||||
self.get(buffer_id)
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))
|
||||
}
|
||||
|
||||
pub fn get_possibly_incomplete(&self, buffer_id: BufferId) -> Option<Model<Buffer>> {
|
||||
pub fn get_possibly_incomplete(&self, buffer_id: BufferId) -> Option<Entity<Buffer>> {
|
||||
self.get(buffer_id).or_else(|| {
|
||||
self.as_remote()
|
||||
.and_then(|remote| remote.loading_remote_buffers_by_id.get(&buffer_id).cloned())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_unstaged_changes(&self, buffer_id: BufferId) -> Option<Model<BufferChangeSet>> {
|
||||
pub fn get_unstaged_changes(&self, buffer_id: BufferId) -> Option<Entity<BufferChangeSet>> {
|
||||
if let OpenBuffer::Complete {
|
||||
unstaged_changes, ..
|
||||
} = self.opened_buffers.get(&buffer_id)?
|
||||
|
@ -1403,10 +1392,7 @@ impl BufferStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn buffer_version_info(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
) -> (Vec<proto::BufferVersion>, Vec<BufferId>) {
|
||||
pub fn buffer_version_info(&self, cx: &App) -> (Vec<proto::BufferVersion>, Vec<BufferId>) {
|
||||
let buffers = self
|
||||
.buffers()
|
||||
.map(|buffer| {
|
||||
|
@ -1424,7 +1410,7 @@ impl BufferStore {
|
|||
(buffers, incomplete_buffer_ids)
|
||||
}
|
||||
|
||||
pub fn disconnected_from_host(&mut self, cx: &mut AppContext) {
|
||||
pub fn disconnected_from_host(&mut self, cx: &mut App) {
|
||||
for open_buffer in self.opened_buffers.values_mut() {
|
||||
if let Some(buffer) = open_buffer.upgrade() {
|
||||
buffer.update(cx, |buffer, _| buffer.give_up_waiting());
|
||||
|
@ -1444,16 +1430,11 @@ impl BufferStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn shared(
|
||||
&mut self,
|
||||
remote_id: u64,
|
||||
downstream_client: AnyProtoClient,
|
||||
_cx: &mut AppContext,
|
||||
) {
|
||||
pub fn shared(&mut self, remote_id: u64, downstream_client: AnyProtoClient, _cx: &mut App) {
|
||||
self.downstream_client = Some((downstream_client, remote_id));
|
||||
}
|
||||
|
||||
pub fn unshared(&mut self, _cx: &mut ModelContext<Self>) {
|
||||
pub fn unshared(&mut self, _cx: &mut Context<Self>) {
|
||||
self.downstream_client.take();
|
||||
self.forget_shared_buffers();
|
||||
}
|
||||
|
@ -1468,8 +1449,8 @@ impl BufferStore {
|
|||
query: &SearchQuery,
|
||||
mut limit: usize,
|
||||
fs: Arc<dyn Fs>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Receiver<Model<Buffer>> {
|
||||
cx: &mut Context<Self>,
|
||||
) -> Receiver<Entity<Buffer>> {
|
||||
let (tx, rx) = smol::channel::unbounded();
|
||||
let mut open_buffers = HashSet::default();
|
||||
let mut unnamed_buffers = Vec::new();
|
||||
|
@ -1520,8 +1501,8 @@ impl BufferStore {
|
|||
|
||||
pub fn recalculate_buffer_diffs(
|
||||
&mut self,
|
||||
buffers: Vec<Model<Buffer>>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
buffers: Vec<Entity<Buffer>>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl Future<Output = ()> {
|
||||
let mut futures = Vec::new();
|
||||
for buffer in buffers {
|
||||
|
@ -1549,9 +1530,9 @@ impl BufferStore {
|
|||
|
||||
fn on_buffer_event(
|
||||
&mut self,
|
||||
buffer: Model<Buffer>,
|
||||
buffer: Entity<Buffer>,
|
||||
event: &BufferEvent,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
match event {
|
||||
BufferEvent::FileHandleChanged => {
|
||||
|
@ -1579,7 +1560,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_update_buffer(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::UpdateBuffer>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::Ack> {
|
||||
|
@ -1626,7 +1607,7 @@ impl BufferStore {
|
|||
pub fn handle_synchronize_buffers(
|
||||
&mut self,
|
||||
envelope: TypedEnvelope<proto::SynchronizeBuffers>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
client: Arc<Client>,
|
||||
) -> Result<proto::SynchronizeBuffersResponse> {
|
||||
let project_id = envelope.payload.project_id;
|
||||
|
@ -1718,7 +1699,7 @@ impl BufferStore {
|
|||
envelope: TypedEnvelope<proto::CreateBufferForPeer>,
|
||||
replica_id: u16,
|
||||
capability: Capability,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Result<()> {
|
||||
let Some(remote) = self.as_remote_mut() else {
|
||||
return Err(anyhow!("buffer store is not a remote"));
|
||||
|
@ -1734,7 +1715,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_update_buffer_file(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::UpdateBufferFile>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
|
@ -1782,7 +1763,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_save_buffer(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::SaveBuffer>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::BufferSaved> {
|
||||
|
@ -1823,7 +1804,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_close_buffer(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::CloseBuffer>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
|
@ -1847,7 +1828,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_buffer_saved(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::BufferSaved>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
|
@ -1875,7 +1856,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_buffer_reloaded(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::BufferReloaded>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
|
@ -1908,7 +1889,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_blame_buffer(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::BlameBuffer>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::BlameBufferResponse> {
|
||||
|
@ -1929,7 +1910,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_get_permalink_to_line(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::GetPermalinkToLine>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::GetPermalinkToLineResponse> {
|
||||
|
@ -1954,7 +1935,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_get_staged_text(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
request: TypedEnvelope<proto::GetStagedText>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::GetStagedTextResponse> {
|
||||
|
@ -1983,7 +1964,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
pub async fn handle_update_diff_base(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
request: TypedEnvelope<proto::UpdateDiffBase>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
|
@ -2014,9 +1995,9 @@ impl BufferStore {
|
|||
|
||||
pub fn reload_buffers(
|
||||
&self,
|
||||
buffers: HashSet<Model<Buffer>>,
|
||||
buffers: HashSet<Entity<Buffer>>,
|
||||
push_to_history: bool,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<ProjectTransaction>> {
|
||||
if buffers.is_empty() {
|
||||
return Task::ready(Ok(ProjectTransaction::default()));
|
||||
|
@ -2028,7 +2009,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
async fn handle_reload_buffers(
|
||||
this: Model<Self>,
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::ReloadBuffers>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::ReloadBuffersResponse> {
|
||||
|
@ -2053,9 +2034,9 @@ impl BufferStore {
|
|||
|
||||
pub fn create_buffer_for_peer(
|
||||
&mut self,
|
||||
buffer: &Model<Buffer>,
|
||||
buffer: &Entity<Buffer>,
|
||||
peer_id: proto::PeerId,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let shared_buffers = self.shared_buffers.entry(peer_id).or_default();
|
||||
|
@ -2140,9 +2121,9 @@ impl BufferStore {
|
|||
&mut self,
|
||||
text: &str,
|
||||
language: Option<Arc<Language>>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Model<Buffer> {
|
||||
let buffer = cx.new_model(|cx| {
|
||||
cx: &mut Context<Self>,
|
||||
) -> Entity<Buffer> {
|
||||
let buffer = cx.new(|cx| {
|
||||
Buffer::local(text, cx)
|
||||
.with_language(language.unwrap_or_else(|| language::PLAIN_TEXT.clone()), cx)
|
||||
});
|
||||
|
@ -2174,7 +2155,7 @@ impl BufferStore {
|
|||
&mut self,
|
||||
message: proto::ProjectTransaction,
|
||||
push_to_history: bool,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<ProjectTransaction>> {
|
||||
if let Some(this) = self.as_remote_mut() {
|
||||
this.deserialize_project_transaction(message, push_to_history, cx)
|
||||
|
@ -2187,8 +2168,8 @@ impl BufferStore {
|
|||
pub fn wait_for_remote_buffer(
|
||||
&mut self,
|
||||
id: BufferId,
|
||||
cx: &mut ModelContext<BufferStore>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
if let Some(this) = self.as_remote_mut() {
|
||||
this.wait_for_remote_buffer(id, cx)
|
||||
} else {
|
||||
|
@ -2201,7 +2182,7 @@ impl BufferStore {
|
|||
&mut self,
|
||||
project_transaction: ProjectTransaction,
|
||||
peer_id: proto::PeerId,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> proto::ProjectTransaction {
|
||||
let mut serialized_transaction = proto::ProjectTransaction {
|
||||
buffer_ids: Default::default(),
|
||||
|
@ -2222,7 +2203,7 @@ impl BufferStore {
|
|||
}
|
||||
|
||||
impl BufferChangeSet {
|
||||
pub fn new(buffer: &Model<Buffer>, cx: &mut ModelContext<Self>) -> Self {
|
||||
pub fn new(buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Self {
|
||||
cx.subscribe(buffer, |this, buffer, event, cx| match event {
|
||||
BufferEvent::LanguageChanged => {
|
||||
this.language = buffer.read(cx).language().cloned();
|
||||
|
@ -2262,8 +2243,8 @@ impl BufferChangeSet {
|
|||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn new_with_base_text(
|
||||
base_text: String,
|
||||
buffer: &Model<Buffer>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
buffer: &Entity<Buffer>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let mut this = Self::new(&buffer, cx);
|
||||
let _ = this.set_base_text(base_text, buffer.read(cx).text_snapshot(), cx);
|
||||
|
@ -2297,7 +2278,7 @@ impl BufferChangeSet {
|
|||
&mut self,
|
||||
mut base_text: String,
|
||||
buffer_snapshot: text::BufferSnapshot,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> oneshot::Receiver<()> {
|
||||
LineEnding::normalize(&mut base_text);
|
||||
self.recalculate_diff_internal(base_text, buffer_snapshot, true, cx)
|
||||
|
@ -2306,7 +2287,7 @@ impl BufferChangeSet {
|
|||
pub fn unset_base_text(
|
||||
&mut self,
|
||||
buffer_snapshot: text::BufferSnapshot,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.base_text.is_some() {
|
||||
self.base_text = None;
|
||||
|
@ -2319,7 +2300,7 @@ impl BufferChangeSet {
|
|||
pub fn recalculate_diff(
|
||||
&mut self,
|
||||
buffer_snapshot: text::BufferSnapshot,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> oneshot::Receiver<()> {
|
||||
if let Some(base_text) = self.base_text.clone() {
|
||||
self.recalculate_diff_internal(base_text.text(), buffer_snapshot, false, cx)
|
||||
|
@ -2333,7 +2314,7 @@ impl BufferChangeSet {
|
|||
base_text: String,
|
||||
buffer_snapshot: text::BufferSnapshot,
|
||||
base_text_changed: bool,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> oneshot::Receiver<()> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.diff_updated_futures.push(tx);
|
||||
|
@ -2381,7 +2362,7 @@ impl BufferChangeSet {
|
|||
mut base_text: String,
|
||||
buffer_snapshot: text::BufferSnapshot,
|
||||
base_text_changed: bool,
|
||||
cx: &mut ModelContext<Self>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
LineEnding::normalize(&mut base_text);
|
||||
let diff = BufferDiff::build(&base_text, &buffer_snapshot);
|
||||
|
@ -2404,7 +2385,7 @@ impl BufferChangeSet {
|
|||
}
|
||||
|
||||
impl OpenBuffer {
|
||||
fn upgrade(&self) -> Option<Model<Buffer>> {
|
||||
fn upgrade(&self) -> Option<Entity<Buffer>> {
|
||||
match self {
|
||||
OpenBuffer::Complete { buffer, .. } => buffer.upgrade(),
|
||||
OpenBuffer::Operations(_) => None,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue