Eliminate GPUI View, ViewContext, and WindowContext types (#22632)
There's still a bit more work to do on this, but this PR is compiling (with warnings) after eliminating the key types. When the tasks below are complete, this will be the new narrative for GPUI: - `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit of state, and if `T` implements `Render`, then `Entity<T>` implements `Element`. - `&mut App` This replaces `AppContext` and represents the app. - `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It is provided by the framework when updating an entity. - `&mut Window` Broken out of `&mut WindowContext` which no longer exists. Every method that once took `&mut WindowContext` now takes `&mut Window, &mut App` and every method that took `&mut ViewContext<T>` now takes `&mut Window, &mut Context<T>` Not pictured here are the two other failed attempts. It's been quite a month! Tasks: - [x] Remove `View`, `ViewContext`, `WindowContext` and thread through `Window` - [x] [@cole-miller @mikayla-maki] Redraw window when entities change - [x] [@cole-miller @mikayla-maki] Get examples and Zed running - [x] [@cole-miller @mikayla-maki] Fix Zed rendering - [x] [@mikayla-maki] Fix todo! macros and comments - [x] Fix a bug where the editor would not be redrawn because of view caching - [x] remove publicness window.notify() and replace with `AppContext::notify` - [x] remove `observe_new_window_models`, replace with `observe_new_models` with an optional window - [x] Fix a bug where the project panel would not be redrawn because of the wrong refresh() call being used - [x] Fix the tests - [x] Fix warnings by eliminating `Window` params or using `_` - [x] Fix conflicts - [x] Simplify generic code where possible - [x] Rename types - [ ] Update docs ### issues post merge - [x] Issues switching between normal and insert mode - [x] Assistant re-rendering failure - [x] Vim test failures - [x] Mac build issue Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev> Co-authored-by: Joseph <joseph@zed.dev> Co-authored-by: max <max@zed.dev> Co-authored-by: Michael Sloan <michael@zed.dev> Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local> Co-authored-by: Mikayla <mikayla.c.maki@gmail.com> Co-authored-by: joão <joao@zed.dev>
This commit is contained in:
parent
21b4a0d50e
commit
6fca1d2b0b
648 changed files with 36248 additions and 28208 deletions
|
@ -8,8 +8,8 @@ use collab_ui::{
|
|||
};
|
||||
use editor::{Editor, ExcerptRange, MultiBuffer};
|
||||
use gpui::{
|
||||
point, BackgroundExecutor, BorrowAppContext, Context, Entity, SharedString, TestAppContext,
|
||||
View, VisualContext, VisualTestContext,
|
||||
point, AppContext as _, BackgroundExecutor, BorrowAppContext, Entity, SharedString,
|
||||
TestAppContext, VisualTestContext,
|
||||
};
|
||||
use language::Capability;
|
||||
use project::WorktreeSettings;
|
||||
|
@ -77,23 +77,23 @@ async fn test_basic_following(
|
|||
let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a);
|
||||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
|
||||
cx_b.update(|cx| {
|
||||
assert!(cx.is_window_active());
|
||||
cx_b.update(|window, _| {
|
||||
assert!(window.is_window_active());
|
||||
});
|
||||
|
||||
// Client A opens some editors.
|
||||
let pane_a = workspace_a.update(cx_a, |workspace, _| workspace.active_pane().clone());
|
||||
let editor_a1 = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
let editor_a2 = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -102,8 +102,8 @@ async fn test_basic_following(
|
|||
|
||||
// Client B opens an editor.
|
||||
let editor_b1 = workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -116,22 +116,24 @@ async fn test_basic_following(
|
|||
let peer_id_d = client_d.peer_id().unwrap();
|
||||
|
||||
// Client A updates their selections in those editors
|
||||
editor_a1.update(cx_a, |editor, cx| {
|
||||
editor.handle_input("a", cx);
|
||||
editor.handle_input("b", cx);
|
||||
editor.handle_input("c", cx);
|
||||
editor.select_left(&Default::default(), cx);
|
||||
editor_a1.update_in(cx_a, |editor, window, cx| {
|
||||
editor.handle_input("a", window, cx);
|
||||
editor.handle_input("b", window, cx);
|
||||
editor.handle_input("c", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![3..2]);
|
||||
});
|
||||
editor_a2.update(cx_a, |editor, cx| {
|
||||
editor.handle_input("d", cx);
|
||||
editor.handle_input("e", cx);
|
||||
editor.select_left(&Default::default(), cx);
|
||||
editor_a2.update_in(cx_a, |editor, window, cx| {
|
||||
editor.handle_input("d", window, cx);
|
||||
editor.handle_input("e", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![2..1]);
|
||||
});
|
||||
|
||||
// When client B starts following client A, only the active view state is replicated to client B.
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(peer_id_a, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_a, window, cx)
|
||||
});
|
||||
|
||||
cx_c.executor().run_until_parked();
|
||||
let editor_b2 = workspace_b.update(cx_b, |workspace, cx| {
|
||||
|
@ -165,7 +167,9 @@ async fn test_basic_following(
|
|||
drop(project_c);
|
||||
|
||||
// Client C also follows client A.
|
||||
workspace_c.update(cx_c, |workspace, cx| workspace.follow(peer_id_a, cx));
|
||||
workspace_c.update_in(cx_c, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_a, window, cx)
|
||||
});
|
||||
|
||||
cx_d.executor().run_until_parked();
|
||||
let active_call_d = cx_d.read(ActiveCall::global);
|
||||
|
@ -188,8 +192,8 @@ async fn test_basic_following(
|
|||
}
|
||||
|
||||
// Client C unfollows client A.
|
||||
workspace_c.update(cx_c, |workspace, cx| {
|
||||
workspace.unfollow(peer_id_a, cx).unwrap();
|
||||
workspace_c.update_in(cx_c, |workspace, window, cx| {
|
||||
workspace.unfollow(peer_id_a, window, cx).unwrap();
|
||||
});
|
||||
|
||||
// All clients see that clients B is following client A.
|
||||
|
@ -203,7 +207,9 @@ async fn test_basic_following(
|
|||
}
|
||||
|
||||
// Client C re-follows client A.
|
||||
workspace_c.update(cx_c, |workspace, cx| workspace.follow(peer_id_a, cx));
|
||||
workspace_c.update_in(cx_c, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_a, window, cx)
|
||||
});
|
||||
|
||||
// All clients see that clients B and C are following client A.
|
||||
cx_c.executor().run_until_parked();
|
||||
|
@ -216,9 +222,13 @@ async fn test_basic_following(
|
|||
}
|
||||
|
||||
// Client D follows client B, then switches to following client C.
|
||||
workspace_d.update(cx_d, |workspace, cx| workspace.follow(peer_id_b, cx));
|
||||
workspace_d.update_in(cx_d, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_b, window, cx)
|
||||
});
|
||||
cx_a.executor().run_until_parked();
|
||||
workspace_d.update(cx_d, |workspace, cx| workspace.follow(peer_id_c, cx));
|
||||
workspace_d.update_in(cx_d, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_c, window, cx)
|
||||
});
|
||||
|
||||
// All clients see that D is following C
|
||||
cx_a.executor().run_until_parked();
|
||||
|
@ -235,8 +245,8 @@ async fn test_basic_following(
|
|||
|
||||
// Client C closes the project.
|
||||
let weak_workspace_c = workspace_c.downgrade();
|
||||
workspace_c.update(cx_c, |workspace, cx| {
|
||||
workspace.close_window(&Default::default(), cx);
|
||||
workspace_c.update_in(cx_c, |workspace, window, cx| {
|
||||
workspace.close_window(&Default::default(), window, cx);
|
||||
});
|
||||
executor.run_until_parked();
|
||||
// are you sure you want to leave the call?
|
||||
|
@ -260,8 +270,8 @@ async fn test_basic_following(
|
|||
}
|
||||
|
||||
// When client A activates a different editor, client B does so as well.
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace.activate_item(&editor_a1, true, true, cx)
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.activate_item(&editor_a1, true, true, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
|
@ -272,7 +282,7 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
// When client A opens a multibuffer, client B does so as well.
|
||||
let multibuffer_a = cx_a.new_model(|cx| {
|
||||
let multibuffer_a = cx_a.new(|cx| {
|
||||
let buffer_a1 = project_a.update(cx, |project, cx| {
|
||||
project
|
||||
.get_open_buffer(&(worktree_id, "1.txt").into(), cx)
|
||||
|
@ -302,11 +312,11 @@ async fn test_basic_following(
|
|||
);
|
||||
result
|
||||
});
|
||||
let multibuffer_editor_a = workspace_a.update(cx_a, |workspace, cx| {
|
||||
let editor = cx.new_view(|cx| {
|
||||
Editor::for_multibuffer(multibuffer_a, Some(project_a.clone()), true, cx)
|
||||
let multibuffer_editor_a = workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
let editor = cx.new(|cx| {
|
||||
Editor::for_multibuffer(multibuffer_a, Some(project_a.clone()), true, window, cx)
|
||||
});
|
||||
workspace.add_item_to_active_pane(Box::new(editor.clone()), None, true, cx);
|
||||
workspace.add_item_to_active_pane(Box::new(editor.clone()), None, true, window, cx);
|
||||
editor
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
@ -324,8 +334,8 @@ async fn test_basic_following(
|
|||
|
||||
// When client A navigates back and forth, client B does so as well.
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.go_back(workspace.active_pane().downgrade(), cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.go_back(workspace.active_pane().downgrade(), window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -338,8 +348,8 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.go_back(workspace.active_pane().downgrade(), cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.go_back(workspace.active_pane().downgrade(), window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -352,8 +362,8 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.go_forward(workspace.active_pane().downgrade(), cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.go_forward(workspace.active_pane().downgrade(), window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -366,8 +376,8 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
// Changes to client A's editor are reflected on client B.
|
||||
editor_a1.update(cx_a, |editor, cx| {
|
||||
editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2]));
|
||||
editor_a1.update_in(cx_a, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| s.select_ranges([1..1, 2..2]));
|
||||
});
|
||||
executor.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
executor.run_until_parked();
|
||||
|
@ -377,13 +387,15 @@ async fn test_basic_following(
|
|||
assert_eq!(editor.selections.ranges(cx), &[1..1, 2..2]);
|
||||
});
|
||||
|
||||
editor_a1.update(cx_a, |editor, cx| editor.set_text("TWO", cx));
|
||||
editor_a1.update_in(cx_a, |editor, window, cx| {
|
||||
editor.set_text("TWO", window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
editor_b1.update(cx_b, |editor, cx| assert_eq!(editor.text(cx), "TWO"));
|
||||
|
||||
editor_a1.update(cx_a, |editor, cx| {
|
||||
editor.change_selections(None, cx, |s| s.select_ranges([3..3]));
|
||||
editor.set_scroll_position(point(0., 100.), cx);
|
||||
editor_a1.update_in(cx_a, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| s.select_ranges([3..3]));
|
||||
editor.set_scroll_position(point(0., 100.), window, cx);
|
||||
});
|
||||
executor.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
executor.run_until_parked();
|
||||
|
@ -392,11 +404,11 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
// After unfollowing, client B stops receiving updates from client A.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.unfollow(peer_id_a, cx).unwrap()
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.unfollow(peer_id_a, window, cx).unwrap()
|
||||
});
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace.activate_item(&editor_a2, true, true, cx)
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.activate_item(&editor_a2, true, true, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
|
@ -408,14 +420,16 @@ async fn test_basic_following(
|
|||
);
|
||||
|
||||
// Client A starts following client B.
|
||||
workspace_a.update(cx_a, |workspace, cx| workspace.follow(peer_id_b, cx));
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_b, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
workspace_a.update(cx_a, |workspace, _| workspace.leader_for_pane(&pane_a)),
|
||||
Some(peer_id_b)
|
||||
);
|
||||
assert_eq!(
|
||||
workspace_a.update(cx_a, |workspace, cx| workspace
|
||||
workspace_a.update_in(cx_a, |workspace, _, cx| workspace
|
||||
.active_item(cx)
|
||||
.unwrap()
|
||||
.item_id()),
|
||||
|
@ -471,8 +485,8 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
// Client B activates a multibuffer that was created by following client A. Client A returns to that multibuffer.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.activate_item(&multibuffer_editor_b, true, true, cx)
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.activate_item(&multibuffer_editor_b, true, true, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
|
@ -483,10 +497,10 @@ async fn test_basic_following(
|
|||
});
|
||||
|
||||
// Client B activates a panel, and the previously-opened screen-sharing item gets activated.
|
||||
let panel = cx_b.new_view(|cx| TestPanel::new(DockPosition::Left, cx));
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.add_panel(panel, cx);
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
let panel = cx_b.new(|cx| TestPanel::new(DockPosition::Left, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.add_panel(panel, window, cx);
|
||||
workspace.toggle_panel_focus::<TestPanel>(window, cx);
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
|
@ -498,8 +512,8 @@ async fn test_basic_following(
|
|||
);
|
||||
|
||||
// Toggling the focus back to the pane causes client A to return to the multibuffer.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(window, cx);
|
||||
});
|
||||
executor.run_until_parked();
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
|
@ -511,10 +525,10 @@ async fn test_basic_following(
|
|||
|
||||
// Client B activates an item that doesn't implement following,
|
||||
// so the previously-opened screen-sharing item gets activated.
|
||||
let unfollowable_item = cx_b.new_view(TestItem::new);
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
let unfollowable_item = cx_b.new(TestItem::new);
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
pane.add_item(Box::new(unfollowable_item), true, true, None, cx)
|
||||
pane.add_item(Box::new(unfollowable_item), true, true, None, window, cx)
|
||||
})
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
@ -593,19 +607,19 @@ async fn test_following_tab_order(
|
|||
|
||||
//Open 1, 3 in that order on client A
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "3.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "3.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let pane_paths = |pane: &View<workspace::Pane>, cx: &mut VisualTestContext| {
|
||||
let pane_paths = |pane: &Entity<workspace::Pane>, cx: &mut VisualTestContext| {
|
||||
pane.update(cx, |pane, cx| {
|
||||
pane.items()
|
||||
.map(|item| {
|
||||
|
@ -624,13 +638,15 @@ async fn test_following_tab_order(
|
|||
assert_eq!(&pane_paths(&pane_a, cx_a), &["1.txt", "3.txt"]);
|
||||
|
||||
//Follow client B as client A
|
||||
workspace_a.update(cx_a, |workspace, cx| workspace.follow(client_b_id, cx));
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.follow(client_b_id, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
||||
//Open just 2 on client B
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -641,8 +657,8 @@ async fn test_following_tab_order(
|
|||
|
||||
//Open just 1 on client B
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -701,8 +717,8 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
// Client A opens a file.
|
||||
let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a);
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -712,8 +728,8 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
// Client B opens a different file.
|
||||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -721,24 +737,38 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
.unwrap();
|
||||
|
||||
// Clients A and B follow each other in split panes
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace.split_and_clone(workspace.active_pane().clone(), SplitDirection::Right, cx);
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.split_and_clone(
|
||||
workspace.active_pane().clone(),
|
||||
SplitDirection::Right,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace.follow(client_b.peer_id().unwrap(), cx)
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.follow(client_b.peer_id().unwrap(), window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.split_and_clone(workspace.active_pane().clone(), SplitDirection::Right, cx);
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.split_and_clone(
|
||||
workspace.active_pane().clone(),
|
||||
SplitDirection::Right,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.follow(client_a.peer_id().unwrap(), cx)
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(client_a.peer_id().unwrap(), window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
||||
// Clients A and B return focus to the original files they had open
|
||||
workspace_a.update(cx_a, |workspace, cx| workspace.activate_next_pane(cx));
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.activate_next_pane(cx));
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.activate_next_pane(window, cx)
|
||||
});
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.activate_next_pane(window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
||||
// Both clients see the other client's focused file in their right pane.
|
||||
|
@ -775,15 +805,15 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
|
||||
// Clients A and B each open a new file.
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "3.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "3.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "4.txt"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "4.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -831,7 +861,9 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
);
|
||||
|
||||
// Client A focuses their right pane, in which they're following client B.
|
||||
workspace_a.update(cx_a, |workspace, cx| workspace.activate_next_pane(cx));
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.activate_next_pane(window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
||||
// Client B sees that client A is now looking at the same file as them.
|
||||
|
@ -877,7 +909,9 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
|
||||
// Client B focuses their right pane, in which they're following client A,
|
||||
// who is following them.
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.activate_next_pane(cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.activate_next_pane(window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
||||
// Client A sees that client B is now looking at the same file as them.
|
||||
|
@ -923,9 +957,9 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
|
||||
// Client B focuses a file that they previously followed A to, breaking
|
||||
// the follow.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
pane.activate_prev_item(true, cx);
|
||||
pane.activate_prev_item(true, window, cx);
|
||||
});
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
@ -974,9 +1008,9 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
|
||||
// Client B closes tabs, some of which were originally opened by client A,
|
||||
// and some of which were originally opened by client B.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
pane.close_inactive_items(&Default::default(), cx)
|
||||
pane.close_inactive_items(&Default::default(), window, cx)
|
||||
.unwrap()
|
||||
.detach();
|
||||
});
|
||||
|
@ -1022,14 +1056,14 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
);
|
||||
|
||||
// Client B follows client A again.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.follow(client_a.peer_id().unwrap(), cx)
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(client_a.peer_id().unwrap(), window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
// Client A cycles through some tabs.
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
pane.activate_prev_item(true, cx);
|
||||
pane.activate_prev_item(true, window, cx);
|
||||
});
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
@ -1071,9 +1105,9 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
]
|
||||
);
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
pane.activate_prev_item(true, cx);
|
||||
pane.activate_prev_item(true, window, cx);
|
||||
});
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
@ -1118,9 +1152,9 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
]
|
||||
);
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
pane.activate_prev_item(true, cx);
|
||||
pane.activate_prev_item(true, window, cx);
|
||||
});
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
@ -1215,8 +1249,8 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
|
||||
let _editor_a1 = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -1228,7 +1262,9 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
let leader_id = project_b.update(cx_b, |project, _| {
|
||||
project.collaborators().values().next().unwrap().peer_id
|
||||
});
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(leader_id, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(leader_id, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
|
@ -1243,15 +1279,17 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
});
|
||||
|
||||
// When client B moves, it automatically stops following client A.
|
||||
editor_b2.update(cx_b, |editor, cx| {
|
||||
editor.move_right(&editor::actions::MoveRight, cx)
|
||||
editor_b2.update_in(cx_b, |editor, window, cx| {
|
||||
editor.move_right(&editor::actions::MoveRight, window, cx)
|
||||
});
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
None
|
||||
);
|
||||
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(leader_id, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(leader_id, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
|
@ -1259,13 +1297,15 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
);
|
||||
|
||||
// When client B edits, it automatically stops following client A.
|
||||
editor_b2.update(cx_b, |editor, cx| editor.insert("X", cx));
|
||||
editor_b2.update_in(cx_b, |editor, window, cx| editor.insert("X", window, cx));
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
workspace_b.update_in(cx_b, |workspace, _, _| workspace.leader_for_pane(&pane_b)),
|
||||
None
|
||||
);
|
||||
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(leader_id, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(leader_id, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
|
@ -1273,15 +1313,17 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
);
|
||||
|
||||
// When client B scrolls, it automatically stops following client A.
|
||||
editor_b2.update(cx_b, |editor, cx| {
|
||||
editor.set_scroll_position(point(0., 3.), cx)
|
||||
editor_b2.update_in(cx_b, |editor, window, cx| {
|
||||
editor.set_scroll_position(point(0., 3.), window, cx)
|
||||
});
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
None
|
||||
);
|
||||
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(leader_id, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(leader_id, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
|
@ -1289,15 +1331,17 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
);
|
||||
|
||||
// When client B activates a different pane, it continues following client A in the original pane.
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.split_and_clone(pane_b.clone(), SplitDirection::Right, cx)
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.split_and_clone(pane_b.clone(), SplitDirection::Right, window, cx)
|
||||
});
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
Some(leader_id)
|
||||
);
|
||||
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.activate_next_pane(cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.activate_next_pane(window, cx)
|
||||
});
|
||||
assert_eq!(
|
||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||
Some(leader_id)
|
||||
|
@ -1305,8 +1349,8 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||
|
||||
// When client B activates a different item in the original pane, it automatically stops following client A.
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1352,8 +1396,12 @@ async fn test_peers_simultaneously_following_each_other(
|
|||
project.collaborators().values().next().unwrap().peer_id
|
||||
});
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| workspace.follow(client_b_id, cx));
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(client_a_id, cx));
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.follow(client_b_id, window, cx)
|
||||
});
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(client_a_id, window, cx)
|
||||
});
|
||||
executor.run_until_parked();
|
||||
|
||||
workspace_a.update(cx_a, |workspace, _| {
|
||||
|
@ -1434,8 +1482,8 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
.unwrap();
|
||||
|
||||
workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id_a, "w.rs"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id_a, "w.rs"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1443,8 +1491,8 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
executor.run_until_parked();
|
||||
assert_eq!(visible_push_notifications(cx_b).len(), 1);
|
||||
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
workspace.follow(client_a.peer_id().unwrap(), cx)
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(client_a.peer_id().unwrap(), window, cx)
|
||||
});
|
||||
|
||||
executor.run_until_parked();
|
||||
|
@ -1490,8 +1538,8 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
|
||||
// b moves to x.rs in a's project, and a follows
|
||||
workspace_b_project_a
|
||||
.update(&mut cx_b2, |workspace, cx| {
|
||||
workspace.open_path((worktree_id_a, "x.rs"), None, true, cx)
|
||||
.update_in(&mut cx_b2, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id_a, "x.rs"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1505,8 +1553,8 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
);
|
||||
});
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
workspace.follow(client_b.peer_id().unwrap(), cx)
|
||||
workspace_a.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.follow(client_b.peer_id().unwrap(), window, cx)
|
||||
});
|
||||
|
||||
executor.run_until_parked();
|
||||
|
@ -1522,8 +1570,8 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
|
||||
// b moves to y.rs in b's project, a is still following but can't yet see
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id_b, "y.rs"), None, true, cx)
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id_b, "y.rs"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1544,7 +1592,7 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
|
||||
executor.run_until_parked();
|
||||
assert_eq!(visible_push_notifications(cx_a).len(), 1);
|
||||
cx_a.update(|cx| {
|
||||
cx_a.update(|_, cx| {
|
||||
workspace::join_in_room_project(
|
||||
project_b_id,
|
||||
client_b.user_id().unwrap(),
|
||||
|
@ -1607,8 +1655,8 @@ async fn test_following_stops_on_unshare(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
});
|
||||
|
||||
// b should follow a to position 1
|
||||
editor_a.update(cx_a, |editor, cx| {
|
||||
editor.change_selections(None, cx, |s| s.select_ranges([1..1]))
|
||||
editor_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| s.select_ranges([1..1]))
|
||||
});
|
||||
cx_a.executor()
|
||||
.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
|
@ -1618,7 +1666,7 @@ async fn test_following_stops_on_unshare(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
});
|
||||
|
||||
// a unshares the project
|
||||
cx_a.update(|cx| {
|
||||
cx_a.update(|_, cx| {
|
||||
let project = workspace_a.read(cx).project().clone();
|
||||
ActiveCall::global(cx).update(cx, |call, cx| {
|
||||
call.unshare_project(project, cx).unwrap();
|
||||
|
@ -1627,8 +1675,8 @@ async fn test_following_stops_on_unshare(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
cx_a.run_until_parked();
|
||||
|
||||
// b should not follow a to position 2
|
||||
editor_a.update(cx_a, |editor, cx| {
|
||||
editor.change_selections(None, cx, |s| s.select_ranges([2..2]))
|
||||
editor_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| s.select_ranges([2..2]))
|
||||
});
|
||||
cx_a.executor()
|
||||
.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
|
@ -1636,7 +1684,7 @@ async fn test_following_stops_on_unshare(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
editor_b.update(cx_b, |editor, cx| {
|
||||
assert_eq!(editor.selections.ranges(cx), vec![1..1])
|
||||
});
|
||||
cx_b.update(|cx| {
|
||||
cx_b.update(|_, cx| {
|
||||
let room = ActiveCall::global(cx).read(cx).room().unwrap().read(cx);
|
||||
let participant = room.remote_participants().get(&client_a.id()).unwrap();
|
||||
assert_eq!(participant.location, ParticipantLocation::UnsharedProject)
|
||||
|
@ -1703,16 +1751,16 @@ async fn test_following_into_excluded_file(
|
|||
|
||||
// Client A opens editors for a regular file and an excluded file.
|
||||
let editor_for_regular = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
let editor_for_excluded_a = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, ".git/COMMIT_EDITMSG"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, ".git/COMMIT_EDITMSG"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -1720,22 +1768,24 @@ async fn test_following_into_excluded_file(
|
|||
.unwrap();
|
||||
|
||||
// Client A updates their selections in those editors
|
||||
editor_for_regular.update(cx_a, |editor, cx| {
|
||||
editor.handle_input("a", cx);
|
||||
editor.handle_input("b", cx);
|
||||
editor.handle_input("c", cx);
|
||||
editor.select_left(&Default::default(), cx);
|
||||
editor_for_regular.update_in(cx_a, |editor, window, cx| {
|
||||
editor.handle_input("a", window, cx);
|
||||
editor.handle_input("b", window, cx);
|
||||
editor.handle_input("c", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![3..2]);
|
||||
});
|
||||
editor_for_excluded_a.update(cx_a, |editor, cx| {
|
||||
editor.select_all(&Default::default(), cx);
|
||||
editor.handle_input("new commit message", cx);
|
||||
editor.select_left(&Default::default(), cx);
|
||||
editor_for_excluded_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.select_all(&Default::default(), window, cx);
|
||||
editor.handle_input("new commit message", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![18..17]);
|
||||
});
|
||||
|
||||
// When client B starts following client A, currently visible file is replicated
|
||||
workspace_b.update(cx_b, |workspace, cx| workspace.follow(peer_id_a, cx));
|
||||
workspace_b.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.follow(peer_id_a, window, cx)
|
||||
});
|
||||
executor.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
executor.run_until_parked();
|
||||
|
||||
|
@ -1755,15 +1805,15 @@ async fn test_following_into_excluded_file(
|
|||
vec![18..17]
|
||||
);
|
||||
|
||||
editor_for_excluded_a.update(cx_a, |editor, cx| {
|
||||
editor.select_right(&Default::default(), cx);
|
||||
editor_for_excluded_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.select_right(&Default::default(), window, cx);
|
||||
});
|
||||
executor.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
executor.run_until_parked();
|
||||
|
||||
// Changes from B to the excluded file are replicated in A's editor
|
||||
editor_for_excluded_b.update(cx_b, |editor, cx| {
|
||||
editor.handle_input("\nCo-Authored-By: B <b@b.b>", cx);
|
||||
editor_for_excluded_b.update_in(cx_b, |editor, window, cx| {
|
||||
editor.handle_input("\nCo-Authored-By: B <b@b.b>", window, cx);
|
||||
});
|
||||
executor.run_until_parked();
|
||||
editor_for_excluded_a.update(cx_a, |editor, cx| {
|
||||
|
@ -1774,13 +1824,11 @@ async fn test_following_into_excluded_file(
|
|||
});
|
||||
}
|
||||
|
||||
fn visible_push_notifications(
|
||||
cx: &mut TestAppContext,
|
||||
) -> Vec<gpui::View<ProjectSharedNotification>> {
|
||||
fn visible_push_notifications(cx: &mut TestAppContext) -> Vec<Entity<ProjectSharedNotification>> {
|
||||
let mut ret = Vec::new();
|
||||
for window in cx.windows() {
|
||||
window
|
||||
.update(cx, |window, _| {
|
||||
.update(cx, |window, _, _| {
|
||||
if let Ok(handle) = window.downcast::<ProjectSharedNotification>() {
|
||||
ret.push(handle)
|
||||
}
|
||||
|
@ -1821,7 +1869,7 @@ fn followers_by_leader(project_id: u64, cx: &TestAppContext) -> Vec<(PeerId, Vec
|
|||
})
|
||||
}
|
||||
|
||||
fn pane_summaries(workspace: &View<Workspace>, cx: &mut VisualTestContext) -> Vec<PaneSummary> {
|
||||
fn pane_summaries(workspace: &Entity<Workspace>, cx: &mut VisualTestContext) -> Vec<PaneSummary> {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let active_pane = workspace.active_pane();
|
||||
workspace
|
||||
|
@ -1924,14 +1972,14 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
|||
|
||||
// Client A opens the notes for channel 1.
|
||||
let channel_notes_1_a = cx_a
|
||||
.update(|cx| ChannelView::open(channel_1_id, None, workspace_a.clone(), cx))
|
||||
.update(|window, cx| ChannelView::open(channel_1_id, None, workspace_a.clone(), window, cx))
|
||||
.await
|
||||
.unwrap();
|
||||
channel_notes_1_a.update(cx_a, |notes, cx| {
|
||||
channel_notes_1_a.update_in(cx_a, |notes, window, cx| {
|
||||
assert_eq!(notes.channel(cx).unwrap().name, "channel-1");
|
||||
notes.editor.update(cx, |editor, cx| {
|
||||
editor.insert("Hello from A.", cx);
|
||||
editor.change_selections(None, cx, |selections| {
|
||||
editor.insert("Hello from A.", window, cx);
|
||||
editor.change_selections(None, window, cx, |selections| {
|
||||
selections.select_ranges(vec![3..4]);
|
||||
});
|
||||
});
|
||||
|
@ -1939,9 +1987,9 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
|||
|
||||
// Client B follows client A.
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace
|
||||
.start_following(client_a.peer_id().unwrap(), cx)
|
||||
.start_following(client_a.peer_id().unwrap(), window, cx)
|
||||
.unwrap()
|
||||
})
|
||||
.await
|
||||
|
@ -1971,7 +2019,7 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
|||
|
||||
// Client A opens the notes for channel 2.
|
||||
let channel_notes_2_a = cx_a
|
||||
.update(|cx| ChannelView::open(channel_2_id, None, workspace_a.clone(), cx))
|
||||
.update(|window, cx| ChannelView::open(channel_2_id, None, workspace_a.clone(), window, cx))
|
||||
.await
|
||||
.unwrap();
|
||||
channel_notes_2_a.update(cx_a, |notes, cx| {
|
||||
|
@ -1997,8 +2045,8 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
|||
|
||||
// Client A opens a local buffer in their unshared project.
|
||||
let _unshared_editor_a1 = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, cx)
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), None, true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -2027,7 +2075,7 @@ pub(crate) async fn join_channel(
|
|||
}
|
||||
|
||||
async fn share_workspace(
|
||||
workspace: &View<Workspace>,
|
||||
workspace: &Entity<Workspace>,
|
||||
cx: &mut VisualTestContext,
|
||||
) -> anyhow::Result<u64> {
|
||||
let project = workspace.update(cx, |workspace, _| workspace.project().clone());
|
||||
|
@ -2069,9 +2117,9 @@ async fn test_following_to_channel_notes_other_workspace(
|
|||
|
||||
// a opens a second workspace and the channel notes
|
||||
let (workspace_a2, cx_a2) = client_a.build_test_workspace(&mut cx_a2).await;
|
||||
cx_a2.update(|cx| cx.activate_window());
|
||||
cx_a2.update(|window, _| window.activate_window());
|
||||
cx_a2
|
||||
.update(|cx| ChannelView::open(channel, None, workspace_a2, cx))
|
||||
.update(|window, cx| ChannelView::open(channel, None, workspace_a2, window, cx))
|
||||
.await
|
||||
.unwrap();
|
||||
cx_a2.run_until_parked();
|
||||
|
@ -2083,7 +2131,7 @@ async fn test_following_to_channel_notes_other_workspace(
|
|||
});
|
||||
|
||||
// a returns to the shared project
|
||||
cx_a.update(|cx| cx.activate_window());
|
||||
cx_a.update(|window, _| window.activate_window());
|
||||
cx_a.run_until_parked();
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
|
@ -2141,7 +2189,7 @@ async fn test_following_while_deactivated(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
|
||||
// a opens a file in a new window
|
||||
let (_, cx_a2) = client_a.build_test_workspace(&mut cx_a2).await;
|
||||
cx_a2.update(|cx| cx.activate_window());
|
||||
cx_a2.update(|window, _| window.activate_window());
|
||||
cx_a2.simulate_keystrokes("cmd-p");
|
||||
cx_a2.run_until_parked();
|
||||
cx_a2.simulate_keystrokes("3 enter");
|
||||
|
@ -2152,7 +2200,7 @@ async fn test_following_while_deactivated(cx_a: &mut TestAppContext, cx_b: &mut
|
|||
cx_a.run_until_parked();
|
||||
|
||||
// a returns to the shared project
|
||||
cx_a.update(|cx| cx.activate_window());
|
||||
cx_a.update(|window, _| window.activate_window());
|
||||
cx_a.run_until_parked();
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue