diff --git a/Cargo.lock b/Cargo.lock index 71675fbee8..a0e0ffefd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4630,7 +4630,6 @@ name = "go_to_line" version = "0.1.0" dependencies = [ "anyhow", - "collections", "editor", "gpui", "indoc", @@ -7033,7 +7032,6 @@ dependencies = [ name = "outline" version = "0.1.0" dependencies = [ - "collections", "editor", "fuzzy", "gpui", diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 2d98f8c3f9..82ad51cd6b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -48,7 +48,7 @@ use anyhow::{anyhow, Context as _, Result}; use blink_manager::BlinkManager; use client::{Collaborator, ParticipantIndex}; use clock::ReplicaId; -use collections::{hash_map, BTreeMap, Bound, HashMap, HashSet, VecDeque}; +use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque}; use convert_case::{Case, Casing}; use debounced_delay::DebouncedDelay; pub use display_map::DisplayPoint; @@ -450,7 +450,7 @@ pub struct Editor { show_wrap_guides: Option, placeholder_text: Option>, highlight_order: usize, - highlighted_rows: HashMap, Option)>>, + highlighted_rows: HashMap>, background_highlights: TreeMap, scrollbar_marker_state: ScrollbarMarkerState, nav_history: Option, @@ -660,6 +660,13 @@ impl SelectionHistory { } } +struct RowHighlight { + index: usize, + range: RangeInclusive, + color: Option, + should_autoscroll: bool, +} + #[derive(Clone, Debug)] struct AddSelectionsState { above: bool, @@ -9814,47 +9821,30 @@ impl Editor { &mut self, rows: RangeInclusive, color: Option, + should_autoscroll: bool, cx: &mut ViewContext, ) { - let multi_buffer_snapshot = self.buffer().read(cx).snapshot(cx); - match self.highlighted_rows.entry(TypeId::of::()) { - hash_map::Entry::Occupied(o) => { - let row_highlights = o.into_mut(); - let existing_highlight_index = - row_highlights.binary_search_by(|(_, highlight_range, _)| { - highlight_range - .start() - .cmp(&rows.start(), &multi_buffer_snapshot) - .then( - highlight_range - .end() - .cmp(&rows.end(), &multi_buffer_snapshot), - ) - }); - match color { - Some(color) => { - let insert_index = match existing_highlight_index { - Ok(i) => i, - Err(i) => i, - }; - row_highlights.insert( - insert_index, - (post_inc(&mut self.highlight_order), rows, Some(color)), - ); - } - None => match existing_highlight_index { - Ok(i) => { - row_highlights.remove(i); - } - Err(i) => { - row_highlights - .insert(i, (post_inc(&mut self.highlight_order), rows, None)); - } - }, - } - } - hash_map::Entry::Vacant(v) => { - v.insert(vec![(post_inc(&mut self.highlight_order), rows, color)]); + let snapshot = self.buffer().read(cx).snapshot(cx); + let row_highlights = self.highlighted_rows.entry(TypeId::of::()).or_default(); + let existing_highlight_index = row_highlights.binary_search_by(|highlight| { + highlight + .range + .start() + .cmp(&rows.start(), &snapshot) + .then(highlight.range.end().cmp(&rows.end(), &snapshot)) + }); + match (color, existing_highlight_index) { + (Some(_), Ok(ix)) | (_, Err(ix)) => row_highlights.insert( + ix, + RowHighlight { + index: post_inc(&mut self.highlight_order), + range: rows, + should_autoscroll, + color, + }, + ), + (None, Ok(i)) => { + row_highlights.remove(i); } } } @@ -9872,7 +9862,7 @@ impl Editor { self.highlighted_rows .get(&TypeId::of::())? .iter() - .map(|(_, range, color)| (range, color.as_ref())), + .map(|highlight| (&highlight.range, highlight.color.as_ref())), ) } @@ -9881,33 +9871,27 @@ impl Editor { /// Allows to ignore certain kinds of highlights. pub fn highlighted_display_rows( &mut self, - exclude_highlights: HashSet, cx: &mut WindowContext, ) -> BTreeMap { let snapshot = self.snapshot(cx); let mut used_highlight_orders = HashMap::default(); self.highlighted_rows .iter() - .filter(|(type_id, _)| !exclude_highlights.contains(type_id)) .flat_map(|(_, highlighted_rows)| highlighted_rows.iter()) .fold( BTreeMap::::new(), - |mut unique_rows, (highlight_order, anchor_range, hsla)| { - let start_row = anchor_range.start().to_display_point(&snapshot).row(); - let end_row = anchor_range.end().to_display_point(&snapshot).row(); + |mut unique_rows, highlight| { + let start_row = highlight.range.start().to_display_point(&snapshot).row(); + let end_row = highlight.range.end().to_display_point(&snapshot).row(); for row in start_row.0..=end_row.0 { let used_index = - used_highlight_orders.entry(row).or_insert(*highlight_order); - if highlight_order >= used_index { - *used_index = *highlight_order; - match hsla { - Some(hsla) => { - unique_rows.insert(DisplayRow(row), *hsla); - } - None => { - unique_rows.remove(&DisplayRow(row)); - } - } + used_highlight_orders.entry(row).or_insert(highlight.index); + if highlight.index >= *used_index { + *used_index = highlight.index; + match highlight.color { + Some(hsla) => unique_rows.insert(DisplayRow(row), hsla), + None => unique_rows.remove(&DisplayRow(row)), + }; } } unique_rows @@ -9915,6 +9899,22 @@ impl Editor { ) } + pub fn highlighted_display_row_for_autoscroll( + &self, + snapshot: &DisplaySnapshot, + ) -> Option { + self.highlighted_rows + .values() + .flat_map(|highlighted_rows| highlighted_rows.iter()) + .filter_map(|highlight| { + if highlight.color.is_none() || !highlight.should_autoscroll { + return None; + } + Some(highlight.range.start().to_display_point(&snapshot).row()) + }) + .min() + } + pub fn set_search_within_ranges( &mut self, ranges: &[Range], diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 58954c96a4..94d8330885 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -26,7 +26,7 @@ use crate::{ }; use anyhow::Result; use client::ParticipantIndex; -use collections::{BTreeMap, HashMap, HashSet}; +use collections::{BTreeMap, HashMap}; use git::{blame::BlameEntry, diff::DiffHunkStatus, Oid}; use gpui::{ anchored, deferred, div, fill, outline, point, px, quad, relative, size, svg, @@ -3948,9 +3948,9 @@ impl Element for EditorElement { ) }; - let highlighted_rows = self.editor.update(cx, |editor, cx| { - editor.highlighted_display_rows(HashSet::default(), cx) - }); + let highlighted_rows = self + .editor + .update(cx, |editor, cx| editor.highlighted_display_rows(cx)); let highlighted_ranges = self.editor.read(cx).background_highlights_in_range( start_anchor..end_anchor, &snapshot.display_snapshot, diff --git a/crates/editor/src/hunk_diff.rs b/crates/editor/src/hunk_diff.rs index 022fed5835..f9db17ac91 100644 --- a/crates/editor/src/hunk_diff.rs +++ b/crates/editor/src/hunk_diff.rs @@ -194,6 +194,7 @@ impl Editor { editor.highlight_rows::( to_inclusive_row_range(removed_rows, &snapshot), None, + false, cx, ); } @@ -269,6 +270,7 @@ impl Editor { self.highlight_rows::( to_inclusive_row_range(hunk_start..hunk_end, &snapshot), Some(added_hunk_color(cx)), + false, cx, ); None @@ -277,6 +279,7 @@ impl Editor { self.highlight_rows::( to_inclusive_row_range(hunk_start..hunk_end, &snapshot), Some(added_hunk_color(cx)), + false, cx, ); self.insert_deleted_text_block(diff_base_buffer, deleted_text_lines, &hunk, cx) @@ -476,6 +479,7 @@ impl Editor { editor.highlight_rows::( to_inclusive_row_range(removed_rows, &snapshot), None, + false, cx, ); } @@ -581,7 +585,7 @@ fn editor_with_deleted_text( .buffer_snapshot .anchor_after(editor.buffer.read(cx).len(cx)); - editor.highlight_rows::(start..=end, Some(deleted_color), cx); + editor.highlight_rows::(start..=end, Some(deleted_color), false, cx); let subscription_editor = parent_editor.clone(); editor._subscriptions.extend([ diff --git a/crates/editor/src/scroll/autoscroll.rs b/crates/editor/src/scroll/autoscroll.rs index b24be19ad6..5c33532f0c 100644 --- a/crates/editor/src/scroll/autoscroll.rs +++ b/crates/editor/src/scroll/autoscroll.rs @@ -1,13 +1,9 @@ -use std::{any::TypeId, cmp, f32}; - -use collections::HashSet; +use crate::{ + display_map::ToDisplayPoint, DisplayRow, Editor, EditorMode, LineWithInvisibles, RowExt, +}; use gpui::{px, Bounds, Pixels, ViewContext}; use language::Point; - -use crate::{ - display_map::ToDisplayPoint, DiffRowHighlight, DisplayRow, Editor, EditorMode, - LineWithInvisibles, RowExt, -}; +use std::{cmp, f32}; #[derive(PartialEq, Eq, Clone, Copy)] pub enum Autoscroll { @@ -107,14 +103,10 @@ impl Editor { let mut target_top; let mut target_bottom; - if let Some(first_highlighted_row) = &self - .highlighted_display_rows( - HashSet::from_iter(Some(TypeId::of::())), - cx, - ) - .first_entry() + if let Some(first_highlighted_row) = + self.highlighted_display_row_for_autoscroll(&display_map) { - target_top = first_highlighted_row.key().as_f32(); + target_top = first_highlighted_row.as_f32(); target_bottom = target_top + 1.; } else { let selections = self.selections.all::(cx); @@ -244,7 +236,10 @@ impl Editor { let mut target_left; let mut target_right; - if self.highlighted_rows.is_empty() { + if self + .highlighted_display_row_for_autoscroll(&display_map) + .is_none() + { target_left = px(f32::INFINITY); target_right = px(0.); for selection in selections { diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index 65fec2ab8f..3a829923c6 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -168,8 +168,7 @@ pub fn expanded_hunks_background_highlights( let mut range_start = 0; let mut previous_highlighted_row = None; - for (highlighted_row, _) in editor.highlighted_display_rows(collections::HashSet::default(), cx) - { + for (highlighted_row, _) in editor.highlighted_display_rows(cx) { match previous_highlighted_row { Some(previous_row) => { if previous_row + 1 != highlighted_row.0 { diff --git a/crates/go_to_line/Cargo.toml b/crates/go_to_line/Cargo.toml index 9cffedaa01..0e19b41b75 100644 --- a/crates/go_to_line/Cargo.toml +++ b/crates/go_to_line/Cargo.toml @@ -14,7 +14,6 @@ doctest = false [dependencies] anyhow.workspace = true -collections.workspace = true editor.workspace = true gpui.workspace = true menu.workspace = true diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 67cbe6c767..1376cc7080 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -122,6 +122,7 @@ impl GoToLine { active_editor.highlight_rows::( anchor..=anchor, Some(cx.theme().colors().editor_highlighted_line_background), + true, cx, ); active_editor.request_autoscroll(Autoscroll::center(), cx); @@ -219,17 +220,14 @@ impl Render for GoToLine { #[cfg(test)] mod tests { - use std::sync::Arc; - - use collections::HashSet; + use super::*; use gpui::{TestAppContext, VisualTestContext}; use indoc::indoc; use project::{FakeFs, Project}; use serde_json::json; + use std::sync::Arc; use workspace::{AppState, Workspace}; - use super::*; - #[gpui::test] async fn test_go_to_line_view_row_highlights(cx: &mut TestAppContext) { init_test(cx); @@ -350,7 +348,7 @@ mod tests { fn highlighted_display_rows(editor: &View, cx: &mut VisualTestContext) -> Vec { editor.update(cx, |editor, cx| { editor - .highlighted_display_rows(HashSet::default(), cx) + .highlighted_display_rows(cx) .into_keys() .map(|r| r.0) .collect() diff --git a/crates/outline/Cargo.toml b/crates/outline/Cargo.toml index 230fb0d358..6f385f5d8d 100644 --- a/crates/outline/Cargo.toml +++ b/crates/outline/Cargo.toml @@ -13,7 +13,6 @@ path = "src/outline.rs" doctest = false [dependencies] -collections.workspace = true editor.workspace = true fuzzy.workspace = true gpui.workspace = true diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index b90e931876..8b2e374e3b 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -144,6 +144,7 @@ impl OutlineViewDelegate { active_editor.highlight_rows::( outline_item.range.start..=outline_item.range.end, Some(cx.theme().colors().editor_highlighted_line_background), + true, cx, ); active_editor.request_autoscroll(Autoscroll::center(), cx); @@ -316,7 +317,7 @@ impl PickerDelegate for OutlineViewDelegate { #[cfg(test)] mod tests { - use collections::HashSet; + use super::*; use gpui::{TestAppContext, VisualTestContext}; use indoc::indoc; use language::{Language, LanguageConfig, LanguageMatcher}; @@ -324,8 +325,6 @@ mod tests { use serde_json::json; use workspace::{AppState, Workspace}; - use super::*; - #[gpui::test] async fn test_outline_view_row_highlights(cx: &mut TestAppContext) { init_test(cx); @@ -484,7 +483,7 @@ mod tests { fn highlighted_display_rows(editor: &View, cx: &mut VisualTestContext) -> Vec { editor.update(cx, |editor, cx| { editor - .highlighted_display_rows(HashSet::default(), cx) + .highlighted_display_rows(cx) .into_keys() .map(|r| r.0) .collect()