Use a single `Bias` enum everywhere

Antonio Scandurra created

Change summary

zed/src/editor.rs                      |  8 --
zed/src/editor/buffer.rs               | 39 +++++++--------
zed/src/editor/buffer/anchor.rs        | 46 +----------------
zed/src/editor/buffer/rope.rs          | 26 +++++-----
zed/src/editor/display_map/fold_map.rs | 46 ++++++++---------
zed/src/sum_tree.rs                    | 71 ++++++++++-----------------
zed/src/sum_tree/cursor.rs             | 23 +++-----
zed/src/util.rs                        | 23 +++++++++
zed/src/worktree.rs                    | 23 ++++----
9 files changed, 128 insertions(+), 177 deletions(-)

Detailed changes

zed/src/editor.rs 🔗

@@ -5,7 +5,7 @@ pub mod movement;
 
 use crate::{
     settings::{Settings, StyleId},
-    util::post_inc,
+    util::{post_inc, Bias},
     workspace,
     worktree::FileHandle,
 };
@@ -4137,12 +4137,6 @@ mod tests {
     }
 }
 
-#[derive(Copy, Clone)]
-pub enum Bias {
-    Left,
-    Right,
-}
-
 trait RangeExt<T> {
     fn sorted(&self) -> Range<T>;
     fn to_inclusive(&self) -> RangeInclusive<T>;

zed/src/editor/buffer.rs 🔗

@@ -13,12 +13,12 @@ use similar::{ChangeTag, TextDiff};
 use tree_sitter::{InputEdit, Parser, QueryCursor};
 
 use crate::{
-    editor::Bias,
     language::{Language, Tree},
     operation_queue::{self, OperationQueue},
     settings::{StyleId, ThemeMap},
-    sum_tree::{self, FilterCursor, SeekBias, SumTree},
+    sum_tree::{self, FilterCursor, SumTree},
     time::{self, ReplicaId},
+    util::Bias,
     worktree::FileHandle,
 };
 use anyhow::{anyhow, Result};
@@ -1135,11 +1135,8 @@ impl Buffer {
         let mut new_ropes =
             RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
         let mut old_fragments = self.fragments.cursor::<VersionedOffset, VersionedOffset>();
-        let mut new_fragments = old_fragments.slice(
-            &VersionedOffset::Offset(ranges[0].start),
-            SeekBias::Left,
-            &cx,
-        );
+        let mut new_fragments =
+            old_fragments.slice(&VersionedOffset::Offset(ranges[0].start), Bias::Left, &cx);
         new_ropes.push_tree(new_fragments.summary().text);
 
         let mut fragment_start = old_fragments.start().offset();
@@ -1162,7 +1159,7 @@ impl Buffer {
                 }
 
                 let slice =
-                    old_fragments.slice(&VersionedOffset::Offset(range.start), SeekBias::Left, &cx);
+                    old_fragments.slice(&VersionedOffset::Offset(range.start), Bias::Left, &cx);
                 new_ropes.push_tree(slice.summary().text);
                 new_fragments.push_tree(slice, &None);
                 fragment_start = old_fragments.start().offset();
@@ -1342,7 +1339,7 @@ impl Buffer {
         let version = Some(edit.version.clone());
 
         let mut old_fragments = self.fragments.cursor::<VersionedOffset, VersionedOffset>();
-        old_fragments.seek(&VersionedOffset::Offset(0), SeekBias::Left, &version);
+        old_fragments.seek(&VersionedOffset::Offset(0), Bias::Left, &version);
 
         let mut new_fragments = SumTree::new();
         let mut new_ropes =
@@ -1354,7 +1351,7 @@ impl Buffer {
             if end_offset < range.start {
                 let preceding_fragments = old_fragments.slice(
                     &VersionedOffset::Offset(range.start),
-                    SeekBias::Left,
+                    Bias::Left,
                     &version,
                 );
                 new_ropes.push_tree(preceding_fragments.summary().text);
@@ -1455,7 +1452,7 @@ impl Buffer {
         let mut new_ropes =
             RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
         let mut old_fragments = self.fragments.cursor::<usize, FragmentTextSummary>();
-        let mut new_fragments = old_fragments.slice(&ranges[0].start, SeekBias::Right, &None);
+        let mut new_fragments = old_fragments.slice(&ranges[0].start, Bias::Right, &None);
         new_ropes.push_tree(new_fragments.summary().text);
 
         let mut fragment_start = old_fragments.start().visible;
@@ -1477,7 +1474,7 @@ impl Buffer {
                     old_fragments.next(&None);
                 }
 
-                let slice = old_fragments.slice(&range.start, SeekBias::Right, &None);
+                let slice = old_fragments.slice(&range.start, Bias::Right, &None);
                 new_ropes.push_tree(slice.summary().text);
                 new_fragments.push_tree(slice, &None);
                 fragment_start = old_fragments.start().visible;
@@ -1562,25 +1559,25 @@ impl Buffer {
     }
 
     pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
-        self.anchor_at(position, AnchorBias::Left)
+        self.anchor_at(position, Bias::Left)
     }
 
     pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
-        self.anchor_at(position, AnchorBias::Right)
+        self.anchor_at(position, Bias::Right)
     }
 
-    pub fn anchor_at<T: ToOffset>(&self, position: T, bias: AnchorBias) -> Anchor {
+    pub fn anchor_at<T: ToOffset>(&self, position: T, bias: Bias) -> Anchor {
         let offset = position.to_offset(self);
         let max_offset = self.len();
         assert!(offset <= max_offset, "offset is out of range");
 
-        if offset == 0 && bias == AnchorBias::Left {
+        if offset == 0 && bias == Bias::Left {
             Anchor::Start
-        } else if offset == max_offset && bias == AnchorBias::Right {
+        } else if offset == max_offset && bias == Bias::Right {
             Anchor::End
         } else {
             let mut cursor = self.fragments.cursor::<usize, FragmentTextSummary>();
-            cursor.seek(&offset, bias.to_seek_bias(), &None);
+            cursor.seek(&offset, bias, &None);
             Anchor::Middle {
                 offset: offset + cursor.start().deleted,
                 bias,
@@ -1603,7 +1600,7 @@ impl Buffer {
                     .cursor::<VersionedOffset, (VersionedOffset, usize)>();
                 cursor.seek(
                     &VersionedOffset::Offset(*offset),
-                    bias.to_seek_bias(),
+                    *bias,
                     &Some(version.clone()),
                 );
                 let fragment = cursor.item().unwrap();
@@ -1635,7 +1632,7 @@ impl Buffer {
                     .cursor::<VersionedOffset, (VersionedOffset, FragmentTextSummary)>();
                 cursor.seek(
                     &VersionedOffset::Offset(*offset),
-                    bias.to_seek_bias(),
+                    *bias,
                     &Some(version.clone()),
                 );
                 let overshoot = offset - cursor.start().0.offset();
@@ -2814,7 +2811,7 @@ mod tests {
             buffer.add_selection_set(
                 (0..3)
                     .map(|row| {
-                        let anchor = buffer.anchor_at(Point::new(row, 0), AnchorBias::Right);
+                        let anchor = buffer.anchor_at(Point::new(row, 0), Bias::Right);
                         Selection {
                             id: row as usize,
                             start: anchor.clone(),

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

@@ -1,5 +1,5 @@
 use super::Buffer;
-use crate::{sum_tree, time};
+use crate::{time, util::Bias};
 use anyhow::Result;
 use std::{cmp::Ordering, ops::Range};
 
@@ -9,47 +9,11 @@ pub enum Anchor {
     End,
     Middle {
         offset: usize,
-        bias: AnchorBias,
+        bias: Bias,
         version: time::Global,
     },
 }
 
-#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
-pub enum AnchorBias {
-    Left,
-    Right,
-}
-
-impl AnchorBias {
-    pub fn to_seek_bias(self) -> sum_tree::SeekBias {
-        match self {
-            AnchorBias::Left => sum_tree::SeekBias::Left,
-            AnchorBias::Right => sum_tree::SeekBias::Right,
-        }
-    }
-}
-
-impl PartialOrd for AnchorBias {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl Ord for AnchorBias {
-    fn cmp(&self, other: &Self) -> Ordering {
-        use AnchorBias::*;
-
-        if self == other {
-            return Ordering::Equal;
-        }
-
-        match (self, other) {
-            (Left, _) => Ordering::Less,
-            (Right, _) => Ordering::Greater,
-        }
-    }
-}
-
 impl Anchor {
     pub fn cmp(&self, other: &Anchor, buffer: &Buffer) -> Result<Ordering> {
         if self == other {
@@ -88,8 +52,7 @@ impl Anchor {
         match self {
             Anchor::Start
             | Anchor::Middle {
-                bias: AnchorBias::Left,
-                ..
+                bias: Bias::Left, ..
             } => self.clone(),
             _ => buffer.anchor_before(self),
         }
@@ -99,8 +62,7 @@ impl Anchor {
         match self {
             Anchor::End
             | Anchor::Middle {
-                bias: AnchorBias::Right,
-                ..
+                bias: Bias::Right, ..
             } => self.clone(),
             _ => buffer.anchor_after(self),
         }

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

@@ -1,7 +1,7 @@
 use super::Point;
 use crate::{
-    editor::Bias,
-    sum_tree::{self, SeekBias, SumTree},
+    sum_tree::{self, SumTree},
+    util::Bias,
 };
 use arrayvec::ArrayString;
 use smallvec::SmallVec;
@@ -129,7 +129,7 @@ impl Rope {
     pub fn to_point(&self, offset: usize) -> Point {
         assert!(offset <= self.summary().bytes);
         let mut cursor = self.chunks.cursor::<usize, TextSummary>();
-        cursor.seek(&offset, SeekBias::Left, &());
+        cursor.seek(&offset, Bias::Left, &());
         let overshoot = offset - cursor.start().bytes;
         cursor.start().lines
             + cursor
@@ -140,14 +140,14 @@ impl Rope {
     pub fn to_offset(&self, point: Point) -> usize {
         assert!(point <= self.summary().lines);
         let mut cursor = self.chunks.cursor::<Point, TextSummary>();
-        cursor.seek(&point, SeekBias::Left, &());
+        cursor.seek(&point, Bias::Left, &());
         let overshoot = point - cursor.start().lines;
         cursor.start().bytes + cursor.item().map_or(0, |chunk| chunk.to_offset(overshoot))
     }
 
     pub fn clip_offset(&self, mut offset: usize, bias: Bias) -> usize {
         let mut cursor = self.chunks.cursor::<usize, usize>();
-        cursor.seek(&offset, SeekBias::Left, &());
+        cursor.seek(&offset, Bias::Left, &());
         if let Some(chunk) = cursor.item() {
             let mut ix = offset - cursor.start();
             while !chunk.0.is_char_boundary(ix) {
@@ -170,7 +170,7 @@ impl Rope {
 
     pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
         let mut cursor = self.chunks.cursor::<Point, Point>();
-        cursor.seek(&point, SeekBias::Right, &());
+        cursor.seek(&point, Bias::Right, &());
         if let Some(chunk) = cursor.item() {
             let overshoot = point - cursor.start();
             *cursor.start() + chunk.clip_point(overshoot, bias)
@@ -197,7 +197,7 @@ pub struct Cursor<'a> {
 impl<'a> Cursor<'a> {
     pub fn new(rope: &'a Rope, offset: usize) -> Self {
         let mut chunks = rope.chunks.cursor();
-        chunks.seek(&offset, SeekBias::Right, &());
+        chunks.seek(&offset, Bias::Right, &());
         Self {
             rope,
             chunks,
@@ -208,7 +208,7 @@ impl<'a> Cursor<'a> {
     pub fn seek_forward(&mut self, end_offset: usize) {
         debug_assert!(end_offset >= self.offset);
 
-        self.chunks.seek_forward(&end_offset, SeekBias::Right, &());
+        self.chunks.seek_forward(&end_offset, Bias::Right, &());
         self.offset = end_offset;
     }
 
@@ -230,7 +230,7 @@ impl<'a> Cursor<'a> {
         if end_offset > self.chunks.end(&()) {
             self.chunks.next(&());
             slice.append(Rope {
-                chunks: self.chunks.slice(&end_offset, SeekBias::Right, &()),
+                chunks: self.chunks.slice(&end_offset, Bias::Right, &()),
             });
             if let Some(end_chunk) = self.chunks.item() {
                 let end_ix = end_offset - self.chunks.start();
@@ -254,7 +254,7 @@ impl<'a> Cursor<'a> {
 
         if end_offset > self.chunks.end(&()) {
             self.chunks.next(&());
-            summary += &self.chunks.summary(&end_offset, SeekBias::Right, &());
+            summary += &self.chunks.summary(&end_offset, Bias::Right, &());
             if let Some(end_chunk) = self.chunks.item() {
                 let end_ix = end_offset - self.chunks.start();
                 summary += TextSummary::from(&end_chunk.0[..end_ix]);
@@ -281,7 +281,7 @@ pub struct Chunks<'a> {
 impl<'a> Chunks<'a> {
     pub fn new(rope: &'a Rope, range: Range<usize>) -> Self {
         let mut chunks = rope.chunks.cursor();
-        chunks.seek(&range.start, SeekBias::Right, &());
+        chunks.seek(&range.start, Bias::Right, &());
         Self { chunks, range }
     }
 
@@ -291,9 +291,9 @@ impl<'a> Chunks<'a> {
 
     pub fn seek(&mut self, offset: usize) {
         if offset >= self.chunks.end(&()) {
-            self.chunks.seek_forward(&offset, SeekBias::Right, &());
+            self.chunks.seek_forward(&offset, Bias::Right, &());
         } else {
-            self.chunks.seek(&offset, SeekBias::Right, &());
+            self.chunks.seek(&offset, Bias::Right, &());
         }
         self.range.start = offset;
     }

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

@@ -1,12 +1,13 @@
 use super::{
     buffer::{AnchorRangeExt, TextSummary},
-    Anchor, Bias, Buffer, DisplayPoint, Edit, Point, ToOffset,
+    Anchor, Buffer, DisplayPoint, Edit, Point, ToOffset,
 };
 use crate::{
     editor::buffer,
     settings::StyleId,
-    sum_tree::{self, Cursor, FilterCursor, SeekBias, SumTree},
+    sum_tree::{self, Cursor, FilterCursor, SumTree},
     time,
+    util::Bias,
 };
 use gpui::{AppContext, ModelHandle};
 use parking_lot::{Mutex, MutexGuard};
@@ -125,7 +126,7 @@ impl FoldMap {
             let mut new_tree = SumTree::new();
             let mut cursor = self.folds.cursor::<_, ()>();
             for fold in folds {
-                new_tree.push_tree(cursor.slice(&fold, SeekBias::Right, buffer), buffer);
+                new_tree.push_tree(cursor.slice(&fold, Bias::Right, buffer), buffer);
                 new_tree.push(fold, buffer);
             }
             new_tree.push_tree(cursor.suffix(buffer), buffer);
@@ -173,7 +174,7 @@ impl FoldMap {
             let mut cursor = self.folds.cursor::<_, ()>();
             let mut folds = SumTree::new();
             for fold_ix in fold_ixs_to_delete {
-                folds.push_tree(cursor.slice(&fold_ix, SeekBias::Right, buffer), buffer);
+                folds.push_tree(cursor.slice(&fold_ix, Bias::Right, buffer), buffer);
                 cursor.next(buffer);
             }
             folds.push_tree(cursor.suffix(buffer), buffer);
@@ -210,14 +211,14 @@ impl FoldMap {
         let offset = offset.to_offset(buffer);
         let transforms = self.sync(cx);
         let mut cursor = transforms.cursor::<usize, usize>();
-        cursor.seek(&offset, SeekBias::Right, &());
+        cursor.seek(&offset, Bias::Right, &());
         cursor.item().map_or(false, |t| t.display_text.is_some())
     }
 
     pub fn is_line_folded(&self, display_row: u32, cx: &AppContext) -> bool {
         let transforms = self.sync(cx);
         let mut cursor = transforms.cursor::<DisplayPoint, DisplayPoint>();
-        cursor.seek(&DisplayPoint::new(display_row, 0), SeekBias::Right, &());
+        cursor.seek(&DisplayPoint::new(display_row, 0), Bias::Right, &());
         while let Some(transform) = cursor.item() {
             if transform.display_text.is_some() {
                 return true;
@@ -242,7 +243,7 @@ impl FoldMap {
     pub fn to_buffer_point(&self, display_point: DisplayPoint, cx: &AppContext) -> Point {
         let transforms = self.sync(cx);
         let mut cursor = transforms.cursor::<DisplayPoint, TransformSummary>();
-        cursor.seek(&display_point, SeekBias::Right, &());
+        cursor.seek(&display_point, Bias::Right, &());
         let overshoot = display_point.0 - cursor.start().display.lines;
         cursor.start().buffer.lines + overshoot
     }
@@ -250,7 +251,7 @@ impl FoldMap {
     pub fn to_display_point(&self, point: Point, cx: &AppContext) -> DisplayPoint {
         let transforms = self.sync(cx);
         let mut cursor = transforms.cursor::<Point, TransformSummary>();
-        cursor.seek(&point, SeekBias::Right, &());
+        cursor.seek(&point, Bias::Right, &());
         let overshoot = point - cursor.start().buffer.lines;
         DisplayPoint(cmp::min(
             cursor.start().display.lines + overshoot,
@@ -275,17 +276,14 @@ impl FoldMap {
         let mut new_transforms = SumTree::new();
         let mut transforms = self.transforms.lock();
         let mut cursor = transforms.cursor::<usize, usize>();
-        cursor.seek(&0, SeekBias::Right, &());
+        cursor.seek(&0, Bias::Right, &());
 
         while let Some(mut edit) = edits.next() {
-            new_transforms.push_tree(
-                cursor.slice(&edit.old_range.start, SeekBias::Left, &()),
-                &(),
-            );
+            new_transforms.push_tree(cursor.slice(&edit.old_range.start, Bias::Left, &()), &());
             edit.new_range.start -= edit.old_range.start - cursor.start();
             edit.old_range.start = *cursor.start();
 
-            cursor.seek(&edit.old_range.end, SeekBias::Right, &());
+            cursor.seek(&edit.old_range.end, Bias::Right, &());
             cursor.next(&());
 
             let mut delta = edit.delta();
@@ -302,7 +300,7 @@ impl FoldMap {
 
                     if next_edit.old_range.end >= edit.old_range.end {
                         edit.old_range.end = next_edit.old_range.end;
-                        cursor.seek(&edit.old_range.end, SeekBias::Right, &());
+                        cursor.seek(&edit.old_range.end, Bias::Right, &());
                         cursor.next(&());
                     }
                 } else {
@@ -315,7 +313,7 @@ impl FoldMap {
 
             let anchor = buffer.anchor_before(edit.new_range.start);
             let mut folds_cursor = self.folds.cursor::<_, ()>();
-            folds_cursor.seek(&Fold(anchor..Anchor::End), SeekBias::Left, buffer);
+            folds_cursor.seek(&Fold(anchor..Anchor::End), Bias::Left, buffer);
             let mut folds = iter::from_fn(move || {
                 let item = folds_cursor
                     .item()
@@ -432,7 +430,7 @@ impl FoldMapSnapshot {
 
         let display_point = Point::new(start_row, 0);
         let mut cursor = self.transforms.cursor();
-        cursor.seek(&DisplayPoint(display_point), SeekBias::Left, &());
+        cursor.seek(&DisplayPoint(display_point), Bias::Left, &());
 
         BufferRows {
             display_point,
@@ -446,7 +444,7 @@ impl FoldMapSnapshot {
 
     pub fn chunks_at(&self, offset: DisplayOffset) -> Chunks {
         let mut transform_cursor = self.transforms.cursor::<DisplayOffset, TransformSummary>();
-        transform_cursor.seek(&offset, SeekBias::Right, &());
+        transform_cursor.seek(&offset, Bias::Right, &());
         let overshoot = offset.0 - transform_cursor.start().display.bytes;
         let buffer_offset = transform_cursor.start().buffer.bytes + overshoot;
         Chunks {
@@ -459,11 +457,11 @@ impl FoldMapSnapshot {
     pub fn highlighted_chunks(&mut self, range: Range<DisplayOffset>) -> HighlightedChunks {
         let mut transform_cursor = self.transforms.cursor::<DisplayOffset, TransformSummary>();
 
-        transform_cursor.seek(&range.end, SeekBias::Right, &());
+        transform_cursor.seek(&range.end, Bias::Right, &());
         let overshoot = range.end.0 - transform_cursor.start().display.bytes;
         let buffer_end = transform_cursor.start().buffer.bytes + overshoot;
 
-        transform_cursor.seek(&range.start, SeekBias::Right, &());
+        transform_cursor.seek(&range.start, Bias::Right, &());
         let overshoot = range.start.0 - transform_cursor.start().display.bytes;
         let buffer_start = transform_cursor.start().buffer.bytes + overshoot;
 
@@ -484,7 +482,7 @@ impl FoldMapSnapshot {
 
     pub fn to_display_offset(&self, point: DisplayPoint) -> DisplayOffset {
         let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
-        cursor.seek(&point, SeekBias::Right, &());
+        cursor.seek(&point, Bias::Right, &());
         let overshoot = point.0 - cursor.start().display.lines;
         let mut offset = cursor.start().display.bytes;
         if !overshoot.is_zero() {
@@ -500,7 +498,7 @@ impl FoldMapSnapshot {
 
     pub fn to_buffer_offset(&self, point: DisplayPoint) -> usize {
         let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
-        cursor.seek(&point, SeekBias::Right, &());
+        cursor.seek(&point, Bias::Right, &());
         let overshoot = point.0 - cursor.start().display.lines;
         self.buffer
             .to_offset(cursor.start().buffer.lines + overshoot)
@@ -509,7 +507,7 @@ impl FoldMapSnapshot {
     #[cfg(test)]
     pub fn clip_offset(&self, offset: DisplayOffset, bias: Bias) -> DisplayOffset {
         let mut cursor = self.transforms.cursor::<DisplayOffset, TransformSummary>();
-        cursor.seek(&offset, SeekBias::Right, &());
+        cursor.seek(&offset, Bias::Right, &());
         if let Some(transform) = cursor.item() {
             let transform_start = cursor.start().display.bytes;
             if transform.display_text.is_some() {
@@ -534,7 +532,7 @@ impl FoldMapSnapshot {
 
     pub fn clip_point(&self, point: DisplayPoint, bias: Bias) -> DisplayPoint {
         let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
-        cursor.seek(&point, SeekBias::Right, &());
+        cursor.seek(&point, Bias::Right, &());
         if let Some(transform) = cursor.item() {
             let transform_start = cursor.start().display.lines;
             if transform.display_text.is_some() {

zed/src/sum_tree.rs 🔗

@@ -1,5 +1,6 @@
 mod cursor;
 
+use crate::util::Bias;
 use arrayvec::ArrayVec;
 pub use cursor::Cursor;
 pub use cursor::FilterCursor;
@@ -58,12 +59,6 @@ impl<'a, S: Summary, T: Dimension<'a, S> + Ord> SeekDimension<'a, S> for T {
     }
 }
 
-#[derive(Copy, Clone, Eq, PartialEq)]
-pub enum SeekBias {
-    Left,
-    Right,
-}
-
 #[derive(Debug, Clone)]
 pub struct SumTree<T: Item>(Arc<Node<T>>);
 
@@ -417,7 +412,7 @@ impl<T: KeyedItem> SumTree<T> {
     pub fn insert(&mut self, item: T, cx: &<T::Summary as Summary>::Context) {
         *self = {
             let mut cursor = self.cursor::<T::Key, ()>();
-            let mut new_tree = cursor.slice(&item.key(), SeekBias::Left, cx);
+            let mut new_tree = cursor.slice(&item.key(), Bias::Left, cx);
             new_tree.push(item, cx);
             new_tree.push_tree(cursor.suffix(cx), cx);
             new_tree
@@ -441,7 +436,7 @@ impl<T: KeyedItem> SumTree<T> {
             let mut new_tree = SumTree::new();
             let mut buffered_items = Vec::new();
 
-            cursor.seek(&T::Key::default(), SeekBias::Left, cx);
+            cursor.seek(&T::Key::default(), Bias::Left, cx);
             for edit in edits {
                 let new_key = edit.key();
                 let mut old_item = cursor.item();
@@ -451,7 +446,7 @@ impl<T: KeyedItem> SumTree<T> {
                     .map_or(false, |old_item| old_item.key() < new_key)
                 {
                     new_tree.extend(buffered_items.drain(..), cx);
-                    let slice = cursor.slice(&new_key, SeekBias::Left, cx);
+                    let slice = cursor.slice(&new_key, Bias::Left, cx);
                     new_tree.push_tree(slice, cx);
                     old_item = cursor.item();
                 }
@@ -481,7 +476,7 @@ impl<T: KeyedItem> SumTree<T> {
 
     pub fn get(&self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<&T> {
         let mut cursor = self.cursor::<T::Key, ()>();
-        if cursor.seek(key, SeekBias::Left, cx) {
+        if cursor.seek(key, Bias::Left, cx) {
             cursor.item()
         } else {
             None
@@ -638,10 +633,10 @@ mod tests {
 
                 tree = {
                     let mut cursor = tree.cursor::<Count, ()>();
-                    let mut new_tree = cursor.slice(&Count(splice_start), SeekBias::Right, &());
+                    let mut new_tree = cursor.slice(&Count(splice_start), Bias::Right, &());
                     new_tree.extend(new_items, &());
-                    cursor.seek(&Count(splice_end), SeekBias::Right, &());
-                    new_tree.push_tree(cursor.slice(&tree_end, SeekBias::Right, &()), &());
+                    cursor.seek(&Count(splice_end), Bias::Right, &());
+                    new_tree.push_tree(cursor.slice(&tree_end, Bias::Right, &()), &());
                     new_tree
                 };
 
@@ -665,7 +660,7 @@ mod tests {
                 let mut pos = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
                 let mut before_start = false;
                 let mut cursor = tree.cursor::<Count, Count>();
-                cursor.seek(&Count(pos), SeekBias::Right, &());
+                cursor.seek(&Count(pos), Bias::Right, &());
 
                 for i in 0..10 {
                     assert_eq!(cursor.start().0, pos);
@@ -701,16 +696,8 @@ mod tests {
             for _ in 0..10 {
                 let end = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
                 let start = rng.gen_range(0..end + 1);
-                let start_bias = if rng.gen() {
-                    SeekBias::Left
-                } else {
-                    SeekBias::Right
-                };
-                let end_bias = if rng.gen() {
-                    SeekBias::Left
-                } else {
-                    SeekBias::Right
-                };
+                let start_bias = if rng.gen() { Bias::Left } else { Bias::Right };
+                let end_bias = if rng.gen() { Bias::Left } else { Bias::Right };
 
                 let mut cursor = tree.cursor::<Count, ()>();
                 cursor.seek(&Count(start), start_bias, &());
@@ -730,7 +717,7 @@ mod tests {
         let tree = SumTree::<u8>::new();
         let mut cursor = tree.cursor::<Count, Sum>();
         assert_eq!(
-            cursor.slice(&Count(0), SeekBias::Right, &()).items(&()),
+            cursor.slice(&Count(0), Bias::Right, &()).items(&()),
             Vec::<u8>::new()
         );
         assert_eq!(cursor.item(), None);
@@ -742,7 +729,7 @@ mod tests {
         tree.extend(vec![1], &());
         let mut cursor = tree.cursor::<Count, Sum>();
         assert_eq!(
-            cursor.slice(&Count(0), SeekBias::Right, &()).items(&()),
+            cursor.slice(&Count(0), Bias::Right, &()).items(&()),
             Vec::<u8>::new()
         );
         assert_eq!(cursor.item(), Some(&1));
@@ -760,18 +747,15 @@ mod tests {
         assert_eq!(cursor.start(), &Sum(0));
 
         let mut cursor = tree.cursor::<Count, Sum>();
-        assert_eq!(
-            cursor.slice(&Count(1), SeekBias::Right, &()).items(&()),
-            [1]
-        );
+        assert_eq!(cursor.slice(&Count(1), Bias::Right, &()).items(&()), [1]);
         assert_eq!(cursor.item(), None);
         assert_eq!(cursor.prev_item(), Some(&1));
         assert_eq!(cursor.start(), &Sum(1));
 
-        cursor.seek(&Count(0), SeekBias::Right, &());
+        cursor.seek(&Count(0), Bias::Right, &());
         assert_eq!(
             cursor
-                .slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
+                .slice(&tree.extent::<Count>(&()), Bias::Right, &())
                 .items(&()),
             [1]
         );
@@ -784,10 +768,7 @@ mod tests {
         tree.extend(vec![1, 2, 3, 4, 5, 6], &());
         let mut cursor = tree.cursor::<Count, Sum>();
 
-        assert_eq!(
-            cursor.slice(&Count(2), SeekBias::Right, &()).items(&()),
-            [1, 2]
-        );
+        assert_eq!(cursor.slice(&Count(2), Bias::Right, &()).items(&()), [1, 2]);
         assert_eq!(cursor.item(), Some(&3));
         assert_eq!(cursor.prev_item(), Some(&2));
         assert_eq!(cursor.start(), &Sum(3));
@@ -856,7 +837,7 @@ mod tests {
         let mut cursor = tree.cursor::<Count, Sum>();
         assert_eq!(
             cursor
-                .slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
+                .slice(&tree.extent::<Count>(&()), Bias::Right, &())
                 .items(&()),
             tree.items(&())
         );
@@ -864,10 +845,10 @@ mod tests {
         assert_eq!(cursor.prev_item(), Some(&6));
         assert_eq!(cursor.start(), &Sum(21));
 
-        cursor.seek(&Count(3), SeekBias::Right, &());
+        cursor.seek(&Count(3), Bias::Right, &());
         assert_eq!(
             cursor
-                .slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
+                .slice(&tree.extent::<Count>(&()), Bias::Right, &())
                 .items(&()),
             [4, 5, 6]
         );
@@ -876,23 +857,23 @@ mod tests {
         assert_eq!(cursor.start(), &Sum(21));
 
         // Seeking can bias left or right
-        cursor.seek(&Count(1), SeekBias::Left, &());
+        cursor.seek(&Count(1), Bias::Left, &());
         assert_eq!(cursor.item(), Some(&1));
-        cursor.seek(&Count(1), SeekBias::Right, &());
+        cursor.seek(&Count(1), Bias::Right, &());
         assert_eq!(cursor.item(), Some(&2));
 
         // Slicing without resetting starts from where the cursor is parked at.
-        cursor.seek(&Count(1), SeekBias::Right, &());
+        cursor.seek(&Count(1), Bias::Right, &());
         assert_eq!(
-            cursor.slice(&Count(3), SeekBias::Right, &()).items(&()),
+            cursor.slice(&Count(3), Bias::Right, &()).items(&()),
             vec![2, 3]
         );
         assert_eq!(
-            cursor.slice(&Count(6), SeekBias::Left, &()).items(&()),
+            cursor.slice(&Count(6), Bias::Left, &()).items(&()),
             vec![4, 5]
         );
         assert_eq!(
-            cursor.slice(&Count(6), SeekBias::Right, &()).items(&()),
+            cursor.slice(&Count(6), Bias::Right, &()).items(&()),
             vec![6]
         );
     }

zed/src/sum_tree/cursor.rs 🔗

@@ -345,7 +345,7 @@ where
     S: SeekDimension<'a, T::Summary>,
     U: Dimension<'a, T::Summary>,
 {
-    pub fn seek(&mut self, pos: &S, bias: SeekBias, cx: &<T::Summary as Summary>::Context) -> bool {
+    pub fn seek(&mut self, pos: &S, bias: Bias, cx: &<T::Summary as Summary>::Context) -> bool {
         self.reset();
         self.seek_internal::<()>(Some(pos), bias, &mut SeekAggregate::None, cx)
     }
@@ -353,7 +353,7 @@ where
     pub fn seek_forward(
         &mut self,
         pos: &S,
-        bias: SeekBias,
+        bias: Bias,
         cx: &<T::Summary as Summary>::Context,
     ) -> bool {
         self.seek_internal::<()>(Some(pos), bias, &mut SeekAggregate::None, cx)
@@ -362,7 +362,7 @@ where
     pub fn slice(
         &mut self,
         end: &S,
-        bias: SeekBias,
+        bias: Bias,
         cx: &<T::Summary as Summary>::Context,
     ) -> SumTree<T> {
         let mut slice = SeekAggregate::Slice(SumTree::new());
@@ -376,7 +376,7 @@ where
 
     pub fn suffix(&mut self, cx: &<T::Summary as Summary>::Context) -> SumTree<T> {
         let mut slice = SeekAggregate::Slice(SumTree::new());
-        self.seek_internal::<()>(None, SeekBias::Right, &mut slice, cx);
+        self.seek_internal::<()>(None, Bias::Right, &mut slice, cx);
         if let SeekAggregate::Slice(slice) = slice {
             slice
         } else {
@@ -384,12 +384,7 @@ where
         }
     }
 
-    pub fn summary<D>(
-        &mut self,
-        end: &S,
-        bias: SeekBias,
-        cx: &<T::Summary as Summary>::Context,
-    ) -> D
+    pub fn summary<D>(&mut self, end: &S, bias: Bias, cx: &<T::Summary as Summary>::Context) -> D
     where
         D: Dimension<'a, T::Summary>,
     {
@@ -405,7 +400,7 @@ where
     fn seek_internal<D>(
         &mut self,
         target: Option<&S>,
-        bias: SeekBias,
+        bias: Bias,
         aggregate: &mut SeekAggregate<T, D>,
         cx: &<T::Summary as Summary>::Context,
     ) -> bool
@@ -453,7 +448,7 @@ where
                         let comparison =
                             target.map_or(Ordering::Greater, |t| t.cmp(&child_end, cx));
                         if comparison == Ordering::Greater
-                            || (comparison == Ordering::Equal && bias == SeekBias::Right)
+                            || (comparison == Ordering::Equal && bias == Bias::Right)
                         {
                             self.seek_dimension = child_end;
                             self.sum_dimension.add_summary(child_summary, cx);
@@ -503,7 +498,7 @@ where
                         let comparison =
                             target.map_or(Ordering::Greater, |t| t.cmp(&child_end, cx));
                         if comparison == Ordering::Greater
-                            || (comparison == Ordering::Equal && bias == SeekBias::Right)
+                            || (comparison == Ordering::Equal && bias == Bias::Right)
                         {
                             self.seek_dimension = child_end;
                             self.sum_dimension.add_summary(item_summary, cx);
@@ -560,7 +555,7 @@ where
         debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
 
         let mut end = self.seek_dimension.clone();
-        if bias == SeekBias::Left {
+        if bias == Bias::Left {
             if let Some(summary) = self.item_summary() {
                 end.add_summary(summary, cx);
             }

zed/src/util.rs 🔗

@@ -1,6 +1,29 @@
 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 🔗

@@ -4,7 +4,8 @@ mod ignore;
 
 use crate::{
     editor::{History, Rope},
-    sum_tree::{self, Cursor, Edit, SeekBias, SumTree},
+    sum_tree::{self, Cursor, Edit, SumTree},
+    util::Bias,
 };
 use ::ignore::gitignore::Gitignore;
 use anyhow::{Context, Result};
@@ -295,7 +296,7 @@ impl Snapshot {
         }
         let path = path.as_ref();
         let mut cursor = self.entries.cursor::<_, ()>();
-        if cursor.seek(&PathSearch::Exact(path), SeekBias::Left, &()) {
+        if cursor.seek(&PathSearch::Exact(path), Bias::Left, &()) {
             let entry = cursor.item().unwrap();
             if entry.path.as_ref() == path {
                 return matches!(entry.kind, EntryKind::PendingDir);
@@ -310,7 +311,7 @@ impl Snapshot {
 
     fn entry_for_path(&self, path: impl AsRef<Path>) -> Option<&Entry> {
         let mut cursor = self.entries.cursor::<_, ()>();
-        if cursor.seek(&PathSearch::Exact(path.as_ref()), SeekBias::Left, &()) {
+        if cursor.seek(&PathSearch::Exact(path.as_ref()), Bias::Left, &()) {
             cursor.item()
         } else {
             None
@@ -367,8 +368,8 @@ impl Snapshot {
     fn remove_path(&mut self, path: &Path) {
         let new_entries = {
             let mut cursor = self.entries.cursor::<_, ()>();
-            let mut new_entries = cursor.slice(&PathSearch::Exact(path), SeekBias::Left, &());
-            cursor.seek_forward(&PathSearch::Successor(path), SeekBias::Left, &());
+            let mut new_entries = cursor.slice(&PathSearch::Exact(path), Bias::Left, &());
+            cursor.seek_forward(&PathSearch::Successor(path), Bias::Left, &());
             new_entries.push_tree(cursor.suffix(&()), &());
             new_entries
         };
@@ -1296,13 +1297,13 @@ pub enum FileIter<'a> {
 impl<'a> FileIter<'a> {
     fn all(snapshot: &'a Snapshot, start: usize) -> Self {
         let mut cursor = snapshot.entries.cursor();
-        cursor.seek(&FileCount(start), SeekBias::Right, &());
+        cursor.seek(&FileCount(start), Bias::Right, &());
         Self::All(cursor)
     }
 
     fn visible(snapshot: &'a Snapshot, start: usize) -> Self {
         let mut cursor = snapshot.entries.cursor();
-        cursor.seek(&VisibleFileCount(start), SeekBias::Right, &());
+        cursor.seek(&VisibleFileCount(start), Bias::Right, &());
         Self::Visible(cursor)
     }
 
@@ -1310,11 +1311,11 @@ impl<'a> FileIter<'a> {
         match self {
             Self::All(cursor) => {
                 let ix = *cursor.start();
-                cursor.seek_forward(&FileCount(ix.0 + 1), SeekBias::Right, &());
+                cursor.seek_forward(&FileCount(ix.0 + 1), Bias::Right, &());
             }
             Self::Visible(cursor) => {
                 let ix = *cursor.start();
-                cursor.seek_forward(&VisibleFileCount(ix.0 + 1), SeekBias::Right, &());
+                cursor.seek_forward(&VisibleFileCount(ix.0 + 1), Bias::Right, &());
             }
         }
     }
@@ -1348,7 +1349,7 @@ struct ChildEntriesIter<'a> {
 impl<'a> ChildEntriesIter<'a> {
     fn new(parent_path: &'a Path, snapshot: &'a Snapshot) -> Self {
         let mut cursor = snapshot.entries.cursor();
-        cursor.seek(&PathSearch::Exact(parent_path), SeekBias::Right, &());
+        cursor.seek(&PathSearch::Exact(parent_path), Bias::Right, &());
         Self {
             parent_path,
             cursor,
@@ -1363,7 +1364,7 @@ impl<'a> Iterator for ChildEntriesIter<'a> {
         if let Some(item) = self.cursor.item() {
             if item.path().starts_with(self.parent_path) {
                 self.cursor
-                    .seek_forward(&PathSearch::Successor(item.path()), SeekBias::Left, &());
+                    .seek_forward(&PathSearch::Successor(item.path()), Bias::Left, &());
                 Some(item)
             } else {
                 None