WIP: Move sum_tree module into gpui so we can use it in List

Nathan Sobo created

Change summary

Cargo.lock                               | 19 +++-
gpui/Cargo.toml                          |  1 
gpui/src/elements.rs                     |  2 
gpui/src/elements/list.rs                | 45 +++++++++++++
gpui/src/lib.rs                          |  1 
gpui/src/sum_tree.rs                     | 48 ++++++++++---
gpui/src/sum_tree/cursor.rs              |  6 
zed/Cargo.toml                           |  2 
zed/src/editor/buffer.rs                 | 46 +++++++------
zed/src/editor/buffer/operation_queue.rs | 85 ++++++++++++-------------
zed/src/editor/buffer/rope.rs            | 10 +-
zed/src/editor/display_map/fold_map.rs   |  9 -
zed/src/editor/display_map/wrap_map.rs   | 17 ++--
zed/src/lib.rs                           |  2 
zed/src/util.rs                          | 24 -------
zed/src/worktree.rs                      |  7 +
16 files changed, 188 insertions(+), 136 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -162,6 +162,12 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
 
+[[package]]
+name = "arrayvec"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd"
+
 [[package]]
 name = "ascii"
 version = "1.0.0"
@@ -626,7 +632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
 dependencies = [
  "arrayref",
- "arrayvec",
+ "arrayvec 0.5.2",
  "constant_time_eq",
 ]
 
@@ -637,7 +643,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3"
 dependencies = [
  "arrayref",
- "arrayvec",
+ "arrayvec 0.5.2",
  "cc",
  "cfg-if 0.1.10",
  "constant_time_eq",
@@ -2145,6 +2151,7 @@ name = "gpui"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "arrayvec 0.7.1",
  "async-task",
  "backtrace",
  "bindgen",
@@ -2632,7 +2639,7 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e30b1df631d23875f230ed3ddd1a88c231f269a04b2044eb6ca87e763b5f4c42"
 dependencies = [
- "arrayvec",
+ "arrayvec 0.5.2",
 ]
 
 [[package]]
@@ -2665,7 +2672,7 @@ version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
 dependencies = [
- "arrayvec",
+ "arrayvec 0.5.2",
  "bitflags 1.2.1",
  "cfg-if 1.0.0",
  "ryu",
@@ -5164,7 +5171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1bf81f2900d2e235220e6f31ec9f63ade6a7f59090c556d74fe949bb3b15e9fe"
 dependencies = [
  "arrayref",
- "arrayvec",
+ "arrayvec 0.5.2",
  "bytemuck",
  "cfg-if 1.0.0",
  "png 0.16.8",
@@ -5792,7 +5799,7 @@ name = "zed"
 version = "0.1.0"
 dependencies = [
  "anyhow",
- "arrayvec",
+ "arrayvec 0.7.1",
  "async-trait",
  "async-tungstenite",
  "cargo-bundle",

gpui/Cargo.toml 🔗

@@ -5,6 +5,7 @@ name = "gpui"
 version = "0.1.0"
 
 [dependencies]
+arrayvec = "0.7.1"
 async-task = "4.0.3"
 backtrace = "0.3"
 ctor = "0.1"

gpui/src/elements.rs 🔗

@@ -7,6 +7,7 @@ mod event_handler;
 mod flex;
 mod label;
 mod line_box;
+mod list;
 mod mouse_event_handler;
 mod stack;
 mod svg;
@@ -22,6 +23,7 @@ pub use event_handler::*;
 pub use flex::*;
 pub use label::*;
 pub use line_box::*;
+pub use list::*;
 pub use mouse_event_handler::*;
 pub use stack::*;
 pub use svg::*;

gpui/src/elements/list.rs 🔗

@@ -0,0 +1,45 @@
+use crate::sum_tree::{self, SumTree};
+use parking_lot::Mutex;
+use std::sync::Arc;
+
+use crate::ElementBox;
+
+pub struct List {
+    state: ListState,
+}
+
+pub struct ListState(Arc<Mutex<StateInner>>);
+
+struct StateInner {
+    elements: Vec<ElementBox>,
+    element_heights: SumTree<ElementHeight>,
+}
+
+#[derive(Clone, Debug)]
+enum ElementHeight {
+    Pending,
+    Ready(f32),
+}
+
+#[derive(Clone, Debug, Default)]
+struct ElementHeightSummary {
+    pending_count: usize,
+    height: f32,
+}
+
+impl sum_tree::Item for ElementHeight {
+    type Summary = ElementHeightSummary;
+
+    fn summary(&self) -> Self::Summary {
+        todo!()
+    }
+}
+
+impl sum_tree::Summary for ElementHeightSummary {
+    type Context = ();
+
+    fn add_summary(&mut self, summary: &Self, cx: &Self::Context) {
+        self.pending_count += summary.pending_count;
+        self.height += summary.height;
+    }
+}

gpui/src/lib.rs 🔗

@@ -1,6 +1,7 @@
 mod app;
 pub use app::*;
 mod assets;
+pub mod sum_tree;
 #[cfg(test)]
 mod test;
 pub use assets::*;

zed/src/sum_tree.rs → gpui/src/sum_tree.rs 🔗

@@ -1,6 +1,5 @@
 mod cursor;
 
-use crate::util::Bias;
 use arrayvec::ArrayVec;
 pub use cursor::Cursor;
 pub use cursor::FilterCursor;
@@ -47,6 +46,29 @@ impl<'a, S: Summary, T: Dimension<'a, S> + Ord> SeekDimension<'a, S> for T {
     }
 }
 
+#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
+pub enum Bias {
+    Left,
+    Right,
+}
+
+impl PartialOrd for Bias {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Bias {
+    fn cmp(&self, other: &Self) -> Ordering {
+        match (self, other) {
+            (Self::Left, Self::Left) => Ordering::Equal,
+            (Self::Left, Self::Right) => Ordering::Less,
+            (Self::Right, Self::Right) => Ordering::Equal,
+            (Self::Right, Self::Left) => Ordering::Greater,
+        }
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct SumTree<T: Item>(Arc<Node<T>>);
 
@@ -253,8 +275,8 @@ impl<T: Item> SumTree<T> {
                 summary.add_summary(other_node.summary(), cx);
 
                 let height_delta = *height - other_node.height();
-                let mut summaries_to_append = ArrayVec::<[T::Summary; 2 * TREE_BASE]>::new();
-                let mut trees_to_append = ArrayVec::<[SumTree<T>; 2 * TREE_BASE]>::new();
+                let mut summaries_to_append = ArrayVec::<T::Summary, { 2 * TREE_BASE }>::new();
+                let mut trees_to_append = ArrayVec::<SumTree<T>, { 2 * TREE_BASE }>::new();
                 if height_delta == 0 {
                     summaries_to_append.extend(other_node.child_summaries().iter().cloned());
                     trees_to_append.extend(other_node.child_trees().iter().cloned());
@@ -277,8 +299,8 @@ impl<T: Item> SumTree<T> {
 
                 let child_count = child_trees.len() + trees_to_append.len();
                 if child_count > 2 * TREE_BASE {
-                    let left_summaries: ArrayVec<_>;
-                    let right_summaries: ArrayVec<_>;
+                    let left_summaries: ArrayVec<_, { 2 * TREE_BASE }>;
+                    let right_summaries: ArrayVec<_, { 2 * TREE_BASE }>;
                     let left_trees;
                     let right_trees;
 
@@ -323,7 +345,7 @@ impl<T: Item> SumTree<T> {
                     let left_items;
                     let right_items;
                     let left_summaries;
-                    let right_summaries: ArrayVec<[T::Summary; 2 * TREE_BASE]>;
+                    let right_summaries: ArrayVec<T::Summary, { 2 * TREE_BASE }>;
 
                     let midpoint = (child_count + child_count % 2) / 2;
                     {
@@ -491,13 +513,13 @@ pub enum Node<T: Item> {
     Internal {
         height: u8,
         summary: T::Summary,
-        child_summaries: ArrayVec<[T::Summary; 2 * TREE_BASE]>,
-        child_trees: ArrayVec<[SumTree<T>; 2 * TREE_BASE]>,
+        child_summaries: ArrayVec<T::Summary, { 2 * TREE_BASE }>,
+        child_trees: ArrayVec<SumTree<T>, { 2 * TREE_BASE }>,
     },
     Leaf {
         summary: T::Summary,
-        items: ArrayVec<[T; 2 * TREE_BASE]>,
-        item_summaries: ArrayVec<[T::Summary; 2 * TREE_BASE]>,
+        items: ArrayVec<T, { 2 * TREE_BASE }>,
+        item_summaries: ArrayVec<T::Summary, { 2 * TREE_BASE }>,
     },
 }
 
@@ -532,14 +554,14 @@ impl<T: Item> Node<T> {
         }
     }
 
-    fn child_trees(&self) -> &ArrayVec<[SumTree<T>; 2 * TREE_BASE]> {
+    fn child_trees(&self) -> &ArrayVec<SumTree<T>, { 2 * TREE_BASE }> {
         match self {
             Node::Internal { child_trees, .. } => child_trees,
             Node::Leaf { .. } => panic!("Leaf nodes have no child trees"),
         }
     }
 
-    fn items(&self) -> &ArrayVec<[T; 2 * TREE_BASE]> {
+    fn items(&self) -> &ArrayVec<T, { 2 * TREE_BASE }> {
         match self {
             Node::Leaf { items, .. } => items,
             Node::Internal { .. } => panic!("Internal nodes have no items"),
@@ -603,7 +625,7 @@ mod tests {
         );
     }
 
-    #[gpui::test(iterations = 100)]
+    #[crate::test(self, iterations = 100)]
     fn test_random(mut rng: StdRng) {
         let rng = &mut rng;
         let mut tree = SumTree::<u8>::new();

zed/src/sum_tree/cursor.rs → gpui/src/sum_tree/cursor.rs 🔗

@@ -13,7 +13,7 @@ struct StackEntry<'a, T: Item, S, U> {
 #[derive(Clone)]
 pub struct Cursor<'a, T: Item, S, U> {
     tree: &'a SumTree<T>,
-    stack: ArrayVec<[StackEntry<'a, T, S, U>; 16]>,
+    stack: ArrayVec<StackEntry<'a, T, S, U>, 16>,
     seek_dimension: S,
     sum_dimension: U,
     did_seek: bool,
@@ -495,8 +495,8 @@ where
                     ref item_summaries,
                     ..
                 } => {
-                    let mut slice_items = ArrayVec::<[T; 2 * TREE_BASE]>::new();
-                    let mut slice_item_summaries = ArrayVec::<[T::Summary; 2 * TREE_BASE]>::new();
+                    let mut slice_items = ArrayVec::<T, { 2 * TREE_BASE }>::new();
+                    let mut slice_item_summaries = ArrayVec::<T::Summary, { 2 * TREE_BASE }>::new();
                     let mut slice_items_summary = match aggregate {
                         SeekAggregate::Slice(_) => Some(T::Summary::default()),
                         _ => None,

zed/Cargo.toml 🔗

@@ -18,8 +18,8 @@ test-support = ["tempdir", "zrpc/test-support"]
 
 [dependencies]
 anyhow = "1.0.38"
-arrayvec = "0.5.2"
 async-trait = "0.1"
+arrayvec = "0.7.1"
 async-tungstenite = { version = "0.14", features = ["async-tls"] }
 crossbeam-channel = "0.5.0"
 ctor = "0.1.20"

zed/src/editor/buffer.rs 🔗

@@ -1,30 +1,30 @@
 mod anchor;
+mod operation_queue;
 mod point;
 pub mod rope;
 mod selection;
 
-pub use anchor::*;
-use parking_lot::Mutex;
-pub use point::*;
-pub use rope::{Chunks, Rope, TextSummary};
-use seahash::SeaHasher;
-pub use selection::*;
-use similar::{ChangeTag, TextDiff};
-use tree_sitter::{InputEdit, Parser, QueryCursor};
-use zrpc::proto;
-
 use crate::{
     language::{Language, Tree},
-    operation_queue::{self, OperationQueue},
     settings::{HighlightId, HighlightMap},
-    sum_tree::{self, FilterCursor, SumTree},
     time::{self, ReplicaId},
     util::Bias,
     worktree::{File, Worktree},
 };
+pub use anchor::*;
 use anyhow::{anyhow, Result};
-use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
+use gpui::{
+    sum_tree::{self, FilterCursor, SumTree},
+    AppContext, Entity, ModelContext, ModelHandle, Task,
+};
 use lazy_static::lazy_static;
+use operation_queue::OperationQueue;
+use parking_lot::Mutex;
+pub use point::*;
+pub use rope::{Chunks, Rope, TextSummary};
+use seahash::SeaHasher;
+pub use selection::*;
+use similar::{ChangeTag, TextDiff};
 use std::{
     cell::RefCell,
     cmp,
@@ -37,6 +37,8 @@ use std::{
     sync::Arc,
     time::{Duration, Instant, SystemTime, UNIX_EPOCH},
 };
+use tree_sitter::{InputEdit, Parser, QueryCursor};
+use zrpc::proto;
 
 #[derive(Clone, Default)]
 struct DeterministicState;
@@ -120,7 +122,7 @@ pub struct Buffer {
     syntax_tree: Mutex<Option<SyntaxTree>>,
     is_parsing: bool,
     selections: HashMap<SelectionSetId, SelectionSet>,
-    deferred_ops: OperationQueue<Operation>,
+    deferred_ops: OperationQueue,
     deferred_replicas: HashSet<ReplicaId>,
     replica_id: ReplicaId,
     remote_id: u64,
@@ -483,6 +485,8 @@ pub enum Operation {
         set_id: Option<SelectionSetId>,
         lamport_timestamp: time::Lamport,
     },
+    #[cfg(test)]
+    Test(time::Lamport),
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -1390,6 +1394,8 @@ impl Buffer {
                 }
                 self.lamport_clock.observe(lamport_timestamp);
             }
+            #[cfg(test)]
+            Operation::Test(_) => {}
         }
         Ok(())
     }
@@ -1731,6 +1737,8 @@ impl Buffer {
                 Operation::SetActiveSelections { set_id, .. } => {
                     set_id.map_or(true, |set_id| self.selections.contains_key(&set_id))
                 }
+                #[cfg(test)]
+                Operation::Test(_) => true,
             }
         }
     }
@@ -2564,6 +2572,8 @@ impl Operation {
             Operation::SetActiveSelections {
                 lamport_timestamp, ..
             } => *lamport_timestamp,
+            #[cfg(test)]
+            Operation::Test(lamport_timestamp) => *lamport_timestamp,
         }
     }
 
@@ -2630,6 +2640,8 @@ impl<'a> Into<proto::Operation> for &'a Operation {
                         lamport_timestamp: lamport_timestamp.value,
                     },
                 ),
+                #[cfg(test)]
+                Operation::Test(_) => unimplemented!()
             }),
         }
     }
@@ -2834,12 +2846,6 @@ impl TryFrom<proto::Selection> for Selection {
     }
 }
 
-impl operation_queue::Operation for Operation {
-    fn timestamp(&self) -> time::Lamport {
-        self.lamport_timestamp()
-    }
-}
-
 pub trait ToOffset {
     fn to_offset<'a>(&self, content: impl Into<Content<'a>>) -> usize;
 }

zed/src/operation_queue.rs → zed/src/editor/buffer/operation_queue.rs 🔗

@@ -1,26 +1,27 @@
-use crate::{
-    sum_tree::{Cursor, Dimension, Edit, Item, KeyedItem, SumTree, Summary},
-    time,
-};
+use super::Operation;
+use crate::time;
+use gpui::sum_tree::{Cursor, Dimension, Edit, Item, KeyedItem, SumTree, Summary};
 use std::{fmt::Debug, ops::Add};
 
-pub trait Operation: Clone + Debug + Eq {
-    fn timestamp(&self) -> time::Lamport;
-}
-
 #[derive(Clone, Debug)]
-pub struct OperationQueue<T: Operation>(SumTree<T>);
+pub struct OperationQueue(SumTree<Operation>);
 
 #[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
 pub struct OperationKey(time::Lamport);
 
 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
 pub struct OperationSummary {
-    key: OperationKey,
-    len: usize,
+    pub key: OperationKey,
+    pub len: usize,
+}
+
+impl OperationKey {
+    pub fn new(timestamp: time::Lamport) -> Self {
+        Self(timestamp)
+    }
 }
 
-impl<T: Operation> OperationQueue<T> {
+impl OperationQueue {
     pub fn new() -> Self {
         OperationQueue(SumTree::new())
     }
@@ -29,9 +30,9 @@ impl<T: Operation> OperationQueue<T> {
         self.0.summary().len
     }
 
-    pub fn insert(&mut self, mut ops: Vec<T>) {
-        ops.sort_by_key(|op| op.timestamp());
-        ops.dedup_by_key(|op| op.timestamp());
+    pub fn insert(&mut self, mut ops: Vec<Operation>) {
+        ops.sort_by_key(|op| op.lamport_timestamp());
+        ops.dedup_by_key(|op| op.lamport_timestamp());
         self.0
             .edit(ops.into_iter().map(Edit::Insert).collect(), &());
     }
@@ -42,30 +43,11 @@ impl<T: Operation> OperationQueue<T> {
         clone
     }
 
-    pub fn cursor(&self) -> Cursor<T, (), ()> {
+    pub fn cursor(&self) -> Cursor<Operation, (), ()> {
         self.0.cursor()
     }
 }
 
-impl<T: Operation> Item for T {
-    type Summary = OperationSummary;
-
-    fn summary(&self) -> Self::Summary {
-        OperationSummary {
-            key: OperationKey(self.timestamp()),
-            len: 1,
-        }
-    }
-}
-
-impl<T: Operation> KeyedItem for T {
-    type Key = OperationKey;
-
-    fn key(&self) -> Self::Key {
-        OperationKey(self.timestamp())
-    }
-}
-
 impl Summary for OperationSummary {
     type Context = ();
 
@@ -95,6 +77,25 @@ impl<'a> Dimension<'a, OperationSummary> for OperationKey {
     }
 }
 
+impl Item for Operation {
+    type Summary = OperationSummary;
+
+    fn summary(&self) -> Self::Summary {
+        OperationSummary {
+            key: OperationKey::new(self.lamport_timestamp()),
+            len: 1,
+        }
+    }
+}
+
+impl KeyedItem for Operation {
+    type Key = OperationKey;
+
+    fn key(&self) -> Self::Key {
+        OperationKey::new(self.lamport_timestamp())
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -107,27 +108,21 @@ mod tests {
         assert_eq!(queue.len(), 0);
 
         queue.insert(vec![
-            TestOperation(clock.tick()),
-            TestOperation(clock.tick()),
+            Operation::Test(clock.tick()),
+            Operation::Test(clock.tick()),
         ]);
         assert_eq!(queue.len(), 2);
 
-        queue.insert(vec![TestOperation(clock.tick())]);
+        queue.insert(vec![Operation::Test(clock.tick())]);
         assert_eq!(queue.len(), 3);
 
         drop(queue.drain());
         assert_eq!(queue.len(), 0);
 
-        queue.insert(vec![TestOperation(clock.tick())]);
+        queue.insert(vec![Operation::Test(clock.tick())]);
         assert_eq!(queue.len(), 1);
     }
 
     #[derive(Clone, Debug, Eq, PartialEq)]
     struct TestOperation(time::Lamport);
-
-    impl Operation for TestOperation {
-        fn timestamp(&self) -> time::Lamport {
-            self.0
-        }
-    }
 }

zed/src/editor/buffer/rope.rs 🔗

@@ -1,9 +1,7 @@
 use super::Point;
-use crate::{
-    sum_tree::{self, SumTree},
-    util::Bias,
-};
+use crate::util::Bias;
 use arrayvec::ArrayString;
+use gpui::sum_tree::{self, SumTree};
 use smallvec::SmallVec;
 use std::{cmp, ops::Range, str};
 
@@ -61,7 +59,7 @@ impl Rope {
                     if last_chunk.0.len() + first_new_chunk_ref.0.len() <= 2 * CHUNK_BASE {
                         last_chunk.0.push_str(&first_new_chunk.take().unwrap().0);
                     } else {
-                        let mut text = ArrayString::<[_; 4 * CHUNK_BASE]>::new();
+                        let mut text = ArrayString::<{ 4 * CHUNK_BASE }>::new();
                         text.push_str(&last_chunk.0);
                         text.push_str(&first_new_chunk_ref.0);
                         let (left, right) = text.split_at(find_split_ix(&text));
@@ -330,7 +328,7 @@ impl<'a> Iterator for Chunks<'a> {
 }
 
 #[derive(Clone, Debug, Default)]
-struct Chunk(ArrayString<[u8; 2 * CHUNK_BASE]>);
+struct Chunk(ArrayString<{ 2 * CHUNK_BASE }>);
 
 impl Chunk {
     fn to_point(&self, target: usize) -> Point {

zed/src/editor/display_map/fold_map.rs 🔗

@@ -2,14 +2,11 @@ use super::{
     buffer::{AnchorRangeExt, TextSummary},
     Anchor, Buffer, Point, ToOffset,
 };
-use crate::{
-    editor::buffer,
-    settings::HighlightId,
+use crate::{editor::buffer, settings::HighlightId, time, util::Bias};
+use gpui::{
     sum_tree::{self, Cursor, FilterCursor, SumTree},
-    time,
-    util::Bias,
+    AppContext, ModelHandle,
 };
-use gpui::{AppContext, ModelHandle};
 use parking_lot::Mutex;
 use std::{
     cmp::{self, Ordering},

zed/src/editor/display_map/wrap_map.rs 🔗

@@ -3,14 +3,11 @@ use super::{
     line_wrapper::LineWrapper,
     tab_map::{self, Edit as TabEdit, Snapshot as TabSnapshot, TabPoint, TextSummary},
 };
-use crate::{
-    editor::Point,
-    settings::HighlightId,
+use crate::{editor::Point, settings::HighlightId, util::Bias, Settings};
+use gpui::{
     sum_tree::{self, Cursor, SumTree},
-    util::Bias,
-    Settings,
+    Entity, ModelContext, Task,
 };
-use gpui::{Entity, ModelContext, Task};
 use lazy_static::lazy_static;
 use smol::future::yield_now;
 use std::{collections::VecDeque, ops::Range, time::Duration};
@@ -816,8 +813,12 @@ fn push_isomorphic(transforms: &mut Vec<Transform>, summary: TextSummary) {
     transforms.push(Transform::isomorphic(summary));
 }
 
-impl SumTree<Transform> {
-    pub fn push_or_extend(&mut self, transform: Transform) {
+trait SumTreeExt {
+    fn push_or_extend(&mut self, transform: Transform);
+}
+
+impl SumTreeExt for SumTree<Transform> {
+    fn push_or_extend(&mut self, transform: Transform) {
         let mut transform = Some(transform);
         self.update_last(
             |last_transform| {

zed/src/lib.rs 🔗

@@ -7,11 +7,9 @@ pub mod fs;
 mod fuzzy;
 pub mod language;
 pub mod menus;
-mod operation_queue;
 pub mod project_browser;
 pub mod rpc;
 pub mod settings;
-mod sum_tree;
 #[cfg(any(test, feature = "test-support"))]
 pub mod test;
 pub mod theme;

zed/src/util.rs 🔗

@@ -1,30 +1,8 @@
 use futures::Future;
+pub use gpui::sum_tree::Bias;
 use rand::prelude::*;
 use std::cmp::Ordering;
 
-#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
-pub enum Bias {
-    Left,
-    Right,
-}
-
-impl PartialOrd for Bias {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl Ord for Bias {
-    fn cmp(&self, other: &Self) -> Ordering {
-        match (self, other) {
-            (Self::Left, Self::Left) => Ordering::Equal,
-            (Self::Left, Self::Right) => Ordering::Less,
-            (Self::Right, Self::Right) => Ordering::Equal,
-            (Self::Right, Self::Left) => Ordering::Greater,
-        }
-    }
-}
-
 pub fn post_inc(value: &mut usize) -> usize {
     let prev = *value;
     *value += 1;

zed/src/worktree.rs 🔗

@@ -8,7 +8,6 @@ use crate::{
     fuzzy::CharBag,
     language::LanguageRegistry,
     rpc::{self, proto},
-    sum_tree::{self, Cursor, Edit, SumTree},
     time::{self, ReplicaId},
     util::{log_async_errors, Bias},
 };
@@ -17,8 +16,10 @@ use anyhow::{anyhow, Result};
 use futures::{Stream, StreamExt};
 pub use fuzzy::{match_paths, PathMatch};
 use gpui::{
-    executor, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext,
-    Task, UpgradeModelHandle, WeakModelHandle,
+    executor,
+    sum_tree::{self, Cursor, Edit, SumTree},
+    AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task,
+    UpgradeModelHandle, WeakModelHandle,
 };
 use lazy_static::lazy_static;
 use parking_lot::Mutex;