mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Make production code compile again
This commit is contained in:
parent
bed94455b9
commit
38ab6b123f
@ -148,7 +148,7 @@ impl ToolbarItemView for Breadcrumbs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pane_focus_update(&mut self, pane_focused: bool, _: &mut gpui::AppContext) {
|
fn pane_focus_update(&mut self, pane_focused: bool, _: &mut ViewContext<Self>) {
|
||||||
self.pane_focused = pane_focused;
|
self.pane_focused = pane_focused;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,27 +26,31 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
|
|
||||||
match &status {
|
match &status {
|
||||||
crate::Status::SigningIn { prompt } => {
|
crate::Status::SigningIn { prompt } => {
|
||||||
if let Some(code_verification_handle) = code_verification.as_mut() {
|
if let Some(code_verification) = code_verification.as_mut() {
|
||||||
if cx.has_window(code_verification_handle.window_id()) {
|
if cx.has_window(code_verification.window_id()) {
|
||||||
code_verification_handle.update(cx, |code_verification_view, cx| {
|
cx.update_window(code_verification.window_id(), |cx| {
|
||||||
code_verification_view.set_status(status, cx);
|
code_verification.update(cx, |code_verification_view, cx| {
|
||||||
cx.activate_window();
|
code_verification_view.set_status(status, cx);
|
||||||
|
cx.activate_window();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
create_copilot_auth_window(cx, &status, &mut code_verification);
|
*code_verification = create_copilot_auth_window(cx, &status);
|
||||||
}
|
}
|
||||||
} else if let Some(_prompt) = prompt {
|
} else if let Some(_prompt) = prompt {
|
||||||
create_copilot_auth_window(cx, &status, &mut code_verification);
|
code_verification = Some(create_copilot_auth_window(cx, &status));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status::Authorized | Status::Unauthorized => {
|
Status::Authorized | Status::Unauthorized => {
|
||||||
if let Some(code_verification) = code_verification.as_ref() {
|
if let Some(code_verification) = code_verification.as_ref() {
|
||||||
code_verification.update(cx, |code_verification, cx| {
|
cx.update_window(code_verification.window_id(), |cx| {
|
||||||
code_verification.set_status(status, cx);
|
code_verification.update(cx, |code_verification, cx| {
|
||||||
cx.activate_window();
|
code_verification.set_status(status, cx);
|
||||||
});
|
cx.activate_window();
|
||||||
|
});
|
||||||
|
|
||||||
cx.platform().activate(true);
|
cx.platform().activate(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -62,8 +66,7 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
fn create_copilot_auth_window(
|
fn create_copilot_auth_window(
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
status: &Status,
|
status: &Status,
|
||||||
code_verification: &mut Option<ViewHandle<CopilotCodeVerification>>,
|
) -> ViewHandle<CopilotCodeVerification> {
|
||||||
) {
|
|
||||||
let window_size = cx.global::<Settings>().theme.copilot.modal.dimensions();
|
let window_size = cx.global::<Settings>().theme.copilot.modal.dimensions();
|
||||||
let window_options = WindowOptions {
|
let window_options = WindowOptions {
|
||||||
bounds: WindowBounds::Fixed(RectF::new(Default::default(), window_size)),
|
bounds: WindowBounds::Fixed(RectF::new(Default::default(), window_size)),
|
||||||
@ -77,7 +80,7 @@ fn create_copilot_auth_window(
|
|||||||
let (_, view) = cx.add_window(window_options, |_cx| {
|
let (_, view) = cx.add_window(window_options, |_cx| {
|
||||||
CopilotCodeVerification::new(status.clone())
|
CopilotCodeVerification::new(status.clone())
|
||||||
});
|
});
|
||||||
*code_verification = Some(view);
|
view
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CopilotCodeVerification {
|
pub struct CopilotCodeVerification {
|
||||||
|
@ -765,7 +765,7 @@ mod tests {
|
|||||||
display_map::{BlockContext, TransformBlock},
|
display_map::{BlockContext, TransformBlock},
|
||||||
DisplayPoint,
|
DisplayPoint,
|
||||||
};
|
};
|
||||||
use gpui::TestAppContext;
|
use gpui::{TestAppContext, WindowContext};
|
||||||
use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16, Unclipped};
|
use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16, Unclipped};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use unindent::Unindent as _;
|
use unindent::Unindent as _;
|
||||||
@ -1175,7 +1175,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn editor_blocks(editor: &ViewHandle<Editor>, cx: &mut AppContext) -> Vec<(u32, String)> {
|
fn editor_blocks(editor: &ViewHandle<Editor>, cx: &mut WindowContext) -> Vec<(u32, String)> {
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
snapshot
|
snapshot
|
||||||
|
@ -6,7 +6,7 @@ use gpui::{
|
|||||||
geometry::{rect::RectF, vector::Vector2F},
|
geometry::{rect::RectF, vector::Vector2F},
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
scene::{MouseDown, MouseDrag},
|
scene::{MouseDown, MouseDrag},
|
||||||
AppContext, Drawable, Element, View, ViewContext, WeakViewHandle,
|
Drawable, Element, View, ViewContext, WeakViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEAD_ZONE: f32 = 4.;
|
const DEAD_ZONE: f32 = 4.;
|
||||||
@ -263,7 +263,7 @@ impl<V: View> DragAndDrop<V> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel_dragging<P: Any>(&mut self, cx: &mut AppContext) {
|
pub fn cancel_dragging<P: Any>(&mut self, cx: &mut WindowContext) {
|
||||||
if let Some(State::Dragging {
|
if let Some(State::Dragging {
|
||||||
payload, window_id, ..
|
payload, window_id, ..
|
||||||
}) = &self.currently_dragged
|
}) = &self.currently_dragged
|
||||||
@ -276,13 +276,13 @@ impl<V: View> DragAndDrop<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish_dragging(&mut self, cx: &mut AppContext) {
|
fn finish_dragging(&mut self, cx: &mut WindowContext) {
|
||||||
if let Some(State::Dragging { window_id, .. }) = self.currently_dragged.take() {
|
if let Some(State::Dragging { window_id, .. }) = self.currently_dragged.take() {
|
||||||
self.notify_containers_for_window(window_id, cx);
|
self.notify_containers_for_window(window_id, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notify_containers_for_window(&mut self, window_id: usize, cx: &mut AppContext) {
|
fn notify_containers_for_window(&mut self, window_id: usize, cx: &mut WindowContext) {
|
||||||
self.containers.retain(|container| {
|
self.containers.retain(|container| {
|
||||||
if let Some(container) = container.upgrade(cx) {
|
if let Some(container) = container.upgrade(cx) {
|
||||||
if container.window_id() == window_id {
|
if container.window_id() == window_id {
|
||||||
|
@ -9,7 +9,7 @@ use gpui::{
|
|||||||
executor::Deterministic,
|
executor::Deterministic,
|
||||||
geometry::{rect::RectF, vector::vec2f},
|
geometry::{rect::RectF, vector::vec2f},
|
||||||
platform::{WindowBounds, WindowOptions},
|
platform::{WindowBounds, WindowOptions},
|
||||||
serde_json,
|
serde_json, TestAppContext,
|
||||||
};
|
};
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use language::{BracketPairConfig, FakeLspAdapter, LanguageConfig, LanguageRegistry, Point};
|
use language::{BracketPairConfig, FakeLspAdapter, LanguageConfig, LanguageRegistry, Point};
|
||||||
@ -28,8 +28,8 @@ use workspace::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_edit_events(cx: &mut AppContext) {
|
fn test_edit_events(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = cx.add_model(|cx| {
|
let buffer = cx.add_model(|cx| {
|
||||||
let mut buffer = language::Buffer::new(0, "123456", cx);
|
let mut buffer = language::Buffer::new(0, "123456", cx);
|
||||||
buffer.set_group_interval(Duration::from_secs(1));
|
buffer.set_group_interval(Duration::from_secs(1));
|
||||||
@ -37,7 +37,7 @@ fn test_edit_events(cx: &mut AppContext) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let events = Rc::new(RefCell::new(Vec::new()));
|
let events = Rc::new(RefCell::new(Vec::new()));
|
||||||
let (_, editor1) = cx.add_window(Default::default(), {
|
let (_, editor1) = cx.add_window({
|
||||||
let events = events.clone();
|
let events = events.clone();
|
||||||
|cx| {
|
|cx| {
|
||||||
cx.subscribe(&cx.handle(), move |_, _, event, _| {
|
cx.subscribe(&cx.handle(), move |_, _, event, _| {
|
||||||
@ -52,7 +52,7 @@ fn test_edit_events(cx: &mut AppContext) {
|
|||||||
Editor::for_buffer(buffer.clone(), None, cx)
|
Editor::for_buffer(buffer.clone(), None, cx)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let (_, editor2) = cx.add_window(Default::default(), {
|
let (_, editor2) = cx.add_window({
|
||||||
let events = events.clone();
|
let events = events.clone();
|
||||||
|cx| {
|
|cx| {
|
||||||
cx.subscribe(&cx.handle(), move |_, _, event, _| {
|
cx.subscribe(&cx.handle(), move |_, _, event, _| {
|
||||||
@ -155,13 +155,13 @@ fn test_edit_events(cx: &mut AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_undo_redo_with_selection_restoration(cx: &mut AppContext) {
|
fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let mut now = Instant::now();
|
let mut now = Instant::now();
|
||||||
let buffer = cx.add_model(|cx| language::Buffer::new(0, "123456", cx));
|
let buffer = cx.add_model(|cx| language::Buffer::new(0, "123456", cx));
|
||||||
let group_interval = buffer.read(cx).transaction_group_interval();
|
let group_interval = buffer.read_with(cx, |buffer, _| buffer.transaction_group_interval());
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
let (_, editor) = cx.add_window(|cx| build_editor(buffer.clone(), cx));
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.start_transaction_at(now, cx);
|
editor.start_transaction_at(now, cx);
|
||||||
@ -225,8 +225,8 @@ fn test_undo_redo_with_selection_restoration(cx: &mut AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_ime_composition(cx: &mut AppContext) {
|
fn test_ime_composition(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = cx.add_model(|cx| {
|
let buffer = cx.add_model(|cx| {
|
||||||
let mut buffer = language::Buffer::new(0, "abcde", cx);
|
let mut buffer = language::Buffer::new(0, "abcde", cx);
|
||||||
// Ensure automatic grouping doesn't occur.
|
// Ensure automatic grouping doesn't occur.
|
||||||
@ -235,7 +235,7 @@ fn test_ime_composition(cx: &mut AppContext) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
cx.add_window(Default::default(), |cx| {
|
cx.add_window(|cx| {
|
||||||
let mut editor = build_editor(buffer.clone(), cx);
|
let mut editor = build_editor(buffer.clone(), cx);
|
||||||
|
|
||||||
// Start a new IME composition.
|
// Start a new IME composition.
|
||||||
@ -327,11 +327,13 @@ fn test_ime_composition(cx: &mut AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_selection_with_mouse(cx: &mut gpui::AppContext) {
|
fn test_selection_with_mouse(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
|
|
||||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx);
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
editor.update(cx, |view, cx| {
|
editor.update(cx, |view, cx| {
|
||||||
view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx);
|
view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx);
|
||||||
});
|
});
|
||||||
@ -392,10 +394,12 @@ fn test_selection_with_mouse(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_canceling_pending_selection(cx: &mut gpui::AppContext) {
|
fn test_canceling_pending_selection(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx);
|
view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx);
|
||||||
@ -424,7 +428,7 @@ fn test_canceling_pending_selection(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_clone(cx: &mut gpui::AppContext) {
|
fn test_clone(cx: &mut TestAppContext) {
|
||||||
let (text, selection_ranges) = marked_text_ranges(
|
let (text, selection_ranges) = marked_text_ranges(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
one
|
one
|
||||||
@ -435,10 +439,12 @@ fn test_clone(cx: &mut gpui::AppContext) {
|
|||||||
"},
|
"},
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&text, cx);
|
|
||||||
|
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
|
let buffer = MultiBuffer::build_simple(&text, cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone()));
|
editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone()));
|
||||||
@ -470,8 +476,8 @@ fn test_clone(cx: &mut gpui::AppContext) {
|
|||||||
snapshot.folds_in_range(0..text.len()).collect::<Vec<_>>(),
|
snapshot.folds_in_range(0..text.len()).collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
assert_set_eq!(
|
assert_set_eq!(
|
||||||
cloned_editor.read(cx).selections.ranges::<Point>(cx),
|
cloned_editor.read_with(cx, |editor, cx| editor.selections.ranges::<Point>(cx)),
|
||||||
editor.read(cx).selections.ranges(cx)
|
editor.read_with(cx, |editor, cx| editor.selections.ranges(cx))
|
||||||
);
|
);
|
||||||
assert_set_eq!(
|
assert_set_eq!(
|
||||||
cloned_editor.update(cx, |e, cx| e.selections.display_ranges(cx)),
|
cloned_editor.update(cx, |e, cx| e.selections.display_ranges(cx)),
|
||||||
@ -480,19 +486,19 @@ fn test_clone(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_navigation_history(cx: &mut gpui::AppContext) {
|
fn test_navigation_history(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
cx.set_global(DragAndDrop::<Workspace>::default());
|
cx.set_global(DragAndDrop::<Workspace>::default());
|
||||||
use workspace::item::Item;
|
use workspace::item::Item;
|
||||||
let (_, pane) = cx.add_window(Default::default(), |cx| Pane::new(0, None, || &[], cx));
|
let (_, pane) = cx.add_window(|cx| Pane::new(0, None, || &[], cx));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx);
|
|
||||||
|
|
||||||
cx.add_view(&pane, |cx| {
|
cx.add_view(&pane, |cx| {
|
||||||
|
let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx);
|
||||||
let mut editor = build_editor(buffer.clone(), cx);
|
let mut editor = build_editor(buffer.clone(), cx);
|
||||||
let handle = cx.handle();
|
let handle = cx.handle();
|
||||||
editor.set_nav_history(Some(pane.read(cx).nav_history_for_item(&handle)));
|
editor.set_nav_history(Some(pane.read(cx).nav_history_for_item(&handle)));
|
||||||
|
|
||||||
fn pop_history(editor: &mut Editor, cx: &mut AppContext) -> Option<NavigationEntry> {
|
fn pop_history(editor: &mut Editor, cx: &mut WindowContext) -> Option<NavigationEntry> {
|
||||||
editor.nav_history.as_mut().unwrap().pop_backward(cx)
|
editor.nav_history.as_mut().unwrap().pop_backward(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,10 +596,12 @@ fn test_navigation_history(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_cancel(cx: &mut gpui::AppContext) {
|
fn test_cancel(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.begin_selection(DisplayPoint::new(3, 4), false, 1, cx);
|
view.begin_selection(DisplayPoint::new(3, 4), false, 1, cx);
|
||||||
@ -630,30 +638,32 @@ fn test_cancel(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_fold_action(cx: &mut gpui::AppContext) {
|
fn test_fold_action(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(
|
let (_, view) = cx.add_window(|cx| {
|
||||||
&"
|
let buffer = MultiBuffer::build_simple(
|
||||||
impl Foo {
|
&"
|
||||||
// Hello!
|
impl Foo {
|
||||||
|
// Hello!
|
||||||
|
|
||||||
fn a() {
|
fn a() {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn b() {
|
fn b() {
|
||||||
2
|
2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c() {
|
fn c() {
|
||||||
3
|
3
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
"
|
||||||
"
|
.unindent(),
|
||||||
.unindent(),
|
cx,
|
||||||
cx,
|
);
|
||||||
);
|
build_editor(buffer.clone(), cx)
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
@ -712,25 +722,26 @@ fn test_fold_action(cx: &mut gpui::AppContext) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
view.unfold_lines(&UnfoldLines, cx);
|
view.unfold_lines(&UnfoldLines, cx);
|
||||||
assert_eq!(view.display_text(cx), buffer.read(cx).read(cx).text());
|
assert_eq!(view.display_text(cx), view.buffer.read(cx).read(cx).text());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_move_cursor(cx: &mut gpui::AppContext) {
|
fn test_move_cursor(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
||||||
|
buffer.update(cx, |buffer, cx| {
|
||||||
buffer.update(cx, |buffer, cx| {
|
buffer.edit(
|
||||||
buffer.edit(
|
vec![
|
||||||
vec![
|
(Point::new(1, 0)..Point::new(1, 0), "\t"),
|
||||||
(Point::new(1, 0)..Point::new(1, 0), "\t"),
|
(Point::new(1, 1)..Point::new(1, 1), "\t"),
|
||||||
(Point::new(1, 1)..Point::new(1, 1), "\t"),
|
],
|
||||||
],
|
None,
|
||||||
None,
|
cx,
|
||||||
cx,
|
);
|
||||||
);
|
});
|
||||||
|
build_editor(buffer.clone(), cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
@ -793,10 +804,12 @@ fn test_move_cursor(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_move_cursor_multibyte(cx: &mut gpui::AppContext) {
|
fn test_move_cursor_multibyte(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx);
|
||||||
|
build_editor(buffer.clone(), cx)
|
||||||
|
});
|
||||||
|
|
||||||
assert_eq!('ⓐ'.len_utf8(), 3);
|
assert_eq!('ⓐ'.len_utf8(), 3);
|
||||||
assert_eq!('α'.len_utf8(), 2);
|
assert_eq!('α'.len_utf8(), 2);
|
||||||
@ -895,10 +908,12 @@ fn test_move_cursor_multibyte(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_move_cursor_different_line_lengths(cx: &mut gpui::AppContext) {
|
fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx);
|
||||||
|
build_editor(buffer.clone(), cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]);
|
s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]);
|
||||||
@ -942,10 +957,12 @@ fn test_move_cursor_different_line_lengths(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_beginning_end_of_line(cx: &mut gpui::AppContext) {
|
fn test_beginning_end_of_line(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("abc\n def", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\n def", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -1102,10 +1119,12 @@ fn test_beginning_end_of_line(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_prev_next_word_boundary(cx: &mut gpui::AppContext) {
|
fn test_prev_next_word_boundary(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -1151,10 +1170,12 @@ fn test_prev_next_word_boundary(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut gpui::AppContext) {
|
fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.set_wrap_width(Some(140.), cx);
|
view.set_wrap_width(Some(140.), cx);
|
||||||
@ -1330,10 +1351,12 @@ async fn test_delete_to_beginning_of_line(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_delete_to_word_boundary(cx: &mut gpui::AppContext) {
|
fn test_delete_to_word_boundary(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("one two three four", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
let buffer = MultiBuffer::build_simple("one two three four", cx);
|
||||||
|
build_editor(buffer.clone(), cx)
|
||||||
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
@ -1345,10 +1368,9 @@ fn test_delete_to_word_boundary(cx: &mut gpui::AppContext) {
|
|||||||
])
|
])
|
||||||
});
|
});
|
||||||
view.delete_to_previous_word_start(&DeleteToPreviousWordStart, cx);
|
view.delete_to_previous_word_start(&DeleteToPreviousWordStart, cx);
|
||||||
|
assert_eq!(view.buffer.read(cx).read(cx).text(), "e two te four");
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(buffer.read(cx).read(cx).text(), "e two te four");
|
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -1359,16 +1381,17 @@ fn test_delete_to_word_boundary(cx: &mut gpui::AppContext) {
|
|||||||
])
|
])
|
||||||
});
|
});
|
||||||
view.delete_to_next_word_end(&DeleteToNextWordEnd, cx);
|
view.delete_to_next_word_end(&DeleteToNextWordEnd, cx);
|
||||||
|
assert_eq!(view.buffer.read(cx).read(cx).text(), "e t te our");
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(buffer.read(cx).read(cx).text(), "e t te our");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_newline(cx: &mut gpui::AppContext) {
|
fn test_newline(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx);
|
||||||
|
build_editor(buffer.clone(), cx)
|
||||||
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
@ -1385,24 +1408,23 @@ fn test_newline(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_newline_with_old_selections(cx: &mut gpui::AppContext) {
|
fn test_newline_with_old_selections(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
"
|
let buffer = MultiBuffer::build_simple(
|
||||||
a
|
"
|
||||||
b(
|
a
|
||||||
X
|
b(
|
||||||
)
|
X
|
||||||
c(
|
)
|
||||||
X
|
c(
|
||||||
)
|
X
|
||||||
"
|
)
|
||||||
.unindent()
|
"
|
||||||
.as_str(),
|
.unindent()
|
||||||
cx,
|
.as_str(),
|
||||||
);
|
cx,
|
||||||
|
);
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| {
|
|
||||||
let mut editor = build_editor(buffer.clone(), cx);
|
let mut editor = build_editor(buffer.clone(), cx);
|
||||||
editor.change_selections(None, cx, |s| {
|
editor.change_selections(None, cx, |s| {
|
||||||
s.select_ranges([
|
s.select_ranges([
|
||||||
@ -1413,28 +1435,27 @@ fn test_newline_with_old_selections(cx: &mut gpui::AppContext) {
|
|||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
|
||||||
buffer.edit(
|
|
||||||
[
|
|
||||||
(Point::new(1, 2)..Point::new(3, 0), ""),
|
|
||||||
(Point::new(4, 2)..Point::new(6, 0), ""),
|
|
||||||
],
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
buffer.read(cx).text(),
|
|
||||||
"
|
|
||||||
a
|
|
||||||
b()
|
|
||||||
c()
|
|
||||||
"
|
|
||||||
.unindent()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
|
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
||||||
|
editor.buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer.edit(
|
||||||
|
[
|
||||||
|
(Point::new(1, 2)..Point::new(3, 0), ""),
|
||||||
|
(Point::new(4, 2)..Point::new(6, 0), ""),
|
||||||
|
],
|
||||||
|
None,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
buffer.read(cx).text(),
|
||||||
|
"
|
||||||
|
a
|
||||||
|
b()
|
||||||
|
c()
|
||||||
|
"
|
||||||
|
.unindent()
|
||||||
|
);
|
||||||
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
editor.selections.ranges(cx),
|
editor.selections.ranges(cx),
|
||||||
&[
|
&[
|
||||||
@ -1517,22 +1538,21 @@ async fn test_newline_below(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_insert_with_old_selections(cx: &mut gpui::AppContext) {
|
fn test_insert_with_old_selections(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("a( X ), b( Y ), c( Z )", cx);
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| {
|
let buffer = MultiBuffer::build_simple("a( X ), b( Y ), c( Z )", cx);
|
||||||
let mut editor = build_editor(buffer.clone(), cx);
|
let mut editor = build_editor(buffer.clone(), cx);
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges([3..4, 11..12, 19..20]));
|
editor.change_selections(None, cx, |s| s.select_ranges([3..4, 11..12, 19..20]));
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
|
||||||
buffer.edit([(2..5, ""), (10..13, ""), (18..21, "")], None, cx);
|
|
||||||
assert_eq!(buffer.read(cx).text(), "a(), b(), c()".unindent());
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
|
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
||||||
|
editor.buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer.edit([(2..5, ""), (10..13, ""), (18..21, "")], None, cx);
|
||||||
|
assert_eq!(buffer.read(cx).text(), "a(), b(), c()".unindent());
|
||||||
|
});
|
||||||
assert_eq!(editor.selections.ranges(cx), &[2..2, 7..7, 12..12],);
|
assert_eq!(editor.selections.ranges(cx), &[2..2, 7..7, 12..12],);
|
||||||
|
|
||||||
editor.insert("Z", cx);
|
editor.insert("Z", cx);
|
||||||
@ -1836,24 +1856,26 @@ async fn test_indent_outdent_with_hard_tabs(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_indent_outdent_with_excerpts(cx: &mut gpui::AppContext) {
|
fn test_indent_outdent_with_excerpts(cx: &mut TestAppContext) {
|
||||||
cx.set_global(
|
cx.update(|cx| {
|
||||||
Settings::test(cx)
|
cx.set_global(
|
||||||
.with_language_defaults(
|
Settings::test(cx)
|
||||||
"TOML",
|
.with_language_defaults(
|
||||||
EditorSettings {
|
"TOML",
|
||||||
tab_size: Some(2.try_into().unwrap()),
|
EditorSettings {
|
||||||
..Default::default()
|
tab_size: Some(2.try_into().unwrap()),
|
||||||
},
|
..Default::default()
|
||||||
)
|
},
|
||||||
.with_language_defaults(
|
)
|
||||||
"Rust",
|
.with_language_defaults(
|
||||||
EditorSettings {
|
"Rust",
|
||||||
tab_size: Some(4.try_into().unwrap()),
|
EditorSettings {
|
||||||
..Default::default()
|
tab_size: Some(4.try_into().unwrap()),
|
||||||
},
|
..Default::default()
|
||||||
),
|
},
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
let toml_language = Arc::new(Language::new(
|
let toml_language = Arc::new(Language::new(
|
||||||
LanguageConfig {
|
LanguageConfig {
|
||||||
name: "TOML".into(),
|
name: "TOML".into(),
|
||||||
@ -1895,7 +1917,7 @@ fn test_indent_outdent_with_excerpts(cx: &mut gpui::AppContext) {
|
|||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.add_window(Default::default(), |cx| {
|
cx.add_window(|cx| {
|
||||||
let mut editor = build_editor(multibuffer, cx);
|
let mut editor = build_editor(multibuffer, cx);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -2022,10 +2044,12 @@ async fn test_delete(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_delete_line(cx: &mut gpui::AppContext) {
|
fn test_delete_line(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -2045,9 +2069,11 @@ fn test_delete_line(cx: &mut gpui::AppContext) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)])
|
s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)])
|
||||||
@ -2062,10 +2088,12 @@ fn test_delete_line(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_duplicate_line(cx: &mut gpui::AppContext) {
|
fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -2088,8 +2116,10 @@ fn test_duplicate_line(cx: &mut gpui::AppContext) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -2110,10 +2140,12 @@ fn test_duplicate_line(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_move_line_up_down(cx: &mut gpui::AppContext) {
|
fn test_move_line_up_down(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.fold_ranges(
|
view.fold_ranges(
|
||||||
vec![
|
vec![
|
||||||
@ -2206,12 +2238,14 @@ fn test_move_line_up_down(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_move_line_up_down_with_blocks(cx: &mut gpui::AppContext) {
|
fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
let snapshot = buffer.read(cx).snapshot(cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
|
let snapshot = editor.buffer.read(cx).snapshot(cx);
|
||||||
editor.insert_blocks(
|
editor.insert_blocks(
|
||||||
[BlockProperties {
|
[BlockProperties {
|
||||||
style: BlockStyle::Fixed,
|
style: BlockStyle::Fixed,
|
||||||
@ -2230,11 +2264,11 @@ fn test_move_line_up_down_with_blocks(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_transpose(cx: &mut gpui::AppContext) {
|
fn test_transpose(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
|
|
||||||
_ = cx
|
_ = cx
|
||||||
.add_window(Default::default(), |cx| {
|
.add_window(|cx| {
|
||||||
let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx);
|
let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx);
|
||||||
|
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges([1..1]));
|
editor.change_selections(None, cx, |s| s.select_ranges([1..1]));
|
||||||
@ -2255,7 +2289,7 @@ fn test_transpose(cx: &mut gpui::AppContext) {
|
|||||||
.1;
|
.1;
|
||||||
|
|
||||||
_ = cx
|
_ = cx
|
||||||
.add_window(Default::default(), |cx| {
|
.add_window(|cx| {
|
||||||
let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx);
|
let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx);
|
||||||
|
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges([3..3]));
|
editor.change_selections(None, cx, |s| s.select_ranges([3..3]));
|
||||||
@ -2281,7 +2315,7 @@ fn test_transpose(cx: &mut gpui::AppContext) {
|
|||||||
.1;
|
.1;
|
||||||
|
|
||||||
_ = cx
|
_ = cx
|
||||||
.add_window(Default::default(), |cx| {
|
.add_window(|cx| {
|
||||||
let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx);
|
let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx);
|
||||||
|
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4]));
|
editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4]));
|
||||||
@ -2310,7 +2344,7 @@ fn test_transpose(cx: &mut gpui::AppContext) {
|
|||||||
.1;
|
.1;
|
||||||
|
|
||||||
_ = cx
|
_ = cx
|
||||||
.add_window(Default::default(), |cx| {
|
.add_window(|cx| {
|
||||||
let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx);
|
let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx);
|
||||||
|
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges([4..4]));
|
editor.change_selections(None, cx, |s| s.select_ranges([4..4]));
|
||||||
@ -2524,10 +2558,12 @@ async fn test_paste_multiline(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_select_all(cx: &mut gpui::AppContext) {
|
fn test_select_all(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.select_all(&SelectAll, cx);
|
view.select_all(&SelectAll, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -2538,10 +2574,12 @@ fn test_select_all(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_select_line(cx: &mut gpui::AppContext) {
|
fn test_select_line(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
s.select_display_ranges([
|
s.select_display_ranges([
|
||||||
@ -2582,10 +2620,12 @@ fn test_select_line(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_split_selection_into_lines(cx: &mut gpui::AppContext) {
|
fn test_split_selection_into_lines(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.fold_ranges(
|
view.fold_ranges(
|
||||||
vec![
|
vec![
|
||||||
@ -2650,10 +2690,12 @@ fn test_split_selection_into_lines(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_add_selection_above_below(cx: &mut gpui::AppContext) {
|
fn test_add_selection_above_below(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx);
|
let (_, view) = cx.add_window(|cx| {
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
|
let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx);
|
||||||
|
build_editor(buffer, cx)
|
||||||
|
});
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
@ -4928,8 +4970,8 @@ async fn test_toggle_block_comment(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_editing_disjoint_excerpts(cx: &mut gpui::AppContext) {
|
fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx));
|
||||||
let multibuffer = cx.add_model(|cx| {
|
let multibuffer = cx.add_model(|cx| {
|
||||||
let mut multibuffer = MultiBuffer::new(0);
|
let mut multibuffer = MultiBuffer::new(0);
|
||||||
@ -4947,12 +4989,11 @@ fn test_editing_disjoint_excerpts(cx: &mut gpui::AppContext) {
|
|||||||
],
|
],
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
assert_eq!(multibuffer.read(cx).text(), "aaaa\nbbbb");
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(multibuffer.read(cx).read(cx).text(), "aaaa\nbbbb");
|
let (_, view) = cx.add_window(|cx| build_editor(multibuffer, cx));
|
||||||
|
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(multibuffer, cx));
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
assert_eq!(view.text(cx), "aaaa\nbbbb");
|
assert_eq!(view.text(cx), "aaaa\nbbbb");
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
@ -4975,8 +5016,8 @@ fn test_editing_disjoint_excerpts(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_editing_overlapping_excerpts(cx: &mut gpui::AppContext) {
|
fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let markers = vec![('[', ']').into(), ('(', ')').into()];
|
let markers = vec![('[', ']').into(), ('(', ')').into()];
|
||||||
let (initial_text, mut excerpt_ranges) = marked_text_ranges_by(
|
let (initial_text, mut excerpt_ranges) = marked_text_ranges_by(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
@ -5000,7 +5041,7 @@ fn test_editing_overlapping_excerpts(cx: &mut gpui::AppContext) {
|
|||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
|
|
||||||
let (_, view) = cx.add_window(Default::default(), |cx| build_editor(multibuffer, cx));
|
let (_, view) = cx.add_window(|cx| build_editor(multibuffer, cx));
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
let (expected_text, selection_ranges) = marked_text_ranges(
|
let (expected_text, selection_ranges) = marked_text_ranges(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
@ -5048,8 +5089,8 @@ fn test_editing_overlapping_excerpts(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_refresh_selections(cx: &mut gpui::AppContext) {
|
fn test_refresh_selections(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx));
|
||||||
let mut excerpt1_id = None;
|
let mut excerpt1_id = None;
|
||||||
let multibuffer = cx.add_model(|cx| {
|
let multibuffer = cx.add_model(|cx| {
|
||||||
@ -5071,13 +5112,11 @@ fn test_refresh_selections(cx: &mut gpui::AppContext) {
|
|||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next();
|
.next();
|
||||||
|
assert_eq!(multibuffer.read(cx).text(), "aaaa\nbbbb\nbbbb\ncccc");
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
assert_eq!(
|
|
||||||
multibuffer.read(cx).read(cx).text(),
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
"aaaa\nbbbb\nbbbb\ncccc"
|
|
||||||
);
|
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| {
|
|
||||||
let mut editor = build_editor(multibuffer.clone(), cx);
|
let mut editor = build_editor(multibuffer.clone(), cx);
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
editor.change_selections(None, cx, |s| {
|
editor.change_selections(None, cx, |s| {
|
||||||
@ -5134,8 +5173,8 @@ fn test_refresh_selections(cx: &mut gpui::AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_refresh_selections_while_selecting_with_mouse(cx: &mut gpui::AppContext) {
|
fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx));
|
||||||
let mut excerpt1_id = None;
|
let mut excerpt1_id = None;
|
||||||
let multibuffer = cx.add_model(|cx| {
|
let multibuffer = cx.add_model(|cx| {
|
||||||
@ -5157,13 +5196,11 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut gpui::AppContext)
|
|||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next();
|
.next();
|
||||||
|
assert_eq!(multibuffer.read(cx).text(), "aaaa\nbbbb\nbbbb\ncccc");
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
assert_eq!(
|
|
||||||
multibuffer.read(cx).read(cx).text(),
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
"aaaa\nbbbb\nbbbb\ncccc"
|
|
||||||
);
|
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| {
|
|
||||||
let mut editor = build_editor(multibuffer.clone(), cx);
|
let mut editor = build_editor(multibuffer.clone(), cx);
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
editor.begin_selection(Point::new(1, 3).to_display_point(&snapshot), false, 1, cx);
|
editor.begin_selection(Point::new(1, 3).to_display_point(&snapshot), false, 1, cx);
|
||||||
@ -5267,17 +5304,18 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_highlighted_ranges(cx: &mut gpui::AppContext) {
|
fn test_highlighted_ranges(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx);
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
cx.set_global(Settings::test(cx));
|
let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx);
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx));
|
build_editor(buffer.clone(), cx)
|
||||||
|
});
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
struct Type1;
|
struct Type1;
|
||||||
struct Type2;
|
struct Type2;
|
||||||
|
|
||||||
let buffer = buffer.read(cx).snapshot(cx);
|
let buffer = editor.buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
let anchor_range =
|
let anchor_range =
|
||||||
|range: Range<Point>| buffer.anchor_after(range.start)..buffer.anchor_after(range.end);
|
|range: Range<Point>| buffer.anchor_after(range.start)..buffer.anchor_after(range.end);
|
||||||
@ -5761,7 +5799,6 @@ async fn go_to_hunk(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppCon
|
|||||||
&r#"
|
&r#"
|
||||||
ˇuse some::modified;
|
ˇuse some::modified;
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("hello there");
|
println!("hello there");
|
||||||
|
|
||||||
@ -5783,7 +5820,6 @@ async fn go_to_hunk(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppCon
|
|||||||
&r#"
|
&r#"
|
||||||
use some::modified;
|
use some::modified;
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
ˇ println!("hello there");
|
ˇ println!("hello there");
|
||||||
|
|
||||||
@ -5807,7 +5843,6 @@ async fn go_to_hunk(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppCon
|
|||||||
&r#"
|
&r#"
|
||||||
ˇuse some::modified;
|
ˇuse some::modified;
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("hello there");
|
println!("hello there");
|
||||||
|
|
||||||
|
@ -2493,24 +2493,24 @@ fn scale_horizontal_mouse_autoscroll_delta(delta: f32) -> f32 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
display_map::{BlockDisposition, BlockProperties},
|
display_map::{BlockDisposition, BlockProperties},
|
||||||
Editor, MultiBuffer,
|
Editor, MultiBuffer,
|
||||||
};
|
};
|
||||||
|
use gpui::TestAppContext;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
use std::sync::Arc;
|
||||||
use util::test::sample_text;
|
use util::test::sample_text;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_layout_line_numbers(cx: &mut gpui::AppContext) {
|
fn test_layout_line_numbers(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| {
|
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
||||||
Editor::new(EditorMode::Full, buffer, None, None, cx)
|
Editor::new(EditorMode::Full, buffer, None, None, cx)
|
||||||
});
|
});
|
||||||
let element = EditorElement::new(editor.read(cx).style(cx));
|
let element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx)));
|
||||||
|
|
||||||
let layouts = editor.update(cx, |editor, cx| {
|
let layouts = editor.update(cx, |editor, cx| {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
@ -2522,10 +2522,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_layout_with_placeholder_text_and_blocks(cx: &mut gpui::AppContext) {
|
fn test_layout_with_placeholder_text_and_blocks(cx: &mut TestAppContext) {
|
||||||
cx.set_global(Settings::test(cx));
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let buffer = MultiBuffer::build_simple("", cx);
|
let (_, editor) = cx.add_window(|cx| {
|
||||||
let (_, editor) = cx.add_window(Default::default(), |cx| {
|
let buffer = MultiBuffer::build_simple("", cx);
|
||||||
Editor::new(EditorMode::Full, buffer, None, None, cx)
|
Editor::new(EditorMode::Full, buffer, None, None, cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2546,7 +2546,7 @@ mod tests {
|
|||||||
cx.blur();
|
cx.blur();
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut element = EditorElement::new(editor.read(cx).style(cx));
|
let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx)));
|
||||||
let (size, mut state) = editor.update(cx, |editor, cx| {
|
let (size, mut state) = editor.update(cx, |editor, cx| {
|
||||||
element.layout(
|
element.layout(
|
||||||
SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
|
SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
|
||||||
|
@ -34,11 +34,10 @@ impl<'a> EditorTestContext<'a> {
|
|||||||
crate::init(cx);
|
crate::init(cx);
|
||||||
|
|
||||||
let (window_id, editor) = cx.add_window(Default::default(), |cx| {
|
let (window_id, editor) = cx.add_window(Default::default(), |cx| {
|
||||||
|
cx.focus_self();
|
||||||
build_editor(MultiBuffer::build_simple("", cx), cx)
|
build_editor(MultiBuffer::build_simple("", cx), cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.update(cx, |_, cx| cx.focus_self());
|
|
||||||
|
|
||||||
(window_id, editor)
|
(window_id, editor)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -132,25 +132,18 @@ impl FeedbackEditor {
|
|||||||
|
|
||||||
if answer == Some(0) {
|
if answer == Some(0) {
|
||||||
match FeedbackEditor::submit_feedback(&feedback_text, client, specs).await {
|
match FeedbackEditor::submit_feedback(&feedback_text, client, specs).await {
|
||||||
Ok(_) => {
|
Ok(_) => this.update(&mut cx, |_, cx| {
|
||||||
cx.update(|cx| {
|
cx.dispatch_action(workspace::CloseActiveItem);
|
||||||
this.update(cx, |_, cx| {
|
}),
|
||||||
cx.dispatch_action(workspace::CloseActiveItem);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::error!("{}", error);
|
log::error!("{}", error);
|
||||||
|
this.update(&mut cx, |_, cx| {
|
||||||
cx.update(|cx| {
|
cx.prompt(
|
||||||
this.update(cx, |_, cx| {
|
PromptLevel::Critical,
|
||||||
cx.prompt(
|
FEEDBACK_SUBMISSION_ERROR_TEXT,
|
||||||
PromptLevel::Critical,
|
&["OK"],
|
||||||
FEEDBACK_SUBMISSION_ERROR_TEXT,
|
);
|
||||||
&["OK"],
|
})
|
||||||
);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,12 +142,14 @@ impl Entity for GoToLine {
|
|||||||
|
|
||||||
fn release(&mut self, cx: &mut AppContext) {
|
fn release(&mut self, cx: &mut AppContext) {
|
||||||
let scroll_position = self.prev_scroll_position.take();
|
let scroll_position = self.prev_scroll_position.take();
|
||||||
self.active_editor.update(cx, |editor, cx| {
|
cx.update_window(self.active_editor.window_id(), |cx| {
|
||||||
editor.highlight_rows(None);
|
self.active_editor.update(cx, |editor, cx| {
|
||||||
if let Some(scroll_position) = scroll_position {
|
editor.highlight_rows(None);
|
||||||
editor.set_scroll_position(scroll_position, cx);
|
if let Some(scroll_position) = scroll_position {
|
||||||
}
|
editor.set_scroll_position(scroll_position, cx);
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,7 +937,7 @@ impl AppContext {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
|
fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
|
||||||
where
|
where
|
||||||
E: Entity,
|
E: Entity,
|
||||||
E::Event: 'static,
|
E::Event: 'static,
|
||||||
@ -1224,19 +1224,28 @@ impl AppContext {
|
|||||||
T: 'static,
|
T: 'static,
|
||||||
F: FnOnce(&mut T, &mut AppContext) -> U,
|
F: FnOnce(&mut T, &mut AppContext) -> U,
|
||||||
{
|
{
|
||||||
self.update(|this| {
|
self.update(|mut this| {
|
||||||
let type_id = TypeId::of::<T>();
|
Self::update_global_internal(&mut this, |global, cx| update(global, cx))
|
||||||
if let Some(mut state) = this.globals.remove(&type_id) {
|
|
||||||
let result = update(state.downcast_mut().unwrap(), this);
|
|
||||||
this.globals.insert(type_id, state);
|
|
||||||
this.notify_global(type_id);
|
|
||||||
result
|
|
||||||
} else {
|
|
||||||
panic!("No global added for {}", std::any::type_name::<T>());
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
|
||||||
|
where
|
||||||
|
C: DerefMut<Target = AppContext>,
|
||||||
|
T: 'static,
|
||||||
|
F: FnOnce(&mut T, &mut C) -> U,
|
||||||
|
{
|
||||||
|
let type_id = TypeId::of::<T>();
|
||||||
|
if let Some(mut state) = this.globals.remove(&type_id) {
|
||||||
|
let result = update(state.downcast_mut().unwrap(), this);
|
||||||
|
this.globals.insert(type_id, state);
|
||||||
|
this.notify_global(type_id);
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
panic!("No global added for {}", std::any::type_name::<T>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear_globals(&mut self) {
|
pub fn clear_globals(&mut self) {
|
||||||
self.globals.clear();
|
self.globals.clear();
|
||||||
}
|
}
|
||||||
@ -2714,15 +2723,6 @@ impl<'a, T: Entity> ModelContext<'a, T> {
|
|||||||
self.app.add_model(build_model)
|
self.app.add_model(build_model)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ModelContext<T>)) {
|
|
||||||
let handle = self.handle();
|
|
||||||
self.app.defer(move |cx| {
|
|
||||||
handle.update(cx, |model, cx| {
|
|
||||||
callback(model, cx);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn emit(&mut self, payload: T::Event) {
|
pub fn emit(&mut self, payload: T::Event) {
|
||||||
self.app.pending_effects.push_back(Effect::Event {
|
self.app.pending_effects.push_back(Effect::Event {
|
||||||
entity_id: self.model_id,
|
entity_id: self.model_id,
|
||||||
@ -3090,21 +3090,17 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
|
|||||||
H: Handle<E>,
|
H: Handle<E>,
|
||||||
F: 'static + FnMut(&mut V, H, &E::Event, &mut ViewContext<V>),
|
F: 'static + FnMut(&mut V, H, &E::Event, &mut ViewContext<V>),
|
||||||
{
|
{
|
||||||
let window_id = self.window_id;
|
|
||||||
let subscriber = self.weak_handle();
|
let subscriber = self.weak_handle();
|
||||||
self.window_context
|
self.window_context
|
||||||
.subscribe_internal(handle, move |emitter, event, cx| {
|
.subscribe_internal(handle, move |emitter, event, cx| {
|
||||||
cx.update_window(window_id, |cx| {
|
if let Some(subscriber) = subscriber.upgrade(cx) {
|
||||||
if let Some(subscriber) = subscriber.upgrade(cx) {
|
subscriber.update(cx, |subscriber, cx| {
|
||||||
subscriber.update(cx, |subscriber, cx| {
|
callback(subscriber, emitter, event, cx);
|
||||||
callback(subscriber, emitter, event, cx);
|
});
|
||||||
});
|
true
|
||||||
true
|
} else {
|
||||||
} else {
|
false
|
||||||
false
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3333,15 +3329,9 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
|
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
|
||||||
let window_id = self.window_id;
|
|
||||||
let handle = self.handle();
|
let handle = self.handle();
|
||||||
self.window_context.defer(move |cx| {
|
self.window_context
|
||||||
cx.update_window(window_id, |cx| {
|
.defer(move |cx| handle.update(cx, |view, cx| callback(view, cx)))
|
||||||
handle.update(cx, |view, cx| {
|
|
||||||
callback(view, cx);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn after_window_update(
|
pub fn after_window_update(
|
||||||
@ -4651,7 +4641,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_defer_and_after_window_update(cx: &mut AppContext) {
|
fn test_defer_and_after_window_update(cx: &mut TestAppContext) {
|
||||||
struct View {
|
struct View {
|
||||||
render_count: usize,
|
render_count: usize,
|
||||||
}
|
}
|
||||||
@ -4671,7 +4661,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, view) = cx.add_window(Default::default(), |_| View { render_count: 0 });
|
let (_, view) = cx.add_window(|_| View { render_count: 0 });
|
||||||
let called_defer = Rc::new(AtomicBool::new(false));
|
let called_defer = Rc::new(AtomicBool::new(false));
|
||||||
let called_after_window_update = Rc::new(AtomicBool::new(false));
|
let called_after_window_update = Rc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
@ -4699,11 +4689,11 @@ mod tests {
|
|||||||
|
|
||||||
assert!(called_defer.load(SeqCst));
|
assert!(called_defer.load(SeqCst));
|
||||||
assert!(called_after_window_update.load(SeqCst));
|
assert!(called_after_window_update.load(SeqCst));
|
||||||
assert_eq!(view.read(cx).render_count, 3);
|
assert_eq!(view.read_with(cx, |view, _| view.render_count), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_view_handles(cx: &mut AppContext) {
|
fn test_view_handles(cx: &mut TestAppContext) {
|
||||||
struct View {
|
struct View {
|
||||||
other: Option<ViewHandle<View>>,
|
other: Option<ViewHandle<View>>,
|
||||||
events: Vec<String>,
|
events: Vec<String>,
|
||||||
@ -4738,33 +4728,39 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, root_view) = cx.add_window(Default::default(), |cx| View::new(None, cx));
|
let (_, root_view) = cx.add_window(|cx| View::new(None, cx));
|
||||||
let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
|
let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
|
||||||
let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
|
let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
|
||||||
assert_eq!(cx.views.len(), 3);
|
assert_eq!(cx.read(|cx| cx.views.len()), 3);
|
||||||
|
|
||||||
handle_1.update(cx, |view, cx| {
|
handle_1.update(cx, |view, cx| {
|
||||||
view.events.push("updated".into());
|
view.events.push("updated".into());
|
||||||
cx.emit(1);
|
cx.emit(1);
|
||||||
cx.emit(2);
|
cx.emit(2);
|
||||||
});
|
});
|
||||||
assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
|
handle_1.read_with(cx, |view, _| {
|
||||||
assert_eq!(
|
assert_eq!(view.events, vec!["updated".to_string()]);
|
||||||
handle_2.read(cx).events,
|
});
|
||||||
vec![
|
handle_2.read_with(cx, |view, _| {
|
||||||
"observed event 1".to_string(),
|
assert_eq!(
|
||||||
"observed event 2".to_string(),
|
view.events,
|
||||||
]
|
vec![
|
||||||
);
|
"observed event 1".to_string(),
|
||||||
|
"observed event 2".to_string(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
handle_2.update(cx, |view, _| {
|
handle_2.update(cx, |view, _| {
|
||||||
drop(handle_1);
|
drop(handle_1);
|
||||||
view.other.take();
|
view.other.take();
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(cx.views.len(), 2);
|
cx.read(|cx| {
|
||||||
assert!(cx.subscriptions.is_empty());
|
assert_eq!(cx.views.len(), 2);
|
||||||
assert!(cx.observations.is_empty());
|
assert!(cx.subscriptions.is_empty());
|
||||||
|
assert!(cx.observations.is_empty());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
@ -4887,14 +4883,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_view_events(cx: &mut AppContext) {
|
fn test_view_events(cx: &mut TestAppContext) {
|
||||||
struct Model;
|
struct Model;
|
||||||
|
|
||||||
impl Entity for Model {
|
impl Entity for Model {
|
||||||
type Event = String;
|
type Event = String;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, handle_1) = cx.add_window(Default::default(), |_| TestView::default());
|
let (_, handle_1) = cx.add_window(|_| TestView::default());
|
||||||
let handle_2 = cx.add_view(&handle_1, |_| TestView::default());
|
let handle_2 = cx.add_view(&handle_1, |_| TestView::default());
|
||||||
let handle_3 = cx.add_model(|_| Model);
|
let handle_3 = cx.add_model(|_| Model);
|
||||||
|
|
||||||
@ -4916,16 +4912,17 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
handle_2.update(cx, |_, c| c.emit("7".into()));
|
handle_2.update(cx, |_, c| c.emit("7".into()));
|
||||||
assert_eq!(handle_1.read(cx).events, vec!["7"]);
|
handle_1.read_with(cx, |view, _| assert_eq!(view.events, ["7"]));
|
||||||
|
|
||||||
handle_2.update(cx, |_, c| c.emit("5".into()));
|
handle_2.update(cx, |_, c| c.emit("5".into()));
|
||||||
assert_eq!(handle_1.read(cx).events, vec!["7", "5", "5 from inner"]);
|
handle_1.read_with(cx, |view, _| {
|
||||||
|
assert_eq!(view.events, ["7", "5", "5 from inner"])
|
||||||
|
});
|
||||||
|
|
||||||
handle_3.update(cx, |_, c| c.emit("9".into()));
|
handle_3.update(cx, |_, c| c.emit("9".into()));
|
||||||
assert_eq!(
|
handle_1.read_with(cx, |view, _| {
|
||||||
handle_1.read(cx).events,
|
assert_eq!(view.events, ["7", "5", "5 from inner", "9"])
|
||||||
vec!["7", "5", "5 from inner", "9"]
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
@ -5113,14 +5110,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_dropping_subscribers(cx: &mut AppContext) {
|
fn test_dropping_subscribers(cx: &mut TestAppContext) {
|
||||||
struct Model;
|
struct Model;
|
||||||
|
|
||||||
impl Entity for Model {
|
impl Entity for Model {
|
||||||
type Event = ();
|
type Event = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, root_view) = cx.add_window(Default::default(), |_| TestView::default());
|
let (_, root_view) = cx.add_window(|_| TestView::default());
|
||||||
let observing_view = cx.add_view(&root_view, |_| TestView::default());
|
let observing_view = cx.add_view(&root_view, |_| TestView::default());
|
||||||
let emitting_view = cx.add_view(&root_view, |_| TestView::default());
|
let emitting_view = cx.add_view(&root_view, |_| TestView::default());
|
||||||
let observing_model = cx.add_model(|_| Model);
|
let observing_model = cx.add_model(|_| Model);
|
||||||
@ -5165,7 +5162,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_observe_and_notify_from_view(cx: &mut AppContext) {
|
fn test_observe_and_notify_from_view(cx: &mut TestAppContext) {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Model {
|
struct Model {
|
||||||
state: String,
|
state: String,
|
||||||
@ -5175,7 +5172,7 @@ mod tests {
|
|||||||
type Event = ();
|
type Event = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, view) = cx.add_window(Default::default(), |_| TestView::default());
|
let (_, view) = cx.add_window(|_| TestView::default());
|
||||||
let model = cx.add_model(|_| Model {
|
let model = cx.add_model(|_| Model {
|
||||||
state: "old-state".into(),
|
state: "old-state".into(),
|
||||||
});
|
});
|
||||||
@ -5191,7 +5188,7 @@ mod tests {
|
|||||||
model.state = "new-state".into();
|
model.state = "new-state".into();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
});
|
||||||
assert_eq!(view.read(cx).events, vec!["new-state"]);
|
view.read_with(cx, |view, _| assert_eq!(view.events, ["new-state"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
@ -5216,14 +5213,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut AppContext) {
|
fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut TestAppContext) {
|
||||||
struct Model;
|
struct Model;
|
||||||
impl Entity for Model {
|
impl Entity for Model {
|
||||||
type Event = ();
|
type Event = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
let model = cx.add_model(|_| Model);
|
let model = cx.add_model(|_| Model);
|
||||||
let (_, view) = cx.add_window(Default::default(), |_| TestView::default());
|
let (_, view) = cx.add_window(|_| TestView::default());
|
||||||
|
|
||||||
view.update(cx, |_, cx| {
|
view.update(cx, |_, cx| {
|
||||||
model.update(cx, |_, cx| cx.notify());
|
model.update(cx, |_, cx| cx.notify());
|
||||||
@ -5236,19 +5233,18 @@ mod tests {
|
|||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
model.update(cx, |_, cx| cx.notify());
|
model.update(cx, |_, cx| cx.notify());
|
||||||
}
|
}
|
||||||
|
view.read_with(cx, |view, _| assert_eq!(view.events, Vec::<&str>::new()));
|
||||||
assert_eq!(view.read(cx).events, Vec::<String>::new());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_dropping_observers(cx: &mut AppContext) {
|
fn test_dropping_observers(cx: &mut TestAppContext) {
|
||||||
struct Model;
|
struct Model;
|
||||||
|
|
||||||
impl Entity for Model {
|
impl Entity for Model {
|
||||||
type Event = ();
|
type Event = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, root_view) = cx.add_window(Default::default(), |_| TestView::default());
|
let (_, root_view) = cx.add_window(|_| TestView::default());
|
||||||
let observing_view = cx.add_view(&root_view, |_| TestView::default());
|
let observing_view = cx.add_view(&root_view, |_| TestView::default());
|
||||||
let observing_model = cx.add_model(|_| Model);
|
let observing_model = cx.add_model(|_| Model);
|
||||||
let observed_model = cx.add_model(|_| Model);
|
let observed_model = cx.add_model(|_| Model);
|
||||||
@ -5269,7 +5265,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_dropping_subscriptions_during_callback(cx: &mut AppContext) {
|
fn test_dropping_subscriptions_during_callback(cx: &mut TestAppContext) {
|
||||||
struct Model;
|
struct Model;
|
||||||
|
|
||||||
impl Entity for Model {
|
impl Entity for Model {
|
||||||
@ -5371,7 +5367,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, root_view) = cx.add_window(Default::default(), |_| View);
|
let (_, root_view) = cx.add_window(|_| View);
|
||||||
let observing_view = cx.add_view(&root_view, |_| View);
|
let observing_view = cx.add_view(&root_view, |_| View);
|
||||||
let observed_view = cx.add_view(&root_view, |_| View);
|
let observed_view = cx.add_view(&root_view, |_| View);
|
||||||
|
|
||||||
@ -5410,13 +5406,15 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
cx.default_global::<()>();
|
cx.update(|cx| {
|
||||||
cx.set_global(());
|
cx.default_global::<()>();
|
||||||
|
cx.set_global(());
|
||||||
|
});
|
||||||
assert_eq!(*observation_count.borrow(), 1);
|
assert_eq!(*observation_count.borrow(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_focus(cx: &mut AppContext) {
|
fn test_focus(cx: &mut TestAppContext) {
|
||||||
struct View {
|
struct View {
|
||||||
name: String,
|
name: String,
|
||||||
events: Arc<Mutex<Vec<String>>>,
|
events: Arc<Mutex<Vec<String>>>,
|
||||||
@ -5449,7 +5447,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let view_events: Arc<Mutex<Vec<String>>> = Default::default();
|
let view_events: Arc<Mutex<Vec<String>>> = Default::default();
|
||||||
let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
|
let (window_id, view_1) = cx.add_window(|_| View {
|
||||||
events: view_events.clone(),
|
events: view_events.clone(),
|
||||||
name: "view 1".to_string(),
|
name: "view 1".to_string(),
|
||||||
});
|
});
|
||||||
@ -6295,7 +6293,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_child_view(cx: &mut AppContext) {
|
fn test_child_view(cx: &mut TestAppContext) {
|
||||||
struct Child {
|
struct Child {
|
||||||
rendered: Rc<Cell<bool>>,
|
rendered: Rc<Cell<bool>>,
|
||||||
dropped: Rc<Cell<bool>>,
|
dropped: Rc<Cell<bool>>,
|
||||||
@ -6346,7 +6344,7 @@ mod tests {
|
|||||||
|
|
||||||
let child_rendered = Rc::new(Cell::new(false));
|
let child_rendered = Rc::new(Cell::new(false));
|
||||||
let child_dropped = Rc::new(Cell::new(false));
|
let child_dropped = Rc::new(Cell::new(false));
|
||||||
let (_, root_view) = cx.add_window(Default::default(), |cx| Parent {
|
let (_, root_view) = cx.add_window(|cx| Parent {
|
||||||
child: Some(cx.add_view(|_| Child {
|
child: Some(cx.add_view(|_| Child {
|
||||||
rendered: child_rendered.clone(),
|
rendered: child_rendered.clone(),
|
||||||
dropped: child_dropped.clone(),
|
dropped: child_dropped.clone(),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
any::Any,
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
mem,
|
mem,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
@ -22,8 +23,8 @@ use crate::{
|
|||||||
platform,
|
platform,
|
||||||
platform::{Event, InputHandler, KeyDownEvent, Platform},
|
platform::{Event, InputHandler, KeyDownEvent, Platform},
|
||||||
Action, AnyViewHandle, AppContext, Entity, FontCache, Handle, ModelContext, ModelHandle,
|
Action, AnyViewHandle, AppContext, Entity, FontCache, Handle, ModelContext, ModelHandle,
|
||||||
ReadModelWith, ReadViewWith, Task, UpdateModel, UpdateView, View, ViewContext, ViewHandle,
|
ReadModelWith, ReadViewWith, Subscription, Task, UpdateModel, UpdateView, View, ViewContext,
|
||||||
WeakHandle, WindowContext,
|
ViewHandle, WeakHandle, WindowContext,
|
||||||
};
|
};
|
||||||
use collections::BTreeMap;
|
use collections::BTreeMap;
|
||||||
|
|
||||||
@ -160,6 +161,26 @@ impl TestAppContext {
|
|||||||
self.cx.borrow_mut().add_view(parent_handle, build_view)
|
self.cx.borrow_mut().add_view(parent_handle, build_view)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn observe_global<E, F>(&mut self, callback: F) -> Subscription
|
||||||
|
where
|
||||||
|
E: Any,
|
||||||
|
F: 'static + FnMut(&mut AppContext),
|
||||||
|
{
|
||||||
|
self.cx.borrow_mut().observe_global::<E, F>(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_global<T: 'static>(&mut self, state: T) {
|
||||||
|
self.cx.borrow_mut().set_global(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscribe_global<E, F>(&mut self, callback: F) -> Subscription
|
||||||
|
where
|
||||||
|
E: Any,
|
||||||
|
F: 'static + FnMut(&E, &mut AppContext),
|
||||||
|
{
|
||||||
|
self.cx.borrow_mut().subscribe_global(callback)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn window_ids(&self) -> Vec<usize> {
|
pub fn window_ids(&self) -> Vec<usize> {
|
||||||
self.cx.borrow().window_ids().collect()
|
self.cx.borrow().window_ids().collect()
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
text_layout::TextLayoutCache,
|
text_layout::TextLayoutCache,
|
||||||
util::post_inc,
|
util::post_inc,
|
||||||
Action, AnyView, AnyViewHandle, AnyWeakViewHandle, AppContext, Drawable, Effect, Entity,
|
Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle,
|
||||||
ModelContext, ModelHandle, MouseRegion, MouseRegionId, ParentId, ReadModel, ReadView,
|
AppContext, Drawable, Effect, Entity, Handle, ModelContext, ModelHandle, MouseRegion,
|
||||||
SceneBuilder, Subscription, UpdateModel, UpdateView, UpgradeViewHandle, View, ViewContext,
|
MouseRegionId, ParentId, ReadModel, ReadView, SceneBuilder, Subscription, UpdateModel,
|
||||||
ViewHandle, WeakViewHandle, WindowInvalidation,
|
UpdateView, UpgradeModelHandle, UpgradeViewHandle, View, ViewContext, ViewHandle,
|
||||||
|
WeakModelHandle, WeakViewHandle, WindowInvalidation,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
@ -175,6 +176,23 @@ impl UpdateView for WindowContext<'_, '_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UpgradeModelHandle for WindowContext<'_, '_> {
|
||||||
|
fn upgrade_model_handle<T: Entity>(
|
||||||
|
&self,
|
||||||
|
handle: &WeakModelHandle<T>,
|
||||||
|
) -> Option<ModelHandle<T>> {
|
||||||
|
self.app_context.upgrade_model_handle(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
|
||||||
|
self.app_context.model_handle_is_upgradable(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
|
||||||
|
self.app_context.upgrade_any_model_handle(handle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UpgradeViewHandle for WindowContext<'_, '_> {
|
impl UpgradeViewHandle for WindowContext<'_, '_> {
|
||||||
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
|
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
|
||||||
self.app_context.upgrade_view_handle(handle)
|
self.app_context.upgrade_view_handle(handle)
|
||||||
@ -239,6 +257,49 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
|||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut WindowContext)) {
|
||||||
|
let window_id = self.window_id;
|
||||||
|
self.app_context.defer(move |cx| {
|
||||||
|
cx.update_window(window_id, |cx| callback(cx));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_global<T, F, U>(&mut self, update: F) -> U
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
F: FnOnce(&mut T, &mut Self) -> U,
|
||||||
|
{
|
||||||
|
AppContext::update_global_internal(self, |global, cx| update(global, cx))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
|
||||||
|
where
|
||||||
|
E: Entity,
|
||||||
|
E::Event: 'static,
|
||||||
|
H: Handle<E>,
|
||||||
|
F: 'static + FnMut(H, &E::Event, &mut WindowContext),
|
||||||
|
{
|
||||||
|
self.subscribe_internal(handle, move |emitter, event, cx| {
|
||||||
|
callback(emitter, event, cx);
|
||||||
|
true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
|
||||||
|
where
|
||||||
|
E: Entity,
|
||||||
|
E::Event: 'static,
|
||||||
|
H: Handle<E>,
|
||||||
|
F: 'static + FnMut(H, &E::Event, &mut WindowContext) -> bool,
|
||||||
|
{
|
||||||
|
let window_id = self.window_id;
|
||||||
|
self.app_context
|
||||||
|
.subscribe_internal(handle, move |emitter, event, cx| {
|
||||||
|
cx.update_window(window_id, |cx| callback(emitter, event, cx))
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn observe_window_activation<F>(&mut self, callback: F) -> Subscription
|
pub(crate) fn observe_window_activation<F>(&mut self, callback: F) -> Subscription
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(bool, &mut WindowContext) -> bool,
|
F: 'static + FnMut(bool, &mut WindowContext) -> bool,
|
||||||
|
@ -174,23 +174,60 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Pass to the test function the number of app contexts that it needs,
|
||||||
|
// based on its parameter list.
|
||||||
|
let mut cx_vars = proc_macro2::TokenStream::new();
|
||||||
|
let mut cx_teardowns = proc_macro2::TokenStream::new();
|
||||||
let mut inner_fn_args = proc_macro2::TokenStream::new();
|
let mut inner_fn_args = proc_macro2::TokenStream::new();
|
||||||
for arg in inner_fn.sig.inputs.iter() {
|
for (ix, arg) in inner_fn.sig.inputs.iter().enumerate() {
|
||||||
if let FnArg::Typed(arg) = arg {
|
if let FnArg::Typed(arg) = arg {
|
||||||
if let Type::Path(ty) = &*arg.ty {
|
if let Type::Path(ty) = &*arg.ty {
|
||||||
let last_segment = ty.path.segments.last();
|
let last_segment = ty.path.segments.last();
|
||||||
|
|
||||||
if let Some("StdRng") = last_segment.map(|s| s.ident.to_string()).as_deref() {
|
if let Some("StdRng") = last_segment.map(|s| s.ident.to_string()).as_deref() {
|
||||||
inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
|
inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if let Type::Reference(ty) = &*arg.ty {
|
||||||
|
if let Type::Path(ty) = &*ty.elem {
|
||||||
|
let last_segment = ty.path.segments.last();
|
||||||
|
match last_segment.map(|s| s.ident.to_string()).as_deref() {
|
||||||
|
Some("AppContext") => {
|
||||||
|
inner_fn_args.extend(quote!(cx,));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Some("TestAppContext") => {
|
||||||
|
let first_entity_id = ix * 100_000;
|
||||||
|
let cx_varname = format_ident!("cx_{}", ix);
|
||||||
|
cx_vars.extend(quote!(
|
||||||
|
let mut #cx_varname = #namespace::TestAppContext::new(
|
||||||
|
foreground_platform.clone(),
|
||||||
|
cx.platform().clone(),
|
||||||
|
deterministic.build_foreground(#ix),
|
||||||
|
deterministic.build_background(),
|
||||||
|
cx.font_cache().clone(),
|
||||||
|
cx.leak_detector(),
|
||||||
|
#first_entity_id,
|
||||||
|
stringify!(#outer_fn_name).to_string(),
|
||||||
|
);
|
||||||
|
));
|
||||||
|
cx_teardowns.extend(quote!(
|
||||||
|
#cx_varname.update(|cx| cx.remove_all_windows());
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
#cx_varname.update(|cx| cx.clear_globals());
|
||||||
|
));
|
||||||
|
inner_fn_args.extend(quote!(&mut #cx_varname,));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
inner_fn_args.extend(quote!(cx,));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return TokenStream::from(
|
|
||||||
syn::Error::new_spanned(arg, "invalid argument").into_compile_error(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TokenStream::from(
|
||||||
|
syn::Error::new_spanned(arg, "invalid argument").into_compile_error(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_quote! {
|
parse_quote! {
|
||||||
@ -203,7 +240,11 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
|
|||||||
#starting_seed as u64,
|
#starting_seed as u64,
|
||||||
#max_retries,
|
#max_retries,
|
||||||
#detect_nondeterminism,
|
#detect_nondeterminism,
|
||||||
&mut |cx, _, _, seed| #inner_fn_name(#inner_fn_args),
|
&mut |cx, foreground_platform, deterministic, seed| {
|
||||||
|
#cx_vars
|
||||||
|
#inner_fn_name(#inner_fn_args);
|
||||||
|
#cx_teardowns
|
||||||
|
},
|
||||||
#on_failure_fn_name,
|
#on_failure_fn_name,
|
||||||
stringify!(#outer_fn_name).to_string(),
|
stringify!(#outer_fn_name).to_string(),
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,7 @@ use editor::{
|
|||||||
use fuzzy::StringMatch;
|
use fuzzy::StringMatch;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, elements::*, geometry::vector::Vector2F, AnyViewHandle, AppContext, Entity,
|
actions, elements::*, geometry::vector::Vector2F, AnyViewHandle, AppContext, Entity,
|
||||||
MouseState, Task, View, ViewContext, ViewHandle,
|
MouseState, Task, View, ViewContext, ViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
use language::Outline;
|
use language::Outline;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
@ -39,7 +39,9 @@ impl Entity for OutlineView {
|
|||||||
type Event = Event;
|
type Event = Event;
|
||||||
|
|
||||||
fn release(&mut self, cx: &mut AppContext) {
|
fn release(&mut self, cx: &mut AppContext) {
|
||||||
self.restore_active_editor(cx);
|
cx.update_window(self.active_editor.window_id(), |cx| {
|
||||||
|
self.restore_active_editor(cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ impl OutlineView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore_active_editor(&mut self, cx: &mut AppContext) {
|
fn restore_active_editor(&mut self, cx: &mut WindowContext) {
|
||||||
self.active_editor.update(cx, |editor, cx| {
|
self.active_editor.update(cx, |editor, cx| {
|
||||||
editor.highlight_rows(None);
|
editor.highlight_rows(None);
|
||||||
if let Some(scroll_position) = self.prev_scroll_position {
|
if let Some(scroll_position) = self.prev_scroll_position {
|
||||||
|
@ -11,13 +11,9 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
|
|
||||||
fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) {
|
fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) {
|
||||||
Vim::update(cx, |vim, cx| {
|
Vim::update(cx, |vim, cx| {
|
||||||
if let Some(previously_active_editor) = vim
|
vim.update_active_editor(cx, |previously_active_editor, cx| {
|
||||||
.active_editor
|
Vim::unhook_vim_settings(previously_active_editor, cx);
|
||||||
.as_ref()
|
});
|
||||||
.and_then(|editor| editor.upgrade(cx))
|
|
||||||
{
|
|
||||||
vim.unhook_vim_settings(previously_active_editor, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
vim.active_editor = Some(editor.downgrade());
|
vim.active_editor = Some(editor.downgrade());
|
||||||
vim.editor_subscription = Some(cx.subscribe(editor, |editor, event, cx| match event {
|
vim.editor_subscription = Some(cx.subscribe(editor, |editor, event, cx| match event {
|
||||||
@ -55,7 +51,10 @@ fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) {
|
|||||||
vim.active_editor = None;
|
vim.active_editor = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vim.unhook_vim_settings(editor.clone(), cx);
|
|
||||||
|
cx.update_window(editor.window_id(), |cx| {
|
||||||
|
editor.update(cx, |editor, cx| Vim::unhook_vim_settings(editor, cx))
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@ use std::sync::Arc;
|
|||||||
use collections::CommandPaletteFilter;
|
use collections::CommandPaletteFilter;
|
||||||
use editor::{Bias, Cancel, Editor, EditorMode};
|
use editor::{Bias, Cancel, Editor, EditorMode};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, impl_actions, AppContext, Subscription, ViewContext, ViewHandle, WeakViewHandle,
|
actions, impl_actions, AppContext, Subscription, ViewContext, WeakViewHandle, WindowContext,
|
||||||
WindowContext,
|
|
||||||
};
|
};
|
||||||
use language::CursorShape;
|
use language::CursorShape;
|
||||||
use motion::Motion;
|
use motion::Motion;
|
||||||
@ -148,10 +147,8 @@ impl Vim {
|
|||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
update: impl FnOnce(&mut Editor, &mut ViewContext<Editor>) -> S,
|
update: impl FnOnce(&mut Editor, &mut ViewContext<Editor>) -> S,
|
||||||
) -> Option<S> {
|
) -> Option<S> {
|
||||||
self.active_editor
|
let editor = self.active_editor.clone()?.upgrade(cx)?;
|
||||||
.clone()
|
cx.update_window(editor.window_id(), |cx| editor.update(cx, update))
|
||||||
.and_then(|ae| ae.upgrade(cx))
|
|
||||||
.map(|ae| ae.update(cx, update))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch_mode(&mut self, mode: Mode, leave_selections: bool, cx: &mut AppContext) {
|
fn switch_mode(&mut self, mode: Mode, leave_selections: bool, cx: &mut AppContext) {
|
||||||
@ -166,27 +163,19 @@ impl Vim {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adjust selections
|
// Adjust selections
|
||||||
if let Some(editor) = self
|
self.update_active_editor(cx, |editor, cx| {
|
||||||
.active_editor
|
editor.change_selections(None, cx, |s| {
|
||||||
.as_ref()
|
s.move_with(|map, selection| {
|
||||||
.and_then(|editor| editor.upgrade(cx))
|
if self.state.empty_selections_only() {
|
||||||
{
|
let new_head = map.clip_point(selection.head(), Bias::Left);
|
||||||
editor.update(cx, |editor, cx| {
|
selection.collapse_to(new_head, selection.goal)
|
||||||
editor.change_selections(None, cx, |s| {
|
} else {
|
||||||
s.move_with(|map, selection| {
|
selection
|
||||||
if self.state.empty_selections_only() {
|
.set_head(map.clip_point(selection.head(), Bias::Left), selection.goal);
|
||||||
let new_head = map.clip_point(selection.head(), Bias::Left);
|
}
|
||||||
selection.collapse_to(new_head, selection.goal)
|
});
|
||||||
} else {
|
|
||||||
selection.set_head(
|
|
||||||
map.clip_point(selection.head(), Bias::Left),
|
|
||||||
selection.goal,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_operator(&mut self, operator: Operator, cx: &mut AppContext) {
|
fn push_operator(&mut self, operator: Operator, cx: &mut AppContext) {
|
||||||
@ -272,33 +261,25 @@ impl Vim {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(editor) = self
|
self.update_active_editor(cx, |editor, cx| {
|
||||||
.active_editor
|
if self.enabled && editor.mode() == EditorMode::Full {
|
||||||
.as_ref()
|
editor.set_cursor_shape(cursor_shape, cx);
|
||||||
.and_then(|editor| editor.upgrade(cx))
|
editor.set_clip_at_line_ends(state.clip_at_line_end(), cx);
|
||||||
{
|
editor.set_input_enabled(!state.vim_controlled());
|
||||||
if self.enabled && editor.read(cx).mode() == EditorMode::Full {
|
editor.selections.line_mode = matches!(state.mode, Mode::Visual { line: true });
|
||||||
editor.update(cx, |editor, cx| {
|
let context_layer = state.keymap_context_layer();
|
||||||
editor.set_cursor_shape(cursor_shape, cx);
|
editor.set_keymap_context_layer::<Self>(context_layer);
|
||||||
editor.set_clip_at_line_ends(state.clip_at_line_end(), cx);
|
|
||||||
editor.set_input_enabled(!state.vim_controlled());
|
|
||||||
editor.selections.line_mode = matches!(state.mode, Mode::Visual { line: true });
|
|
||||||
let context_layer = state.keymap_context_layer();
|
|
||||||
editor.set_keymap_context_layer::<Self>(context_layer);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
self.unhook_vim_settings(editor, cx);
|
Self::unhook_vim_settings(editor, cx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unhook_vim_settings(&self, editor: ViewHandle<Editor>, cx: &mut AppContext) {
|
|
||||||
editor.update(cx, |editor, cx| {
|
|
||||||
editor.set_cursor_shape(CursorShape::Bar, cx);
|
|
||||||
editor.set_clip_at_line_ends(false, cx);
|
|
||||||
editor.set_input_enabled(true);
|
|
||||||
editor.selections.line_mode = false;
|
|
||||||
editor.remove_keymap_context_layer::<Self>();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unhook_vim_settings(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
|
||||||
|
editor.set_cursor_shape(CursorShape::Bar, cx);
|
||||||
|
editor.set_clip_at_line_ends(false, cx);
|
||||||
|
editor.set_input_enabled(true);
|
||||||
|
editor.selections.line_mode = false;
|
||||||
|
editor.remove_keymap_context_layer::<Self>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ pub trait ItemHandle: 'static + fmt::Debug {
|
|||||||
fn subscribe_to_item_events(
|
fn subscribe_to_item_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(ItemEvent, &mut AppContext)>,
|
handler: Box<dyn Fn(ItemEvent, &mut WindowContext)>,
|
||||||
) -> gpui::Subscription;
|
) -> gpui::Subscription;
|
||||||
fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option<Cow<'a, str>>;
|
fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option<Cow<'a, str>>;
|
||||||
fn tab_content(
|
fn tab_content(
|
||||||
@ -254,7 +254,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
|||||||
fn subscribe_to_item_events(
|
fn subscribe_to_item_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(ItemEvent, &mut AppContext)>,
|
handler: Box<dyn Fn(ItemEvent, &mut WindowContext)>,
|
||||||
) -> gpui::Subscription {
|
) -> gpui::Subscription {
|
||||||
cx.subscribe(self, move |_, event, cx| {
|
cx.subscribe(self, move |_, event, cx| {
|
||||||
for item_event in T::to_item_events(event) {
|
for item_event in T::to_item_events(event) {
|
||||||
@ -677,7 +677,7 @@ pub trait FollowableItem: Item {
|
|||||||
|
|
||||||
pub trait FollowableItemHandle: ItemHandle {
|
pub trait FollowableItemHandle: ItemHandle {
|
||||||
fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId>;
|
fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId>;
|
||||||
fn set_leader_replica_id(&self, leader_replica_id: Option<u16>, cx: &mut AppContext);
|
fn set_leader_replica_id(&self, leader_replica_id: Option<u16>, cx: &mut WindowContext);
|
||||||
fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant>;
|
fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant>;
|
||||||
fn add_event_to_update_proto(
|
fn add_event_to_update_proto(
|
||||||
&self,
|
&self,
|
||||||
@ -689,7 +689,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
|||||||
&self,
|
&self,
|
||||||
project: &ModelHandle<Project>,
|
project: &ModelHandle<Project>,
|
||||||
message: proto::update_view::Variant,
|
message: proto::update_view::Variant,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> Task<Result<()>>;
|
) -> Task<Result<()>>;
|
||||||
fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool;
|
fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool;
|
||||||
}
|
}
|
||||||
@ -704,7 +704,7 @@ impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_leader_replica_id(&self, leader_replica_id: Option<u16>, cx: &mut AppContext) {
|
fn set_leader_replica_id(&self, leader_replica_id: Option<u16>, cx: &mut WindowContext) {
|
||||||
self.update(cx, |this, cx| {
|
self.update(cx, |this, cx| {
|
||||||
this.set_leader_replica_id(leader_replica_id, cx)
|
this.set_leader_replica_id(leader_replica_id, cx)
|
||||||
})
|
})
|
||||||
@ -731,7 +731,7 @@ impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
|
|||||||
&self,
|
&self,
|
||||||
project: &ModelHandle<Project>,
|
project: &ModelHandle<Project>,
|
||||||
message: proto::update_view::Variant,
|
message: proto::update_view::Variant,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
|
self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
|
||||||
}
|
}
|
||||||
|
@ -1890,15 +1890,15 @@ fn render_tab_bar_button<A: Action + Clone>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ItemNavHistory {
|
impl ItemNavHistory {
|
||||||
pub fn push<D: 'static + Any>(&self, data: Option<D>, cx: &mut AppContext) {
|
pub fn push<D: 'static + Any>(&self, data: Option<D>, cx: &mut WindowContext) {
|
||||||
self.history.borrow_mut().push(data, self.item.clone(), cx);
|
self.history.borrow_mut().push(data, self.item.clone(), cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_backward(&self, cx: &mut AppContext) -> Option<NavigationEntry> {
|
pub fn pop_backward(&self, cx: &mut WindowContext) -> Option<NavigationEntry> {
|
||||||
self.history.borrow_mut().pop(NavigationMode::GoingBack, cx)
|
self.history.borrow_mut().pop(NavigationMode::GoingBack, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_forward(&self, cx: &mut AppContext) -> Option<NavigationEntry> {
|
pub fn pop_forward(&self, cx: &mut WindowContext) -> Option<NavigationEntry> {
|
||||||
self.history
|
self.history
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.pop(NavigationMode::GoingForward, cx)
|
.pop(NavigationMode::GoingForward, cx)
|
||||||
@ -1918,7 +1918,7 @@ impl NavHistory {
|
|||||||
self.mode = NavigationMode::Normal;
|
self.mode = NavigationMode::Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop(&mut self, mode: NavigationMode, cx: &mut AppContext) -> Option<NavigationEntry> {
|
fn pop(&mut self, mode: NavigationMode, cx: &mut WindowContext) -> Option<NavigationEntry> {
|
||||||
let entry = match mode {
|
let entry = match mode {
|
||||||
NavigationMode::Normal | NavigationMode::Disabled | NavigationMode::ClosingItem => {
|
NavigationMode::Normal | NavigationMode::Disabled | NavigationMode::ClosingItem => {
|
||||||
return None
|
return None
|
||||||
@ -1938,7 +1938,7 @@ impl NavHistory {
|
|||||||
&mut self,
|
&mut self,
|
||||||
data: Option<D>,
|
data: Option<D>,
|
||||||
item: Rc<dyn WeakItemHandle>,
|
item: Rc<dyn WeakItemHandle>,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) {
|
) {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
NavigationMode::Disabled => {}
|
NavigationMode::Disabled => {}
|
||||||
@ -1983,7 +1983,7 @@ impl NavHistory {
|
|||||||
self.did_update(cx);
|
self.did_update(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_update(&self, cx: &mut AppContext) {
|
fn did_update(&self, cx: &mut WindowContext) {
|
||||||
if let Some(pane) = self.pane.upgrade(cx) {
|
if let Some(pane) = self.pane.upgrade(cx) {
|
||||||
cx.defer(move |cx| pane.update(cx, |pane, cx| pane.history_updated(cx)));
|
cx.defer(move |cx| pane.update(cx, |pane, cx| pane.history_updated(cx)));
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::any::Any;
|
|||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyViewHandle, AnyWeakViewHandle, AppContext, Subscription, Task, ViewContext, ViewHandle,
|
AnyViewHandle, AnyWeakViewHandle, AppContext, Subscription, Task, ViewContext, ViewHandle,
|
||||||
WeakViewHandle,
|
WeakViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
use project::search::SearchQuery;
|
use project::search::SearchQuery;
|
||||||
|
|
||||||
@ -90,29 +90,34 @@ pub trait SearchableItemHandle: ItemHandle {
|
|||||||
fn supported_options(&self) -> SearchOptions;
|
fn supported_options(&self) -> SearchOptions;
|
||||||
fn subscribe_to_search_events(
|
fn subscribe_to_search_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(SearchEvent, &mut AppContext)>,
|
handler: Box<dyn Fn(SearchEvent, &mut WindowContext)>,
|
||||||
) -> Subscription;
|
) -> Subscription;
|
||||||
fn clear_matches(&self, cx: &mut AppContext);
|
fn clear_matches(&self, cx: &mut WindowContext);
|
||||||
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut AppContext);
|
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut WindowContext);
|
||||||
fn query_suggestion(&self, cx: &mut AppContext) -> String;
|
fn query_suggestion(&self, cx: &mut WindowContext) -> String;
|
||||||
fn activate_match(&self, index: usize, matches: &Vec<Box<dyn Any + Send>>, cx: &mut AppContext);
|
fn activate_match(
|
||||||
|
&self,
|
||||||
|
index: usize,
|
||||||
|
matches: &Vec<Box<dyn Any + Send>>,
|
||||||
|
cx: &mut WindowContext,
|
||||||
|
);
|
||||||
fn match_index_for_direction(
|
fn match_index_for_direction(
|
||||||
&self,
|
&self,
|
||||||
matches: &Vec<Box<dyn Any + Send>>,
|
matches: &Vec<Box<dyn Any + Send>>,
|
||||||
current_index: usize,
|
current_index: usize,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> usize;
|
) -> usize;
|
||||||
fn find_matches(
|
fn find_matches(
|
||||||
&self,
|
&self,
|
||||||
query: SearchQuery,
|
query: SearchQuery,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> Task<Vec<Box<dyn Any + Send>>>;
|
) -> Task<Vec<Box<dyn Any + Send>>>;
|
||||||
fn active_match_index(
|
fn active_match_index(
|
||||||
&self,
|
&self,
|
||||||
matches: &Vec<Box<dyn Any + Send>>,
|
matches: &Vec<Box<dyn Any + Send>>,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> Option<usize>;
|
) -> Option<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,8 +136,8 @@ impl<T: SearchableItem> SearchableItemHandle for ViewHandle<T> {
|
|||||||
|
|
||||||
fn subscribe_to_search_events(
|
fn subscribe_to_search_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(SearchEvent, &mut AppContext)>,
|
handler: Box<dyn Fn(SearchEvent, &mut WindowContext)>,
|
||||||
) -> Subscription {
|
) -> Subscription {
|
||||||
cx.subscribe(self, move |_, event, cx| {
|
cx.subscribe(self, move |_, event, cx| {
|
||||||
if let Some(search_event) = T::to_search_event(event) {
|
if let Some(search_event) = T::to_search_event(event) {
|
||||||
@ -141,21 +146,21 @@ impl<T: SearchableItem> SearchableItemHandle for ViewHandle<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_matches(&self, cx: &mut AppContext) {
|
fn clear_matches(&self, cx: &mut WindowContext) {
|
||||||
self.update(cx, |this, cx| this.clear_matches(cx));
|
self.update(cx, |this, cx| this.clear_matches(cx));
|
||||||
}
|
}
|
||||||
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut AppContext) {
|
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut WindowContext) {
|
||||||
let matches = downcast_matches(matches);
|
let matches = downcast_matches(matches);
|
||||||
self.update(cx, |this, cx| this.update_matches(matches, cx));
|
self.update(cx, |this, cx| this.update_matches(matches, cx));
|
||||||
}
|
}
|
||||||
fn query_suggestion(&self, cx: &mut AppContext) -> String {
|
fn query_suggestion(&self, cx: &mut WindowContext) -> String {
|
||||||
self.update(cx, |this, cx| this.query_suggestion(cx))
|
self.update(cx, |this, cx| this.query_suggestion(cx))
|
||||||
}
|
}
|
||||||
fn activate_match(
|
fn activate_match(
|
||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
matches: &Vec<Box<dyn Any + Send>>,
|
matches: &Vec<Box<dyn Any + Send>>,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) {
|
) {
|
||||||
let matches = downcast_matches(matches);
|
let matches = downcast_matches(matches);
|
||||||
self.update(cx, |this, cx| this.activate_match(index, matches, cx));
|
self.update(cx, |this, cx| this.activate_match(index, matches, cx));
|
||||||
@ -165,7 +170,7 @@ impl<T: SearchableItem> SearchableItemHandle for ViewHandle<T> {
|
|||||||
matches: &Vec<Box<dyn Any + Send>>,
|
matches: &Vec<Box<dyn Any + Send>>,
|
||||||
current_index: usize,
|
current_index: usize,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let matches = downcast_matches(matches);
|
let matches = downcast_matches(matches);
|
||||||
self.update(cx, |this, cx| {
|
self.update(cx, |this, cx| {
|
||||||
@ -175,7 +180,7 @@ impl<T: SearchableItem> SearchableItemHandle for ViewHandle<T> {
|
|||||||
fn find_matches(
|
fn find_matches(
|
||||||
&self,
|
&self,
|
||||||
query: SearchQuery,
|
query: SearchQuery,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> Task<Vec<Box<dyn Any + Send>>> {
|
) -> Task<Vec<Box<dyn Any + Send>>> {
|
||||||
let matches = self.update(cx, |this, cx| this.find_matches(query, cx));
|
let matches = self.update(cx, |this, cx| this.find_matches(query, cx));
|
||||||
cx.foreground().spawn(async {
|
cx.foreground().spawn(async {
|
||||||
@ -189,7 +194,7 @@ impl<T: SearchableItem> SearchableItemHandle for ViewHandle<T> {
|
|||||||
fn active_match_index(
|
fn active_match_index(
|
||||||
&self,
|
&self,
|
||||||
matches: &Vec<Box<dyn Any + Send>>,
|
matches: &Vec<Box<dyn Any + Send>>,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
let matches = downcast_matches(matches);
|
let matches = downcast_matches(matches);
|
||||||
self.update(cx, |this, cx| this.active_match_index(matches, cx))
|
self.update(cx, |this, cx| this.active_match_index(matches, cx))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{ItemHandle, Pane};
|
use crate::{ItemHandle, Pane};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyViewHandle, AppContext,
|
elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyViewHandle, AppContext,
|
||||||
Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
|
Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ pub trait ToolbarItemView: View {
|
|||||||
current_location
|
current_location
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pane_focus_update(&mut self, _pane_focused: bool, _cx: &mut AppContext) {}
|
fn pane_focus_update(&mut self, _pane_focused: bool, _cx: &mut ViewContext<Self>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ToolbarItemViewHandle {
|
trait ToolbarItemViewHandle {
|
||||||
@ -30,9 +30,9 @@ trait ToolbarItemViewHandle {
|
|||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&self,
|
&self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> ToolbarItemLocation;
|
) -> ToolbarItemLocation;
|
||||||
fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut AppContext);
|
fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut WindowContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
@ -263,7 +263,7 @@ impl Toolbar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut AppContext) {
|
pub fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut ViewContext<Self>) {
|
||||||
for (toolbar_item, _) in self.items.iter_mut() {
|
for (toolbar_item, _) in self.items.iter_mut() {
|
||||||
toolbar_item.pane_focus_update(pane_focused, cx);
|
toolbar_item.pane_focus_update(pane_focused, cx);
|
||||||
}
|
}
|
||||||
@ -292,14 +292,14 @@ impl<T: ToolbarItemView> ToolbarItemViewHandle for ViewHandle<T> {
|
|||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&self,
|
&self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut AppContext,
|
cx: &mut WindowContext,
|
||||||
) -> ToolbarItemLocation {
|
) -> ToolbarItemLocation {
|
||||||
self.update(cx, |this, cx| {
|
self.update(cx, |this, cx| {
|
||||||
this.set_active_pane_item(active_pane_item, cx)
|
this.set_active_pane_item(active_pane_item, cx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut AppContext) {
|
fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut WindowContext) {
|
||||||
self.update(cx, |this, cx| this.pane_focus_update(pane_focused, cx));
|
self.update(cx, |this, cx| this.pane_focus_update(pane_focused, cx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,20 +397,18 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
|||||||
.await
|
.await
|
||||||
.context("Failed to create CLI symlink");
|
.context("Failed to create CLI symlink");
|
||||||
|
|
||||||
cx.update(|cx| {
|
workspace.update(&mut cx, |workspace, cx| {
|
||||||
workspace.update(cx, |workspace, cx| {
|
if matches!(err, Err(_)) {
|
||||||
if matches!(err, Err(_)) {
|
err.notify_err(workspace, cx);
|
||||||
err.notify_err(workspace, cx);
|
} else {
|
||||||
} else {
|
workspace.show_notification(1, cx, |cx| {
|
||||||
workspace.show_notification(1, cx, |cx| {
|
cx.add_view(|_| {
|
||||||
cx.add_view(|_| {
|
MessageNotification::new_message(
|
||||||
MessageNotification::new_message(
|
"Successfully installed the `zed` binary",
|
||||||
"Successfully installed the `zed` binary",
|
)
|
||||||
)
|
})
|
||||||
})
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
@ -724,11 +722,9 @@ impl Workspace {
|
|||||||
Stream::map(current_user, drop).merge(Stream::map(connection_status, drop));
|
Stream::map(current_user, drop).merge(Stream::map(connection_status, drop));
|
||||||
|
|
||||||
while stream.recv().await.is_some() {
|
while stream.recv().await.is_some() {
|
||||||
cx.update(|cx| {
|
if let Some(this) = this.upgrade(&cx) {
|
||||||
if let Some(this) = this.upgrade(cx) {
|
this.update(&mut cx, |_, cx| cx.notify());
|
||||||
this.update(cx, |_, cx| cx.notify());
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let handle = cx.handle();
|
let handle = cx.handle();
|
||||||
|
@ -1012,12 +1012,11 @@ mod tests {
|
|||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
|
||||||
|
|
||||||
// Open a file within an existing worktree.
|
// Open a file within an existing worktree.
|
||||||
cx.update(|cx| {
|
workspace
|
||||||
workspace.update(cx, |view, cx| {
|
.update(cx, |view, cx| {
|
||||||
view.open_paths(vec!["/dir1/a.txt".into()], true, cx)
|
view.open_paths(vec!["/dir1/a.txt".into()], true, cx)
|
||||||
})
|
})
|
||||||
})
|
.await;
|
||||||
.await;
|
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
workspace
|
workspace
|
||||||
@ -1036,12 +1035,11 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Open a file outside of any existing worktree.
|
// Open a file outside of any existing worktree.
|
||||||
cx.update(|cx| {
|
workspace
|
||||||
workspace.update(cx, |view, cx| {
|
.update(cx, |view, cx| {
|
||||||
view.open_paths(vec!["/dir2/b.txt".into()], true, cx)
|
view.open_paths(vec!["/dir2/b.txt".into()], true, cx)
|
||||||
})
|
})
|
||||||
})
|
.await;
|
||||||
.await;
|
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let worktree_roots = workspace
|
let worktree_roots = workspace
|
||||||
.read(cx)
|
.read(cx)
|
||||||
@ -1072,12 +1070,11 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Ensure opening a directory and one of its children only adds one worktree.
|
// Ensure opening a directory and one of its children only adds one worktree.
|
||||||
cx.update(|cx| {
|
workspace
|
||||||
workspace.update(cx, |view, cx| {
|
.update(cx, |view, cx| {
|
||||||
view.open_paths(vec!["/dir3".into(), "/dir3/c.txt".into()], true, cx)
|
view.open_paths(vec!["/dir3".into(), "/dir3/c.txt".into()], true, cx)
|
||||||
})
|
})
|
||||||
})
|
.await;
|
||||||
.await;
|
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let worktree_roots = workspace
|
let worktree_roots = workspace
|
||||||
.read(cx)
|
.read(cx)
|
||||||
@ -1108,12 +1105,11 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Ensure opening invisibly a file outside an existing worktree adds a new, invisible worktree.
|
// Ensure opening invisibly a file outside an existing worktree adds a new, invisible worktree.
|
||||||
cx.update(|cx| {
|
workspace
|
||||||
workspace.update(cx, |view, cx| {
|
.update(cx, |view, cx| {
|
||||||
view.open_paths(vec!["/d.txt".into()], false, cx)
|
view.open_paths(vec!["/d.txt".into()], false, cx)
|
||||||
})
|
})
|
||||||
})
|
.await;
|
||||||
.await;
|
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let worktree_roots = workspace
|
let worktree_roots = workspace
|
||||||
.read(cx)
|
.read(cx)
|
||||||
@ -1171,19 +1167,18 @@ mod tests {
|
|||||||
let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
|
let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
|
||||||
|
|
||||||
// Open a file within an existing worktree.
|
// Open a file within an existing worktree.
|
||||||
cx.update(|cx| {
|
workspace
|
||||||
workspace.update(cx, |view, cx| {
|
.update(cx, |view, cx| {
|
||||||
view.open_paths(vec![PathBuf::from("/root/a.txt")], true, cx)
|
view.open_paths(vec![PathBuf::from("/root/a.txt")], true, cx)
|
||||||
})
|
})
|
||||||
})
|
.await;
|
||||||
.await;
|
|
||||||
let editor = cx.read(|cx| {
|
let editor = cx.read(|cx| {
|
||||||
let pane = workspace.read(cx).active_pane().read(cx);
|
let pane = workspace.read(cx).active_pane().read(cx);
|
||||||
let item = pane.active_item().unwrap();
|
let item = pane.active_item().unwrap();
|
||||||
item.downcast::<Editor>().unwrap()
|
item.downcast::<Editor>().unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.update(|cx| editor.update(cx, |editor, cx| editor.handle_input("x", cx)));
|
editor.update(cx, |editor, cx| editor.handle_input("x", cx));
|
||||||
app_state
|
app_state
|
||||||
.fs
|
.fs
|
||||||
.as_fake()
|
.as_fake()
|
||||||
|
Loading…
Reference in New Issue
Block a user