From bf9daf1529edbbc8baa17d811ee953ffe048ce6d Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 14 Dec 2021 09:58:28 -0800 Subject: [PATCH] Allow left-biased anchors at the beginnings of excerpts Co-Authored-By: Antonio Scandurra --- crates/editor/src/editor.rs | 53 ++++++++++++++++++++++++++++++- crates/editor/src/multi_buffer.rs | 15 +++------ 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c82a3c9c98..5a1641b75b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -3958,7 +3958,6 @@ mod tests { view.update_selection(DisplayPoint::new(0, 0), 0, Vector2F::zero(), cx); }); - eprintln!(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); assert_eq!( editor.update(cx, |view, cx| view.selected_display_ranges(cx)), [ @@ -5857,6 +5856,58 @@ mod tests { }); } + #[gpui::test] + fn test_multi_buffer_editing(cx: &mut gpui::MutableAppContext) { + let settings = EditorSettings::test(cx); + let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx)); + let multibuffer = cx.add_model(|cx| { + let mut multibuffer = MultiBuffer::new(0); + multibuffer.push_excerpt( + ExcerptProperties { + buffer: &buffer, + range: Point::new(0, 0)..Point::new(0, 4), + header_height: 0, + }, + cx, + ); + multibuffer.push_excerpt( + ExcerptProperties { + buffer: &buffer, + range: Point::new(1, 0)..Point::new(1, 4), + header_height: 0, + }, + cx, + ); + multibuffer + }); + + assert_eq!(multibuffer.read(cx).read(cx).text(), "aaaa\nbbbb\n"); + + let (_, view) = cx.add_window(Default::default(), |cx| { + build_editor(multibuffer, settings, cx) + }); + view.update(cx, |view, cx| { + view.select_display_ranges( + &[ + DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), + DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), + ], + cx, + ) + .unwrap(); + + view.handle_input(&Input("X".to_string()), cx); + assert_eq!(view.text(cx), "Xaaaa\nXbbbb\n"); + assert_eq!( + view.selected_display_ranges(cx), + &[ + DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), + DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), + ] + ) + }); + } + #[gpui::test] async fn test_extra_newline_insertion(mut cx: gpui::TestAppContext) { let settings = cx.read(EditorSettings::test); diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index cb714541dd..e99d4b59af 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -55,11 +55,11 @@ struct Transaction { last_edit_at: Instant, } -pub trait ToOffset: 'static { +pub trait ToOffset: 'static + std::fmt::Debug { fn to_offset(&self, snapshot: &MultiBufferSnapshot) -> usize; } -pub trait ToPoint: 'static { +pub trait ToPoint: 'static + std::fmt::Debug { fn to_point(&self, snapshot: &MultiBufferSnapshot) -> Point; } @@ -171,7 +171,7 @@ impl MultiBuffer { } pub fn as_singleton(&self) -> Option<&ModelHandle> { - if self.buffers.len() == 1 { + if self.singleton { return Some(&self.buffers.values().next().unwrap().buffer); } else { None @@ -1150,16 +1150,11 @@ impl MultiBufferSnapshot { pub fn anchor_at(&self, position: T, bias: Bias) -> Anchor { let offset = position.to_offset(self); let mut cursor = self.excerpts.cursor::<(usize, Option<&ExcerptId>)>(); - cursor.seek(&offset, bias, &()); + cursor.seek(&offset, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let start_after_header = cursor.start().0 + excerpt.header_height as usize; - let mut end_before_newline = cursor.end(&()).0; - if excerpt.has_trailing_newline { - end_before_newline -= 1; - } - let buffer_start = excerpt.range.start.to_offset(&excerpt.buffer); - let overshoot = cmp::min(offset, end_before_newline).saturating_sub(start_after_header); + let overshoot = offset.saturating_sub(start_after_header); Anchor { excerpt_id: excerpt.id.clone(), text_anchor: excerpt.buffer.anchor_at(buffer_start + overshoot, bias),