WIP
This commit is contained in:
parent
3c938a7377
commit
afcc0d621b
13 changed files with 300 additions and 262 deletions
|
@ -64,7 +64,7 @@ fn test_edit_events(cx: &mut TestAppContext) {
|
||||||
Editor::for_buffer(buffer.clone(), None, cx)
|
Editor::for_buffer(buffer.clone(), None, cx)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let editor2 = cx
|
let editor2 = cx
|
||||||
.add_window({
|
.add_window({
|
||||||
let events = events.clone();
|
let events = events.clone();
|
||||||
|
@ -81,7 +81,7 @@ fn test_edit_events(cx: &mut TestAppContext) {
|
||||||
Editor::for_buffer(buffer.clone(), None, cx)
|
Editor::for_buffer(buffer.clone(), None, cx)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
assert_eq!(mem::take(&mut *events.borrow_mut()), []);
|
assert_eq!(mem::take(&mut *events.borrow_mut()), []);
|
||||||
|
|
||||||
// Mutating editor 1 will emit an `Edited` event only for that editor.
|
// Mutating editor 1 will emit an `Edited` event only for that editor.
|
||||||
|
@ -179,7 +179,7 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
let editor = cx
|
let editor = cx
|
||||||
.add_window(|cx| build_editor(buffer.clone(), cx))
|
.add_window(|cx| build_editor(buffer.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.start_transaction_at(now, cx);
|
editor.start_transaction_at(now, cx);
|
||||||
|
@ -354,7 +354,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx);
|
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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);
|
||||||
});
|
});
|
||||||
|
@ -423,7 +423,7 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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);
|
||||||
|
@ -471,7 +471,7 @@ fn test_clone(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&text, cx);
|
let buffer = MultiBuffer::build_simple(&text, cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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()));
|
||||||
|
@ -489,7 +489,7 @@ fn test_clone(cx: &mut TestAppContext) {
|
||||||
.update(cx, |editor, cx| {
|
.update(cx, |editor, cx| {
|
||||||
cx.add_window(Default::default(), |cx| editor.clone(cx))
|
cx.add_window(Default::default(), |cx| editor.clone(cx))
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
let snapshot = editor.update(cx, |e, cx| e.snapshot(cx));
|
let snapshot = editor.update(cx, |e, cx| e.snapshot(cx));
|
||||||
let cloned_snapshot = cloned_editor.update(cx, |e, cx| e.snapshot(cx));
|
let cloned_snapshot = cloned_editor.update(cx, |e, cx| e.snapshot(cx));
|
||||||
|
@ -639,7 +639,7 @@ fn test_cancel(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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);
|
||||||
|
@ -704,7 +704,7 @@ fn test_fold_action(cx: &mut TestAppContext) {
|
||||||
);
|
);
|
||||||
build_editor(buffer.clone(), cx)
|
build_editor(buffer.clone(), cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
|
@ -774,7 +774,7 @@ fn test_move_cursor(cx: &mut TestAppContext) {
|
||||||
let buffer = cx.update(|cx| MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx));
|
let buffer = cx.update(|cx| MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx));
|
||||||
let view = cx
|
let view = cx
|
||||||
.add_window(|cx| build_editor(buffer.clone(), cx))
|
.add_window(|cx| build_editor(buffer.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
buffer.update(cx, |buffer, cx| {
|
||||||
buffer.edit(
|
buffer.edit(
|
||||||
|
@ -854,7 +854,7 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx);
|
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx);
|
||||||
build_editor(buffer.clone(), cx)
|
build_editor(buffer.clone(), cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
assert_eq!('ⓐ'.len_utf8(), 3);
|
assert_eq!('ⓐ'.len_utf8(), 3);
|
||||||
assert_eq!('α'.len_utf8(), 2);
|
assert_eq!('α'.len_utf8(), 2);
|
||||||
|
@ -961,7 +961,7 @@ fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx);
|
let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx);
|
||||||
build_editor(buffer.clone(), cx)
|
build_editor(buffer.clone(), cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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())]);
|
||||||
|
@ -1013,7 +1013,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\n def", cx);
|
let buffer = MultiBuffer::build_simple("abc\n def", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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([
|
||||||
|
@ -1178,7 +1178,7 @@ fn test_prev_next_word_boundary(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx);
|
let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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([
|
||||||
|
@ -1233,7 +1233,7 @@ fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) {
|
||||||
MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx);
|
MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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);
|
||||||
|
@ -1568,7 +1568,7 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("one two three four", cx);
|
let buffer = MultiBuffer::build_simple("one two three four", cx);
|
||||||
build_editor(buffer.clone(), cx)
|
build_editor(buffer.clone(), cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
|
@ -1606,7 +1606,7 @@ fn test_newline(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx);
|
let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx);
|
||||||
build_editor(buffer.clone(), cx)
|
build_editor(buffer.clone(), cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
|
@ -1651,7 +1651,7 @@ fn test_newline_with_old_selections(cx: &mut TestAppContext) {
|
||||||
});
|
});
|
||||||
editor
|
editor
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
||||||
|
@ -1863,7 +1863,7 @@ fn test_insert_with_old_selections(cx: &mut TestAppContext) {
|
||||||
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
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
// Edit the buffer directly, deleting ranges surrounding the editor's selections
|
||||||
|
@ -2375,7 +2375,7 @@ fn test_delete_line(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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([
|
||||||
|
@ -2400,7 +2400,7 @@ fn test_delete_line(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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)])
|
||||||
|
@ -2704,7 +2704,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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([
|
||||||
|
@ -2732,7 +2732,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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([
|
||||||
|
@ -2761,7 +2761,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.fold_ranges(
|
view.fold_ranges(
|
||||||
vec![
|
vec![
|
||||||
|
@ -2862,7 +2862,7 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
let snapshot = editor.buffer.read(cx).snapshot(cx);
|
let snapshot = editor.buffer.read(cx).snapshot(cx);
|
||||||
editor.insert_blocks(
|
editor.insert_blocks(
|
||||||
|
@ -3182,7 +3182,7 @@ fn test_select_all(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx);
|
let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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!(
|
||||||
|
@ -3201,7 +3201,7 @@ fn test_select_line(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(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([
|
||||||
|
@ -3250,7 +3250,7 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.fold_ranges(
|
view.fold_ranges(
|
||||||
vec![
|
vec![
|
||||||
|
@ -3323,7 +3323,7 @@ fn test_add_selection_above_below(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx);
|
let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx);
|
||||||
build_editor(buffer, cx)
|
build_editor(buffer, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.change_selections(None, cx, |s| {
|
view.change_selections(None, cx, |s| {
|
||||||
|
@ -3608,7 +3608,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx);
|
let view = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -3771,7 +3771,7 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) {
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
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(|cx| build_editor(buffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
editor
|
editor
|
||||||
.condition(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx))
|
.condition(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx))
|
||||||
.await;
|
.await;
|
||||||
|
@ -4334,7 +4334,7 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) {
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx);
|
let view = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -4482,7 +4482,7 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) {
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
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(|cx| build_editor(buffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
editor
|
editor
|
||||||
.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
||||||
.await;
|
.await;
|
||||||
|
@ -4572,7 +4572,7 @@ async fn test_snippets(cx: &mut gpui::TestAppContext) {
|
||||||
);
|
);
|
||||||
|
|
||||||
let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx));
|
let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx));
|
||||||
let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap();
|
let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap();
|
||||||
|
@ -4702,7 +4702,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
||||||
let fake_server = fake_servers.next().await.unwrap();
|
let fake_server = fake_servers.next().await.unwrap();
|
||||||
|
|
||||||
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(|cx| build_editor(buffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||||
assert!(cx.read(|cx| editor.is_dirty(cx)));
|
assert!(cx.read(|cx| editor.is_dirty(cx)));
|
||||||
|
|
||||||
|
@ -4814,7 +4814,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
||||||
let fake_server = fake_servers.next().await.unwrap();
|
let fake_server = fake_servers.next().await.unwrap();
|
||||||
|
|
||||||
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(|cx| build_editor(buffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||||
assert!(cx.read(|cx| editor.is_dirty(cx)));
|
assert!(cx.read(|cx| editor.is_dirty(cx)));
|
||||||
|
|
||||||
|
@ -4928,7 +4928,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
||||||
let fake_server = fake_servers.next().await.unwrap();
|
let fake_server = fake_servers.next().await.unwrap();
|
||||||
|
|
||||||
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(|cx| build_editor(buffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||||
|
|
||||||
let format = editor.update(cx, |editor, cx| {
|
let format = editor.update(cx, |editor, cx| {
|
||||||
|
@ -5706,7 +5706,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
|
|
||||||
let view = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx);
|
let view = cx.add_window(|cx| build_editor(multibuffer, cx)).root(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| {
|
||||||
|
@ -5776,7 +5776,7 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
|
|
||||||
let view = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx);
|
let view = cx.add_window(|cx| build_editor(multibuffer, cx)).root(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! {"
|
||||||
|
@ -5869,7 +5869,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
|
||||||
);
|
);
|
||||||
editor
|
editor
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
// Refreshing selections is a no-op when excerpts haven't changed.
|
// Refreshing selections is a no-op when excerpts haven't changed.
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
|
@ -5950,7 +5950,7 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) {
|
||||||
);
|
);
|
||||||
editor
|
editor
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
multibuffer.update(cx, |multibuffer, cx| {
|
multibuffer.update(cx, |multibuffer, cx| {
|
||||||
multibuffer.remove_excerpts([excerpt1_id.unwrap()], cx);
|
multibuffer.remove_excerpts([excerpt1_id.unwrap()], cx);
|
||||||
|
@ -6013,7 +6013,7 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) {
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx);
|
let view = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -6054,7 +6054,7 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx);
|
||||||
build_editor(buffer.clone(), cx)
|
build_editor(buffer.clone(), cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
struct Type1;
|
struct Type1;
|
||||||
|
@ -6145,7 +6145,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
|
||||||
});
|
});
|
||||||
let leader = cx
|
let leader = cx
|
||||||
.add_window(|cx| build_editor(buffer.clone(), cx))
|
.add_window(|cx| build_editor(buffer.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let follower = cx
|
let follower = cx
|
||||||
.update(|cx| {
|
.update(|cx| {
|
||||||
cx.add_window(
|
cx.add_window(
|
||||||
|
@ -6156,7 +6156,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
|
||||||
|cx| build_editor(buffer.clone(), cx),
|
|cx| build_editor(buffer.clone(), cx),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
let is_still_following = Rc::new(RefCell::new(true));
|
let is_still_following = Rc::new(RefCell::new(true));
|
||||||
let follower_edit_event_count = Rc::new(RefCell::new(0));
|
let follower_edit_event_count = Rc::new(RefCell::new(0));
|
||||||
|
@ -6289,7 +6289,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) {
|
||||||
let project = Project::test(fs, ["/file.rs".as_ref()], cx).await;
|
let project = Project::test(fs, ["/file.rs".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
let leader = pane.update(cx, |_, cx| {
|
let leader = pane.update(cx, |_, cx| {
|
||||||
|
@ -7033,7 +7033,7 @@ async fn test_copilot_multibuffer(
|
||||||
);
|
);
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).root(cx);
|
||||||
|
|
||||||
handle_copilot_completion_request(
|
handle_copilot_completion_request(
|
||||||
&copilot_lsp,
|
&copilot_lsp,
|
||||||
|
@ -7163,7 +7163,7 @@ async fn test_copilot_disabled_globs(
|
||||||
);
|
);
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx);
|
let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).root(cx);
|
||||||
|
|
||||||
let mut copilot_requests = copilot_lsp
|
let mut copilot_requests = copilot_lsp
|
||||||
.handle_request::<copilot::request::GetCompletions, _, _>(move |_params, _cx| async move {
|
.handle_request::<copilot::request::GetCompletions, _, _>(move |_params, _cx| async move {
|
||||||
|
@ -7244,7 +7244,7 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
||||||
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||||
workspace.project().read_with(cx, |project, cx| {
|
workspace.project().read_with(cx, |project, cx| {
|
||||||
project.worktrees(cx).next().unwrap().read(cx).id()
|
project.worktrees(cx).next().unwrap().read(cx).id()
|
||||||
|
|
|
@ -3007,7 +3007,7 @@ mod tests {
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), 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)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.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| {
|
||||||
|
@ -3028,7 +3028,7 @@ mod tests {
|
||||||
let buffer = MultiBuffer::build_simple("", cx);
|
let buffer = MultiBuffer::build_simple("", cx);
|
||||||
Editor::new(EditorMode::Full, buffer, None, None, cx)
|
Editor::new(EditorMode::Full, buffer, None, None, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.set_placeholder_text("hello", cx);
|
editor.set_placeholder_text("hello", cx);
|
||||||
|
@ -3240,7 +3240,7 @@ mod tests {
|
||||||
let buffer = MultiBuffer::build_simple(&input_text, cx);
|
let buffer = MultiBuffer::build_simple(&input_text, cx);
|
||||||
Editor::new(editor_mode, buffer, None, None, cx)
|
Editor::new(editor_mode, buffer, None, None, cx)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx)));
|
let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx)));
|
||||||
let (_, layout_state) = editor.update(cx, |editor, cx| {
|
let (_, layout_state) = editor.update(cx, |editor, cx| {
|
||||||
|
|
|
@ -1138,7 +1138,7 @@ mod tests {
|
||||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||||
workspace.project().read_with(cx, |project, cx| {
|
workspace.project().read_with(cx, |project, cx| {
|
||||||
project.worktrees(cx).next().unwrap().read(cx).id()
|
project.worktrees(cx).next().unwrap().read(cx).id()
|
||||||
|
@ -1840,7 +1840,7 @@ mod tests {
|
||||||
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||||
workspace.project().read_with(cx, |project, cx| {
|
workspace.project().read_with(cx, |project, cx| {
|
||||||
project.worktrees(cx).next().unwrap().read(cx).id()
|
project.worktrees(cx).next().unwrap().read(cx).id()
|
||||||
|
@ -1995,7 +1995,7 @@ mod tests {
|
||||||
});
|
});
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||||
workspace.project().read_with(cx, |project, cx| {
|
workspace.project().read_with(cx, |project, cx| {
|
||||||
project.worktrees(cx).next().unwrap().read(cx).id()
|
project.worktrees(cx).next().unwrap().read(cx).id()
|
||||||
|
@ -2083,7 +2083,7 @@ mod tests {
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
let editor = cx
|
let editor = cx
|
||||||
.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx))
|
.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let editor_edited = Arc::new(AtomicBool::new(false));
|
let editor_edited = Arc::new(AtomicBool::new(false));
|
||||||
let fake_server = fake_servers.next().await.unwrap();
|
let fake_server = fake_servers.next().await.unwrap();
|
||||||
let closure_editor_edited = Arc::clone(&editor_edited);
|
let closure_editor_edited = Arc::clone(&editor_edited);
|
||||||
|
@ -2337,7 +2337,7 @@ all hints should be invalidated and requeried for all of its visible excerpts"
|
||||||
});
|
});
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||||
workspace.project().read_with(cx, |project, cx| {
|
workspace.project().read_with(cx, |project, cx| {
|
||||||
project.worktrees(cx).next().unwrap().read(cx).id()
|
project.worktrees(cx).next().unwrap().read(cx).id()
|
||||||
|
@ -2384,7 +2384,7 @@ all hints should be invalidated and requeried for all of its visible excerpts"
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
let editor = cx
|
let editor = cx
|
||||||
.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx))
|
.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let editor_edited = Arc::new(AtomicBool::new(false));
|
let editor_edited = Arc::new(AtomicBool::new(false));
|
||||||
let fake_server = fake_servers.next().await.unwrap();
|
let fake_server = fake_servers.next().await.unwrap();
|
||||||
let closure_editor_edited = Arc::clone(&editor_edited);
|
let closure_editor_edited = Arc::clone(&editor_edited);
|
||||||
|
@ -2574,7 +2574,7 @@ all hints should be invalidated and requeried for all of its visible excerpts"
|
||||||
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||||
workspace.project().read_with(cx, |project, cx| {
|
workspace.project().read_with(cx, |project, cx| {
|
||||||
project.worktrees(cx).next().unwrap().read(cx).id()
|
project.worktrees(cx).next().unwrap().read(cx).id()
|
||||||
|
|
|
@ -842,7 +842,7 @@ mod tests {
|
||||||
let project = Project::test(app_state.fs.clone(), ["/dir".as_ref()], cx).await;
|
let project = Project::test(app_state.fs.clone(), ["/dir".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let finder = cx
|
let finder = cx
|
||||||
.add_window(|cx| {
|
.add_window(|cx| {
|
||||||
Picker::new(
|
Picker::new(
|
||||||
|
@ -856,7 +856,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
let query = test_path_like("hi");
|
let query = test_path_like("hi");
|
||||||
finder
|
finder
|
||||||
|
@ -940,7 +940,7 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let finder = cx
|
let finder = cx
|
||||||
.add_window(|cx| {
|
.add_window(|cx| {
|
||||||
Picker::new(
|
Picker::new(
|
||||||
|
@ -954,7 +954,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
finder
|
finder
|
||||||
.update(cx, |f, cx| {
|
.update(cx, |f, cx| {
|
||||||
f.delegate_mut().spawn_search(test_path_like("hi"), cx)
|
f.delegate_mut().spawn_search(test_path_like("hi"), cx)
|
||||||
|
@ -980,7 +980,7 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let finder = cx
|
let finder = cx
|
||||||
.add_window(|cx| {
|
.add_window(|cx| {
|
||||||
Picker::new(
|
Picker::new(
|
||||||
|
@ -994,7 +994,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
// Even though there is only one worktree, that worktree's filename
|
// Even though there is only one worktree, that worktree's filename
|
||||||
// is included in the matching, because the worktree is a single file.
|
// is included in the matching, because the worktree is a single file.
|
||||||
|
@ -1051,7 +1051,7 @@ mod tests {
|
||||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let worktree_id = cx.read(|cx| {
|
let worktree_id = cx.read(|cx| {
|
||||||
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
|
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
|
||||||
assert_eq!(worktrees.len(), 1);
|
assert_eq!(worktrees.len(), 1);
|
||||||
|
@ -1078,7 +1078,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
finder
|
finder
|
||||||
.update(cx, |f, cx| {
|
.update(cx, |f, cx| {
|
||||||
|
@ -1117,7 +1117,7 @@ mod tests {
|
||||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let finder = cx
|
let finder = cx
|
||||||
.add_window(|cx| {
|
.add_window(|cx| {
|
||||||
Picker::new(
|
Picker::new(
|
||||||
|
@ -1131,7 +1131,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
finder
|
finder
|
||||||
.update(cx, |f, cx| {
|
.update(cx, |f, cx| {
|
||||||
f.delegate_mut().spawn_search(test_path_like("dir"), cx)
|
f.delegate_mut().spawn_search(test_path_like("dir"), cx)
|
||||||
|
|
|
@ -130,12 +130,12 @@ pub trait BorrowAppContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BorrowWindowContext {
|
pub trait BorrowWindowContext {
|
||||||
type Return<T>;
|
type Result<T>;
|
||||||
|
|
||||||
fn read_with<T, F>(&self, window_id: usize, f: F) -> Self::Return<T>
|
fn read_window_with<T, F>(&self, window_id: usize, f: F) -> Self::Result<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(&WindowContext) -> T;
|
F: FnOnce(&WindowContext) -> T;
|
||||||
fn update<T, F>(&mut self, window_id: usize, f: F) -> Self::Return<T>
|
fn update_window<T, F>(&mut self, window_id: usize, f: F) -> Self::Result<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut WindowContext) -> T;
|
F: FnOnce(&mut WindowContext) -> T;
|
||||||
}
|
}
|
||||||
|
@ -458,6 +458,26 @@ impl BorrowAppContext for AsyncAppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BorrowWindowContext for AsyncAppContext {
|
||||||
|
type Result<T> = Option<T>;
|
||||||
|
|
||||||
|
fn read_window_with<T, F>(&self, window_id: usize, f: F) -> Self::Result<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(&WindowContext) -> T,
|
||||||
|
{
|
||||||
|
self.0.borrow().read_with(|cx| cx.read_window(window_id, f))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_window<T, F>(&mut self, window_id: usize, f: F) -> Self::Result<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut WindowContext) -> T,
|
||||||
|
{
|
||||||
|
self.0
|
||||||
|
.borrow_mut()
|
||||||
|
.update(|cx| cx.update_window(window_id, f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize);
|
type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize);
|
||||||
type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext);
|
type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext);
|
||||||
|
|
||||||
|
@ -2162,6 +2182,24 @@ impl BorrowAppContext for AppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BorrowWindowContext for AppContext {
|
||||||
|
type Result<T> = Option<T>;
|
||||||
|
|
||||||
|
fn read_window_with<T, F>(&self, window_id: usize, f: F) -> Self::Result<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(&WindowContext) -> T,
|
||||||
|
{
|
||||||
|
AppContext::read_window(self, window_id, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_window<T, F>(&mut self, window_id: usize, f: F) -> Self::Result<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut WindowContext) -> T,
|
||||||
|
{
|
||||||
|
AppContext::update_window(self, window_id, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ParentId {
|
pub enum ParentId {
|
||||||
View(usize),
|
View(usize),
|
||||||
|
@ -3360,14 +3398,18 @@ impl<V> BorrowAppContext for ViewContext<'_, '_, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
|
impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
|
||||||
type Return<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
fn read_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
fn read_window_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
||||||
BorrowWindowContext::read_with(&*self.window_context, window_id, f)
|
BorrowWindowContext::read_window_with(&*self.window_context, window_id, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<T, F: FnOnce(&mut WindowContext) -> T>(&mut self, window_id: usize, f: F) -> T {
|
fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||||
BorrowWindowContext::update(&mut *self.window_context, window_id, f)
|
&mut self,
|
||||||
|
window_id: usize,
|
||||||
|
f: F,
|
||||||
|
) -> T {
|
||||||
|
BorrowWindowContext::update_window(&mut *self.window_context, window_id, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3467,14 +3509,18 @@ impl<V: View> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: View> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
|
impl<V: View> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
|
||||||
type Return<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
fn read_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
fn read_window_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
||||||
BorrowWindowContext::read_with(&*self.view_context, window_id, f)
|
BorrowWindowContext::read_window_with(&*self.view_context, window_id, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<T, F: FnOnce(&mut WindowContext) -> T>(&mut self, window_id: usize, f: F) -> T {
|
fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||||
BorrowWindowContext::update(&mut *self.view_context, window_id, f)
|
&mut self,
|
||||||
|
window_id: usize,
|
||||||
|
f: F,
|
||||||
|
) -> T {
|
||||||
|
BorrowWindowContext::update_window(&mut *self.view_context, window_id, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3521,14 +3567,18 @@ impl<V: View> BorrowAppContext for EventContext<'_, '_, '_, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: View> BorrowWindowContext for EventContext<'_, '_, '_, V> {
|
impl<V: View> BorrowWindowContext for EventContext<'_, '_, '_, V> {
|
||||||
type Return<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
fn read_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
fn read_window_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
||||||
BorrowWindowContext::read_with(&*self.view_context, window_id, f)
|
BorrowWindowContext::read_window_with(&*self.view_context, window_id, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<T, F: FnOnce(&mut WindowContext) -> T>(&mut self, window_id: usize, f: F) -> T {
|
fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||||
BorrowWindowContext::update(&mut *self.view_context, window_id, f)
|
&mut self,
|
||||||
|
window_id: usize,
|
||||||
|
f: F,
|
||||||
|
) -> T {
|
||||||
|
BorrowWindowContext::update_window(&mut *self.view_context, window_id, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3830,32 +3880,16 @@ impl<V: View> WindowHandle<V> {
|
||||||
self.any_handle.id()
|
self.any_handle.id()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root(&self, cx: &impl BorrowAppContext) -> ViewHandle<V> {
|
pub fn root<C: BorrowWindowContext>(&self, cx: &C) -> C::Result<ViewHandle<V>> {
|
||||||
self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap())
|
self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Keep this window open until it's explicitly closed.
|
pub fn read_with<C, F, R>(&self, cx: &C, read: F) -> C::Result<R>
|
||||||
//
|
|
||||||
// TODO: Implement window dropping behavior when we don't call this.
|
|
||||||
pub fn detach(mut self, cx: &impl BorrowAppContext) -> ViewHandle<V> {
|
|
||||||
let root = self.root(cx);
|
|
||||||
let ref_counts = self.any_handle.ref_counts.take();
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
|
||||||
ref_counts
|
|
||||||
.unwrap()
|
|
||||||
.lock()
|
|
||||||
.leak_detector
|
|
||||||
.lock()
|
|
||||||
.handle_dropped(self.id(), self.any_handle.handle_id);
|
|
||||||
root
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_with<C, F, R>(&self, cx: &C, read: F) -> R
|
|
||||||
where
|
where
|
||||||
C: BorrowAppContext,
|
C: BorrowWindowContext,
|
||||||
F: FnOnce(&WindowContext) -> R,
|
F: FnOnce(&WindowContext) -> R,
|
||||||
{
|
{
|
||||||
cx.read_with(|cx| cx.read_window(self.id(), read).unwrap())
|
cx.read_window_with(self.id(), |cx| read(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update<C, F, R>(&self, cx: &mut C, update: F) -> R
|
pub fn update<C, F, R>(&self, cx: &mut C, update: F) -> R
|
||||||
|
@ -3891,9 +3925,9 @@ impl<V: View> WindowHandle<V> {
|
||||||
root_view.read(cx)
|
root_view.read(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_root_with<C, F, R>(&self, cx: &C, read: F) -> R
|
pub fn read_root_with<C, F, R>(&self, cx: &C, read: F) -> C::Result<R>
|
||||||
where
|
where
|
||||||
C: BorrowAppContext,
|
C: BorrowWindowContext,
|
||||||
F: FnOnce(&V, &ViewContext<V>) -> R,
|
F: FnOnce(&V, &ViewContext<V>) -> R,
|
||||||
{
|
{
|
||||||
self.read_with(cx, |cx| {
|
self.read_with(cx, |cx| {
|
||||||
|
@ -4021,25 +4055,25 @@ impl<T: View> ViewHandle<T> {
|
||||||
cx.read_view(self)
|
cx.read_view(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> C::Return<S>
|
pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> C::Result<S>
|
||||||
where
|
where
|
||||||
C: BorrowWindowContext,
|
C: BorrowWindowContext,
|
||||||
F: FnOnce(&T, &ViewContext<T>) -> S,
|
F: FnOnce(&T, &ViewContext<T>) -> S,
|
||||||
{
|
{
|
||||||
cx.read_with(self.window_id, |cx| {
|
cx.read_window_with(self.window_id, |cx| {
|
||||||
let cx = ViewContext::immutable(cx, self.view_id);
|
let cx = ViewContext::immutable(cx, self.view_id);
|
||||||
read(cx.read_view(self), &cx)
|
read(cx.read_view(self), &cx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Return<S>
|
pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Result<S>
|
||||||
where
|
where
|
||||||
C: BorrowWindowContext,
|
C: BorrowWindowContext,
|
||||||
F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
|
F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
|
||||||
{
|
{
|
||||||
let mut update = Some(update);
|
let mut update = Some(update);
|
||||||
|
|
||||||
cx.update(self.window_id, |cx| {
|
cx.update_window(self.window_id, |cx| {
|
||||||
cx.update_view(self, &mut |view, cx| {
|
cx.update_view(self, &mut |view, cx| {
|
||||||
let update = update.take().unwrap();
|
let update = update.take().unwrap();
|
||||||
update(view, cx)
|
update(view, cx)
|
||||||
|
@ -5005,7 +5039,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_entity_release_hooks(cx: &mut AppContext) {
|
fn test_entity_release_hooks(cx: &mut TestAppContext) {
|
||||||
struct Model {
|
struct Model {
|
||||||
released: Rc<Cell<bool>>,
|
released: Rc<Cell<bool>>,
|
||||||
}
|
}
|
||||||
|
@ -5048,7 +5082,7 @@ mod tests {
|
||||||
let model = cx.add_model(|_| Model {
|
let model = cx.add_model(|_| Model {
|
||||||
released: model_released.clone(),
|
released: model_released.clone(),
|
||||||
});
|
});
|
||||||
let window = cx.add_window(Default::default(), |_| View {
|
let window = cx.add_window(|_| View {
|
||||||
released: view_released.clone(),
|
released: view_released.clone(),
|
||||||
});
|
});
|
||||||
let view = window.root(cx);
|
let view = window.root(cx);
|
||||||
|
@ -5056,16 +5090,18 @@ mod tests {
|
||||||
assert!(!model_released.get());
|
assert!(!model_released.get());
|
||||||
assert!(!view_released.get());
|
assert!(!view_released.get());
|
||||||
|
|
||||||
cx.observe_release(&model, {
|
cx.update(|cx| {
|
||||||
let model_release_observed = model_release_observed.clone();
|
cx.observe_release(&model, {
|
||||||
move |_, _| model_release_observed.set(true)
|
let model_release_observed = model_release_observed.clone();
|
||||||
})
|
move |_, _| model_release_observed.set(true)
|
||||||
.detach();
|
})
|
||||||
cx.observe_release(&view, {
|
.detach();
|
||||||
let view_release_observed = view_release_observed.clone();
|
cx.observe_release(&view, {
|
||||||
move |_, _| view_release_observed.set(true)
|
let view_release_observed = view_release_observed.clone();
|
||||||
})
|
move |_, _| view_release_observed.set(true)
|
||||||
.detach();
|
})
|
||||||
|
.detach();
|
||||||
|
});
|
||||||
|
|
||||||
cx.update(move |_| {
|
cx.update(move |_| {
|
||||||
drop(model);
|
drop(model);
|
||||||
|
@ -5795,7 +5831,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_dispatch_action(cx: &mut AppContext) {
|
fn test_dispatch_action(cx: &mut TestAppContext) {
|
||||||
struct ViewA {
|
struct ViewA {
|
||||||
id: usize,
|
id: usize,
|
||||||
child: Option<AnyViewHandle>,
|
child: Option<AnyViewHandle>,
|
||||||
|
@ -5846,68 +5882,70 @@ mod tests {
|
||||||
impl_actions!(test, [Action]);
|
impl_actions!(test, [Action]);
|
||||||
|
|
||||||
let actions = Rc::new(RefCell::new(Vec::new()));
|
let actions = Rc::new(RefCell::new(Vec::new()));
|
||||||
|
|
||||||
cx.add_global_action({
|
|
||||||
let actions = actions.clone();
|
|
||||||
move |_: &Action, _: &mut AppContext| {
|
|
||||||
actions.borrow_mut().push("global".to_string());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.add_action({
|
|
||||||
let actions = actions.clone();
|
|
||||||
move |view: &mut ViewA, action: &Action, cx| {
|
|
||||||
assert_eq!(action.0, "bar");
|
|
||||||
cx.propagate_action();
|
|
||||||
actions.borrow_mut().push(format!("{} a", view.id));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.add_action({
|
|
||||||
let actions = actions.clone();
|
|
||||||
move |view: &mut ViewA, _: &Action, cx| {
|
|
||||||
if view.id != 1 {
|
|
||||||
cx.add_view(|cx| {
|
|
||||||
cx.propagate_action(); // Still works on a nested ViewContext
|
|
||||||
ViewB { id: 5, child: None }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
actions.borrow_mut().push(format!("{} b", view.id));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.add_action({
|
|
||||||
let actions = actions.clone();
|
|
||||||
move |view: &mut ViewB, _: &Action, cx| {
|
|
||||||
cx.propagate_action();
|
|
||||||
actions.borrow_mut().push(format!("{} c", view.id));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.add_action({
|
|
||||||
let actions = actions.clone();
|
|
||||||
move |view: &mut ViewB, _: &Action, cx| {
|
|
||||||
cx.propagate_action();
|
|
||||||
actions.borrow_mut().push(format!("{} d", view.id));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.capture_action({
|
|
||||||
let actions = actions.clone();
|
|
||||||
move |view: &mut ViewA, _: &Action, cx| {
|
|
||||||
cx.propagate_action();
|
|
||||||
actions.borrow_mut().push(format!("{} capture", view.id));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let observed_actions = Rc::new(RefCell::new(Vec::new()));
|
let observed_actions = Rc::new(RefCell::new(Vec::new()));
|
||||||
cx.observe_actions({
|
|
||||||
let observed_actions = observed_actions.clone();
|
|
||||||
move |action_id, _| observed_actions.borrow_mut().push(action_id)
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
|
|
||||||
let window = cx.add_window(Default::default(), |_| ViewA { id: 1, child: None });
|
cx.update(|cx| {
|
||||||
|
cx.add_global_action({
|
||||||
|
let actions = actions.clone();
|
||||||
|
move |_: &Action, _: &mut AppContext| {
|
||||||
|
actions.borrow_mut().push("global".to_string());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.add_action({
|
||||||
|
let actions = actions.clone();
|
||||||
|
move |view: &mut ViewA, action: &Action, cx| {
|
||||||
|
assert_eq!(action.0, "bar");
|
||||||
|
cx.propagate_action();
|
||||||
|
actions.borrow_mut().push(format!("{} a", view.id));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.add_action({
|
||||||
|
let actions = actions.clone();
|
||||||
|
move |view: &mut ViewA, _: &Action, cx| {
|
||||||
|
if view.id != 1 {
|
||||||
|
cx.add_view(|cx| {
|
||||||
|
cx.propagate_action(); // Still works on a nested ViewContext
|
||||||
|
ViewB { id: 5, child: None }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
actions.borrow_mut().push(format!("{} b", view.id));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.add_action({
|
||||||
|
let actions = actions.clone();
|
||||||
|
move |view: &mut ViewB, _: &Action, cx| {
|
||||||
|
cx.propagate_action();
|
||||||
|
actions.borrow_mut().push(format!("{} c", view.id));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.add_action({
|
||||||
|
let actions = actions.clone();
|
||||||
|
move |view: &mut ViewB, _: &Action, cx| {
|
||||||
|
cx.propagate_action();
|
||||||
|
actions.borrow_mut().push(format!("{} d", view.id));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.capture_action({
|
||||||
|
let actions = actions.clone();
|
||||||
|
move |view: &mut ViewA, _: &Action, cx| {
|
||||||
|
cx.propagate_action();
|
||||||
|
actions.borrow_mut().push(format!("{} capture", view.id));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.observe_actions({
|
||||||
|
let observed_actions = observed_actions.clone();
|
||||||
|
move |action_id, _| observed_actions.borrow_mut().push(action_id)
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
});
|
||||||
|
|
||||||
|
let window = cx.add_window(|_| ViewA { id: 1, child: None });
|
||||||
let view_1 = window.root(cx);
|
let view_1 = window.root(cx);
|
||||||
let view_2 = window.update(cx, |cx| {
|
let view_2 = window.update(cx, |cx| {
|
||||||
let child = cx.add_view(|_| ViewB { id: 2, child: None });
|
let child = cx.add_view(|_| ViewB { id: 2, child: None });
|
||||||
|
@ -5956,7 +5994,7 @@ mod tests {
|
||||||
|
|
||||||
// Remove view_1, which doesn't propagate the action
|
// Remove view_1, which doesn't propagate the action
|
||||||
|
|
||||||
let window = cx.add_window(Default::default(), |_| ViewB { id: 2, child: None });
|
let window = cx.add_window(|_| ViewB { id: 2, child: None });
|
||||||
let view_2 = window.root(cx);
|
let view_2 = window.root(cx);
|
||||||
let view_3 = window.update(cx, |cx| {
|
let view_3 = window.update(cx, |cx| {
|
||||||
let child = cx.add_view(|_| ViewA { id: 3, child: None });
|
let child = cx.add_view(|_| ViewA { id: 3, child: None });
|
||||||
|
@ -6457,7 +6495,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test(self)]
|
#[crate::test(self)]
|
||||||
fn test_refresh_windows(cx: &mut AppContext) {
|
fn test_refresh_windows(cx: &mut TestAppContext) {
|
||||||
struct View(usize);
|
struct View(usize);
|
||||||
|
|
||||||
impl super::Entity for View {
|
impl super::Entity for View {
|
||||||
|
@ -6474,7 +6512,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let window = cx.add_window(Default::default(), |_| View(0));
|
let window = cx.add_window(|_| View(0));
|
||||||
let root_view = window.root(cx);
|
let root_view = window.root(cx);
|
||||||
window.update(cx, |cx| {
|
window.update(cx, |cx| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -406,16 +406,20 @@ impl BorrowAppContext for TestAppContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BorrowWindowContext for TestAppContext {
|
impl BorrowWindowContext for TestAppContext {
|
||||||
type Return<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
fn read_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
fn read_window_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
||||||
self.cx
|
self.cx
|
||||||
.borrow()
|
.borrow()
|
||||||
.read_window(window_id, f)
|
.read_window(window_id, f)
|
||||||
.expect("window was closed")
|
.expect("window was closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<T, F: FnOnce(&mut WindowContext) -> T>(&mut self, window_id: usize, f: F) -> T {
|
fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||||
|
&mut self,
|
||||||
|
window_id: usize,
|
||||||
|
f: F,
|
||||||
|
) -> T {
|
||||||
self.cx
|
self.cx
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.update_window(window_id, f)
|
.update_window(window_id, f)
|
||||||
|
|
|
@ -142,9 +142,9 @@ impl BorrowAppContext for WindowContext<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BorrowWindowContext for WindowContext<'_> {
|
impl BorrowWindowContext for WindowContext<'_> {
|
||||||
type Return<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
fn read_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
fn read_window_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
||||||
if self.window_id == window_id {
|
if self.window_id == window_id {
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,7 +152,11 @@ impl BorrowWindowContext for WindowContext<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<T, F: FnOnce(&mut WindowContext) -> T>(&mut self, window_id: usize, f: F) -> T {
|
fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||||
|
&mut self,
|
||||||
|
window_id: usize,
|
||||||
|
f: F,
|
||||||
|
) -> T {
|
||||||
if self.window_id == window_id {
|
if self.window_id == window_id {
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -63,7 +63,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) {
|
||||||
|
|
||||||
let log_view = cx
|
let log_view = cx
|
||||||
.add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx))
|
.add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
language_server.notify::<lsp::notification::LogMessage>(lsp::LogMessageParams {
|
language_server.notify::<lsp::notification::LogMessage>(lsp::LogMessageParams {
|
||||||
message: "hello from the server".into(),
|
message: "hello from the server".into(),
|
||||||
|
|
|
@ -1782,7 +1782,7 @@ mod tests {
|
||||||
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
visible_entries_as_strings(&panel, 0..50, cx),
|
visible_entries_as_strings(&panel, 0..50, cx),
|
||||||
|
@ -2327,7 +2327,7 @@ mod tests {
|
||||||
let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
|
|
||||||
panel.update(cx, |panel, cx| {
|
panel.update(cx, |panel, cx| {
|
||||||
|
@ -2641,7 +2641,7 @@ mod tests {
|
||||||
let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
|
|
||||||
let new_search_events_count = Arc::new(AtomicUsize::new(0));
|
let new_search_events_count = Arc::new(AtomicUsize::new(0));
|
||||||
|
@ -2730,7 +2730,7 @@ mod tests {
|
||||||
let project = Project::test(fs.clone(), ["/project_root".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/project_root".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
|
|
||||||
panel.update(cx, |panel, cx| {
|
panel.update(cx, |panel, cx| {
|
||||||
|
|
|
@ -1449,7 +1449,7 @@ pub mod tests {
|
||||||
let search = cx.add_model(|cx| ProjectSearch::new(project, cx));
|
let search = cx.add_model(|cx| ProjectSearch::new(project, cx));
|
||||||
let search_view = cx
|
let search_view = cx
|
||||||
.add_window(|cx| ProjectSearchView::new(search.clone(), cx))
|
.add_window(|cx| ProjectSearchView::new(search.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
search_view.update(cx, |search_view, cx| {
|
search_view.update(cx, |search_view, cx| {
|
||||||
search_view
|
search_view
|
||||||
|
@ -1754,7 +1754,7 @@ pub mod tests {
|
||||||
});
|
});
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
let active_item = cx.read(|cx| {
|
let active_item = cx.read(|cx| {
|
||||||
workspace
|
workspace
|
||||||
|
|
|
@ -1072,7 +1072,7 @@ mod tests {
|
||||||
let project = Project::test(params.fs.clone(), [], cx).await;
|
let project = Project::test(params.fs.clone(), [], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
(project, workspace)
|
(project, workspace)
|
||||||
}
|
}
|
||||||
|
|
|
@ -793,68 +793,60 @@ impl Workspace {
|
||||||
DB.next_id().await.unwrap_or(0)
|
DB.next_id().await.unwrap_or(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let window = requesting_window_id
|
let window = requesting_window_id.and_then(|window_id| {
|
||||||
.and_then(|window_id| {
|
cx.update(|cx| {
|
||||||
cx.update(|cx| {
|
cx.replace_root_view(window_id, |cx| {
|
||||||
cx.replace_root_view(window_id, |cx| {
|
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
|
||||||
Workspace::new(
|
|
||||||
workspace_id,
|
|
||||||
project_handle.clone(),
|
|
||||||
app_state.clone(),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
});
|
||||||
let window_bounds_override = window_bounds_env_override(&cx);
|
let window = window.unwrap_or_else(|| {
|
||||||
let (bounds, display) = if let Some(bounds) = window_bounds_override {
|
let window_bounds_override = window_bounds_env_override(&cx);
|
||||||
(Some(bounds), None)
|
let (bounds, display) = if let Some(bounds) = window_bounds_override {
|
||||||
} else {
|
(Some(bounds), None)
|
||||||
serialized_workspace
|
} else {
|
||||||
.as_ref()
|
serialized_workspace
|
||||||
.and_then(|serialized_workspace| {
|
.as_ref()
|
||||||
let display = serialized_workspace.display?;
|
.and_then(|serialized_workspace| {
|
||||||
let mut bounds = serialized_workspace.bounds?;
|
let display = serialized_workspace.display?;
|
||||||
|
let mut bounds = serialized_workspace.bounds?;
|
||||||
|
|
||||||
// Stored bounds are relative to the containing display.
|
// Stored bounds are relative to the containing display.
|
||||||
// So convert back to global coordinates if that screen still exists
|
// So convert back to global coordinates if that screen still exists
|
||||||
if let WindowBounds::Fixed(mut window_bounds) = bounds {
|
if let WindowBounds::Fixed(mut window_bounds) = bounds {
|
||||||
if let Some(screen) = cx.platform().screen_by_id(display) {
|
if let Some(screen) = cx.platform().screen_by_id(display) {
|
||||||
let screen_bounds = screen.bounds();
|
let screen_bounds = screen.bounds();
|
||||||
window_bounds.set_origin_x(
|
window_bounds.set_origin_x(
|
||||||
window_bounds.origin_x() + screen_bounds.origin_x(),
|
window_bounds.origin_x() + screen_bounds.origin_x(),
|
||||||
);
|
);
|
||||||
window_bounds.set_origin_y(
|
window_bounds.set_origin_y(
|
||||||
window_bounds.origin_y() + screen_bounds.origin_y(),
|
window_bounds.origin_y() + screen_bounds.origin_y(),
|
||||||
);
|
);
|
||||||
bounds = WindowBounds::Fixed(window_bounds);
|
bounds = WindowBounds::Fixed(window_bounds);
|
||||||
} else {
|
} else {
|
||||||
// Screen no longer exists. Return none here.
|
// Screen no longer exists. Return none here.
|
||||||
return None;
|
return None;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some((bounds, display))
|
Some((bounds, display))
|
||||||
})
|
})
|
||||||
.unzip()
|
.unzip()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use the serialized workspace to construct the new window
|
// Use the serialized workspace to construct the new window
|
||||||
cx.add_window(
|
cx.add_window(
|
||||||
(app_state.build_window_options)(bounds, display, cx.platform().as_ref()),
|
(app_state.build_window_options)(bounds, display, cx.platform().as_ref()),
|
||||||
|cx| {
|
|cx| {
|
||||||
Workspace::new(
|
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
|
||||||
workspace_id,
|
},
|
||||||
project_handle.clone(),
|
)
|
||||||
app_state.clone(),
|
});
|
||||||
cx,
|
|
||||||
)
|
// We haven't yielded the main thread since obtaining the window handle,
|
||||||
},
|
// so the window exists.
|
||||||
)
|
let workspace = window.root(&cx).unwrap();
|
||||||
});
|
|
||||||
|
|
||||||
let workspace = window.root(&cx);
|
|
||||||
(app_state.initialize_workspace)(
|
(app_state.initialize_workspace)(
|
||||||
workspace.downgrade(),
|
workspace.downgrade(),
|
||||||
serialized_workspace.is_some(),
|
serialized_workspace.is_some(),
|
||||||
|
@ -3985,7 +3977,7 @@ pub fn join_remote_project(
|
||||||
),
|
),
|
||||||
|cx| Workspace::new(0, project, app_state.clone(), cx),
|
|cx| Workspace::new(0, project, app_state.clone(), cx),
|
||||||
);
|
);
|
||||||
let workspace = window.root(&cx);
|
let workspace = window.root(&cx).unwrap();
|
||||||
(app_state.initialize_workspace)(
|
(app_state.initialize_workspace)(
|
||||||
workspace.downgrade(),
|
workspace.downgrade(),
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -985,7 +985,7 @@ mod tests {
|
||||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
|
|
||||||
let entries = cx.read(|cx| workspace.file_project_paths(cx));
|
let entries = cx.read(|cx| workspace.file_project_paths(cx));
|
||||||
let file1 = entries[0].clone();
|
let file1 = entries[0].clone();
|
||||||
|
@ -1566,7 +1566,7 @@ mod tests {
|
||||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
let entries = cx.read(|cx| workspace.file_project_paths(cx));
|
let entries = cx.read(|cx| workspace.file_project_paths(cx));
|
||||||
|
@ -1845,7 +1845,7 @@ mod tests {
|
||||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project, cx))
|
.add_window(|cx| Workspace::test_new(project, cx))
|
||||||
.detach(cx);
|
.root(cx);
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
let entries = cx.read(|cx| workspace.file_project_paths(cx));
|
let entries = cx.read(|cx| workspace.file_project_paths(cx));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue