Remove workspace::Item trait
Co-Authored-By: Nathan Sobo <nathan@zed.dev> Co-Authored-By: Keith Simmons <keith@zed.dev> Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
parent
e8efaed1b2
commit
a88320dc5f
10 changed files with 281 additions and 517 deletions
|
@ -28,7 +28,6 @@ use gpui::{
|
|||
ModelHandle, MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle,
|
||||
WeakViewHandle,
|
||||
};
|
||||
use items::{BufferItemHandle, MultiBufferItemHandle};
|
||||
use itertools::Itertools as _;
|
||||
pub use language::{char_kind, CharKind};
|
||||
use language::{
|
||||
|
@ -836,7 +835,32 @@ impl Editor {
|
|||
Self::new(EditorMode::Full, buffer, project, None, cx)
|
||||
}
|
||||
|
||||
pub fn clone(&self, nav_history: ItemNavHistory, cx: &mut ViewContext<Self>) -> Self {
|
||||
pub fn find_or_create(
|
||||
workspace: &mut Workspace,
|
||||
buffer: ModelHandle<Buffer>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> ViewHandle<Editor> {
|
||||
let project = workspace.project().clone();
|
||||
|
||||
if let Some(project_entry) =
|
||||
project::File::from_dyn(buffer.read(cx).file()).and_then(|file| file.project_entry(cx))
|
||||
{
|
||||
return workspace
|
||||
.open_item_for_project_entry(project_entry, cx, |cx| {
|
||||
let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
Editor::for_buffer(multibuffer, Some(project.clone()), cx)
|
||||
})
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let editor = cx.add_view(|cx| Editor::for_buffer(multibuffer, Some(project.clone()), cx));
|
||||
workspace.open_item(Box::new(editor.clone()), cx);
|
||||
editor
|
||||
}
|
||||
|
||||
pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self {
|
||||
let mut clone = Self::new(
|
||||
self.mode,
|
||||
self.buffer.clone(),
|
||||
|
@ -846,7 +870,6 @@ impl Editor {
|
|||
);
|
||||
clone.scroll_position = self.scroll_position;
|
||||
clone.scroll_top_anchor = self.scroll_top_anchor.clone();
|
||||
clone.nav_history = Some(nav_history);
|
||||
clone.searchable = self.searchable;
|
||||
clone
|
||||
}
|
||||
|
@ -938,14 +961,20 @@ impl Editor {
|
|||
_: &workspace::OpenNew,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
let project = workspace.project();
|
||||
let project = workspace.project().clone();
|
||||
if project.read(cx).is_remote() {
|
||||
cx.propagate_action();
|
||||
} else if let Some(buffer) = project
|
||||
.update(cx, |project, cx| project.create_buffer(cx))
|
||||
.log_err()
|
||||
{
|
||||
workspace.open_item(BufferItemHandle(buffer), cx);
|
||||
let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
workspace.open_item(
|
||||
Box::new(
|
||||
cx.add_view(|cx| Editor::for_buffer(multibuffer, Some(project.clone()), cx)),
|
||||
),
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2349,7 +2378,11 @@ impl Editor {
|
|||
});
|
||||
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let editor = workspace.open_item(MultiBufferItemHandle(excerpt_buffer), cx);
|
||||
let project = workspace.project().clone();
|
||||
let editor = workspace.open_item(
|
||||
Box::new(cx.add_view(|cx| Editor::for_buffer(excerpt_buffer, Some(project), cx))),
|
||||
cx,
|
||||
);
|
||||
if let Some(editor) = editor.act_as::<Self>(cx) {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let color = editor.style(cx).highlighted_line_background;
|
||||
|
@ -4280,20 +4313,17 @@ impl Editor {
|
|||
return;
|
||||
};
|
||||
|
||||
let definitions = workspace
|
||||
.project()
|
||||
.update(cx, |project, cx| project.definition(&buffer, head, cx));
|
||||
let project = workspace.project().clone();
|
||||
let definitions = project.update(cx, |project, cx| project.definition(&buffer, head, cx));
|
||||
cx.spawn(|workspace, mut cx| async move {
|
||||
let definitions = definitions.await?;
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let nav_history = workspace.active_pane().read(cx).nav_history().clone();
|
||||
for definition in definitions {
|
||||
let range = definition.range.to_offset(definition.buffer.read(cx));
|
||||
let target_editor_handle = workspace
|
||||
.open_item(BufferItemHandle(definition.buffer), cx)
|
||||
.downcast::<Self>()
|
||||
.unwrap();
|
||||
|
||||
let target_editor_handle =
|
||||
Self::find_or_create(workspace, definition.buffer, cx);
|
||||
target_editor_handle.update(cx, |target_editor, cx| {
|
||||
// When selecting a definition in a different buffer, disable the nav history
|
||||
// to avoid creating a history entry at the previous cursor location.
|
||||
|
@ -4324,9 +4354,8 @@ impl Editor {
|
|||
let (buffer, head) = editor.buffer.read(cx).text_anchor_for_position(head, cx)?;
|
||||
let replica_id = editor.replica_id(cx);
|
||||
|
||||
let references = workspace
|
||||
.project()
|
||||
.update(cx, |project, cx| project.references(&buffer, head, cx));
|
||||
let project = workspace.project().clone();
|
||||
let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
|
||||
Some(cx.spawn(|workspace, mut cx| async move {
|
||||
let mut locations = references.await?;
|
||||
if locations.is_empty() {
|
||||
|
@ -4370,13 +4399,13 @@ impl Editor {
|
|||
});
|
||||
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let editor = workspace.open_item(MultiBufferItemHandle(excerpt_buffer), cx);
|
||||
if let Some(editor) = editor.act_as::<Self>(cx) {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let color = editor.style(cx).highlighted_line_background;
|
||||
editor.highlight_background::<Self>(ranges_to_highlight, color, cx);
|
||||
});
|
||||
}
|
||||
let editor =
|
||||
cx.add_view(|cx| Editor::for_buffer(excerpt_buffer, Some(project), cx));
|
||||
editor.update(cx, |editor, cx| {
|
||||
let color = editor.style(cx).highlighted_line_background;
|
||||
editor.highlight_background::<Self>(ranges_to_highlight, color, cx);
|
||||
});
|
||||
workspace.open_item(Box::new(editor), cx);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -5563,17 +5592,10 @@ impl Editor {
|
|||
// and activating a new item causes the pane to call a method on us reentrantly,
|
||||
// which panics if we're on the stack.
|
||||
cx.defer(move |workspace, cx| {
|
||||
for (ix, (buffer, ranges)) in new_selections_by_buffer.into_iter().enumerate() {
|
||||
let buffer = BufferItemHandle(buffer);
|
||||
if ix == 0 && !workspace.activate_pane_for_item(&buffer, cx) {
|
||||
workspace.activate_next_pane(cx);
|
||||
}
|
||||
|
||||
let editor = workspace
|
||||
.open_item(buffer, cx)
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
workspace.activate_next_pane(cx);
|
||||
|
||||
for (buffer, ranges) in new_selections_by_buffer.into_iter() {
|
||||
let editor = Self::find_or_create(workspace, buffer, cx);
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.select_ranges(ranges, Some(Autoscroll::Newest), cx);
|
||||
});
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
use crate::{Autoscroll, Editor, Event, MultiBuffer, NavigationData, ToOffset, ToPoint as _};
|
||||
use anyhow::Result;
|
||||
use gpui::{
|
||||
elements::*, AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, RenderContext,
|
||||
Subscription, Task, View, ViewContext, ViewHandle, WeakModelHandle,
|
||||
elements::*, AppContext, Entity, ModelContext, ModelHandle, RenderContext, Subscription, Task,
|
||||
View, ViewContext, ViewHandle, WeakModelHandle,
|
||||
};
|
||||
use language::{Bias, Buffer, Diagnostic, File as _};
|
||||
use project::{File, Project, ProjectPath};
|
||||
use project::{File, Project, ProjectEntry, ProjectPath};
|
||||
use std::fmt::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::{cell::RefCell, fmt::Write};
|
||||
use text::{Point, Selection};
|
||||
use util::ResultExt;
|
||||
use workspace::{
|
||||
ItemHandle, ItemNavHistory, ItemView, ItemViewHandle, NavHistory, PathOpener, Settings,
|
||||
StatusItemView, WeakItemHandle, Workspace,
|
||||
};
|
||||
use workspace::{ItemNavHistory, ItemView, ItemViewHandle, PathOpener, Settings, StatusItemView};
|
||||
|
||||
pub struct BufferOpener;
|
||||
|
||||
|
@ -35,127 +31,22 @@ impl PathOpener for BufferOpener {
|
|||
&self,
|
||||
project: &mut Project,
|
||||
project_path: ProjectPath,
|
||||
window_id: usize,
|
||||
cx: &mut ModelContext<Project>,
|
||||
) -> Option<Task<Result<Box<dyn ItemHandle>>>> {
|
||||
) -> Option<Task<Result<Box<dyn ItemViewHandle>>>> {
|
||||
let buffer = project.open_buffer(project_path, cx);
|
||||
let task = cx.spawn(|_, _| async move {
|
||||
Some(cx.spawn(|project, mut cx| async move {
|
||||
let buffer = buffer.await?;
|
||||
Ok(Box::new(BufferItemHandle(buffer)) as Box<dyn ItemHandle>)
|
||||
});
|
||||
Some(task)
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemHandle for BufferItemHandle {
|
||||
fn add_view(
|
||||
&self,
|
||||
window_id: usize,
|
||||
workspace: &Workspace,
|
||||
nav_history: Rc<RefCell<NavHistory>>,
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Box<dyn ItemViewHandle> {
|
||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(self.0.clone(), cx));
|
||||
Box::new(cx.add_view(window_id, |cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, Some(workspace.project().clone()), cx);
|
||||
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
||||
editor
|
||||
let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let editor = cx.add_view(window_id, |cx| {
|
||||
Editor::for_buffer(multibuffer, Some(project), cx)
|
||||
});
|
||||
Ok(Box::new(editor) as Box<dyn ItemViewHandle>)
|
||||
}))
|
||||
}
|
||||
|
||||
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn to_any(&self) -> gpui::AnyModelHandle {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn downgrade(&self) -> Box<dyn workspace::WeakItemHandle> {
|
||||
Box::new(WeakBufferItemHandle(self.0.downgrade()))
|
||||
}
|
||||
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
||||
File::from_dyn(self.0.read(cx).file()).map(|f| ProjectPath {
|
||||
worktree_id: f.worktree_id(cx),
|
||||
path: f.path().clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.0.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemHandle for MultiBufferItemHandle {
|
||||
fn add_view(
|
||||
&self,
|
||||
window_id: usize,
|
||||
workspace: &Workspace,
|
||||
nav_history: Rc<RefCell<NavHistory>>,
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Box<dyn ItemViewHandle> {
|
||||
Box::new(cx.add_view(window_id, |cx| {
|
||||
let mut editor =
|
||||
Editor::for_buffer(self.0.clone(), Some(workspace.project().clone()), cx);
|
||||
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
||||
editor
|
||||
}))
|
||||
}
|
||||
|
||||
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn to_any(&self) -> gpui::AnyModelHandle {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn downgrade(&self) -> Box<dyn WeakItemHandle> {
|
||||
Box::new(WeakMultiBufferItemHandle(self.0.downgrade()))
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &AppContext) -> Option<ProjectPath> {
|
||||
None
|
||||
}
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.0.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl WeakItemHandle for WeakBufferItemHandle {
|
||||
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn ItemHandle>> {
|
||||
self.0
|
||||
.upgrade(cx)
|
||||
.map(|buffer| Box::new(BufferItemHandle(buffer)) as Box<dyn ItemHandle>)
|
||||
}
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.0.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl WeakItemHandle for WeakMultiBufferItemHandle {
|
||||
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn ItemHandle>> {
|
||||
self.0
|
||||
.upgrade(cx)
|
||||
.map(|buffer| Box::new(MultiBufferItemHandle(buffer)) as Box<dyn ItemHandle>)
|
||||
}
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.0.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemView for Editor {
|
||||
fn item(&self, cx: &AppContext) -> Box<dyn ItemHandle> {
|
||||
if let Some(buffer) = self.buffer.read(cx).as_singleton() {
|
||||
Box::new(BufferItemHandle(buffer))
|
||||
} else {
|
||||
Box::new(MultiBufferItemHandle(self.buffer.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) {
|
||||
if let Some(data) = data.downcast_ref::<NavigationData>() {
|
||||
let buffer = self.buffer.read(cx).read(cx);
|
||||
|
@ -184,15 +75,19 @@ impl ItemView for Editor {
|
|||
})
|
||||
}
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
nav_history: ItemNavHistory,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<Self>
|
||||
fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
|
||||
File::from_dyn(self.buffer().read(cx).file(cx)).and_then(|file| file.project_entry(cx))
|
||||
}
|
||||
|
||||
fn clone_on_split(&self, cx: &mut ViewContext<Self>) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Some(self.clone(nav_history, cx))
|
||||
Some(self.clone(cx))
|
||||
}
|
||||
|
||||
fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext<Self>) {
|
||||
self.nav_history = Some(history);
|
||||
}
|
||||
|
||||
fn deactivated(&mut self, cx: &mut ViewContext<Self>) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue