Draw rest of the owl
This commit is contained in:
parent
750f901f9c
commit
72e42a0d89
13 changed files with 99 additions and 57 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -329,6 +329,7 @@ dependencies = [
|
||||||
"collections",
|
"collections",
|
||||||
"ctor",
|
"ctor",
|
||||||
"editor",
|
"editor",
|
||||||
|
"editor_extensions",
|
||||||
"env_logger 0.9.3",
|
"env_logger 0.9.3",
|
||||||
"fs",
|
"fs",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
@ -1726,6 +1727,7 @@ dependencies = [
|
||||||
"db",
|
"db",
|
||||||
"drag_and_drop",
|
"drag_and_drop",
|
||||||
"editor",
|
"editor",
|
||||||
|
"editor_extensions",
|
||||||
"feature_flags",
|
"feature_flags",
|
||||||
"feedback",
|
"feedback",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
@ -2941,6 +2943,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"client",
|
"client",
|
||||||
"editor",
|
"editor",
|
||||||
|
"editor_extensions",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
"gpui",
|
"gpui",
|
||||||
"human_bytes",
|
"human_bytes",
|
||||||
|
@ -11148,6 +11151,7 @@ dependencies = [
|
||||||
"db",
|
"db",
|
||||||
"diagnostics",
|
"diagnostics",
|
||||||
"editor",
|
"editor",
|
||||||
|
"editor_extensions",
|
||||||
"env_logger 0.9.3",
|
"env_logger 0.9.3",
|
||||||
"feature_flags",
|
"feature_flags",
|
||||||
"feedback",
|
"feedback",
|
||||||
|
|
|
@ -13,6 +13,7 @@ ai = { path = "../ai" }
|
||||||
client = { path = "../client" }
|
client = { path = "../client" }
|
||||||
collections = { path = "../collections"}
|
collections = { path = "../collections"}
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
|
editor_extensions = { path = "../editor_extensions" }
|
||||||
fs = { path = "../fs" }
|
fs = { path = "../fs" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
language = { path = "../language" }
|
language = { path = "../language" }
|
||||||
|
|
|
@ -24,6 +24,7 @@ use editor::{
|
||||||
scroll::autoscroll::{Autoscroll, AutoscrollStrategy},
|
scroll::autoscroll::{Autoscroll, AutoscrollStrategy},
|
||||||
Anchor, Editor, MoveDown, MoveUp, MultiBufferSnapshot, ToOffset, ToPoint,
|
Anchor, Editor, MoveDown, MoveUp, MultiBufferSnapshot, ToOffset, ToPoint,
|
||||||
};
|
};
|
||||||
|
use editor_extensions::FollowableEditor;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -2196,7 +2197,7 @@ struct ConversationEditor {
|
||||||
conversation: ModelHandle<Conversation>,
|
conversation: ModelHandle<Conversation>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
editor: ViewHandle<Editor>,
|
editor: ViewHandle<FollowableEditor>,
|
||||||
blocks: HashSet<BlockId>,
|
blocks: HashSet<BlockId>,
|
||||||
scroll_position: Option<ScrollPosition>,
|
scroll_position: Option<ScrollPosition>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
|
@ -2222,10 +2223,11 @@ impl ConversationEditor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let editor = cx.add_view(|cx| {
|
let editor = cx.add_view(|cx| {
|
||||||
let mut editor = Editor::for_buffer(conversation.read(cx).buffer.clone(), None, cx);
|
let mut editor = FollowableEditor::for_raw_buffer(conversation.read(cx).buffer.clone(), cx);
|
||||||
editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
|
editor.0.update(cx, |this, cx| {this.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
|
||||||
editor.set_show_gutter(false, cx);
|
this.set_show_gutter(false, cx);
|
||||||
editor.set_show_wrap_guides(false, cx);
|
this.set_show_wrap_guides(false, cx);
|
||||||
|
});
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2277,11 +2279,11 @@ impl ConversationEditor {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if !new_selections.is_empty() {
|
if !new_selections.is_empty() {
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
editor.change_selections(
|
editor.0.update(cx, |this, cx| this.change_selections(
|
||||||
Some(Autoscroll::Strategy(AutoscrollStrategy::Fit)),
|
Some(Autoscroll::Strategy(AutoscrollStrategy::Fit)),
|
||||||
cx,
|
cx,
|
||||||
|selections| selections.select_ranges(new_selections),
|
|selections| selections.select_ranges(new_selections),
|
||||||
);
|
));
|
||||||
});
|
});
|
||||||
// Avoid scrolling to the new cursor position so the assistant's output is stable.
|
// Avoid scrolling to the new cursor position so the assistant's output is stable.
|
||||||
cx.defer(|this, _| this.scroll_position = None);
|
cx.defer(|this, _| this.scroll_position = None);
|
||||||
|
@ -2310,7 +2312,7 @@ impl ConversationEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursors(&self, cx: &AppContext) -> Vec<usize> {
|
fn cursors(&self, cx: &AppContext) -> Vec<usize> {
|
||||||
let selections = self.editor.read(cx).selections.all::<usize>(cx);
|
let selections = self.editor.read(cx).0.read(cx).selections.all::<usize>(cx);
|
||||||
selections
|
selections
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| selection.head())
|
.map(|selection| selection.head())
|
||||||
|
@ -2339,14 +2341,14 @@ impl ConversationEditor {
|
||||||
ConversationEvent::StreamedCompletion => {
|
ConversationEvent::StreamedCompletion => {
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
if let Some(scroll_position) = self.scroll_position {
|
if let Some(scroll_position) = self.scroll_position {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.0.update(cx, |this, cx| this.snapshot(cx));
|
||||||
let cursor_point = scroll_position.cursor.to_display_point(&snapshot);
|
let cursor_point = scroll_position.cursor.to_display_point(&snapshot);
|
||||||
let scroll_top =
|
let scroll_top =
|
||||||
cursor_point.row() as f32 - scroll_position.offset_before_cursor.y();
|
cursor_point.row() as f32 - scroll_position.offset_before_cursor.y();
|
||||||
editor.set_scroll_position(
|
editor.0.update(cx, |this, cx| this.set_scroll_position(
|
||||||
vec2f(scroll_position.offset_before_cursor.x(), scroll_top),
|
vec2f(scroll_position.offset_before_cursor.x(), scroll_top),
|
||||||
cx,
|
cx,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2355,7 +2357,7 @@ impl ConversationEditor {
|
||||||
|
|
||||||
fn handle_editor_event(
|
fn handle_editor_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ViewHandle<Editor>,
|
_: ViewHandle<FollowableEditor>,
|
||||||
event: &editor::Event,
|
event: &editor::Event,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
@ -2377,15 +2379,15 @@ impl ConversationEditor {
|
||||||
|
|
||||||
fn cursor_scroll_position(&self, cx: &mut ViewContext<Self>) -> Option<ScrollPosition> {
|
fn cursor_scroll_position(&self, cx: &mut ViewContext<Self>) -> Option<ScrollPosition> {
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.0.update(cx, |this, cx| this.snapshot(cx));
|
||||||
let cursor = editor.selections.newest_anchor().head();
|
let cursor = editor.0.read(cx).selections.newest_anchor().head();
|
||||||
let cursor_row = cursor.to_display_point(&snapshot.display_snapshot).row() as f32;
|
let cursor_row = cursor.to_display_point(&snapshot.display_snapshot).row() as f32;
|
||||||
let scroll_position = editor
|
let scroll_position = editor.0.read(cx)
|
||||||
.scroll_manager
|
.scroll_manager
|
||||||
.anchor()
|
.anchor()
|
||||||
.scroll_position(&snapshot.display_snapshot);
|
.scroll_position(&snapshot.display_snapshot);
|
||||||
|
|
||||||
let scroll_bottom = scroll_position.y() + editor.visible_line_count().unwrap_or(0.);
|
let scroll_bottom = scroll_position.y() + editor.0.read(cx).visible_line_count().unwrap_or(0.);
|
||||||
if (scroll_position.y()..scroll_bottom).contains(&cursor_row) {
|
if (scroll_position.y()..scroll_bottom).contains(&cursor_row) {
|
||||||
Some(ScrollPosition {
|
Some(ScrollPosition {
|
||||||
cursor,
|
cursor,
|
||||||
|
@ -2402,7 +2404,7 @@ impl ConversationEditor {
|
||||||
|
|
||||||
fn update_message_headers(&mut self, cx: &mut ViewContext<Self>) {
|
fn update_message_headers(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
let buffer = editor.0.read(cx).buffer().read(cx).snapshot(cx);
|
||||||
let excerpt_id = *buffer.as_singleton().unwrap().0;
|
let excerpt_id = *buffer.as_singleton().unwrap().0;
|
||||||
let old_blocks = std::mem::take(&mut self.blocks);
|
let old_blocks = std::mem::take(&mut self.blocks);
|
||||||
let new_blocks = self
|
let new_blocks = self
|
||||||
|
@ -2505,8 +2507,10 @@ impl ConversationEditor {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
editor.remove_blocks(old_blocks, None, cx);
|
let ids = editor.0.update(cx, |this, cx| {
|
||||||
let ids = editor.insert_blocks(new_blocks, None, cx);
|
this.remove_blocks(old_blocks, None, cx);
|
||||||
|
this.insert_blocks(new_blocks, None, cx)
|
||||||
|
});
|
||||||
self.blocks = HashSet::from_iter(ids);
|
self.blocks = HashSet::from_iter(ids);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2568,14 +2572,14 @@ impl ConversationEditor {
|
||||||
conversation.update(cx, |conversation, cx| {
|
conversation.update(cx, |conversation, cx| {
|
||||||
conversation
|
conversation
|
||||||
.editor
|
.editor
|
||||||
.update(cx, |editor, cx| editor.insert(&text, cx))
|
.update(cx, |editor, cx| editor.0.update(cx, |this, cx| this.insert(&text, cx)))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy(&mut self, _: &editor::Copy, cx: &mut ViewContext<Self>) {
|
fn copy(&mut self, _: &editor::Copy, cx: &mut ViewContext<Self>) {
|
||||||
let editor = self.editor.read(cx);
|
let editor = self.editor.read(cx).0.read(cx);
|
||||||
let conversation = self.conversation.read(cx);
|
let conversation = self.conversation.read(cx);
|
||||||
if editor.selections.count() == 1 {
|
if editor.selections.count() == 1 {
|
||||||
let selection = editor.selections.newest::<usize>(cx);
|
let selection = editor.selections.newest::<usize>(cx);
|
||||||
|
@ -2610,9 +2614,9 @@ impl ConversationEditor {
|
||||||
|
|
||||||
fn split(&mut self, _: &Split, cx: &mut ViewContext<Self>) {
|
fn split(&mut self, _: &Split, cx: &mut ViewContext<Self>) {
|
||||||
self.conversation.update(cx, |conversation, cx| {
|
self.conversation.update(cx, |conversation, cx| {
|
||||||
let selections = self.editor.read(cx).selections.disjoint_anchors();
|
let selections = self.editor.read(cx).0.read(cx).selections.disjoint_anchors();
|
||||||
for selection in selections.into_iter() {
|
for selection in selections.into_iter() {
|
||||||
let buffer = self.editor.read(cx).buffer().read(cx).snapshot(cx);
|
let buffer = self.editor.read(cx).0.read(cx).buffer().read(cx).snapshot(cx);
|
||||||
let range = selection
|
let range = selection
|
||||||
.map(|endpoint| endpoint.to_offset(&buffer))
|
.map(|endpoint| endpoint.to_offset(&buffer))
|
||||||
.range();
|
.range();
|
||||||
|
|
|
@ -32,6 +32,7 @@ collections = { path = "../collections" }
|
||||||
context_menu = { path = "../context_menu" }
|
context_menu = { path = "../context_menu" }
|
||||||
drag_and_drop = { path = "../drag_and_drop" }
|
drag_and_drop = { path = "../drag_and_drop" }
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
|
editor_extensions = { path = "../editor_extensions" }
|
||||||
feedback = { path = "../feedback" }
|
feedback = { path = "../feedback" }
|
||||||
fuzzy = { path = "../fuzzy" }
|
fuzzy = { path = "../fuzzy" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
|
|
|
@ -7,6 +7,7 @@ use client::{
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::{CollaborationHub, Editor};
|
use editor::{CollaborationHub, Editor};
|
||||||
|
use editor_extensions::FollowableEditor;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::{ChildView, Label},
|
elements::{ChildView, Label},
|
||||||
|
@ -35,7 +36,7 @@ pub fn init(cx: &mut AppContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChannelView {
|
pub struct ChannelView {
|
||||||
pub editor: ViewHandle<Editor>,
|
pub editor: ViewHandle<FollowableEditor>,
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
channel_store: ModelHandle<ChannelStore>,
|
channel_store: ModelHandle<ChannelStore>,
|
||||||
channel_buffer: ModelHandle<ChannelBuffer>,
|
channel_buffer: ModelHandle<ChannelBuffer>,
|
||||||
|
@ -137,16 +138,18 @@ impl ChannelView {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let buffer = channel_buffer.read(cx).buffer();
|
let buffer = channel_buffer.read(cx).buffer();
|
||||||
let editor = cx.add_view(|cx| {
|
let editor = cx.add_view(|cx| {
|
||||||
let mut editor = Editor::for_buffer(buffer, None, cx);
|
let mut editor = FollowableEditor::for_raw_buffer(buffer, cx);
|
||||||
editor.set_collaboration_hub(Box::new(ChannelBufferCollaborationHub(
|
editor.0.update(cx, |this, cx| {
|
||||||
|
this.set_collaboration_hub(Box::new(ChannelBufferCollaborationHub(
|
||||||
channel_buffer.clone(),
|
channel_buffer.clone(),
|
||||||
)));
|
)));
|
||||||
editor.set_read_only(
|
this.set_read_only(
|
||||||
!channel_buffer
|
!channel_buffer
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.channel(cx)
|
.channel(cx)
|
||||||
.is_some_and(|c| c.can_edit_notes()),
|
.is_some_and(|c| c.can_edit_notes()),
|
||||||
);
|
);
|
||||||
|
});
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
let _editor_event_subscription = cx.subscribe(&editor, |_, _, e, cx| cx.emit(e.clone()));
|
let _editor_event_subscription = cx.subscribe(&editor, |_, _, e, cx| cx.emit(e.clone()));
|
||||||
|
@ -176,12 +179,12 @@ impl ChannelView {
|
||||||
) {
|
) {
|
||||||
match event {
|
match event {
|
||||||
ChannelBufferEvent::Disconnected => self.editor.update(cx, |editor, cx| {
|
ChannelBufferEvent::Disconnected => self.editor.update(cx, |editor, cx| {
|
||||||
editor.set_read_only(true);
|
editor.0.update(cx, |this, cx| this.set_read_only(true));
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}),
|
}),
|
||||||
ChannelBufferEvent::ChannelChanged => {
|
ChannelBufferEvent::ChannelChanged => {
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
editor.set_read_only(!self.channel(cx).is_some_and(|c| c.can_edit_notes()));
|
editor.0.update(cx, |this, cx| this.set_read_only(!self.channel(cx).is_some_and(|c| c.can_edit_notes())));
|
||||||
cx.emit(editor::Event::TitleChanged);
|
cx.emit(editor::Event::TitleChanged);
|
||||||
cx.notify()
|
cx.notify()
|
||||||
});
|
});
|
||||||
|
@ -320,7 +323,7 @@ impl Item for ChannelView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_item_events(event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
|
fn to_item_events(event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
|
||||||
editor::Editor::to_item_events(event)
|
FollowableEditor::to_item_events(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +433,7 @@ impl FollowableItem for ChannelView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_unfollow_on_event(event: &Self::Event, cx: &AppContext) -> bool {
|
fn should_unfollow_on_event(event: &Self::Event, cx: &AppContext) -> bool {
|
||||||
Editor::should_unfollow_on_event(event, cx)
|
FollowableEditor::should_unfollow_on_event(event, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_project_item(&self, _cx: &AppContext) -> bool {
|
fn is_project_item(&self, _cx: &AppContext) -> bool {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use context_menu::{ContextMenu, ContextMenuItem};
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use drag_and_drop::{DragAndDrop, Draggable};
|
use drag_and_drop::{DragAndDrop, Draggable};
|
||||||
use editor::{Cancel, Editor};
|
use editor::{Cancel, Editor};
|
||||||
|
use editor_extensions::FollowableEditor;
|
||||||
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
|
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use fuzzy::{match_strings, StringMatchCandidate};
|
use fuzzy::{match_strings, StringMatchCandidate};
|
||||||
|
@ -274,7 +275,7 @@ pub struct CollabPanel {
|
||||||
pending_serialization: Task<Option<()>>,
|
pending_serialization: Task<Option<()>>,
|
||||||
context_menu: ViewHandle<ContextMenu>,
|
context_menu: ViewHandle<ContextMenu>,
|
||||||
filter_editor: ViewHandle<Editor>,
|
filter_editor: ViewHandle<Editor>,
|
||||||
channel_name_editor: ViewHandle<Editor>,
|
channel_name_editor: ViewHandle<FollowableEditor>,
|
||||||
channel_editing_state: Option<ChannelEditingState>,
|
channel_editing_state: Option<ChannelEditingState>,
|
||||||
entries: Vec<ListEntry>,
|
entries: Vec<ListEntry>,
|
||||||
selection: Option<usize>,
|
selection: Option<usize>,
|
||||||
|
@ -409,7 +410,7 @@ impl CollabPanel {
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
let channel_name_editor = cx.add_view(|cx| {
|
let channel_name_editor = cx.add_view(|cx| {
|
||||||
Editor::single_line(
|
FollowableEditor::single_line(
|
||||||
Some(Arc::new(|theme| {
|
Some(Arc::new(|theme| {
|
||||||
theme.collab_panel.user_query_editor.clone()
|
theme.collab_panel.user_query_editor.clone()
|
||||||
})),
|
})),
|
||||||
|
@ -1433,7 +1434,7 @@ impl CollabPanel {
|
||||||
fn take_editing_state(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
fn take_editing_state(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
||||||
if let Some(_) = self.channel_editing_state.take() {
|
if let Some(_) = self.channel_editing_state.take() {
|
||||||
self.channel_name_editor.update(cx, |editor, cx| {
|
self.channel_name_editor.update(cx, |editor, cx| {
|
||||||
editor.set_text("", cx);
|
editor.0.update(cx, |this, cx| this.set_text("", cx));
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -2822,7 +2823,7 @@ impl CollabPanel {
|
||||||
fn insert_space(&mut self, _: &InsertSpace, cx: &mut ViewContext<Self>) {
|
fn insert_space(&mut self, _: &InsertSpace, cx: &mut ViewContext<Self>) {
|
||||||
if self.channel_editing_state.is_some() {
|
if self.channel_editing_state.is_some() {
|
||||||
self.channel_name_editor.update(cx, |editor, cx| {
|
self.channel_name_editor.update(cx, |editor, cx| {
|
||||||
editor.insert(" ", cx);
|
editor.0.update(cx, |this, cx| this.insert(" ", cx));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2838,7 +2839,7 @@ impl CollabPanel {
|
||||||
if pending_name.is_some() {
|
if pending_name.is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let channel_name = self.channel_name_editor.read(cx).text(cx);
|
let channel_name = self.channel_name_editor.read(cx).0.read(cx).text(cx);
|
||||||
|
|
||||||
*pending_name = Some(channel_name.clone());
|
*pending_name = Some(channel_name.clone());
|
||||||
|
|
||||||
|
@ -2856,7 +2857,7 @@ impl CollabPanel {
|
||||||
if pending_name.is_some() {
|
if pending_name.is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let channel_name = self.channel_name_editor.read(cx).text(cx);
|
let channel_name = self.channel_name_editor.read(cx).0.read(cx).text(cx);
|
||||||
*pending_name = Some(channel_name.clone());
|
*pending_name = Some(channel_name.clone());
|
||||||
|
|
||||||
self.channel_store
|
self.channel_store
|
||||||
|
@ -3025,8 +3026,11 @@ impl CollabPanel {
|
||||||
pending_name: None,
|
pending_name: None,
|
||||||
});
|
});
|
||||||
self.channel_name_editor.update(cx, |editor, cx| {
|
self.channel_name_editor.update(cx, |editor, cx| {
|
||||||
editor.set_text(channel.name.clone(), cx);
|
editor.0.update(cx, |this, cx| {
|
||||||
editor.select_all(&Default::default(), cx);
|
this.set_text(channel.name.clone(), cx);
|
||||||
|
this.select_all(&Default::default(), cx);
|
||||||
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
cx.focus(self.channel_name_editor.as_any());
|
cx.focus(self.channel_name_editor.as_any());
|
||||||
self.update_entries(false, cx);
|
self.update_entries(false, cx);
|
||||||
|
|
|
@ -617,7 +617,7 @@ pub const MAX_TAB_TITLE_LEN: usize = 24;
|
||||||
|
|
||||||
type CompletionId = usize;
|
type CompletionId = usize;
|
||||||
|
|
||||||
type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
|
pub type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
|
||||||
type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
|
type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
|
||||||
|
|
||||||
type BackgroundHighlight = (fn(&Theme) -> Color, Vec<Range<Anchor>>);
|
type BackgroundHighlight = (fn(&Theme) -> Color, Vec<Range<Anchor>>);
|
||||||
|
|
|
@ -453,6 +453,27 @@ impl FollowableEditor {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
pub fn for_raw_buffer(
|
||||||
|
buffer: ModelHandle<Buffer>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Self {
|
||||||
|
Self(
|
||||||
|
cx.add_view(|cx| {
|
||||||
|
Editor::for_buffer(buffer, None, cx)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn single_line(
|
||||||
|
field_editor_style: Option<Arc<editor::GetFieldEditorTheme>>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Self {
|
||||||
|
Self(
|
||||||
|
cx.add_view(|cx| {
|
||||||
|
Editor::single_line(field_editor_style, cx)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl gpui::View for FollowableEditor {
|
impl gpui::View for FollowableEditor {
|
||||||
|
|
|
@ -13,6 +13,7 @@ test-support = []
|
||||||
[dependencies]
|
[dependencies]
|
||||||
client = { path = "../client" }
|
client = { path = "../client" }
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
|
editor_extensions = { path = "../editor_extensions" }
|
||||||
language = { path = "../language" }
|
language = { path = "../language" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
project = { path = "../project" }
|
project = { path = "../project" }
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::system_specs::SystemSpecs;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
|
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
|
||||||
use editor::{Anchor, Editor};
|
use editor::{Anchor, Editor};
|
||||||
|
use editor_extensions::FollowableEditor;
|
||||||
use futures::AsyncReadExt;
|
use futures::AsyncReadExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
|
@ -58,7 +59,7 @@ struct FeedbackRequestBody<'a> {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct FeedbackEditor {
|
pub(crate) struct FeedbackEditor {
|
||||||
system_specs: SystemSpecs,
|
system_specs: SystemSpecs,
|
||||||
editor: ViewHandle<Editor>,
|
editor: ViewHandle<FollowableEditor>,
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
pub allow_submission: bool,
|
pub allow_submission: bool,
|
||||||
}
|
}
|
||||||
|
@ -71,8 +72,8 @@ impl FeedbackEditor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let editor = cx.add_view(|cx| {
|
let editor = cx.add_view(|cx| {
|
||||||
let mut editor = Editor::for_buffer(buffer, Some(Arc::new(project.clone())), cx);
|
let mut editor = FollowableEditor::for_buffer(buffer, project.clone(), cx);
|
||||||
editor.set_vertical_scroll_margin(5, cx);
|
editor.0.update(cx, |this, cx| this.set_vertical_scroll_margin(5, cx));
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ impl FeedbackEditor {
|
||||||
return Task::ready(Ok(()));
|
return Task::ready(Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let feedback_text = self.editor.read(cx).text(cx);
|
let feedback_text = self.editor.read(cx).0.read(cx).text(cx);
|
||||||
let feedback_char_count = feedback_text.chars().count();
|
let feedback_char_count = feedback_text.chars().count();
|
||||||
let feedback_text = feedback_text.trim().to_string();
|
let feedback_text = feedback_text.trim().to_string();
|
||||||
|
|
||||||
|
@ -339,7 +340,7 @@ impl Item for FeedbackEditor {
|
||||||
{
|
{
|
||||||
let buffer = self
|
let buffer = self
|
||||||
.editor
|
.editor
|
||||||
.read(cx)
|
.read(cx).0.read(cx)
|
||||||
.buffer()
|
.buffer()
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.as_singleton()
|
.as_singleton()
|
||||||
|
@ -373,7 +374,7 @@ impl Item for FeedbackEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_item_events(event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
|
fn to_item_events(event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
|
||||||
Editor::to_item_events(event)
|
FollowableEditor::to_item_events(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ copilot_button = { path = "../copilot_button" }
|
||||||
diagnostics = { path = "../diagnostics" }
|
diagnostics = { path = "../diagnostics" }
|
||||||
db = { path = "../db" }
|
db = { path = "../db" }
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
|
editor_extensions = { path = "../editor_extensions" }
|
||||||
feedback = { path = "../feedback" }
|
feedback = { path = "../feedback" }
|
||||||
file_finder = { path = "../file_finder" }
|
file_finder = { path = "../file_finder" }
|
||||||
search = { path = "../search" }
|
search = { path = "../search" }
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn main() {
|
||||||
if cx.has_global::<Weak<AppState>>() {
|
if cx.has_global::<Weak<AppState>>() {
|
||||||
if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
|
if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
|
||||||
workspace::open_new(&app_state, cx, |workspace, cx| {
|
workspace::open_new(&app_state, cx, |workspace, cx| {
|
||||||
Editor::new_file(workspace, &Default::default(), cx)
|
editor_extensions::new_file(workspace, &Default::default(), cx)
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ async fn restore_or_create_workspace(app_state: &Arc<AppState>, mut cx: AsyncApp
|
||||||
} else {
|
} else {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
workspace::open_new(app_state, cx, |workspace, cx| {
|
workspace::open_new(app_state, cx, |workspace, cx| {
|
||||||
Editor::new_file(workspace, &Default::default(), cx)
|
editor_extensions::new_file(workspace, &Default::default(), cx)
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,6 +15,7 @@ use collab_ui::CollabTitlebarItem; // TODO: Add back toggle collab ui shortcut
|
||||||
use collections::VecDeque;
|
use collections::VecDeque;
|
||||||
pub use editor;
|
pub use editor;
|
||||||
use editor::{Editor, MultiBuffer};
|
use editor::{Editor, MultiBuffer};
|
||||||
|
use editor_extensions::FollowableEditor;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use feedback::{
|
use feedback::{
|
||||||
|
@ -195,9 +196,9 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
||||||
});
|
});
|
||||||
workspace.add_item(
|
workspace.add_item(
|
||||||
Box::new(cx.add_view(|cx| {
|
Box::new(cx.add_view(|cx| {
|
||||||
Editor::for_multibuffer(
|
FollowableEditor::for_multibuffer(
|
||||||
buffer,
|
buffer,
|
||||||
Some(Arc::new(project.clone())),
|
project.clone(),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})),
|
})),
|
||||||
|
@ -250,7 +251,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
||||||
move |_: &NewWindow, cx: &mut AppContext| {
|
move |_: &NewWindow, cx: &mut AppContext| {
|
||||||
if let Some(app_state) = app_state.upgrade() {
|
if let Some(app_state) = app_state.upgrade() {
|
||||||
open_new(&app_state, cx, |workspace, cx| {
|
open_new(&app_state, cx, |workspace, cx| {
|
||||||
Editor::new_file(workspace, &Default::default(), cx)
|
editor_extensions::new_file(workspace, &Default::default(), cx)
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
@ -261,7 +262,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
||||||
move |_: &NewFile, cx: &mut AppContext| {
|
move |_: &NewFile, cx: &mut AppContext| {
|
||||||
if let Some(app_state) = app_state.upgrade() {
|
if let Some(app_state) = app_state.upgrade() {
|
||||||
open_new(&app_state, cx, |workspace, cx| {
|
open_new(&app_state, cx, |workspace, cx| {
|
||||||
Editor::new_file(workspace, &Default::default(), cx)
|
editor_extensions::new_file(workspace, &Default::default(), cx)
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
@ -336,7 +337,7 @@ pub fn initialize_workspace(
|
||||||
let feedback_button = cx.add_view(|_| {
|
let feedback_button = cx.add_view(|_| {
|
||||||
feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
|
feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
|
||||||
});
|
});
|
||||||
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
let cursor_position = cx.add_view(|_| editor_extensions::CursorPosition::new());
|
||||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||||
status_bar.add_left_item(diagnostic_summary, cx);
|
status_bar.add_left_item(diagnostic_summary, cx);
|
||||||
status_bar.add_left_item(activity_indicator, cx);
|
status_bar.add_left_item(activity_indicator, cx);
|
||||||
|
@ -540,7 +541,7 @@ fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
|
||||||
});
|
});
|
||||||
workspace.add_item(
|
workspace.add_item(
|
||||||
Box::new(cx.add_view(|cx| {
|
Box::new(cx.add_view(|cx| {
|
||||||
Editor::for_multibuffer(buffer, Some(Arc::new(project)), cx)
|
FollowableEditor::for_multibuffer(buffer, project, cx)
|
||||||
})),
|
})),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -708,7 +709,7 @@ fn open_telemetry_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Works
|
||||||
MultiBuffer::singleton(buffer, cx).with_title("Telemetry Log".into())
|
MultiBuffer::singleton(buffer, cx).with_title("Telemetry Log".into())
|
||||||
});
|
});
|
||||||
workspace.add_item(
|
workspace.add_item(
|
||||||
Box::new(cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(Arc::new(project)), cx))),
|
Box::new(cx.add_view(|cx| FollowableEditor::for_multibuffer(buffer, project, cx))),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}).log_err()?;
|
}).log_err()?;
|
||||||
|
@ -743,7 +744,7 @@ fn open_bundled_file(
|
||||||
});
|
});
|
||||||
workspace.add_item(
|
workspace.add_item(
|
||||||
Box::new(cx.add_view(|cx| {
|
Box::new(cx.add_view(|cx| {
|
||||||
Editor::for_multibuffer(buffer, Some(Arc::new(project.clone())), cx)
|
FollowableEditor::for_multibuffer(buffer, project.clone(), cx)
|
||||||
})),
|
})),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue