Merge branch 'zed2' of github.com:zed-industries/zed into zed2

Marshall Bowers created

Change summary

Cargo.lock                           |    1 
crates/gpui2_macros/src/test.rs      |    8 
crates/language2/Cargo.toml          |    4 
crates/language2/src/buffer_tests.rs | 4494 ++++++++++++++---------------
4 files changed, 2,252 insertions(+), 2,255 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -4304,7 +4304,6 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "settings",
  "settings2",
  "similar",
  "smallvec",

crates/gpui2_macros/src/test.rs 🔗

@@ -86,7 +86,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
                     let last_segment = ty.path.segments.last();
                     match last_segment.map(|s| s.ident.to_string()).as_deref() {
                         Some("StdRng") => {
-                            inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
+                            inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(_seed),));
                             continue;
                         }
                         Some("Executor") => {
@@ -133,7 +133,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
                 gpui2::run_test(
                     #num_iterations as u64,
                     #max_retries,
-                    &mut |dispatcher| {
+                    &mut |dispatcher, _seed| {
                         let executor = gpui2::Executor::new(std::sync::Arc::new(dispatcher.clone()));
                         #cx_vars
                         executor.block(#inner_fn_name(#inner_fn_args));
@@ -156,7 +156,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
                     let last_segment = ty.path.segments.last();
 
                     if let Some("StdRng") = last_segment.map(|s| s.ident.to_string()).as_deref() {
-                        inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
+                        inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(_seed),));
                         continue;
                     }
                 } else if let Type::Reference(ty) = &*arg.ty {
@@ -212,7 +212,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
                 gpui2::run_test(
                     #num_iterations as u64,
                     #max_retries,
-                    &mut |dispatcher| {
+                    &mut |dispatcher, _seed| {
                         #cx_vars
                         #inner_fn_name(#inner_fn_args);
                         #cx_teardowns

crates/language2/Cargo.toml 🔗

@@ -17,7 +17,7 @@ test-support = [
     "text/test-support",
     "tree-sitter-rust",
     "tree-sitter-typescript",
-    "settings/test-support",
+    "settings2/test-support",
     "util/test-support",
 ]
 
@@ -65,7 +65,7 @@ collections = { path = "../collections", features = ["test-support"] }
 gpui2 = { path = "../gpui2", features = ["test-support"] }
 lsp2 = { path = "../lsp2", features = ["test-support"] }
 text = { path = "../text", features = ["test-support"] }
-settings = { path = "../settings", features = ["test-support"] }
+settings2 = { path = "../settings2", features = ["test-support"] }
 util = { path = "../util", features = ["test-support"] }
 ctor.workspace = true
 env_logger.workspace = true

crates/language2/src/buffer_tests.rs 🔗

@@ -1,229 +1,220 @@
+use super::*;
+use crate::language_settings::{
+    AllLanguageSettings, AllLanguageSettingsContent, LanguageSettingsContent,
+};
 use crate::Buffer;
+use clock::ReplicaId;
+use collections::BTreeMap;
+use gpui2::{AppContext, Handle};
 use gpui2::{Context, TestAppContext};
+use indoc::indoc;
+use proto::deserialize_operation;
+use rand::prelude::*;
+use regex::RegexBuilder;
+use settings2::SettingsStore;
+use std::{
+    env,
+    ops::Range,
+    time::{Duration, Instant},
+};
+use text::network::Network;
+use text::LineEnding;
 use text::{Point, ToPoint};
+use unindent::Unindent as _;
+use util::{assert_set_eq, post_inc, test::marked_text_ranges, RandomCharIter};
+
+lazy_static! {
+    static ref TRAILING_WHITESPACE_REGEX: Regex = RegexBuilder::new("[ \t]+$")
+        .multi_line(true)
+        .build()
+        .unwrap();
+}
 
-// use crate::language_settings::{
-//     AllLanguageSettings, AllLanguageSettingsContent, LanguageSettingsContent,
-// };
-
-// use super::*;
-// use clock::ReplicaId;
-// use collections::BTreeMap;
-// use gpui2::{AppContext, Handle};
-// use indoc::indoc;
-// use proto::deserialize_operation;
-// use rand::prelude::*;
-// use regex::RegexBuilder;
-// use settings::SettingsStore;
-// use std::{
-//     cell::RefCell,
-//     env,
-//     ops::Range,
-//     rc::Rc,
-//     time::{Duration, Instant},
-// };
-// use text::network::Network;
-// use text::LineEnding;
-// use unindent::Unindent as _;
-// use util::{assert_set_eq, post_inc, test::marked_text_ranges, RandomCharIter};
-
-// lazy_static! {
-//     static ref TRAILING_WHITESPACE_REGEX: Regex = RegexBuilder::new("[ \t]+$")
-//         .multi_line(true)
-//         .build()
-//         .unwrap();
-// }
-
-// #[cfg(test)]
-// #[ctor::ctor]
-// fn init_logger() {
-//     if std::env::var("RUST_LOG").is_ok() {
-//         env_logger::init();
-//     }
-// }
-
-// #[gpui::test]
-// fn test_line_endings(cx: &mut gpui::AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let mut buffer = Buffer::new(0, cx.model_id() as u64, "one\r\ntwo\rthree")
-//             .with_language(Arc::new(rust_lang()), cx);
-//         assert_eq!(buffer.text(), "one\ntwo\nthree");
-//         assert_eq!(buffer.line_ending(), LineEnding::Windows);
-
-//         buffer.check_invariants();
-//         buffer.edit(
-//             [(buffer.len()..buffer.len(), "\r\nfour")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         buffer.edit([(0..0, "zero\r\n")], None, cx);
-//         assert_eq!(buffer.text(), "zero\none\ntwo\nthree\nfour");
-//         assert_eq!(buffer.line_ending(), LineEnding::Windows);
-//         buffer.check_invariants();
-
-//         buffer
-//     });
-// }
-
-// #[gpui::test]
-// fn test_select_language() {
-//     let registry = Arc::new(LanguageRegistry::test());
-//     registry.add(Arc::new(Language::new(
-//         LanguageConfig {
-//             name: "Rust".into(),
-//             path_suffixes: vec!["rs".to_string()],
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_rust::language()),
-//     )));
-//     registry.add(Arc::new(Language::new(
-//         LanguageConfig {
-//             name: "Make".into(),
-//             path_suffixes: vec!["Makefile".to_string(), "mk".to_string()],
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_rust::language()),
-//     )));
-
-//     // matching file extension
-//     assert_eq!(
-//         registry
-//             .language_for_file("zed/lib.rs", None)
-//             .now_or_never()
-//             .and_then(|l| Some(l.ok()?.name())),
-//         Some("Rust".into())
-//     );
-//     assert_eq!(
-//         registry
-//             .language_for_file("zed/lib.mk", None)
-//             .now_or_never()
-//             .and_then(|l| Some(l.ok()?.name())),
-//         Some("Make".into())
-//     );
-
-//     // matching filename
-//     assert_eq!(
-//         registry
-//             .language_for_file("zed/Makefile", None)
-//             .now_or_never()
-//             .and_then(|l| Some(l.ok()?.name())),
-//         Some("Make".into())
-//     );
+#[cfg(test)]
+#[ctor::ctor]
+fn init_logger() {
+    if std::env::var("RUST_LOG").is_ok() {
+        env_logger::init();
+    }
+}
 
-//     // matching suffix that is not the full file extension or filename
-//     assert_eq!(
-//         registry
-//             .language_for_file("zed/cars", None)
-//             .now_or_never()
-//             .and_then(|l| Some(l.ok()?.name())),
-//         None
-//     );
-//     assert_eq!(
-//         registry
-//             .language_for_file("zed/a.cars", None)
-//             .now_or_never()
-//             .and_then(|l| Some(l.ok()?.name())),
-//         None
-//     );
-//     assert_eq!(
-//         registry
-//             .language_for_file("zed/sumk", None)
-//             .now_or_never()
-//             .and_then(|l| Some(l.ok()?.name())),
-//         None
-//     );
-// }
+#[gpui2::test]
+fn test_line_endings(cx: &mut gpui2::AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "one\r\ntwo\rthree")
+            .with_language(Arc::new(rust_lang()), cx);
+        assert_eq!(buffer.text(), "one\ntwo\nthree");
+        assert_eq!(buffer.line_ending(), LineEnding::Windows);
+
+        buffer.check_invariants();
+        buffer.edit(
+            [(buffer.len()..buffer.len(), "\r\nfour")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        buffer.edit([(0..0, "zero\r\n")], None, cx);
+        assert_eq!(buffer.text(), "zero\none\ntwo\nthree\nfour");
+        assert_eq!(buffer.line_ending(), LineEnding::Windows);
+        buffer.check_invariants();
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_edit_events(cx: &mut gpui::AppContext) {
-//     let mut now = Instant::now();
-//     let buffer_1_events = Rc::new(RefCell::new(Vec::new()));
-//     let buffer_2_events = Rc::new(RefCell::new(Vec::new()));
-
-//     let buffer1 = cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, "abcdef"));
-//     let buffer2 = cx.add_model(|cx| Buffer::new(1, cx.model_id() as u64, "abcdef"));
-//     let buffer1_ops = Rc::new(RefCell::new(Vec::new()));
-//     buffer1.update(cx, {
-//         let buffer1_ops = buffer1_ops.clone();
-//         |buffer, cx| {
-//             let buffer_1_events = buffer_1_events.clone();
-//             cx.subscribe(&buffer1, move |_, _, event, _| match event.clone() {
-//                 Event::Operation(op) => buffer1_ops.borrow_mut().push(op),
-//                 event => buffer_1_events.borrow_mut().push(event),
-//             })
-//             .detach();
-//             let buffer_2_events = buffer_2_events.clone();
-//             cx.subscribe(&buffer2, move |_, _, event, _| {
-//                 buffer_2_events.borrow_mut().push(event.clone())
-//             })
-//             .detach();
-
-//             // An edit emits an edited event, followed by a dirty changed event,
-//             // since the buffer was previously in a clean state.
-//             buffer.edit([(2..4, "XYZ")], None, cx);
-
-//             // An empty transaction does not emit any events.
-//             buffer.start_transaction();
-//             buffer.end_transaction(cx);
-
-//             // A transaction containing two edits emits one edited event.
-//             now += Duration::from_secs(1);
-//             buffer.start_transaction_at(now);
-//             buffer.edit([(5..5, "u")], None, cx);
-//             buffer.edit([(6..6, "w")], None, cx);
-//             buffer.end_transaction_at(now, cx);
-
-//             // Undoing a transaction emits one edited event.
-//             buffer.undo(cx);
-//         }
-//     });
+#[gpui2::test]
+fn test_select_language() {
+    let registry = Arc::new(LanguageRegistry::test());
+    registry.add(Arc::new(Language::new(
+        LanguageConfig {
+            name: "Rust".into(),
+            path_suffixes: vec!["rs".to_string()],
+            ..Default::default()
+        },
+        Some(tree_sitter_rust::language()),
+    )));
+    registry.add(Arc::new(Language::new(
+        LanguageConfig {
+            name: "Make".into(),
+            path_suffixes: vec!["Makefile".to_string(), "mk".to_string()],
+            ..Default::default()
+        },
+        Some(tree_sitter_rust::language()),
+    )));
+
+    // matching file extension
+    assert_eq!(
+        registry
+            .language_for_file("zed/lib.rs", None)
+            .now_or_never()
+            .and_then(|l| Some(l.ok()?.name())),
+        Some("Rust".into())
+    );
+    assert_eq!(
+        registry
+            .language_for_file("zed/lib.mk", None)
+            .now_or_never()
+            .and_then(|l| Some(l.ok()?.name())),
+        Some("Make".into())
+    );
+
+    // matching filename
+    assert_eq!(
+        registry
+            .language_for_file("zed/Makefile", None)
+            .now_or_never()
+            .and_then(|l| Some(l.ok()?.name())),
+        Some("Make".into())
+    );
+
+    // matching suffix that is not the full file extension or filename
+    assert_eq!(
+        registry
+            .language_for_file("zed/cars", None)
+            .now_or_never()
+            .and_then(|l| Some(l.ok()?.name())),
+        None
+    );
+    assert_eq!(
+        registry
+            .language_for_file("zed/a.cars", None)
+            .now_or_never()
+            .and_then(|l| Some(l.ok()?.name())),
+        None
+    );
+    assert_eq!(
+        registry
+            .language_for_file("zed/sumk", None)
+            .now_or_never()
+            .and_then(|l| Some(l.ok()?.name())),
+        None
+    );
+}
 
-//     // Incorporating a set of remote ops emits a single edited event,
-//     // followed by a dirty changed event.
-//     buffer2.update(cx, |buffer, cx| {
-//         buffer
-//             .apply_ops(buffer1_ops.borrow_mut().drain(..), cx)
-//             .unwrap();
-//     });
-//     assert_eq!(
-//         mem::take(&mut *buffer_1_events.borrow_mut()),
-//         vec![
-//             Event::Edited,
-//             Event::DirtyChanged,
-//             Event::Edited,
-//             Event::Edited,
-//         ]
-//     );
-//     assert_eq!(
-//         mem::take(&mut *buffer_2_events.borrow_mut()),
-//         vec![Event::Edited, Event::DirtyChanged]
-//     );
+#[gpui2::test]
+fn test_edit_events(cx: &mut gpui2::AppContext) {
+    let mut now = Instant::now();
+    let buffer_1_events = Arc::new(Mutex::new(Vec::new()));
+    let buffer_2_events = Arc::new(Mutex::new(Vec::new()));
+
+    let buffer1 = cx.entity(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcdef"));
+    let buffer2 = cx.entity(|cx| Buffer::new(1, cx.entity_id().as_u64(), "abcdef"));
+    let buffer1_ops = Arc::new(Mutex::new(Vec::new()));
+    buffer1.update(cx, {
+        let buffer1_ops = buffer1_ops.clone();
+        |buffer, cx| {
+            let buffer_1_events = buffer_1_events.clone();
+            cx.subscribe(&buffer1, move |_, _, event, _| match event.clone() {
+                Event::Operation(op) => buffer1_ops.lock().push(op),
+                event => buffer_1_events.lock().push(event),
+            })
+            .detach();
+            let buffer_2_events = buffer_2_events.clone();
+            cx.subscribe(&buffer2, move |_, _, event, _| {
+                buffer_2_events.lock().push(event.clone())
+            })
+            .detach();
+
+            // An edit emits an edited event, followed by a dirty changed event,
+            // since the buffer was previously in a clean state.
+            buffer.edit([(2..4, "XYZ")], None, cx);
+
+            // An empty transaction does not emit any events.
+            buffer.start_transaction();
+            buffer.end_transaction(cx);
+
+            // A transaction containing two edits emits one edited event.
+            now += Duration::from_secs(1);
+            buffer.start_transaction_at(now);
+            buffer.edit([(5..5, "u")], None, cx);
+            buffer.edit([(6..6, "w")], None, cx);
+            buffer.end_transaction_at(now, cx);
+
+            // Undoing a transaction emits one edited event.
+            buffer.undo(cx);
+        }
+    });
 
-//     buffer1.update(cx, |buffer, cx| {
-//         // Undoing the first transaction emits edited event, followed by a
-//         // dirty changed event, since the buffer is again in a clean state.
-//         buffer.undo(cx);
-//     });
-//     // Incorporating the remote ops again emits a single edited event,
-//     // followed by a dirty changed event.
-//     buffer2.update(cx, |buffer, cx| {
-//         buffer
-//             .apply_ops(buffer1_ops.borrow_mut().drain(..), cx)
-//             .unwrap();
-//     });
-//     assert_eq!(
-//         mem::take(&mut *buffer_1_events.borrow_mut()),
-//         vec![Event::Edited, Event::DirtyChanged,]
-//     );
-//     assert_eq!(
-//         mem::take(&mut *buffer_2_events.borrow_mut()),
-//         vec![Event::Edited, Event::DirtyChanged]
-//     );
-// }
+    // Incorporating a set of remote ops emits a single edited event,
+    // followed by a dirty changed event.
+    buffer2.update(cx, |buffer, cx| {
+        buffer.apply_ops(buffer1_ops.lock().drain(..), cx).unwrap();
+    });
+    assert_eq!(
+        mem::take(&mut *buffer_1_events.lock()),
+        vec![
+            Event::Edited,
+            Event::DirtyChanged,
+            Event::Edited,
+            Event::Edited,
+        ]
+    );
+    assert_eq!(
+        mem::take(&mut *buffer_2_events.lock()),
+        vec![Event::Edited, Event::DirtyChanged]
+    );
+
+    buffer1.update(cx, |buffer, cx| {
+        // Undoing the first transaction emits edited event, followed by a
+        // dirty changed event, since the buffer is again in a clean state.
+        buffer.undo(cx);
+    });
+    // Incorporating the remote ops again emits a single edited event,
+    // followed by a dirty changed event.
+    buffer2.update(cx, |buffer, cx| {
+        buffer.apply_ops(buffer1_ops.lock().drain(..), cx).unwrap();
+    });
+    assert_eq!(
+        mem::take(&mut *buffer_1_events.lock()),
+        vec![Event::Edited, Event::DirtyChanged,]
+    );
+    assert_eq!(
+        mem::take(&mut *buffer_2_events.lock()),
+        vec![Event::Edited, Event::DirtyChanged]
+    );
+}
 
-// #[gpui::test] todo!()
 #[gpui2::test]
 async fn test_apply_diff(cx: &mut TestAppContext) {
     let text = "a\nbb\nccc\ndddd\neeeee\nffffff\n";
@@ -247,88 +238,89 @@ async fn test_apply_diff(cx: &mut TestAppContext) {
     });
 }
 
-// #[gpui::test(iterations = 10)]
-// async fn test_normalize_whitespace(cx: &mut gpui::TestAppContext) {
-//     let text = [
-//         "zero",     //
-//         "one  ",    // 2 trailing spaces
-//         "two",      //
-//         "three   ", // 3 trailing spaces
-//         "four",     //
-//         "five    ", // 4 trailing spaces
-//     ]
-//     .join("\n");
-
-//     let buffer = cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, text));
-
-//     // Spawn a task to format the buffer's whitespace.
-//     // Pause so that the foratting task starts running.
-//     let format = buffer.read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx));
-//     smol::future::yield_now().await;
-
-//     // Edit the buffer while the normalization task is running.
-//     let version_before_edit = buffer.read_with(cx, |buffer, _| buffer.version());
-//     buffer.update(cx, |buffer, cx| {
-//         buffer.edit(
-//             [
-//                 (Point::new(0, 1)..Point::new(0, 1), "EE"),
-//                 (Point::new(3, 5)..Point::new(3, 5), "EEE"),
-//             ],
-//             None,
-//             cx,
-//         );
-//     });
+#[gpui2::test(iterations = 10)]
+async fn test_normalize_whitespace(cx: &mut gpui2::TestAppContext) {
+    let text = [
+        "zero",     //
+        "one  ",    // 2 trailing spaces
+        "two",      //
+        "three   ", // 3 trailing spaces
+        "four",     //
+        "five    ", // 4 trailing spaces
+    ]
+    .join("\n");
 
-//     let format_diff = format.await;
-//     buffer.update(cx, |buffer, cx| {
-//         let version_before_format = format_diff.base_version.clone();
-//         buffer.apply_diff(format_diff, cx);
-
-//         // The outcome depends on the order of concurrent taks.
-//         //
-//         // If the edit occurred while searching for trailing whitespace ranges,
-//         // then the trailing whitespace region touched by the edit is left intact.
-//         if version_before_format == version_before_edit {
-//             assert_eq!(
-//                 buffer.text(),
-//                 [
-//                     "zEEero",      //
-//                     "one",         //
-//                     "two",         //
-//                     "threeEEE   ", //
-//                     "four",        //
-//                     "five",        //
-//                 ]
-//                 .join("\n")
-//             );
-//         }
-//         // Otherwise, all trailing whitespace is removed.
-//         else {
-//             assert_eq!(
-//                 buffer.text(),
-//                 [
-//                     "zEEero",   //
-//                     "one",      //
-//                     "two",      //
-//                     "threeEEE", //
-//                     "four",     //
-//                     "five",     //
-//                 ]
-//                 .join("\n")
-//             );
-//         }
-//     });
-// }
+    let buffer = cx.entity(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
+
+    // Spawn a task to format the buffer's whitespace.
+    // Pause so that the foratting task starts running.
+    let format = buffer.update(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx));
+    smol::future::yield_now().await;
+
+    // Edit the buffer while the normalization task is running.
+    let version_before_edit = buffer.update(cx, |buffer, _| buffer.version());
+    buffer.update(cx, |buffer, cx| {
+        buffer.edit(
+            [
+                (Point::new(0, 1)..Point::new(0, 1), "EE"),
+                (Point::new(3, 5)..Point::new(3, 5), "EEE"),
+            ],
+            None,
+            cx,
+        );
+    });
 
-// #[gpui::test]
-// async fn test_reparse(cx: &mut gpui::TestAppContext) {
+    let format_diff = format.await;
+    buffer.update(cx, |buffer, cx| {
+        let version_before_format = format_diff.base_version.clone();
+        buffer.apply_diff(format_diff, cx);
+
+        // The outcome depends on the order of concurrent taks.
+        //
+        // If the edit occurred while searching for trailing whitespace ranges,
+        // then the trailing whitespace region touched by the edit is left intact.
+        if version_before_format == version_before_edit {
+            assert_eq!(
+                buffer.text(),
+                [
+                    "zEEero",      //
+                    "one",         //
+                    "two",         //
+                    "threeEEE   ", //
+                    "four",        //
+                    "five",        //
+                ]
+                .join("\n")
+            );
+        }
+        // Otherwise, all trailing whitespace is removed.
+        else {
+            assert_eq!(
+                buffer.text(),
+                [
+                    "zEEero",   //
+                    "one",      //
+                    "two",      //
+                    "threeEEE", //
+                    "four",     //
+                    "five",     //
+                ]
+                .join("\n")
+            );
+        }
+    });
+}
+
+// #[gpui2::test]
+// async fn test_reparse(cx: &mut gpui2::TestAppContext) {
 //     let text = "fn a() {}";
-//     let buffer = cx.add_model(|cx| {
-//         Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx)
+//     let buffer = cx.entity(|cx| {
+//         Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
 //     });
 
 //     // Wait for the initial text to parse
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
+//     cx.executor().run_until_parked();
+//     assert!(!buffer.update(cx, |buffer, _| buffer.is_parsing()));
 //     assert_eq!(
 //         get_tree_sexp(&buffer, cx),
 //         concat!(
@@ -359,7 +351,8 @@ async fn test_apply_diff(cx: &mut TestAppContext) {
 //         assert_eq!(buf.text(), "fn a(b: C) { d; }");
 //         assert!(buf.is_parsing());
 //     });
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
+//     cx.executor().run_until_parked();
+//     assert!(!buffer.update(cx, |buffer, _| buffer.is_parsing()));
 //     assert_eq!(
 //         get_tree_sexp(&buffer, cx),
 //         concat!(
@@ -391,7 +384,7 @@ async fn test_apply_diff(cx: &mut TestAppContext) {
 //         assert_eq!(buf.text(), "fn a(b: C) { d.e::<G>(f); }");
 //         assert!(buf.is_parsing());
 //     });
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
+//     cx.executor().run_until_parked();
 //     assert_eq!(
 //         get_tree_sexp(&buffer, cx),
 //         concat!(
@@ -413,7 +406,8 @@ async fn test_apply_diff(cx: &mut TestAppContext) {
 //         assert_eq!(buf.text(), "fn a() {}");
 //         assert!(buf.is_parsing());
 //     });
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
+
+//     cx.executor().run_until_parked();
 //     assert_eq!(
 //         get_tree_sexp(&buffer, cx),
 //         concat!(
@@ -431,7 +425,7 @@ async fn test_apply_diff(cx: &mut TestAppContext) {
 //         assert_eq!(buf.text(), "fn a(b: C) { d.e::<G>(f); }");
 //         assert!(buf.is_parsing());
 //     });
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
+//     cx.executor().run_until_parked();
 //     assert_eq!(
 //         get_tree_sexp(&buffer, cx),
 //         concat!(
@@ -446,2002 +440,2006 @@ async fn test_apply_diff(cx: &mut TestAppContext) {
 //     );
 // }
 
-// #[gpui::test]
-// async fn test_resetting_language(cx: &mut gpui::TestAppContext) {
-//     let buffer = cx.add_model(|cx| {
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, "{}").with_language(Arc::new(rust_lang()), cx);
-//         buffer.set_sync_parse_timeout(Duration::ZERO);
-//         buffer
-//     });
-
-//     // Wait for the initial text to parse
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
-//     assert_eq!(
-//         get_tree_sexp(&buffer, cx),
-//         "(source_file (expression_statement (block)))"
-//     );
-
-//     buffer.update(cx, |buffer, cx| {
-//         buffer.set_language(Some(Arc::new(json_lang())), cx)
-//     });
-//     buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await;
-//     assert_eq!(get_tree_sexp(&buffer, cx), "(document (object))");
-// }
-
-// #[gpui::test]
-// async fn test_outline(cx: &mut gpui::TestAppContext) {
-//     let text = r#"
-//         struct Person {
-//             name: String,
-//             age: usize,
-//         }
-
-//         mod module {
-//             enum LoginState {
-//                 LoggedOut,
-//                 LoggingOn,
-//                 LoggedIn {
-//                     person: Person,
-//                     time: Instant,
-//                 }
-//             }
-//         }
-
-//         impl Eq for Person {}
-
-//         impl Drop for Person {
-//             fn drop(&mut self) {
-//                 println!("bye");
-//             }
-//         }
-//     "#
-//     .unindent();
-
-//     let buffer = cx.add_model(|cx| {
-//         Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx)
-//     });
-//     let outline = buffer
-//         .read_with(cx, |buffer, _| buffer.snapshot().outline(None))
-//         .unwrap();
-
-//     assert_eq!(
-//         outline
-//             .items
-//             .iter()
-//             .map(|item| (item.text.as_str(), item.depth))
-//             .collect::<Vec<_>>(),
-//         &[
-//             ("struct Person", 0),
-//             ("name", 1),
-//             ("age", 1),
-//             ("mod module", 0),
-//             ("enum LoginState", 1),
-//             ("LoggedOut", 2),
-//             ("LoggingOn", 2),
-//             ("LoggedIn", 2),
-//             ("person", 3),
-//             ("time", 3),
-//             ("impl Eq for Person", 0),
-//             ("impl Drop for Person", 0),
-//             ("fn drop", 1),
-//         ]
-//     );
-
-//     // Without space, we only match on names
-//     assert_eq!(
-//         search(&outline, "oon", cx).await,
-//         &[
-//             ("mod module", vec![]),                    // included as the parent of a match
-//             ("enum LoginState", vec![]),               // included as the parent of a match
-//             ("LoggingOn", vec![1, 7, 8]),              // matches
-//             ("impl Drop for Person", vec![7, 18, 19]), // matches in two disjoint names
-//         ]
-//     );
-
-//     assert_eq!(
-//         search(&outline, "dp p", cx).await,
-//         &[
-//             ("impl Drop for Person", vec![5, 8, 9, 14]),
-//             ("fn drop", vec![]),
-//         ]
-//     );
-//     assert_eq!(
-//         search(&outline, "dpn", cx).await,
-//         &[("impl Drop for Person", vec![5, 14, 19])]
-//     );
-//     assert_eq!(
-//         search(&outline, "impl ", cx).await,
-//         &[
-//             ("impl Eq for Person", vec![0, 1, 2, 3, 4]),
-//             ("impl Drop for Person", vec![0, 1, 2, 3, 4]),
-//             ("fn drop", vec![]),
-//         ]
-//     );
-
-//     async fn search<'a>(
-//         outline: &'a Outline<Anchor>,
-//         query: &'a str,
-//         cx: &'a gpui::TestAppContext,
-//     ) -> Vec<(&'a str, Vec<usize>)> {
-//         let matches = cx
-//             .read(|cx| outline.search(query, cx.background().clone()))
-//             .await;
-//         matches
-//             .into_iter()
-//             .map(|mat| (outline.items[mat.candidate_id].text.as_str(), mat.positions))
-//             .collect::<Vec<_>>()
-//     }
-// }
-
-// #[gpui::test]
-// async fn test_outline_nodes_with_newlines(cx: &mut gpui::TestAppContext) {
-//     let text = r#"
-//         impl A for B<
-//             C
-//         > {
-//         };
-//     "#
-//     .unindent();
-
-//     let buffer = cx.add_model(|cx| {
-//         Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx)
-//     });
-//     let outline = buffer
-//         .read_with(cx, |buffer, _| buffer.snapshot().outline(None))
-//         .unwrap();
-
-//     assert_eq!(
-//         outline
-//             .items
-//             .iter()
-//             .map(|item| (item.text.as_str(), item.depth))
-//             .collect::<Vec<_>>(),
-//         &[("impl A for B<", 0)]
-//     );
-// }
-
-// #[gpui::test]
-// async fn test_outline_with_extra_context(cx: &mut gpui::TestAppContext) {
-//     let language = javascript_lang()
-//         .with_outline_query(
-//             r#"
-//             (function_declaration
-//                 "function" @context
-//                 name: (_) @name
-//                 parameters: (formal_parameters
-//                     "(" @context.extra
-//                     ")" @context.extra)) @item
-//             "#,
-//         )
-//         .unwrap();
-
-//     let text = r#"
-//         function a() {}
-//         function b(c) {}
-//     "#
-//     .unindent();
-
-//     let buffer = cx.add_model(|cx| {
-//         Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(language), cx)
-//     });
-//     let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
-
-//     // extra context nodes are included in the outline.
-//     let outline = snapshot.outline(None).unwrap();
-//     assert_eq!(
-//         outline
-//             .items
-//             .iter()
-//             .map(|item| (item.text.as_str(), item.depth))
-//             .collect::<Vec<_>>(),
-//         &[("function a()", 0), ("function b( )", 0),]
-//     );
-
-//     // extra context nodes do not appear in breadcrumbs.
-//     let symbols = snapshot.symbols_containing(3, None).unwrap();
-//     assert_eq!(
-//         symbols
-//             .iter()
-//             .map(|item| (item.text.as_str(), item.depth))
-//             .collect::<Vec<_>>(),
-//         &[("function a", 0)]
-//     );
-// }
-
-// #[gpui::test]
-// async fn test_symbols_containing(cx: &mut gpui::TestAppContext) {
-//     let text = r#"
-//         impl Person {
-//             fn one() {
-//                 1
-//             }
-
-//             fn two() {
-//                 2
-//             }fn three() {
-//                 3
-//             }
-//         }
-//     "#
-//     .unindent();
-
-//     let buffer = cx.add_model(|cx| {
-//         Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx)
-//     });
-//     let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
-
-//     // point is at the start of an item
-//     assert_eq!(
-//         symbols_containing(Point::new(1, 4), &snapshot),
-//         vec![
-//             (
-//                 "impl Person".to_string(),
-//                 Point::new(0, 0)..Point::new(10, 1)
-//             ),
-//             ("fn one".to_string(), Point::new(1, 4)..Point::new(3, 5))
-//         ]
-//     );
-
-//     // point is in the middle of an item
-//     assert_eq!(
-//         symbols_containing(Point::new(2, 8), &snapshot),
-//         vec![
-//             (
-//                 "impl Person".to_string(),
-//                 Point::new(0, 0)..Point::new(10, 1)
-//             ),
-//             ("fn one".to_string(), Point::new(1, 4)..Point::new(3, 5))
-//         ]
-//     );
-
-//     // point is at the end of an item
-//     assert_eq!(
-//         symbols_containing(Point::new(3, 5), &snapshot),
-//         vec![
-//             (
-//                 "impl Person".to_string(),
-//                 Point::new(0, 0)..Point::new(10, 1)
-//             ),
-//             ("fn one".to_string(), Point::new(1, 4)..Point::new(3, 5))
-//         ]
-//     );
-
-//     // point is in between two adjacent items
-//     assert_eq!(
-//         symbols_containing(Point::new(7, 5), &snapshot),
-//         vec![
-//             (
-//                 "impl Person".to_string(),
-//                 Point::new(0, 0)..Point::new(10, 1)
-//             ),
-//             ("fn two".to_string(), Point::new(5, 4)..Point::new(7, 5))
-//         ]
-//     );
-
-//     fn symbols_containing(
-//         position: Point,
-//         snapshot: &BufferSnapshot,
-//     ) -> Vec<(String, Range<Point>)> {
-//         snapshot
-//             .symbols_containing(position, None)
-//             .unwrap()
-//             .into_iter()
-//             .map(|item| {
-//                 (
-//                     item.text,
-//                     item.range.start.to_point(snapshot)..item.range.end.to_point(snapshot),
-//                 )
-//             })
-//             .collect()
-//     }
-// }
-
-// #[gpui::test]
-// fn test_enclosing_bracket_ranges(cx: &mut AppContext) {
-//     let mut assert = |selection_text, range_markers| {
-//         assert_bracket_pairs(selection_text, range_markers, rust_lang(), cx)
-//     };
-
-//     assert(
-//         indoc! {"
-//             mod x {
-//                 moˇd y {
-
-//                 }
-//             }
-//             let foo = 1;"},
-//         vec![indoc! {"
-//             mod x «{»
-//                 mod y {
-
-//                 }
-//             «}»
-//             let foo = 1;"}],
-//     );
-
-//     assert(
-//         indoc! {"
-//             mod x {
-//                 mod y ˇ{
-
-//                 }
-//             }
-//             let foo = 1;"},
-//         vec![
-//             indoc! {"
-//                 mod x «{»
-//                     mod y {
-
-//                     }
-//                 «}»
-//                 let foo = 1;"},
-//             indoc! {"
-//                 mod x {
-//                     mod y «{»
-
-//                     «}»
-//                 }
-//                 let foo = 1;"},
-//         ],
-//     );
+#[gpui2::test]
+async fn test_resetting_language(cx: &mut gpui2::TestAppContext) {
+    let buffer = cx.entity(|cx| {
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), "{}").with_language(Arc::new(rust_lang()), cx);
+        buffer.set_sync_parse_timeout(Duration::ZERO);
+        buffer
+    });
 
-//     assert(
-//         indoc! {"
-//             mod x {
-//                 mod y {
-
-//                 }ˇ
-//             }
-//             let foo = 1;"},
-//         vec![
-//             indoc! {"
-//                 mod x «{»
-//                     mod y {
-
-//                     }
-//                 «}»
-//                 let foo = 1;"},
-//             indoc! {"
-//                 mod x {
-//                     mod y «{»
-
-//                     «}»
-//                 }
-//                 let foo = 1;"},
-//         ],
-//     );
+    // Wait for the initial text to parse
+    cx.executor().run_until_parked();
+    assert_eq!(
+        get_tree_sexp(&buffer, cx),
+        "(source_file (expression_statement (block)))"
+    );
 
-//     assert(
-//         indoc! {"
-//             mod x {
-//                 mod y {
-
-//                 }
-//             ˇ}
-//             let foo = 1;"},
-//         vec![indoc! {"
-//             mod x «{»
-//                 mod y {
-
-//                 }
-//             «}»
-//             let foo = 1;"}],
-//     );
+    buffer.update(cx, |buffer, cx| {
+        buffer.set_language(Some(Arc::new(json_lang())), cx)
+    });
+    cx.executor().run_until_parked();
+    assert_eq!(get_tree_sexp(&buffer, cx), "(document (object))");
+}
 
-//     assert(
-//         indoc! {"
-//             mod x {
-//                 mod y {
+#[gpui2::test]
+async fn test_outline(cx: &mut gpui2::TestAppContext) {
+    let text = r#"
+        struct Person {
+            name: String,
+            age: usize,
+        }
+
+        mod module {
+            enum LoginState {
+                LoggedOut,
+                LoggingOn,
+                LoggedIn {
+                    person: Person,
+                    time: Instant,
+                }
+            }
+        }
+
+        impl Eq for Person {}
+
+        impl Drop for Person {
+            fn drop(&mut self) {
+                println!("bye");
+            }
+        }
+    "#
+    .unindent();
+
+    let buffer = cx.entity(|cx| {
+        Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
+    });
+    let outline = buffer
+        .update(cx, |buffer, _| buffer.snapshot().outline(None))
+        .unwrap();
+
+    assert_eq!(
+        outline
+            .items
+            .iter()
+            .map(|item| (item.text.as_str(), item.depth))
+            .collect::<Vec<_>>(),
+        &[
+            ("struct Person", 0),
+            ("name", 1),
+            ("age", 1),
+            ("mod module", 0),
+            ("enum LoginState", 1),
+            ("LoggedOut", 2),
+            ("LoggingOn", 2),
+            ("LoggedIn", 2),
+            ("person", 3),
+            ("time", 3),
+            ("impl Eq for Person", 0),
+            ("impl Drop for Person", 0),
+            ("fn drop", 1),
+        ]
+    );
+
+    // Without space, we only match on names
+    assert_eq!(
+        search(&outline, "oon", cx).await,
+        &[
+            ("mod module", vec![]),                    // included as the parent of a match
+            ("enum LoginState", vec![]),               // included as the parent of a match
+            ("LoggingOn", vec![1, 7, 8]),              // matches
+            ("impl Drop for Person", vec![7, 18, 19]), // matches in two disjoint names
+        ]
+    );
+
+    assert_eq!(
+        search(&outline, "dp p", cx).await,
+        &[
+            ("impl Drop for Person", vec![5, 8, 9, 14]),
+            ("fn drop", vec![]),
+        ]
+    );
+    assert_eq!(
+        search(&outline, "dpn", cx).await,
+        &[("impl Drop for Person", vec![5, 14, 19])]
+    );
+    assert_eq!(
+        search(&outline, "impl ", cx).await,
+        &[
+            ("impl Eq for Person", vec![0, 1, 2, 3, 4]),
+            ("impl Drop for Person", vec![0, 1, 2, 3, 4]),
+            ("fn drop", vec![]),
+        ]
+    );
+
+    async fn search<'a>(
+        outline: &'a Outline<Anchor>,
+        query: &'a str,
+        cx: &'a gpui2::TestAppContext,
+    ) -> Vec<(&'a str, Vec<usize>)> {
+        let matches = cx
+            .update(|cx| outline.search(query, cx.executor().clone()))
+            .await;
+        matches
+            .into_iter()
+            .map(|mat| (outline.items[mat.candidate_id].text.as_str(), mat.positions))
+            .collect::<Vec<_>>()
+    }
+}
 
-//                 }
-//             }
-//             let fˇoo = 1;"},
-//         vec![],
-//     );
+#[gpui2::test]
+async fn test_outline_nodes_with_newlines(cx: &mut gpui2::TestAppContext) {
+    let text = r#"
+        impl A for B<
+            C
+        > {
+        };
+    "#
+    .unindent();
+
+    let buffer = cx.entity(|cx| {
+        Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
+    });
+    let outline = buffer
+        .update(cx, |buffer, _| buffer.snapshot().outline(None))
+        .unwrap();
+
+    assert_eq!(
+        outline
+            .items
+            .iter()
+            .map(|item| (item.text.as_str(), item.depth))
+            .collect::<Vec<_>>(),
+        &[("impl A for B<", 0)]
+    );
+}
 
-//     // Regression test: avoid crash when querying at the end of the buffer.
-//     assert(
-//         indoc! {"
-//             mod x {
-//                 mod y {
+#[gpui2::test]
+async fn test_outline_with_extra_context(cx: &mut gpui2::TestAppContext) {
+    let language = javascript_lang()
+        .with_outline_query(
+            r#"
+            (function_declaration
+                "function" @context
+                name: (_) @name
+                parameters: (formal_parameters
+                    "(" @context.extra
+                    ")" @context.extra)) @item
+            "#,
+        )
+        .unwrap();
+
+    let text = r#"
+        function a() {}
+        function b(c) {}
+    "#
+    .unindent();
+
+    let buffer = cx.entity(|cx| {
+        Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(language), cx)
+    });
+    let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
+
+    // extra context nodes are included in the outline.
+    let outline = snapshot.outline(None).unwrap();
+    assert_eq!(
+        outline
+            .items
+            .iter()
+            .map(|item| (item.text.as_str(), item.depth))
+            .collect::<Vec<_>>(),
+        &[("function a()", 0), ("function b( )", 0),]
+    );
+
+    // extra context nodes do not appear in breadcrumbs.
+    let symbols = snapshot.symbols_containing(3, None).unwrap();
+    assert_eq!(
+        symbols
+            .iter()
+            .map(|item| (item.text.as_str(), item.depth))
+            .collect::<Vec<_>>(),
+        &[("function a", 0)]
+    );
+}
 
-//                 }
-//             }
-//             let foo = 1;ˇ"},
-//         vec![],
-//     );
-// }
+#[gpui2::test]
+async fn test_symbols_containing(cx: &mut gpui2::TestAppContext) {
+    let text = r#"
+        impl Person {
+            fn one() {
+                1
+            }
+
+            fn two() {
+                2
+            }fn three() {
+                3
+            }
+        }
+    "#
+    .unindent();
+
+    let buffer = cx.entity(|cx| {
+        Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
+    });
+    let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
+
+    // point is at the start of an item
+    assert_eq!(
+        symbols_containing(Point::new(1, 4), &snapshot),
+        vec![
+            (
+                "impl Person".to_string(),
+                Point::new(0, 0)..Point::new(10, 1)
+            ),
+            ("fn one".to_string(), Point::new(1, 4)..Point::new(3, 5))
+        ]
+    );
+
+    // point is in the middle of an item
+    assert_eq!(
+        symbols_containing(Point::new(2, 8), &snapshot),
+        vec![
+            (
+                "impl Person".to_string(),
+                Point::new(0, 0)..Point::new(10, 1)
+            ),
+            ("fn one".to_string(), Point::new(1, 4)..Point::new(3, 5))
+        ]
+    );
+
+    // point is at the end of an item
+    assert_eq!(
+        symbols_containing(Point::new(3, 5), &snapshot),
+        vec![
+            (
+                "impl Person".to_string(),
+                Point::new(0, 0)..Point::new(10, 1)
+            ),
+            ("fn one".to_string(), Point::new(1, 4)..Point::new(3, 5))
+        ]
+    );
+
+    // point is in between two adjacent items
+    assert_eq!(
+        symbols_containing(Point::new(7, 5), &snapshot),
+        vec![
+            (
+                "impl Person".to_string(),
+                Point::new(0, 0)..Point::new(10, 1)
+            ),
+            ("fn two".to_string(), Point::new(5, 4)..Point::new(7, 5))
+        ]
+    );
+
+    fn symbols_containing(
+        position: Point,
+        snapshot: &BufferSnapshot,
+    ) -> Vec<(String, Range<Point>)> {
+        snapshot
+            .symbols_containing(position, None)
+            .unwrap()
+            .into_iter()
+            .map(|item| {
+                (
+                    item.text,
+                    item.range.start.to_point(snapshot)..item.range.end.to_point(snapshot),
+                )
+            })
+            .collect()
+    }
+}
 
-// #[gpui::test]
-// fn test_enclosing_bracket_ranges_where_brackets_are_not_outermost_children(cx: &mut AppContext) {
-//     let mut assert = |selection_text, bracket_pair_texts| {
-//         assert_bracket_pairs(selection_text, bracket_pair_texts, javascript_lang(), cx)
-//     };
-
-//     assert(
-//         indoc! {"
-//         for (const a in b)ˇ {
-//             // a comment that's longer than the for-loop header
-//         }"},
-//         vec![indoc! {"
-//         for «(»const a in b«)» {
-//             // a comment that's longer than the for-loop header
-//         }"}],
-//     );
+#[gpui2::test]
+fn test_enclosing_bracket_ranges(cx: &mut AppContext) {
+    let mut assert = |selection_text, range_markers| {
+        assert_bracket_pairs(selection_text, range_markers, rust_lang(), cx)
+    };
+
+    assert(
+        indoc! {"
+            mod x {
+                moˇd y {
+
+                }
+            }
+            let foo = 1;"},
+        vec![indoc! {"
+            mod x «{»
+                mod y {
+
+                }
+            «}»
+            let foo = 1;"}],
+    );
+
+    assert(
+        indoc! {"
+            mod x {
+                mod y ˇ{
+
+                }
+            }
+            let foo = 1;"},
+        vec![
+            indoc! {"
+                mod x «{»
+                    mod y {
+
+                    }
+                «}»
+                let foo = 1;"},
+            indoc! {"
+                mod x {
+                    mod y «{»
+
+                    «}»
+                }
+                let foo = 1;"},
+        ],
+    );
+
+    assert(
+        indoc! {"
+            mod x {
+                mod y {
+
+                }ˇ
+            }
+            let foo = 1;"},
+        vec![
+            indoc! {"
+                mod x «{»
+                    mod y {
+
+                    }
+                «}»
+                let foo = 1;"},
+            indoc! {"
+                mod x {
+                    mod y «{»
+
+                    «}»
+                }
+                let foo = 1;"},
+        ],
+    );
+
+    assert(
+        indoc! {"
+            mod x {
+                mod y {
+
+                }
+            ˇ}
+            let foo = 1;"},
+        vec![indoc! {"
+            mod x «{»
+                mod y {
+
+                }
+            «}»
+            let foo = 1;"}],
+    );
+
+    assert(
+        indoc! {"
+            mod x {
+                mod y {
+
+                }
+            }
+            let fˇoo = 1;"},
+        vec![],
+    );
+
+    // Regression test: avoid crash when querying at the end of the buffer.
+    assert(
+        indoc! {"
+            mod x {
+                mod y {
+
+                }
+            }
+            let foo = 1;ˇ"},
+        vec![],
+    );
+}
 
-//     // Regression test: even though the parent node of the parentheses (the for loop) does
-//     // intersect the given range, the parentheses themselves do not contain the range, so
-//     // they should not be returned. Only the curly braces contain the range.
-//     assert(
-//         indoc! {"
-//         for (const a in b) {ˇ
-//             // a comment that's longer than the for-loop header
-//         }"},
-//         vec![indoc! {"
-//         for (const a in b) «{»
-//             // a comment that's longer than the for-loop header
-//         «}»"}],
-//     );
-// }
+#[gpui2::test]
+fn test_enclosing_bracket_ranges_where_brackets_are_not_outermost_children(cx: &mut AppContext) {
+    let mut assert = |selection_text, bracket_pair_texts| {
+        assert_bracket_pairs(selection_text, bracket_pair_texts, javascript_lang(), cx)
+    };
+
+    assert(
+        indoc! {"
+        for (const a in b)ˇ {
+            // a comment that's longer than the for-loop header
+        }"},
+        vec![indoc! {"
+        for «(»const a in b«)» {
+            // a comment that's longer than the for-loop header
+        }"}],
+    );
+
+    // Regression test: even though the parent node of the parentheses (the for loop) does
+    // intersect the given range, the parentheses themselves do not contain the range, so
+    // they should not be returned. Only the curly braces contain the range.
+    assert(
+        indoc! {"
+        for (const a in b) {ˇ
+            // a comment that's longer than the for-loop header
+        }"},
+        vec![indoc! {"
+        for (const a in b) «{»
+            // a comment that's longer than the for-loop header
+        «}»"}],
+    );
+}
 
-// #[gpui::test]
-// fn test_range_for_syntax_ancestor(cx: &mut AppContext) {
-//     cx.add_model(|cx| {
-//         let text = "fn a() { b(|c| {}) }";
-//         let buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-//         let snapshot = buffer.snapshot();
-
-//         assert_eq!(
-//             snapshot.range_for_syntax_ancestor(empty_range_at(text, "|")),
-//             Some(range_of(text, "|"))
-//         );
-//         assert_eq!(
-//             snapshot.range_for_syntax_ancestor(range_of(text, "|")),
-//             Some(range_of(text, "|c|"))
-//         );
-//         assert_eq!(
-//             snapshot.range_for_syntax_ancestor(range_of(text, "|c|")),
-//             Some(range_of(text, "|c| {}"))
-//         );
-//         assert_eq!(
-//             snapshot.range_for_syntax_ancestor(range_of(text, "|c| {}")),
-//             Some(range_of(text, "(|c| {})"))
-//         );
-
-//         buffer
-//     });
+#[gpui2::test]
+fn test_range_for_syntax_ancestor(cx: &mut AppContext) {
+    cx.entity(|cx| {
+        let text = "fn a() { b(|c| {}) }";
+        let buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+        let snapshot = buffer.snapshot();
+
+        assert_eq!(
+            snapshot.range_for_syntax_ancestor(empty_range_at(text, "|")),
+            Some(range_of(text, "|"))
+        );
+        assert_eq!(
+            snapshot.range_for_syntax_ancestor(range_of(text, "|")),
+            Some(range_of(text, "|c|"))
+        );
+        assert_eq!(
+            snapshot.range_for_syntax_ancestor(range_of(text, "|c|")),
+            Some(range_of(text, "|c| {}"))
+        );
+        assert_eq!(
+            snapshot.range_for_syntax_ancestor(range_of(text, "|c| {}")),
+            Some(range_of(text, "(|c| {})"))
+        );
+
+        buffer
+    });
 
-//     fn empty_range_at(text: &str, part: &str) -> Range<usize> {
-//         let start = text.find(part).unwrap();
-//         start..start
-//     }
+    fn empty_range_at(text: &str, part: &str) -> Range<usize> {
+        let start = text.find(part).unwrap();
+        start..start
+    }
 
-//     fn range_of(text: &str, part: &str) -> Range<usize> {
-//         let start = text.find(part).unwrap();
-//         start..start + part.len()
-//     }
-// }
+    fn range_of(text: &str, part: &str) -> Range<usize> {
+        let start = text.find(part).unwrap();
+        start..start + part.len()
+    }
+}
 
-// #[gpui::test]
-// fn test_autoindent_with_soft_tabs(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = "fn a() {}";
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-
-//         buffer.edit([(8..8, "\n\n")], Some(AutoindentMode::EachLine), cx);
-//         assert_eq!(buffer.text(), "fn a() {\n    \n}");
-
-//         buffer.edit(
-//             [(Point::new(1, 4)..Point::new(1, 4), "b()\n")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "fn a() {\n    b()\n    \n}");
-
-//         // Create a field expression on a new line, causing that line
-//         // to be indented.
-//         buffer.edit(
-//             [(Point::new(2, 4)..Point::new(2, 4), ".c")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "fn a() {\n    b()\n        .c\n}");
-
-//         // Remove the dot so that the line is no longer a field expression,
-//         // causing the line to be outdented.
-//         buffer.edit(
-//             [(Point::new(2, 8)..Point::new(2, 9), "")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "fn a() {\n    b()\n    c\n}");
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_with_soft_tabs(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = "fn a() {}";
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+
+        buffer.edit([(8..8, "\n\n")], Some(AutoindentMode::EachLine), cx);
+        assert_eq!(buffer.text(), "fn a() {\n    \n}");
+
+        buffer.edit(
+            [(Point::new(1, 4)..Point::new(1, 4), "b()\n")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "fn a() {\n    b()\n    \n}");
+
+        // Create a field expression on a new line, causing that line
+        // to be indented.
+        buffer.edit(
+            [(Point::new(2, 4)..Point::new(2, 4), ".c")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "fn a() {\n    b()\n        .c\n}");
+
+        // Remove the dot so that the line is no longer a field expression,
+        // causing the line to be outdented.
+        buffer.edit(
+            [(Point::new(2, 8)..Point::new(2, 9), "")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "fn a() {\n    b()\n    c\n}");
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_with_hard_tabs(cx: &mut AppContext) {
-//     init_settings(cx, |settings| {
-//         settings.defaults.hard_tabs = Some(true);
-//     });
+#[gpui2::test]
+fn test_autoindent_with_hard_tabs(cx: &mut AppContext) {
+    init_settings(cx, |settings| {
+        settings.defaults.hard_tabs = Some(true);
+    });
 
-//     cx.add_model(|cx| {
-//         let text = "fn a() {}";
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-
-//         buffer.edit([(8..8, "\n\n")], Some(AutoindentMode::EachLine), cx);
-//         assert_eq!(buffer.text(), "fn a() {\n\t\n}");
-
-//         buffer.edit(
-//             [(Point::new(1, 1)..Point::new(1, 1), "b()\n")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "fn a() {\n\tb()\n\t\n}");
-
-//         // Create a field expression on a new line, causing that line
-//         // to be indented.
-//         buffer.edit(
-//             [(Point::new(2, 1)..Point::new(2, 1), ".c")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "fn a() {\n\tb()\n\t\t.c\n}");
-
-//         // Remove the dot so that the line is no longer a field expression,
-//         // causing the line to be outdented.
-//         buffer.edit(
-//             [(Point::new(2, 2)..Point::new(2, 3), "")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "fn a() {\n\tb()\n\tc\n}");
-
-//         buffer
-//     });
-// }
+    cx.entity(|cx| {
+        let text = "fn a() {}";
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+
+        buffer.edit([(8..8, "\n\n")], Some(AutoindentMode::EachLine), cx);
+        assert_eq!(buffer.text(), "fn a() {\n\t\n}");
+
+        buffer.edit(
+            [(Point::new(1, 1)..Point::new(1, 1), "b()\n")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "fn a() {\n\tb()\n\t\n}");
+
+        // Create a field expression on a new line, causing that line
+        // to be indented.
+        buffer.edit(
+            [(Point::new(2, 1)..Point::new(2, 1), ".c")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "fn a() {\n\tb()\n\t\t.c\n}");
+
+        // Remove the dot so that the line is no longer a field expression,
+        // causing the line to be outdented.
+        buffer.edit(
+            [(Point::new(2, 2)..Point::new(2, 3), "")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "fn a() {\n\tb()\n\tc\n}");
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let mut buffer = Buffer::new(
-//             0,
-//             cx.model_id() as u64,
-//             "
-//             fn a() {
-//             c;
-//             d;
-//             }
-//             "
-//             .unindent(),
-//         )
-//         .with_language(Arc::new(rust_lang()), cx);
-
-//         // Lines 2 and 3 don't match the indentation suggestion. When editing these lines,
-//         // their indentation is not adjusted.
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a() {
-//             c«()»;
-//             d«()»;
-//             }
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a() {
-//             c();
-//             d();
-//             }
-//             "
-//             .unindent()
-//         );
-
-//         // When appending new content after these lines, the indentation is based on the
-//         // preceding lines' actual indentation.
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a() {
-//             c«
-//             .f
-//             .g()»;
-//             d«
-//             .f
-//             .g()»;
-//             }
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a() {
-//             c
-//                 .f
-//                 .g();
-//             d
-//                 .f
-//                 .g();
-//             }
-//             "
-//             .unindent()
-//         );
-//         buffer
-//     });
+#[gpui2::test]
+fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let entity_id = cx.entity_id();
+        let mut buffer = Buffer::new(
+            0,
+            entity_id.as_u64(),
+            "
+            fn a() {
+            c;
+            d;
+            }
+            "
+            .unindent(),
+        )
+        .with_language(Arc::new(rust_lang()), cx);
+
+        // Lines 2 and 3 don't match the indentation suggestion. When editing these lines,
+        // their indentation is not adjusted.
+        buffer.edit_via_marked_text(
+            &"
+            fn a() {
+            c«()»;
+            d«()»;
+            }
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a() {
+            c();
+            d();
+            }
+            "
+            .unindent()
+        );
+
+        // When appending new content after these lines, the indentation is based on the
+        // preceding lines' actual indentation.
+        buffer.edit_via_marked_text(
+            &"
+            fn a() {
+            c«
+            .f
+            .g()»;
+            d«
+            .f
+            .g()»;
+            }
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a() {
+            c
+                .f
+                .g();
+            d
+                .f
+                .g();
+            }
+            "
+            .unindent()
+        );
+        buffer
+    });
 
-//     cx.add_model(|cx| {
-//         let mut buffer = Buffer::new(
-//             0,
-//             cx.model_id() as u64,
-//             "
-//             fn a() {
-//                 b();
-//                 |
-//             "
-//             .replace("|", "") // marker to preserve trailing whitespace
-//             .unindent(),
-//         )
-//         .with_language(Arc::new(rust_lang()), cx);
-
-//         // Insert a closing brace. It is outdented.
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a() {
-//                 b();
-//                 «}»
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a() {
-//                 b();
-//             }
-//             "
-//             .unindent()
-//         );
-
-//         // Manually edit the leading whitespace. The edit is preserved.
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a() {
-//                 b();
-//             «    »}
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a() {
-//                 b();
-//                 }
-//             "
-//             .unindent()
-//         );
-//         buffer
-//     });
-// }
+    cx.entity(|cx| {
+        eprintln!("second buffer: {:?}", cx.entity_id());
+
+        let mut buffer = Buffer::new(
+            0,
+            cx.entity_id().as_u64(),
+            "
+            fn a() {
+                b();
+                |
+            "
+            .replace("|", "") // marker to preserve trailing whitespace
+            .unindent(),
+        )
+        .with_language(Arc::new(rust_lang()), cx);
+
+        // Insert a closing brace. It is outdented.
+        buffer.edit_via_marked_text(
+            &"
+            fn a() {
+                b();
+                «}»
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a() {
+                b();
+            }
+            "
+            .unindent()
+        );
+
+        // Manually edit the leading whitespace. The edit is preserved.
+        buffer.edit_via_marked_text(
+            &"
+            fn a() {
+                b();
+            «    »}
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a() {
+                b();
+                }
+            "
+            .unindent()
+        );
+        buffer
+    });
 
-// #[gpui::test]
-// fn test_autoindent_does_not_adjust_lines_within_newly_created_errors(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let mut buffer = Buffer::new(
-//             0,
-//             cx.model_id() as u64,
-//             "
-//             fn a() {
-//                 i
-//             }
-//             "
-//             .unindent(),
-//         )
-//         .with_language(Arc::new(rust_lang()), cx);
-
-//         // Regression test: line does not get outdented due to syntax error
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a() {
-//                 i«f let Some(x) = y»
-//             }
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a() {
-//                 if let Some(x) = y
-//             }
-//             "
-//             .unindent()
-//         );
-
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a() {
-//                 if let Some(x) = y« {»
-//             }
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a() {
-//                 if let Some(x) = y {
-//             }
-//             "
-//             .unindent()
-//         );
-
-//         buffer
-//     });
-// }
+    eprintln!("DONE");
+}
 
-// #[gpui::test]
-// fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let mut buffer = Buffer::new(
-//             0,
-//             cx.model_id() as u64,
-//             "
-//             fn a() {}
-//             "
-//             .unindent(),
-//         )
-//         .with_language(Arc::new(rust_lang()), cx);
-
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a(«
-//             b») {}
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             fn a(
-//                 b) {}
-//             "
-//             .unindent()
-//         );
-
-//         // The indentation suggestion changed because `@end` node (a close paren)
-//         // is now at the beginning of the line.
-//         buffer.edit_via_marked_text(
-//             &"
-//             fn a(
-//                 ˇ) {}
-//             "
-//             .unindent(),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//                 fn a(
-//                 ) {}
-//             "
-//             .unindent()
-//         );
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_does_not_adjust_lines_within_newly_created_errors(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let mut buffer = Buffer::new(
+            0,
+            cx.entity_id().as_u64(),
+            "
+            fn a() {
+                i
+            }
+            "
+            .unindent(),
+        )
+        .with_language(Arc::new(rust_lang()), cx);
+
+        // Regression test: line does not get outdented due to syntax error
+        buffer.edit_via_marked_text(
+            &"
+            fn a() {
+                i«f let Some(x) = y»
+            }
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a() {
+                if let Some(x) = y
+            }
+            "
+            .unindent()
+        );
+
+        buffer.edit_via_marked_text(
+            &"
+            fn a() {
+                if let Some(x) = y« {»
+            }
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a() {
+                if let Some(x) = y {
+            }
+            "
+            .unindent()
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_with_edit_at_end_of_buffer(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = "a\nb";
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-//         buffer.edit(
-//             [(0..1, "\n"), (2..3, "\n")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(buffer.text(), "\n\n\n");
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let mut buffer = Buffer::new(
+            0,
+            cx.entity_id().as_u64(),
+            "
+            fn a() {}
+            "
+            .unindent(),
+        )
+        .with_language(Arc::new(rust_lang()), cx);
+
+        buffer.edit_via_marked_text(
+            &"
+            fn a(«
+            b») {}
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            fn a(
+                b) {}
+            "
+            .unindent()
+        );
+
+        // The indentation suggestion changed because `@end` node (a close paren)
+        // is now at the beginning of the line.
+        buffer.edit_via_marked_text(
+            &"
+            fn a(
+                ˇ) {}
+            "
+            .unindent(),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+                fn a(
+                ) {}
+            "
+            .unindent()
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_multi_line_insertion(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = "
-//             const a: usize = 1;
-//             fn b() {
-//                 if c {
-//                     let d = 2;
-//                 }
-//             }
-//         "
-//         .unindent();
-
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-//         buffer.edit(
-//             [(Point::new(3, 0)..Point::new(3, 0), "e(\n    f()\n);\n")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//                 const a: usize = 1;
-//                 fn b() {
-//                     if c {
-//                         e(
-//                             f()
-//                         );
-//                         let d = 2;
-//                     }
-//                 }
-//             "
-//             .unindent()
-//         );
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_with_edit_at_end_of_buffer(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = "a\nb";
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+        buffer.edit(
+            [(0..1, "\n"), (2..3, "\n")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(buffer.text(), "\n\n\n");
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_block_mode(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = r#"
-//             fn a() {
-//                 b();
-//             }
-//         "#
-//         .unindent();
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-
-//         // When this text was copied, both of the quotation marks were at the same
-//         // indent level, but the indentation of the first line was not included in
-//         // the copied text. This information is retained in the
-//         // 'original_indent_columns' vector.
-//         let original_indent_columns = vec![4];
-//         let inserted_text = r#"
-//             "
-//                   c
-//                     d
-//                       e
-//                 "
-//         "#
-//         .unindent();
-
-//         // Insert the block at column zero. The entire block is indented
-//         // so that the first line matches the previous line's indentation.
-//         buffer.edit(
-//             [(Point::new(2, 0)..Point::new(2, 0), inserted_text.clone())],
-//             Some(AutoindentMode::Block {
-//                 original_indent_columns: original_indent_columns.clone(),
-//             }),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             r#"
-//             fn a() {
-//                 b();
-//                 "
-//                   c
-//                     d
-//                       e
-//                 "
-//             }
-//             "#
-//             .unindent()
-//         );
-
-//         // Grouping is disabled in tests, so we need 2 undos
-//         buffer.undo(cx); // Undo the auto-indent
-//         buffer.undo(cx); // Undo the original edit
-
-//         // Insert the block at a deeper indent level. The entire block is outdented.
-//         buffer.edit([(Point::new(2, 0)..Point::new(2, 0), "        ")], None, cx);
-//         buffer.edit(
-//             [(Point::new(2, 8)..Point::new(2, 8), inserted_text)],
-//             Some(AutoindentMode::Block {
-//                 original_indent_columns: original_indent_columns.clone(),
-//             }),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             r#"
-//             fn a() {
-//                 b();
-//                 "
-//                   c
-//                     d
-//                       e
-//                 "
-//             }
-//             "#
-//             .unindent()
-//         );
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_multi_line_insertion(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = "
+            const a: usize = 1;
+            fn b() {
+                if c {
+                    let d = 2;
+                }
+            }
+        "
+        .unindent();
+
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+        buffer.edit(
+            [(Point::new(3, 0)..Point::new(3, 0), "e(\n    f()\n);\n")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+                const a: usize = 1;
+                fn b() {
+                    if c {
+                        e(
+                            f()
+                        );
+                        let d = 2;
+                    }
+                }
+            "
+            .unindent()
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = r#"
-//             fn a() {
-//                 if b() {
-
-//                 }
-//             }
-//         "#
-//         .unindent();
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(rust_lang()), cx);
-
-//         // The original indent columns are not known, so this text is
-//         // auto-indented in a block as if the first line was copied in
-//         // its entirety.
-//         let original_indent_columns = Vec::new();
-//         let inserted_text = "    c\n        .d()\n        .e();";
-
-//         // Insert the block at column zero. The entire block is indented
-//         // so that the first line matches the previous line's indentation.
-//         buffer.edit(
-//             [(Point::new(2, 0)..Point::new(2, 0), inserted_text)],
-//             Some(AutoindentMode::Block {
-//                 original_indent_columns: original_indent_columns.clone(),
-//             }),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             r#"
-//             fn a() {
-//                 if b() {
-//                     c
-//                         .d()
-//                         .e();
-//                 }
-//             }
-//             "#
-//             .unindent()
-//         );
-
-//         // Grouping is disabled in tests, so we need 2 undos
-//         buffer.undo(cx); // Undo the auto-indent
-//         buffer.undo(cx); // Undo the original edit
-
-//         // Insert the block at a deeper indent level. The entire block is outdented.
-//         buffer.edit(
-//             [(Point::new(2, 0)..Point::new(2, 0), " ".repeat(12))],
-//             None,
-//             cx,
-//         );
-//         buffer.edit(
-//             [(Point::new(2, 12)..Point::new(2, 12), inserted_text)],
-//             Some(AutoindentMode::Block {
-//                 original_indent_columns: Vec::new(),
-//             }),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             r#"
-//             fn a() {
-//                 if b() {
-//                     c
-//                         .d()
-//                         .e();
-//                 }
-//             }
-//             "#
-//             .unindent()
-//         );
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_block_mode(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = r#"
+            fn a() {
+                b();
+            }
+        "#
+        .unindent();
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+
+        // When this text was copied, both of the quotation marks were at the same
+        // indent level, but the indentation of the first line was not included in
+        // the copied text. This information is retained in the
+        // 'original_indent_columns' vector.
+        let original_indent_columns = vec![4];
+        let inserted_text = r#"
+            "
+                  c
+                    d
+                      e
+                "
+        "#
+        .unindent();
+
+        // Insert the block at column zero. The entire block is indented
+        // so that the first line matches the previous line's indentation.
+        buffer.edit(
+            [(Point::new(2, 0)..Point::new(2, 0), inserted_text.clone())],
+            Some(AutoindentMode::Block {
+                original_indent_columns: original_indent_columns.clone(),
+            }),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            r#"
+            fn a() {
+                b();
+                "
+                  c
+                    d
+                      e
+                "
+            }
+            "#
+            .unindent()
+        );
+
+        // Grouping is disabled in tests, so we need 2 undos
+        buffer.undo(cx); // Undo the auto-indent
+        buffer.undo(cx); // Undo the original edit
+
+        // Insert the block at a deeper indent level. The entire block is outdented.
+        buffer.edit([(Point::new(2, 0)..Point::new(2, 0), "        ")], None, cx);
+        buffer.edit(
+            [(Point::new(2, 8)..Point::new(2, 8), inserted_text)],
+            Some(AutoindentMode::Block {
+                original_indent_columns: original_indent_columns.clone(),
+            }),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            r#"
+            fn a() {
+                b();
+                "
+                  c
+                    d
+                      e
+                "
+            }
+            "#
+            .unindent()
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_language_without_indents_query(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = "
-//             * one
-//                 - a
-//                 - b
-//             * two
-//         "
-//         .unindent();
-
-//         let mut buffer = Buffer::new(0, cx.model_id() as u64, text).with_language(
-//             Arc::new(Language::new(
-//                 LanguageConfig {
-//                     name: "Markdown".into(),
-//                     auto_indent_using_last_non_empty_line: false,
-//                     ..Default::default()
-//                 },
-//                 Some(tree_sitter_json::language()),
-//             )),
-//             cx,
-//         );
-//         buffer.edit(
-//             [(Point::new(3, 0)..Point::new(3, 0), "\n")],
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//             * one
-//                 - a
-//                 - b
-
-//             * two
-//             "
-//             .unindent()
-//         );
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = r#"
+            fn a() {
+                if b() {
+
+                }
+            }
+        "#
+        .unindent();
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
+
+        // The original indent columns are not known, so this text is
+        // auto-indented in a block as if the first line was copied in
+        // its entirety.
+        let original_indent_columns = Vec::new();
+        let inserted_text = "    c\n        .d()\n        .e();";
+
+        // Insert the block at column zero. The entire block is indented
+        // so that the first line matches the previous line's indentation.
+        buffer.edit(
+            [(Point::new(2, 0)..Point::new(2, 0), inserted_text)],
+            Some(AutoindentMode::Block {
+                original_indent_columns: original_indent_columns.clone(),
+            }),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            r#"
+            fn a() {
+                if b() {
+                    c
+                        .d()
+                        .e();
+                }
+            }
+            "#
+            .unindent()
+        );
+
+        // Grouping is disabled in tests, so we need 2 undos
+        buffer.undo(cx); // Undo the auto-indent
+        buffer.undo(cx); // Undo the original edit
+
+        // Insert the block at a deeper indent level. The entire block is outdented.
+        buffer.edit(
+            [(Point::new(2, 0)..Point::new(2, 0), " ".repeat(12))],
+            None,
+            cx,
+        );
+        buffer.edit(
+            [(Point::new(2, 12)..Point::new(2, 12), inserted_text)],
+            Some(AutoindentMode::Block {
+                original_indent_columns: Vec::new(),
+            }),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            r#"
+            fn a() {
+                if b() {
+                    c
+                        .d()
+                        .e();
+                }
+            }
+            "#
+            .unindent()
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_autoindent_with_injected_languages(cx: &mut AppContext) {
-//     init_settings(cx, |settings| {
-//         settings.languages.extend([
-//             (
-//                 "HTML".into(),
-//                 LanguageSettingsContent {
-//                     tab_size: Some(2.try_into().unwrap()),
-//                     ..Default::default()
-//                 },
-//             ),
-//             (
-//                 "JavaScript".into(),
-//                 LanguageSettingsContent {
-//                     tab_size: Some(8.try_into().unwrap()),
-//                     ..Default::default()
-//                 },
-//             ),
-//         ])
-//     });
+#[gpui2::test]
+fn test_autoindent_language_without_indents_query(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = "
+            * one
+                - a
+                - b
+            * two
+        "
+        .unindent();
+
+        let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), text).with_language(
+            Arc::new(Language::new(
+                LanguageConfig {
+                    name: "Markdown".into(),
+                    auto_indent_using_last_non_empty_line: false,
+                    ..Default::default()
+                },
+                Some(tree_sitter_json::language()),
+            )),
+            cx,
+        );
+        buffer.edit(
+            [(Point::new(3, 0)..Point::new(3, 0), "\n")],
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+            * one
+                - a
+                - b
+
+            * two
+            "
+            .unindent()
+        );
+        buffer
+    });
+}
 
-//     let html_language = Arc::new(html_lang());
-
-//     let javascript_language = Arc::new(javascript_lang());
-
-//     let language_registry = Arc::new(LanguageRegistry::test());
-//     language_registry.add(html_language.clone());
-//     language_registry.add(javascript_language.clone());
-
-//     cx.add_model(|cx| {
-//         let (text, ranges) = marked_text_ranges(
-//             &"
-//                 <div>ˇ
-//                 </div>
-//                 <script>
-//                     init({ˇ
-//                     })
-//                 </script>
-//                 <span>ˇ
-//                 </span>
-//             "
-//             .unindent(),
-//             false,
-//         );
-
-//         let mut buffer = Buffer::new(0, cx.model_id() as u64, text);
-//         buffer.set_language_registry(language_registry);
-//         buffer.set_language(Some(html_language), cx);
-//         buffer.edit(
-//             ranges.into_iter().map(|range| (range, "\na")),
-//             Some(AutoindentMode::EachLine),
-//             cx,
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             "
-//                 <div>
-//                   a
-//                 </div>
-//                 <script>
-//                     init({
-//                             a
-//                     })
-//                 </script>
-//                 <span>
-//                   a
-//                 </span>
-//             "
-//             .unindent()
-//         );
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_with_injected_languages(cx: &mut AppContext) {
+    init_settings(cx, |settings| {
+        settings.languages.extend([
+            (
+                "HTML".into(),
+                LanguageSettingsContent {
+                    tab_size: Some(2.try_into().unwrap()),
+                    ..Default::default()
+                },
+            ),
+            (
+                "JavaScript".into(),
+                LanguageSettingsContent {
+                    tab_size: Some(8.try_into().unwrap()),
+                    ..Default::default()
+                },
+            ),
+        ])
+    });
 
-// #[gpui::test]
-// fn test_autoindent_query_with_outdent_captures(cx: &mut AppContext) {
-//     init_settings(cx, |settings| {
-//         settings.defaults.tab_size = Some(2.try_into().unwrap());
-//     });
+    let html_language = Arc::new(html_lang());
+
+    let javascript_language = Arc::new(javascript_lang());
+
+    let language_registry = Arc::new(LanguageRegistry::test());
+    language_registry.add(html_language.clone());
+    language_registry.add(javascript_language.clone());
+
+    cx.entity(|cx| {
+        let (text, ranges) = marked_text_ranges(
+            &"
+                <div>ˇ
+                </div>
+                <script>
+                    init({ˇ
+                    })
+                </script>
+                <span>ˇ
+                </span>
+            "
+            .unindent(),
+            false,
+        );
+
+        let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), text);
+        buffer.set_language_registry(language_registry);
+        buffer.set_language(Some(html_language), cx);
+        buffer.edit(
+            ranges.into_iter().map(|range| (range, "\na")),
+            Some(AutoindentMode::EachLine),
+            cx,
+        );
+        assert_eq!(
+            buffer.text(),
+            "
+                <div>
+                  a
+                </div>
+                <script>
+                    init({
+                            a
+                    })
+                </script>
+                <span>
+                  a
+                </span>
+            "
+            .unindent()
+        );
+        buffer
+    });
+}
 
-//     cx.add_model(|cx| {
-//         let mut buffer =
-//             Buffer::new(0, cx.model_id() as u64, "").with_language(Arc::new(ruby_lang()), cx);
-
-//         let text = r#"
-//             class C
-//             def a(b, c)
-//             puts b
-//             puts c
-//             rescue
-//             puts "errored"
-//             exit 1
-//             end
-//             end
-//         "#
-//         .unindent();
-
-//         buffer.edit([(0..0, text)], Some(AutoindentMode::EachLine), cx);
-
-//         assert_eq!(
-//             buffer.text(),
-//             r#"
-//                 class C
-//                   def a(b, c)
-//                     puts b
-//                     puts c
-//                   rescue
-//                     puts "errored"
-//                     exit 1
-//                   end
-//                 end
-//             "#
-//             .unindent()
-//         );
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_autoindent_query_with_outdent_captures(cx: &mut AppContext) {
+    init_settings(cx, |settings| {
+        settings.defaults.tab_size = Some(2.try_into().unwrap());
+    });
 
-// #[gpui::test]
-// fn test_language_scope_at_with_javascript(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let language = Language::new(
-//             LanguageConfig {
-//                 name: "JavaScript".into(),
-//                 line_comment: Some("// ".into()),
-//                 brackets: BracketPairConfig {
-//                     pairs: vec![
-//                         BracketPair {
-//                             start: "{".into(),
-//                             end: "}".into(),
-//                             close: true,
-//                             newline: false,
-//                         },
-//                         BracketPair {
-//                             start: "'".into(),
-//                             end: "'".into(),
-//                             close: true,
-//                             newline: false,
-//                         },
-//                     ],
-//                     disabled_scopes_by_bracket_ix: vec![
-//                         Vec::new(), //
-//                         vec!["string".into()],
-//                     ],
-//                 },
-//                 overrides: [(
-//                     "element".into(),
-//                     LanguageConfigOverride {
-//                         line_comment: Override::Remove { remove: true },
-//                         block_comment: Override::Set(("{/*".into(), "*/}".into())),
-//                         ..Default::default()
-//                     },
-//                 )]
-//                 .into_iter()
-//                 .collect(),
-//                 ..Default::default()
-//             },
-//             Some(tree_sitter_typescript::language_tsx()),
-//         )
-//         .with_override_query(
-//             r#"
-//                 (jsx_element) @element
-//                 (string) @string
-//             "#,
-//         )
-//         .unwrap();
-
-//         let text = r#"a["b"] = <C d="e"></C>;"#;
-
-//         let buffer =
-//             Buffer::new(0, cx.model_id() as u64, text).with_language(Arc::new(language), cx);
-//         let snapshot = buffer.snapshot();
-
-//         let config = snapshot.language_scope_at(0).unwrap();
-//         assert_eq!(config.line_comment_prefix().unwrap().as_ref(), "// ");
-//         // Both bracket pairs are enabled
-//         assert_eq!(
-//             config.brackets().map(|e| e.1).collect::<Vec<_>>(),
-//             &[true, true]
-//         );
-
-//         let string_config = snapshot.language_scope_at(3).unwrap();
-//         assert_eq!(string_config.line_comment_prefix().unwrap().as_ref(), "// ");
-//         // Second bracket pair is disabled
-//         assert_eq!(
-//             string_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
-//             &[true, false]
-//         );
-
-//         let element_config = snapshot.language_scope_at(10).unwrap();
-//         assert_eq!(element_config.line_comment_prefix(), None);
-//         assert_eq!(
-//             element_config.block_comment_delimiters(),
-//             Some((&"{/*".into(), &"*/}".into()))
-//         );
-//         // Both bracket pairs are enabled
-//         assert_eq!(
-//             element_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
-//             &[true, true]
-//         );
-
-//         buffer
-//     });
-// }
+    cx.entity(|cx| {
+        let mut buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), "").with_language(Arc::new(ruby_lang()), cx);
+
+        let text = r#"
+            class C
+            def a(b, c)
+            puts b
+            puts c
+            rescue
+            puts "errored"
+            exit 1
+            end
+            end
+        "#
+        .unindent();
+
+        buffer.edit([(0..0, text)], Some(AutoindentMode::EachLine), cx);
+
+        assert_eq!(
+            buffer.text(),
+            r#"
+                class C
+                  def a(b, c)
+                    puts b
+                    puts c
+                  rescue
+                    puts "errored"
+                    exit 1
+                  end
+                end
+            "#
+            .unindent()
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_language_scope_at_with_rust(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let language = Language::new(
-//             LanguageConfig {
-//                 name: "Rust".into(),
-//                 brackets: BracketPairConfig {
-//                     pairs: vec![
-//                         BracketPair {
-//                             start: "{".into(),
-//                             end: "}".into(),
-//                             close: true,
-//                             newline: false,
-//                         },
-//                         BracketPair {
-//                             start: "'".into(),
-//                             end: "'".into(),
-//                             close: true,
-//                             newline: false,
-//                         },
-//                     ],
-//                     disabled_scopes_by_bracket_ix: vec![
-//                         Vec::new(), //
-//                         vec!["string".into()],
-//                     ],
-//                 },
-//                 ..Default::default()
-//             },
-//             Some(tree_sitter_rust::language()),
-//         )
-//         .with_override_query(
-//             r#"
-//                 (string_literal) @string
-//             "#,
-//         )
-//         .unwrap();
-
-//         let text = r#"
-//             const S: &'static str = "hello";
-//         "#
-//         .unindent();
-
-//         let buffer = Buffer::new(0, cx.model_id() as u64, text.clone())
-//             .with_language(Arc::new(language), cx);
-//         let snapshot = buffer.snapshot();
-
-//         // By default, all brackets are enabled
-//         let config = snapshot.language_scope_at(0).unwrap();
-//         assert_eq!(
-//             config.brackets().map(|e| e.1).collect::<Vec<_>>(),
-//             &[true, true]
-//         );
-
-//         // Within a string, the quotation brackets are disabled.
-//         let string_config = snapshot
-//             .language_scope_at(text.find("ello").unwrap())
-//             .unwrap();
-//         assert_eq!(
-//             string_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
-//             &[true, false]
-//         );
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_language_scope_at_with_javascript(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let language = Language::new(
+            LanguageConfig {
+                name: "JavaScript".into(),
+                line_comment: Some("// ".into()),
+                brackets: BracketPairConfig {
+                    pairs: vec![
+                        BracketPair {
+                            start: "{".into(),
+                            end: "}".into(),
+                            close: true,
+                            newline: false,
+                        },
+                        BracketPair {
+                            start: "'".into(),
+                            end: "'".into(),
+                            close: true,
+                            newline: false,
+                        },
+                    ],
+                    disabled_scopes_by_bracket_ix: vec![
+                        Vec::new(), //
+                        vec!["string".into()],
+                    ],
+                },
+                overrides: [(
+                    "element".into(),
+                    LanguageConfigOverride {
+                        line_comment: Override::Remove { remove: true },
+                        block_comment: Override::Set(("{/*".into(), "*/}".into())),
+                        ..Default::default()
+                    },
+                )]
+                .into_iter()
+                .collect(),
+                ..Default::default()
+            },
+            Some(tree_sitter_typescript::language_tsx()),
+        )
+        .with_override_query(
+            r#"
+                (jsx_element) @element
+                (string) @string
+            "#,
+        )
+        .unwrap();
+
+        let text = r#"a["b"] = <C d="e"></C>;"#;
+
+        let buffer =
+            Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(language), cx);
+        let snapshot = buffer.snapshot();
+
+        let config = snapshot.language_scope_at(0).unwrap();
+        assert_eq!(config.line_comment_prefix().unwrap().as_ref(), "// ");
+        // Both bracket pairs are enabled
+        assert_eq!(
+            config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, true]
+        );
+
+        let string_config = snapshot.language_scope_at(3).unwrap();
+        assert_eq!(string_config.line_comment_prefix().unwrap().as_ref(), "// ");
+        // Second bracket pair is disabled
+        assert_eq!(
+            string_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, false]
+        );
+
+        let element_config = snapshot.language_scope_at(10).unwrap();
+        assert_eq!(element_config.line_comment_prefix(), None);
+        assert_eq!(
+            element_config.block_comment_delimiters(),
+            Some((&"{/*".into(), &"*/}".into()))
+        );
+        // Both bracket pairs are enabled
+        assert_eq!(
+            element_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, true]
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_language_scope_at_with_combined_injections(cx: &mut AppContext) {
-//     init_settings(cx, |_| {});
-
-//     cx.add_model(|cx| {
-//         let text = r#"
-//             <ol>
-//             <% people.each do |person| %>
-//                 <li>
-//                     <%= person.name %>
-//                 </li>
-//             <% end %>
-//             </ol>
-//         "#
-//         .unindent();
-
-//         let language_registry = Arc::new(LanguageRegistry::test());
-//         language_registry.add(Arc::new(ruby_lang()));
-//         language_registry.add(Arc::new(html_lang()));
-//         language_registry.add(Arc::new(erb_lang()));
-
-//         let mut buffer = Buffer::new(0, cx.model_id() as u64, text);
-//         buffer.set_language_registry(language_registry.clone());
-//         buffer.set_language(
-//             language_registry
-//                 .language_for_name("ERB")
-//                 .now_or_never()
-//                 .unwrap()
-//                 .ok(),
-//             cx,
-//         );
-
-//         let snapshot = buffer.snapshot();
-//         let html_config = snapshot.language_scope_at(Point::new(2, 4)).unwrap();
-//         assert_eq!(html_config.line_comment_prefix(), None);
-//         assert_eq!(
-//             html_config.block_comment_delimiters(),
-//             Some((&"<!--".into(), &"-->".into()))
-//         );
-
-//         let ruby_config = snapshot.language_scope_at(Point::new(3, 12)).unwrap();
-//         assert_eq!(ruby_config.line_comment_prefix().unwrap().as_ref(), "# ");
-//         assert_eq!(ruby_config.block_comment_delimiters(), None);
-
-//         buffer
-//     });
-// }
+#[gpui2::test]
+fn test_language_scope_at_with_rust(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let language = Language::new(
+            LanguageConfig {
+                name: "Rust".into(),
+                brackets: BracketPairConfig {
+                    pairs: vec![
+                        BracketPair {
+                            start: "{".into(),
+                            end: "}".into(),
+                            close: true,
+                            newline: false,
+                        },
+                        BracketPair {
+                            start: "'".into(),
+                            end: "'".into(),
+                            close: true,
+                            newline: false,
+                        },
+                    ],
+                    disabled_scopes_by_bracket_ix: vec![
+                        Vec::new(), //
+                        vec!["string".into()],
+                    ],
+                },
+                ..Default::default()
+            },
+            Some(tree_sitter_rust::language()),
+        )
+        .with_override_query(
+            r#"
+                (string_literal) @string
+            "#,
+        )
+        .unwrap();
+
+        let text = r#"
+            const S: &'static str = "hello";
+        "#
+        .unindent();
+
+        let buffer = Buffer::new(0, cx.entity_id().as_u64(), text.clone())
+            .with_language(Arc::new(language), cx);
+        let snapshot = buffer.snapshot();
+
+        // By default, all brackets are enabled
+        let config = snapshot.language_scope_at(0).unwrap();
+        assert_eq!(
+            config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, true]
+        );
+
+        // Within a string, the quotation brackets are disabled.
+        let string_config = snapshot
+            .language_scope_at(text.find("ello").unwrap())
+            .unwrap();
+        assert_eq!(
+            string_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, false]
+        );
+
+        buffer
+    });
+}
 
-// #[gpui::test]
-// fn test_serialization(cx: &mut gpui::AppContext) {
-//     let mut now = Instant::now();
+#[gpui2::test]
+fn test_language_scope_at_with_combined_injections(cx: &mut AppContext) {
+    init_settings(cx, |_| {});
+
+    cx.entity(|cx| {
+        let text = r#"
+            <ol>
+            <% people.each do |person| %>
+                <li>
+                    <%= person.name %>
+                </li>
+            <% end %>
+            </ol>
+        "#
+        .unindent();
+
+        let language_registry = Arc::new(LanguageRegistry::test());
+        language_registry.add(Arc::new(ruby_lang()));
+        language_registry.add(Arc::new(html_lang()));
+        language_registry.add(Arc::new(erb_lang()));
+
+        let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), text);
+        buffer.set_language_registry(language_registry.clone());
+        buffer.set_language(
+            language_registry
+                .language_for_name("ERB")
+                .now_or_never()
+                .unwrap()
+                .ok(),
+            cx,
+        );
+
+        let snapshot = buffer.snapshot();
+        let html_config = snapshot.language_scope_at(Point::new(2, 4)).unwrap();
+        assert_eq!(html_config.line_comment_prefix(), None);
+        assert_eq!(
+            html_config.block_comment_delimiters(),
+            Some((&"<!--".into(), &"-->".into()))
+        );
+
+        let ruby_config = snapshot.language_scope_at(Point::new(3, 12)).unwrap();
+        assert_eq!(ruby_config.line_comment_prefix().unwrap().as_ref(), "# ");
+        assert_eq!(ruby_config.block_comment_delimiters(), None);
+
+        buffer
+    });
+}
 
-//     let buffer1 = cx.add_model(|cx| {
-//         let mut buffer = Buffer::new(0, cx.model_id() as u64, "abc");
-//         buffer.edit([(3..3, "D")], None, cx);
+#[gpui2::test]
+fn test_serialization(cx: &mut gpui2::AppContext) {
+    let mut now = Instant::now();
 
-//         now += Duration::from_secs(1);
-//         buffer.start_transaction_at(now);
-//         buffer.edit([(4..4, "E")], None, cx);
-//         buffer.end_transaction_at(now, cx);
-//         assert_eq!(buffer.text(), "abcDE");
+    let buffer1 = cx.entity(|cx| {
+        let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "abc");
+        buffer.edit([(3..3, "D")], None, cx);
 
-//         buffer.undo(cx);
-//         assert_eq!(buffer.text(), "abcD");
+        now += Duration::from_secs(1);
+        buffer.start_transaction_at(now);
+        buffer.edit([(4..4, "E")], None, cx);
+        buffer.end_transaction_at(now, cx);
+        assert_eq!(buffer.text(), "abcDE");
 
-//         buffer.edit([(4..4, "F")], None, cx);
-//         assert_eq!(buffer.text(), "abcDF");
-//         buffer
-//     });
-//     assert_eq!(buffer1.read(cx).text(), "abcDF");
-
-//     let state = buffer1.read(cx).to_proto();
-//     let ops = cx
-//         .background()
-//         .block(buffer1.read(cx).serialize_ops(None, cx));
-//     let buffer2 = cx.add_model(|cx| {
-//         let mut buffer = Buffer::from_proto(1, state, None).unwrap();
-//         buffer
-//             .apply_ops(
-//                 ops.into_iter()
-//                     .map(|op| proto::deserialize_operation(op).unwrap()),
-//                 cx,
-//             )
-//             .unwrap();
-//         buffer
-//     });
-//     assert_eq!(buffer2.read(cx).text(), "abcDF");
-// }
+        buffer.undo(cx);
+        assert_eq!(buffer.text(), "abcD");
 
-// #[gpui::test(iterations = 100)]
-// fn test_random_collaboration(cx: &mut AppContext, mut rng: StdRng) {
-//     let min_peers = env::var("MIN_PEERS")
-//         .map(|i| i.parse().expect("invalid `MIN_PEERS` variable"))
-//         .unwrap_or(1);
-//     let max_peers = env::var("MAX_PEERS")
-//         .map(|i| i.parse().expect("invalid `MAX_PEERS` variable"))
-//         .unwrap_or(5);
-//     let operations = env::var("OPERATIONS")
-//         .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
-//         .unwrap_or(10);
-
-//     let base_text_len = rng.gen_range(0..10);
-//     let base_text = RandomCharIter::new(&mut rng)
-//         .take(base_text_len)
-//         .collect::<String>();
-//     let mut replica_ids = Vec::new();
-//     let mut buffers = Vec::new();
-//     let network = Rc::new(RefCell::new(Network::new(rng.clone())));
-//     let base_buffer = cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, base_text.as_str()));
-
-//     for i in 0..rng.gen_range(min_peers..=max_peers) {
-//         let buffer = cx.add_model(|cx| {
-//             let state = base_buffer.read(cx).to_proto();
-//             let ops = cx
-//                 .background()
-//                 .block(base_buffer.read(cx).serialize_ops(None, cx));
-//             let mut buffer = Buffer::from_proto(i as ReplicaId, state, None).unwrap();
-//             buffer
-//                 .apply_ops(
-//                     ops.into_iter()
-//                         .map(|op| proto::deserialize_operation(op).unwrap()),
-//                     cx,
-//                 )
-//                 .unwrap();
-//             buffer.set_group_interval(Duration::from_millis(rng.gen_range(0..=200)));
-//             let network = network.clone();
-//             cx.subscribe(&cx.handle(), move |buffer, _, event, _| {
-//                 if let Event::Operation(op) = event {
-//                     network
-//                         .borrow_mut()
-//                         .broadcast(buffer.replica_id(), vec![proto::serialize_operation(op)]);
-//                 }
-//             })
-//             .detach();
-//             buffer
-//         });
-//         buffers.push(buffer);
-//         replica_ids.push(i as ReplicaId);
-//         network.borrow_mut().add_peer(i as ReplicaId);
-//         log::info!("Adding initial peer with replica id {}", i);
-//     }
-
-//     log::info!("initial text: {:?}", base_text);
-
-//     let mut now = Instant::now();
-//     let mut mutation_count = operations;
-//     let mut next_diagnostic_id = 0;
-//     let mut active_selections = BTreeMap::default();
-//     loop {
-//         let replica_index = rng.gen_range(0..replica_ids.len());
-//         let replica_id = replica_ids[replica_index];
-//         let buffer = &mut buffers[replica_index];
-//         let mut new_buffer = None;
-//         match rng.gen_range(0..100) {
-//             0..=29 if mutation_count != 0 => {
-//                 buffer.update(cx, |buffer, cx| {
-//                     buffer.start_transaction_at(now);
-//                     buffer.randomly_edit(&mut rng, 5, cx);
-//                     buffer.end_transaction_at(now, cx);
-//                     log::info!("buffer {} text: {:?}", buffer.replica_id(), buffer.text());
-//                 });
-//                 mutation_count -= 1;
-//             }
-//             30..=39 if mutation_count != 0 => {
-//                 buffer.update(cx, |buffer, cx| {
-//                     if rng.gen_bool(0.2) {
-//                         log::info!("peer {} clearing active selections", replica_id);
-//                         active_selections.remove(&replica_id);
-//                         buffer.remove_active_selections(cx);
-//                     } else {
-//                         let mut selections = Vec::new();
-//                         for id in 0..rng.gen_range(1..=5) {
-//                             let range = buffer.random_byte_range(0, &mut rng);
-//                             selections.push(Selection {
-//                                 id,
-//                                 start: buffer.anchor_before(range.start),
-//                                 end: buffer.anchor_before(range.end),
-//                                 reversed: false,
-//                                 goal: SelectionGoal::None,
-//                             });
-//                         }
-//                         let selections: Arc<[Selection<Anchor>]> = selections.into();
-//                         log::info!(
-//                             "peer {} setting active selections: {:?}",
-//                             replica_id,
-//                             selections
-//                         );
-//                         active_selections.insert(replica_id, selections.clone());
-//                         buffer.set_active_selections(selections, false, Default::default(), cx);
-//                     }
-//                 });
-//                 mutation_count -= 1;
-//             }
-//             40..=49 if mutation_count != 0 && replica_id == 0 => {
-//                 let entry_count = rng.gen_range(1..=5);
-//                 buffer.update(cx, |buffer, cx| {
-//                     let diagnostics = DiagnosticSet::new(
-//                         (0..entry_count).map(|_| {
-//                             let range = buffer.random_byte_range(0, &mut rng);
-//                             let range = range.to_point_utf16(buffer);
-//                             let range = range.start..range.end;
-//                             DiagnosticEntry {
-//                                 range,
-//                                 diagnostic: Diagnostic {
-//                                     message: post_inc(&mut next_diagnostic_id).to_string(),
-//                                     ..Default::default()
-//                                 },
-//                             }
-//                         }),
-//                         buffer,
-//                     );
-//                     log::info!("peer {} setting diagnostics: {:?}", replica_id, diagnostics);
-//                     buffer.update_diagnostics(LanguageServerId(0), diagnostics, cx);
-//                 });
-//                 mutation_count -= 1;
-//             }
-//             50..=59 if replica_ids.len() < max_peers => {
-//                 let old_buffer_state = buffer.read(cx).to_proto();
-//                 let old_buffer_ops = cx
-//                     .background()
-//                     .block(buffer.read(cx).serialize_ops(None, cx));
-//                 let new_replica_id = (0..=replica_ids.len() as ReplicaId)
-//                     .filter(|replica_id| *replica_id != buffer.read(cx).replica_id())
-//                     .choose(&mut rng)
-//                     .unwrap();
-//                 log::info!(
-//                     "Adding new replica {} (replicating from {})",
-//                     new_replica_id,
-//                     replica_id
-//                 );
-//                 new_buffer = Some(cx.add_model(|cx| {
-//                     let mut new_buffer =
-//                         Buffer::from_proto(new_replica_id, old_buffer_state, None).unwrap();
-//                     new_buffer
-//                         .apply_ops(
-//                             old_buffer_ops
-//                                 .into_iter()
-//                                 .map(|op| deserialize_operation(op).unwrap()),
-//                             cx,
-//                         )
-//                         .unwrap();
-//                     log::info!(
-//                         "New replica {} text: {:?}",
-//                         new_buffer.replica_id(),
-//                         new_buffer.text()
-//                     );
-//                     new_buffer.set_group_interval(Duration::from_millis(rng.gen_range(0..=200)));
-//                     let network = network.clone();
-//                     cx.subscribe(&cx.handle(), move |buffer, _, event, _| {
-//                         if let Event::Operation(op) = event {
-//                             network.borrow_mut().broadcast(
-//                                 buffer.replica_id(),
-//                                 vec![proto::serialize_operation(op)],
-//                             );
-//                         }
-//                     })
-//                     .detach();
-//                     new_buffer
-//                 }));
-//                 network.borrow_mut().replicate(replica_id, new_replica_id);
-
-//                 if new_replica_id as usize == replica_ids.len() {
-//                     replica_ids.push(new_replica_id);
-//                 } else {
-//                     let new_buffer = new_buffer.take().unwrap();
-//                     while network.borrow().has_unreceived(new_replica_id) {
-//                         let ops = network
-//                             .borrow_mut()
-//                             .receive(new_replica_id)
-//                             .into_iter()
-//                             .map(|op| proto::deserialize_operation(op).unwrap());
-//                         if ops.len() > 0 {
-//                             log::info!(
-//                                 "peer {} (version: {:?}) applying {} ops from the network. {:?}",
-//                                 new_replica_id,
-//                                 buffer.read(cx).version(),
-//                                 ops.len(),
-//                                 ops
-//                             );
-//                             new_buffer.update(cx, |new_buffer, cx| {
-//                                 new_buffer.apply_ops(ops, cx).unwrap();
-//                             });
-//                         }
-//                     }
-//                     buffers[new_replica_id as usize] = new_buffer;
-//                 }
-//             }
-//             60..=69 if mutation_count != 0 => {
-//                 buffer.update(cx, |buffer, cx| {
-//                     buffer.randomly_undo_redo(&mut rng, cx);
-//                     log::info!("buffer {} text: {:?}", buffer.replica_id(), buffer.text());
-//                 });
-//                 mutation_count -= 1;
-//             }
-//             _ if network.borrow().has_unreceived(replica_id) => {
-//                 let ops = network
-//                     .borrow_mut()
-//                     .receive(replica_id)
-//                     .into_iter()
-//                     .map(|op| proto::deserialize_operation(op).unwrap());
-//                 if ops.len() > 0 {
-//                     log::info!(
-//                         "peer {} (version: {:?}) applying {} ops from the network. {:?}",
-//                         replica_id,
-//                         buffer.read(cx).version(),
-//                         ops.len(),
-//                         ops
-//                     );
-//                     buffer.update(cx, |buffer, cx| buffer.apply_ops(ops, cx).unwrap());
-//                 }
-//             }
-//             _ => {}
-//         }
-
-//         now += Duration::from_millis(rng.gen_range(0..=200));
-//         buffers.extend(new_buffer);
-
-//         for buffer in &buffers {
-//             buffer.read(cx).check_invariants();
-//         }
-
-//         if mutation_count == 0 && network.borrow().is_idle() {
-//             break;
-//         }
-//     }
-
-//     let first_buffer = buffers[0].read(cx).snapshot();
-//     for buffer in &buffers[1..] {
-//         let buffer = buffer.read(cx).snapshot();
-//         assert_eq!(
-//             buffer.version(),
-//             first_buffer.version(),
-//             "Replica {} version != Replica 0 version",
-//             buffer.replica_id()
-//         );
-//         assert_eq!(
-//             buffer.text(),
-//             first_buffer.text(),
-//             "Replica {} text != Replica 0 text",
-//             buffer.replica_id()
-//         );
-//         assert_eq!(
-//             buffer
-//                 .diagnostics_in_range::<_, usize>(0..buffer.len(), false)
-//                 .collect::<Vec<_>>(),
-//             first_buffer
-//                 .diagnostics_in_range::<_, usize>(0..first_buffer.len(), false)
-//                 .collect::<Vec<_>>(),
-//             "Replica {} diagnostics != Replica 0 diagnostics",
-//             buffer.replica_id()
-//         );
-//     }
-
-//     for buffer in &buffers {
-//         let buffer = buffer.read(cx).snapshot();
-//         let actual_remote_selections = buffer
-//             .remote_selections_in_range(Anchor::MIN..Anchor::MAX)
-//             .map(|(replica_id, _, _, selections)| (replica_id, selections.collect::<Vec<_>>()))
-//             .collect::<Vec<_>>();
-//         let expected_remote_selections = active_selections
-//             .iter()
-//             .filter(|(replica_id, _)| **replica_id != buffer.replica_id())
-//             .map(|(replica_id, selections)| (*replica_id, selections.iter().collect::<Vec<_>>()))
-//             .collect::<Vec<_>>();
-//         assert_eq!(
-//             actual_remote_selections,
-//             expected_remote_selections,
-//             "Replica {} remote selections != expected selections",
-//             buffer.replica_id()
-//         );
-//     }
-// }
+        buffer.edit([(4..4, "F")], None, cx);
+        assert_eq!(buffer.text(), "abcDF");
+        buffer
+    });
+    assert_eq!(buffer1.read(cx).text(), "abcDF");
+
+    let state = buffer1.read(cx).to_proto();
+    let ops = cx
+        .executor()
+        .block(buffer1.read(cx).serialize_ops(None, cx));
+    let buffer2 = cx.entity(|cx| {
+        let mut buffer = Buffer::from_proto(1, state, None).unwrap();
+        buffer
+            .apply_ops(
+                ops.into_iter()
+                    .map(|op| proto::deserialize_operation(op).unwrap()),
+                cx,
+            )
+            .unwrap();
+        buffer
+    });
+    assert_eq!(buffer2.read(cx).text(), "abcDF");
+}
 
-// #[test]
-// fn test_contiguous_ranges() {
-//     assert_eq!(
-//         contiguous_ranges([1, 2, 3, 5, 6, 9, 10, 11, 12].into_iter(), 100).collect::<Vec<_>>(),
-//         &[1..4, 5..7, 9..13]
-//     );
+#[gpui2::test(iterations = 100)]
+fn test_random_collaboration(cx: &mut AppContext, mut rng: StdRng) {
+    let min_peers = env::var("MIN_PEERS")
+        .map(|i| i.parse().expect("invalid `MIN_PEERS` variable"))
+        .unwrap_or(1);
+    let max_peers = env::var("MAX_PEERS")
+        .map(|i| i.parse().expect("invalid `MAX_PEERS` variable"))
+        .unwrap_or(5);
+    let operations = env::var("OPERATIONS")
+        .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
+        .unwrap_or(10);
+
+    let base_text_len = rng.gen_range(0..10);
+    let base_text = RandomCharIter::new(&mut rng)
+        .take(base_text_len)
+        .collect::<String>();
+    let mut replica_ids = Vec::new();
+    let mut buffers = Vec::new();
+    let network = Arc::new(Mutex::new(Network::new(rng.clone())));
+    let base_buffer = cx.entity(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text.as_str()));
+
+    for i in 0..rng.gen_range(min_peers..=max_peers) {
+        let buffer = cx.entity(|cx| {
+            let state = base_buffer.read(cx).to_proto();
+            let ops = cx
+                .executor()
+                .block(base_buffer.read(cx).serialize_ops(None, cx));
+            let mut buffer = Buffer::from_proto(i as ReplicaId, state, None).unwrap();
+            buffer
+                .apply_ops(
+                    ops.into_iter()
+                        .map(|op| proto::deserialize_operation(op).unwrap()),
+                    cx,
+                )
+                .unwrap();
+            buffer.set_group_interval(Duration::from_millis(rng.gen_range(0..=200)));
+            let network = network.clone();
+            cx.subscribe(&cx.handle(), move |buffer, _, event, _| {
+                if let Event::Operation(op) = event {
+                    network
+                        .lock()
+                        .broadcast(buffer.replica_id(), vec![proto::serialize_operation(op)]);
+                }
+            })
+            .detach();
+            buffer
+        });
+        buffers.push(buffer);
+        replica_ids.push(i as ReplicaId);
+        network.lock().add_peer(i as ReplicaId);
+        log::info!("Adding initial peer with replica id {}", i);
+    }
+
+    log::info!("initial text: {:?}", base_text);
+
+    let mut now = Instant::now();
+    let mut mutation_count = operations;
+    let mut next_diagnostic_id = 0;
+    let mut active_selections = BTreeMap::default();
+    loop {
+        let replica_index = rng.gen_range(0..replica_ids.len());
+        let replica_id = replica_ids[replica_index];
+        let buffer = &mut buffers[replica_index];
+        let mut new_buffer = None;
+        match rng.gen_range(0..100) {
+            0..=29 if mutation_count != 0 => {
+                buffer.update(cx, |buffer, cx| {
+                    buffer.start_transaction_at(now);
+                    buffer.randomly_edit(&mut rng, 5, cx);
+                    buffer.end_transaction_at(now, cx);
+                    log::info!("buffer {} text: {:?}", buffer.replica_id(), buffer.text());
+                });
+                mutation_count -= 1;
+            }
+            30..=39 if mutation_count != 0 => {
+                buffer.update(cx, |buffer, cx| {
+                    if rng.gen_bool(0.2) {
+                        log::info!("peer {} clearing active selections", replica_id);
+                        active_selections.remove(&replica_id);
+                        buffer.remove_active_selections(cx);
+                    } else {
+                        let mut selections = Vec::new();
+                        for id in 0..rng.gen_range(1..=5) {
+                            let range = buffer.random_byte_range(0, &mut rng);
+                            selections.push(Selection {
+                                id,
+                                start: buffer.anchor_before(range.start),
+                                end: buffer.anchor_before(range.end),
+                                reversed: false,
+                                goal: SelectionGoal::None,
+                            });
+                        }
+                        let selections: Arc<[Selection<Anchor>]> = selections.into();
+                        log::info!(
+                            "peer {} setting active selections: {:?}",
+                            replica_id,
+                            selections
+                        );
+                        active_selections.insert(replica_id, selections.clone());
+                        buffer.set_active_selections(selections, false, Default::default(), cx);
+                    }
+                });
+                mutation_count -= 1;
+            }
+            40..=49 if mutation_count != 0 && replica_id == 0 => {
+                let entry_count = rng.gen_range(1..=5);
+                buffer.update(cx, |buffer, cx| {
+                    let diagnostics = DiagnosticSet::new(
+                        (0..entry_count).map(|_| {
+                            let range = buffer.random_byte_range(0, &mut rng);
+                            let range = range.to_point_utf16(buffer);
+                            let range = range.start..range.end;
+                            DiagnosticEntry {
+                                range,
+                                diagnostic: Diagnostic {
+                                    message: post_inc(&mut next_diagnostic_id).to_string(),
+                                    ..Default::default()
+                                },
+                            }
+                        }),
+                        buffer,
+                    );
+                    log::info!("peer {} setting diagnostics: {:?}", replica_id, diagnostics);
+                    buffer.update_diagnostics(LanguageServerId(0), diagnostics, cx);
+                });
+                mutation_count -= 1;
+            }
+            50..=59 if replica_ids.len() < max_peers => {
+                let old_buffer_state = buffer.read(cx).to_proto();
+                let old_buffer_ops = cx.executor().block(buffer.read(cx).serialize_ops(None, cx));
+                let new_replica_id = (0..=replica_ids.len() as ReplicaId)
+                    .filter(|replica_id| *replica_id != buffer.read(cx).replica_id())
+                    .choose(&mut rng)
+                    .unwrap();
+                log::info!(
+                    "Adding new replica {} (replicating from {})",
+                    new_replica_id,
+                    replica_id
+                );
+                new_buffer = Some(cx.entity(|cx| {
+                    let mut new_buffer =
+                        Buffer::from_proto(new_replica_id, old_buffer_state, None).unwrap();
+                    new_buffer
+                        .apply_ops(
+                            old_buffer_ops
+                                .into_iter()
+                                .map(|op| deserialize_operation(op).unwrap()),
+                            cx,
+                        )
+                        .unwrap();
+                    log::info!(
+                        "New replica {} text: {:?}",
+                        new_buffer.replica_id(),
+                        new_buffer.text()
+                    );
+                    new_buffer.set_group_interval(Duration::from_millis(rng.gen_range(0..=200)));
+                    let network = network.clone();
+                    cx.subscribe(&cx.handle(), move |buffer, _, event, _| {
+                        if let Event::Operation(op) = event {
+                            network.lock().broadcast(
+                                buffer.replica_id(),
+                                vec![proto::serialize_operation(op)],
+                            );
+                        }
+                    })
+                    .detach();
+                    new_buffer
+                }));
+                network.lock().replicate(replica_id, new_replica_id);
+
+                if new_replica_id as usize == replica_ids.len() {
+                    replica_ids.push(new_replica_id);
+                } else {
+                    let new_buffer = new_buffer.take().unwrap();
+                    while network.lock().has_unreceived(new_replica_id) {
+                        let ops = network
+                            .lock()
+                            .receive(new_replica_id)
+                            .into_iter()
+                            .map(|op| proto::deserialize_operation(op).unwrap());
+                        if ops.len() > 0 {
+                            log::info!(
+                                "peer {} (version: {:?}) applying {} ops from the network. {:?}",
+                                new_replica_id,
+                                buffer.read(cx).version(),
+                                ops.len(),
+                                ops
+                            );
+                            new_buffer.update(cx, |new_buffer, cx| {
+                                new_buffer.apply_ops(ops, cx).unwrap();
+                            });
+                        }
+                    }
+                    buffers[new_replica_id as usize] = new_buffer;
+                }
+            }
+            60..=69 if mutation_count != 0 => {
+                buffer.update(cx, |buffer, cx| {
+                    buffer.randomly_undo_redo(&mut rng, cx);
+                    log::info!("buffer {} text: {:?}", buffer.replica_id(), buffer.text());
+                });
+                mutation_count -= 1;
+            }
+            _ if network.lock().has_unreceived(replica_id) => {
+                let ops = network
+                    .lock()
+                    .receive(replica_id)
+                    .into_iter()
+                    .map(|op| proto::deserialize_operation(op).unwrap());
+                if ops.len() > 0 {
+                    log::info!(
+                        "peer {} (version: {:?}) applying {} ops from the network. {:?}",
+                        replica_id,
+                        buffer.read(cx).version(),
+                        ops.len(),
+                        ops
+                    );
+                    buffer.update(cx, |buffer, cx| buffer.apply_ops(ops, cx).unwrap());
+                }
+            }
+            _ => {}
+        }
+
+        now += Duration::from_millis(rng.gen_range(0..=200));
+        buffers.extend(new_buffer);
+
+        for buffer in &buffers {
+            buffer.read(cx).check_invariants();
+        }
+
+        if mutation_count == 0 && network.lock().is_idle() {
+            break;
+        }
+    }
+
+    let first_buffer = buffers[0].read(cx).snapshot();
+    for buffer in &buffers[1..] {
+        let buffer = buffer.read(cx).snapshot();
+        assert_eq!(
+            buffer.version(),
+            first_buffer.version(),
+            "Replica {} version != Replica 0 version",
+            buffer.replica_id()
+        );
+        assert_eq!(
+            buffer.text(),
+            first_buffer.text(),
+            "Replica {} text != Replica 0 text",
+            buffer.replica_id()
+        );
+        assert_eq!(
+            buffer
+                .diagnostics_in_range::<_, usize>(0..buffer.len(), false)
+                .collect::<Vec<_>>(),
+            first_buffer
+                .diagnostics_in_range::<_, usize>(0..first_buffer.len(), false)
+                .collect::<Vec<_>>(),
+            "Replica {} diagnostics != Replica 0 diagnostics",
+            buffer.replica_id()
+        );
+    }
+
+    for buffer in &buffers {
+        let buffer = buffer.read(cx).snapshot();
+        let actual_remote_selections = buffer
+            .remote_selections_in_range(Anchor::MIN..Anchor::MAX)
+            .map(|(replica_id, _, _, selections)| (replica_id, selections.collect::<Vec<_>>()))
+            .collect::<Vec<_>>();
+        let expected_remote_selections = active_selections
+            .iter()
+            .filter(|(replica_id, _)| **replica_id != buffer.replica_id())
+            .map(|(replica_id, selections)| (*replica_id, selections.iter().collect::<Vec<_>>()))
+            .collect::<Vec<_>>();
+        assert_eq!(
+            actual_remote_selections,
+            expected_remote_selections,
+            "Replica {} remote selections != expected selections",
+            buffer.replica_id()
+        );
+    }
+}
 
-//     // Respects the `max_len` parameter
-//     assert_eq!(
-//         contiguous_ranges(
-//             [2, 3, 4, 5, 6, 7, 8, 9, 23, 24, 25, 26, 30, 31].into_iter(),
-//             3
-//         )
-//         .collect::<Vec<_>>(),
-//         &[2..5, 5..8, 8..10, 23..26, 26..27, 30..32],
-//     );
-// }
+#[test]
+fn test_contiguous_ranges() {
+    assert_eq!(
+        contiguous_ranges([1, 2, 3, 5, 6, 9, 10, 11, 12].into_iter(), 100).collect::<Vec<_>>(),
+        &[1..4, 5..7, 9..13]
+    );
+
+    // Respects the `max_len` parameter
+    assert_eq!(
+        contiguous_ranges(
+            [2, 3, 4, 5, 6, 7, 8, 9, 23, 24, 25, 26, 30, 31].into_iter(),
+            3
+        )
+        .collect::<Vec<_>>(),
+        &[2..5, 5..8, 8..10, 23..26, 26..27, 30..32],
+    );
+}
 
-// #[gpui::test(iterations = 500)]
-// fn test_trailing_whitespace_ranges(mut rng: StdRng) {
-//     // Generate a random multi-line string containing
-//     // some lines with trailing whitespace.
-//     let mut text = String::new();
-//     for _ in 0..rng.gen_range(0..16) {
-//         for _ in 0..rng.gen_range(0..36) {
-//             text.push(match rng.gen_range(0..10) {
-//                 0..=1 => ' ',
-//                 3 => '\t',
-//                 _ => rng.gen_range('a'..'z'),
-//             });
-//         }
-//         text.push('\n');
-//     }
-
-//     match rng.gen_range(0..10) {
-//         // sometimes remove the last newline
-//         0..=1 => drop(text.pop()), //
-
-//         // sometimes add extra newlines
-//         2..=3 => text.push_str(&"\n".repeat(rng.gen_range(1..5))),
-//         _ => {}
-//     }
-
-//     let rope = Rope::from(text.as_str());
-//     let actual_ranges = trailing_whitespace_ranges(&rope);
-//     let expected_ranges = TRAILING_WHITESPACE_REGEX
-//         .find_iter(&text)
-//         .map(|m| m.range())
-//         .collect::<Vec<_>>();
-//     assert_eq!(
-//         actual_ranges,
-//         expected_ranges,
-//         "wrong ranges for text lines:\n{:?}",
-//         text.split("\n").collect::<Vec<_>>()
-//     );
-// }
+#[gpui2::test(iterations = 500)]
+fn test_trailing_whitespace_ranges(mut rng: StdRng) {
+    // Generate a random multi-line string containing
+    // some lines with trailing whitespace.
+    let mut text = String::new();
+    for _ in 0..rng.gen_range(0..16) {
+        for _ in 0..rng.gen_range(0..36) {
+            text.push(match rng.gen_range(0..10) {
+                0..=1 => ' ',
+                3 => '\t',
+                _ => rng.gen_range('a'..'z'),
+            });
+        }
+        text.push('\n');
+    }
+
+    match rng.gen_range(0..10) {
+        // sometimes remove the last newline
+        0..=1 => drop(text.pop()), //
+
+        // sometimes add extra newlines
+        2..=3 => text.push_str(&"\n".repeat(rng.gen_range(1..5))),
+        _ => {}
+    }
+
+    let rope = Rope::from(text.as_str());
+    let actual_ranges = trailing_whitespace_ranges(&rope);
+    let expected_ranges = TRAILING_WHITESPACE_REGEX
+        .find_iter(&text)
+        .map(|m| m.range())
+        .collect::<Vec<_>>();
+    assert_eq!(
+        actual_ranges,
+        expected_ranges,
+        "wrong ranges for text lines:\n{:?}",
+        text.split("\n").collect::<Vec<_>>()
+    );
+}
 
-// fn ruby_lang() -> Language {
-//     Language::new(
-//         LanguageConfig {
-//             name: "Ruby".into(),
-//             path_suffixes: vec!["rb".to_string()],
-//             line_comment: Some("# ".into()),
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_ruby::language()),
-//     )
-//     .with_indents_query(
-//         r#"
-//             (class "end" @end) @indent
-//             (method "end" @end) @indent
-//             (rescue) @outdent
-//             (then) @indent
-//         "#,
-//     )
-//     .unwrap()
-// }
+fn ruby_lang() -> Language {
+    Language::new(
+        LanguageConfig {
+            name: "Ruby".into(),
+            path_suffixes: vec!["rb".to_string()],
+            line_comment: Some("# ".into()),
+            ..Default::default()
+        },
+        Some(tree_sitter_ruby::language()),
+    )
+    .with_indents_query(
+        r#"
+            (class "end" @end) @indent
+            (method "end" @end) @indent
+            (rescue) @outdent
+            (then) @indent
+        "#,
+    )
+    .unwrap()
+}
 
-// fn html_lang() -> Language {
-//     Language::new(
-//         LanguageConfig {
-//             name: "HTML".into(),
-//             block_comment: Some(("<!--".into(), "-->".into())),
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_html::language()),
-//     )
-//     .with_indents_query(
-//         "
-//         (element
-//           (start_tag) @start
-//           (end_tag)? @end) @indent
-//         ",
-//     )
-//     .unwrap()
-//     .with_injection_query(
-//         r#"
-//         (script_element
-//             (raw_text) @content
-//             (#set! "language" "javascript"))
-//         "#,
-//     )
-//     .unwrap()
-// }
+fn html_lang() -> Language {
+    Language::new(
+        LanguageConfig {
+            name: "HTML".into(),
+            block_comment: Some(("<!--".into(), "-->".into())),
+            ..Default::default()
+        },
+        Some(tree_sitter_html::language()),
+    )
+    .with_indents_query(
+        "
+        (element
+          (start_tag) @start
+          (end_tag)? @end) @indent
+        ",
+    )
+    .unwrap()
+    .with_injection_query(
+        r#"
+        (script_element
+            (raw_text) @content
+            (#set! "language" "javascript"))
+        "#,
+    )
+    .unwrap()
+}
 
-// fn erb_lang() -> Language {
-//     Language::new(
-//         LanguageConfig {
-//             name: "ERB".into(),
-//             path_suffixes: vec!["erb".to_string()],
-//             block_comment: Some(("<%#".into(), "%>".into())),
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_embedded_template::language()),
-//     )
-//     .with_injection_query(
-//         r#"
-//             (
-//                 (code) @content
-//                 (#set! "language" "ruby")
-//                 (#set! "combined")
-//             )
-
-//             (
-//                 (content) @content
-//                 (#set! "language" "html")
-//                 (#set! "combined")
-//             )
-//         "#,
-//     )
-//     .unwrap()
-// }
+fn erb_lang() -> Language {
+    Language::new(
+        LanguageConfig {
+            name: "ERB".into(),
+            path_suffixes: vec!["erb".to_string()],
+            block_comment: Some(("<%#".into(), "%>".into())),
+            ..Default::default()
+        },
+        Some(tree_sitter_embedded_template::language()),
+    )
+    .with_injection_query(
+        r#"
+            (
+                (code) @content
+                (#set! "language" "ruby")
+                (#set! "combined")
+            )
+
+            (
+                (content) @content
+                (#set! "language" "html")
+                (#set! "combined")
+            )
+        "#,
+    )
+    .unwrap()
+}
 
-// fn rust_lang() -> Language {
-//     Language::new(
-//         LanguageConfig {
-//             name: "Rust".into(),
-//             path_suffixes: vec!["rs".to_string()],
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_rust::language()),
-//     )
-//     .with_indents_query(
-//         r#"
-//         (call_expression) @indent
-//         (field_expression) @indent
-//         (_ "(" ")" @end) @indent
-//         (_ "{" "}" @end) @indent
-//         "#,
-//     )
-//     .unwrap()
-//     .with_brackets_query(
-//         r#"
-//         ("{" @open "}" @close)
-//         "#,
-//     )
-//     .unwrap()
-//     .with_outline_query(
-//         r#"
-//         (struct_item
-//             "struct" @context
-//             name: (_) @name) @item
-//         (enum_item
-//             "enum" @context
-//             name: (_) @name) @item
-//         (enum_variant
-//             name: (_) @name) @item
-//         (field_declaration
-//             name: (_) @name) @item
-//         (impl_item
-//             "impl" @context
-//             trait: (_)? @name
-//             "for"? @context
-//             type: (_) @name) @item
-//         (function_item
-//             "fn" @context
-//             name: (_) @name) @item
-//         (mod_item
-//             "mod" @context
-//             name: (_) @name) @item
-//         "#,
-//     )
-//     .unwrap()
-// }
+fn rust_lang() -> Language {
+    Language::new(
+        LanguageConfig {
+            name: "Rust".into(),
+            path_suffixes: vec!["rs".to_string()],
+            ..Default::default()
+        },
+        Some(tree_sitter_rust::language()),
+    )
+    .with_indents_query(
+        r#"
+        (call_expression) @indent
+        (field_expression) @indent
+        (_ "(" ")" @end) @indent
+        (_ "{" "}" @end) @indent
+        "#,
+    )
+    .unwrap()
+    .with_brackets_query(
+        r#"
+        ("{" @open "}" @close)
+        "#,
+    )
+    .unwrap()
+    .with_outline_query(
+        r#"
+        (struct_item
+            "struct" @context
+            name: (_) @name) @item
+        (enum_item
+            "enum" @context
+            name: (_) @name) @item
+        (enum_variant
+            name: (_) @name) @item
+        (field_declaration
+            name: (_) @name) @item
+        (impl_item
+            "impl" @context
+            trait: (_)? @name
+            "for"? @context
+            type: (_) @name) @item
+        (function_item
+            "fn" @context
+            name: (_) @name) @item
+        (mod_item
+            "mod" @context
+            name: (_) @name) @item
+        "#,
+    )
+    .unwrap()
+}
 
-// fn json_lang() -> Language {
-//     Language::new(
-//         LanguageConfig {
-//             name: "Json".into(),
-//             path_suffixes: vec!["js".to_string()],
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_json::language()),
-//     )
-// }
+fn json_lang() -> Language {
+    Language::new(
+        LanguageConfig {
+            name: "Json".into(),
+            path_suffixes: vec!["js".to_string()],
+            ..Default::default()
+        },
+        Some(tree_sitter_json::language()),
+    )
+}
 
-// fn javascript_lang() -> Language {
-//     Language::new(
-//         LanguageConfig {
-//             name: "JavaScript".into(),
-//             ..Default::default()
-//         },
-//         Some(tree_sitter_typescript::language_tsx()),
-//     )
-//     .with_brackets_query(
-//         r#"
-//         ("{" @open "}" @close)
-//         ("(" @open ")" @close)
-//         "#,
-//     )
-//     .unwrap()
-//     .with_indents_query(
-//         r#"
-//         (object "}" @end) @indent
-//         "#,
-//     )
-//     .unwrap()
-// }
+fn javascript_lang() -> Language {
+    Language::new(
+        LanguageConfig {
+            name: "JavaScript".into(),
+            ..Default::default()
+        },
+        Some(tree_sitter_typescript::language_tsx()),
+    )
+    .with_brackets_query(
+        r#"
+        ("{" @open "}" @close)
+        ("(" @open ")" @close)
+        "#,
+    )
+    .unwrap()
+    .with_indents_query(
+        r#"
+        (object "}" @end) @indent
+        "#,
+    )
+    .unwrap()
+}
 
-// fn get_tree_sexp(buffer: &ModelHandle<Buffer>, cx: &gpui::TestAppContext) -> String {
-//     buffer.read_with(cx, |buffer, _| {
-//         let snapshot = buffer.snapshot();
-//         let layers = snapshot.syntax.layers(buffer.as_text_snapshot());
-//         layers[0].node().to_sexp()
-//     })
-// }
+fn get_tree_sexp(buffer: &Handle<Buffer>, cx: &mut gpui2::TestAppContext) -> String {
+    buffer.update(cx, |buffer, _| {
+        let snapshot = buffer.snapshot();
+        let layers = snapshot.syntax.layers(buffer.as_text_snapshot());
+        layers[0].node().to_sexp()
+    })
+}
 
-// // Assert that the enclosing bracket ranges around the selection match the pairs indicated by the marked text in `range_markers`
-// fn assert_bracket_pairs(
-//     selection_text: &'static str,
-//     bracket_pair_texts: Vec<&'static str>,
-//     language: Language,
-//     cx: &mut AppContext,
-// ) {
-//     let (expected_text, selection_ranges) = marked_text_ranges(selection_text, false);
-//     let buffer = cx.add_model(|cx| {
-//         Buffer::new(0, cx.model_id() as u64, expected_text.clone())
-//             .with_language(Arc::new(language), cx)
-//     });
-//     let buffer = buffer.update(cx, |buffer, _cx| buffer.snapshot());
-
-//     let selection_range = selection_ranges[0].clone();
-
-//     let bracket_pairs = bracket_pair_texts
-//         .into_iter()
-//         .map(|pair_text| {
-//             let (bracket_text, ranges) = marked_text_ranges(pair_text, false);
-//             assert_eq!(bracket_text, expected_text);
-//             (ranges[0].clone(), ranges[1].clone())
-//         })
-//         .collect::<Vec<_>>();
-
-//     assert_set_eq!(
-//         buffer.bracket_ranges(selection_range).collect::<Vec<_>>(),
-//         bracket_pairs
-//     );
-// }
+// Assert that the enclosing bracket ranges around the selection match the pairs indicated by the marked text in `range_markers`
+fn assert_bracket_pairs(
+    selection_text: &'static str,
+    bracket_pair_texts: Vec<&'static str>,
+    language: Language,
+    cx: &mut AppContext,
+) {
+    let (expected_text, selection_ranges) = marked_text_ranges(selection_text, false);
+    let buffer = cx.entity(|cx| {
+        Buffer::new(0, cx.entity_id().as_u64(), expected_text.clone())
+            .with_language(Arc::new(language), cx)
+    });
+    let buffer = buffer.update(cx, |buffer, _cx| buffer.snapshot());
+
+    let selection_range = selection_ranges[0].clone();
+
+    let bracket_pairs = bracket_pair_texts
+        .into_iter()
+        .map(|pair_text| {
+            let (bracket_text, ranges) = marked_text_ranges(pair_text, false);
+            assert_eq!(bracket_text, expected_text);
+            (ranges[0].clone(), ranges[1].clone())
+        })
+        .collect::<Vec<_>>();
+
+    assert_set_eq!(
+        buffer.bracket_ranges(selection_range).collect::<Vec<_>>(),
+        bracket_pairs
+    );
+}
 
-// fn init_settings(cx: &mut AppContext, f: fn(&mut AllLanguageSettingsContent)) {
-//     cx.set_global(SettingsStore::test(cx));
-//     crate::init(cx);
-//     cx.update_global::<SettingsStore, _, _>(|settings, cx| {
-//         settings.update_user_settings::<AllLanguageSettings>(cx, f);
-//     });
-// }
+fn init_settings(cx: &mut AppContext, f: fn(&mut AllLanguageSettingsContent)) {
+    let settings_store = SettingsStore::test(cx);
+    cx.set_global(settings_store);
+    crate::init(cx);
+    cx.update_global::<SettingsStore, _>(|settings, cx| {
+        settings.update_user_settings::<AllLanguageSettings>(cx, f);
+    });
+}