Detailed changes
@@ -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",
@@ -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<bool>,
placeholder_text: Option<Arc<str>>,
highlight_order: usize,
- highlighted_rows: HashMap<TypeId, Vec<(usize, RangeInclusive<Anchor>, Option<Hsla>)>>,
+ highlighted_rows: HashMap<TypeId, Vec<RowHighlight>>,
background_highlights: TreeMap<TypeId, BackgroundHighlight>,
scrollbar_marker_state: ScrollbarMarkerState,
nav_history: Option<ItemNavHistory>,
@@ -660,6 +660,13 @@ impl SelectionHistory {
}
}
+struct RowHighlight {
+ index: usize,
+ range: RangeInclusive<Anchor>,
+ color: Option<Hsla>,
+ should_autoscroll: bool,
+}
+
#[derive(Clone, Debug)]
struct AddSelectionsState {
above: bool,
@@ -9814,47 +9821,30 @@ impl Editor {
&mut self,
rows: RangeInclusive<Anchor>,
color: Option<Hsla>,
+ should_autoscroll: bool,
cx: &mut ViewContext<Self>,
) {
- let multi_buffer_snapshot = self.buffer().read(cx).snapshot(cx);
- match self.highlighted_rows.entry(TypeId::of::<T>()) {
- 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::<T>()).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::<T>())?
.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<TypeId>,
cx: &mut WindowContext,
) -> BTreeMap<DisplayRow, Hsla> {
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::<DisplayRow, Hsla>::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<DisplayRow> {
+ 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<Anchor>],
@@ -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,
@@ -194,6 +194,7 @@ impl Editor {
editor.highlight_rows::<DiffRowHighlight>(
to_inclusive_row_range(removed_rows, &snapshot),
None,
+ false,
cx,
);
}
@@ -269,6 +270,7 @@ impl Editor {
self.highlight_rows::<DiffRowHighlight>(
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::<DiffRowHighlight>(
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::<DiffRowHighlight>(
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::<DiffRowHighlight>(start..=end, Some(deleted_color), cx);
+ editor.highlight_rows::<DiffRowHighlight>(start..=end, Some(deleted_color), false, cx);
let subscription_editor = parent_editor.clone();
editor._subscriptions.extend([
@@ -1,13 +1,9 @@
-use std::{any::TypeId, cmp, f32};
-
-use collections::HashSet;
-use gpui::{px, Bounds, Pixels, ViewContext};
-use language::Point;
-
use crate::{
- display_map::ToDisplayPoint, DiffRowHighlight, DisplayRow, Editor, EditorMode,
- LineWithInvisibles, RowExt,
+ display_map::ToDisplayPoint, DisplayRow, Editor, EditorMode, LineWithInvisibles, RowExt,
};
+use gpui::{px, Bounds, Pixels, ViewContext};
+use language::Point;
+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::<DiffRowHighlight>())),
- 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::<Point>(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 {
@@ -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 {
@@ -14,7 +14,6 @@ doctest = false
[dependencies]
anyhow.workspace = true
-collections.workspace = true
editor.workspace = true
gpui.workspace = true
menu.workspace = true
@@ -122,6 +122,7 @@ impl GoToLine {
active_editor.highlight_rows::<GoToLineRowHighlights>(
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<Editor>, cx: &mut VisualTestContext) -> Vec<u32> {
editor.update(cx, |editor, cx| {
editor
- .highlighted_display_rows(HashSet::default(), cx)
+ .highlighted_display_rows(cx)
.into_keys()
.map(|r| r.0)
.collect()
@@ -13,7 +13,6 @@ path = "src/outline.rs"
doctest = false
[dependencies]
-collections.workspace = true
editor.workspace = true
fuzzy.workspace = true
gpui.workspace = true
@@ -144,6 +144,7 @@ impl OutlineViewDelegate {
active_editor.highlight_rows::<OutlineRowHighlights>(
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<Editor>, cx: &mut VisualTestContext) -> Vec<u32> {
editor.update(cx, |editor, cx| {
editor
- .highlighted_display_rows(HashSet::default(), cx)
+ .highlighted_display_rows(cx)
.into_keys()
.map(|r| r.0)
.collect()