diff --git a/crates/ai/src/assistant.rs b/crates/ai/src/assistant.rs index 775e99c988..39309fd361 100644 --- a/crates/ai/src/assistant.rs +++ b/crates/ai/src/assistant.rs @@ -7,11 +7,8 @@ use chrono::{DateTime, Local}; use collections::{HashMap, HashSet}; use editor::{ display_map::{BlockDisposition, BlockId, BlockProperties, BlockStyle, ToDisplayPoint}, - scroll::{ - autoscroll::{Autoscroll, AutoscrollStrategy}, - ScrollAnchor, - }, - Anchor, DisplayPoint, Editor, ToOffset as _, + scroll::autoscroll::{Autoscroll, AutoscrollStrategy}, + Anchor, Editor, ToOffset as _, }; use fs::Fs; use futures::{io::BufReader, AsyncBufReadExt, AsyncReadExt, Stream, StreamExt}; @@ -19,7 +16,7 @@ use gpui::{ actions, elements::*, executor::Background, - geometry::vector::vec2f, + geometry::vector::{vec2f, Vector2F}, platform::{CursorStyle, MouseButton}, Action, AppContext, AsyncAppContext, ClipboardItem, Entity, ModelContext, ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext, @@ -801,11 +798,17 @@ enum AssistantEditorEvent { TabContentChanged, } +#[derive(Copy, Clone, Debug, PartialEq)] +struct ScrollPosition { + offset_before_cursor: Vector2F, + cursor: Anchor, +} + struct AssistantEditor { assistant: ModelHandle, editor: ViewHandle, blocks: HashSet, - scroll_bottom: ScrollAnchor, + scroll_position: Option, _subscriptions: Vec, } @@ -833,10 +836,7 @@ impl AssistantEditor { assistant, editor, blocks: Default::default(), - scroll_bottom: ScrollAnchor { - offset: Default::default(), - anchor: Anchor::max(), - }, + scroll_position: None, _subscriptions, }; this.update_message_headers(cx); @@ -874,7 +874,7 @@ impl AssistantEditor { |selections| selections.select_ranges([cursor..cursor]), ); }); - self.update_scroll_bottom(cx); + self.scroll_position = self.cursor_scroll_position(cx); } } @@ -900,18 +900,16 @@ impl AssistantEditor { } AssistantEvent::StreamedCompletion => { self.editor.update(cx, |editor, cx| { - let snapshot = editor.snapshot(cx); - let scroll_bottom_row = self - .scroll_bottom - .anchor - .to_display_point(&snapshot.display_snapshot) - .row(); - - let scroll_bottom = scroll_bottom_row as f32 + self.scroll_bottom.offset.y(); - let visible_line_count = editor.visible_line_count().unwrap_or(0.); - let scroll_top = scroll_bottom - visible_line_count; - editor - .set_scroll_position(vec2f(self.scroll_bottom.offset.x(), scroll_top), cx); + if let Some(scroll_position) = self.scroll_position { + let snapshot = editor.snapshot(cx); + let cursor_point = scroll_position.cursor.to_display_point(&snapshot); + let scroll_top = + cursor_point.row() as f32 - scroll_position.offset_before_cursor.y(); + editor.set_scroll_position( + vec2f(scroll_position.offset_before_cursor.x(), scroll_top), + cx, + ); + } }); } } @@ -924,11 +922,43 @@ impl AssistantEditor { cx: &mut ViewContext, ) { match event { - editor::Event::ScrollPositionChanged { .. } => self.update_scroll_bottom(cx), + editor::Event::ScrollPositionChanged { .. } => { + if self.cursor_scroll_position(cx) != self.scroll_position { + self.scroll_position = None; + } + } + editor::Event::SelectionsChanged { .. } => { + self.scroll_position = self.cursor_scroll_position(cx); + } _ => {} } } + fn cursor_scroll_position(&self, cx: &mut ViewContext) -> Option { + self.editor.update(cx, |editor, cx| { + let snapshot = editor.snapshot(cx); + let cursor = editor.selections.newest_anchor().head(); + let cursor_row = cursor.to_display_point(&snapshot.display_snapshot).row() as f32; + let scroll_position = editor + .scroll_manager + .anchor() + .scroll_position(&snapshot.display_snapshot); + + let scroll_bottom = scroll_position.y() + editor.visible_line_count().unwrap_or(0.); + if (scroll_position.y()..scroll_bottom).contains(&cursor_row) { + Some(ScrollPosition { + cursor, + offset_before_cursor: vec2f( + scroll_position.x(), + cursor_row - scroll_position.y(), + ), + }) + } else { + None + } + }) + } + fn update_message_headers(&mut self, cx: &mut ViewContext) { self.editor.update(cx, |editor, cx| { let buffer = editor.buffer().read(cx).snapshot(cx); @@ -1031,32 +1061,6 @@ impl AssistantEditor { }); } - fn update_scroll_bottom(&mut self, cx: &mut ViewContext) { - self.editor.update(cx, |editor, cx| { - let snapshot = editor.snapshot(cx); - let scroll_position = editor - .scroll_manager - .anchor() - .scroll_position(&snapshot.display_snapshot); - let scroll_bottom = scroll_position.y() + editor.visible_line_count().unwrap_or(0.); - let scroll_bottom_point = cmp::min( - DisplayPoint::new(scroll_bottom.floor() as u32, 0), - snapshot.display_snapshot.max_point(), - ); - let scroll_bottom_anchor = snapshot - .buffer_snapshot - .anchor_after(scroll_bottom_point.to_point(&snapshot.display_snapshot)); - let scroll_bottom_offset = vec2f( - scroll_position.x(), - scroll_bottom - scroll_bottom_point.row() as f32, - ); - self.scroll_bottom = ScrollAnchor { - anchor: scroll_bottom_anchor, - offset: scroll_bottom_offset, - }; - }); - } - fn quote_selection( workspace: &mut Workspace, _: &QuoteSelection,