From 4762e52d310503565c52b59362b62fe1ebfb57ae Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 10 May 2024 02:02:56 +0300 Subject: [PATCH] Properly calculate expanded git diff hunk highlight ranges (#11632) Closes https://github.com/zed-industries/zed/issues/11576 Release Notes: - Fixed expanded diff hunks highlighting an extra row as added ([11576](https://github.com/zed-industries/zed/issues/11576)) --- crates/collab/src/tests/editor_tests.rs | 18 ++-- crates/editor/src/editor.rs | 55 ++++++++---- crates/editor/src/editor_tests.rs | 115 +++++++++++------------- crates/editor/src/hunk_diff.rs | 49 +++++++--- crates/editor/src/test.rs | 39 +++++--- crates/go_to_line/src/go_to_line.rs | 2 +- crates/outline/src/outline.rs | 4 +- 7 files changed, 161 insertions(+), 121 deletions(-) diff --git a/crates/collab/src/tests/editor_tests.rs b/crates/collab/src/tests/editor_tests.rs index e46702ad94..c19692789e 100644 --- a/crates/collab/src/tests/editor_tests.rs +++ b/crates/collab/src/tests/editor_tests.rs @@ -2110,10 +2110,7 @@ struct Row10;"#}; let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new(), - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!( all_hunks, vec![ @@ -2135,8 +2132,8 @@ struct Row10;"#}; let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![1..3, 8..9], + expanded_hunks_background_highlights(editor, cx), + vec![1..=2, 8..=8], ); assert_eq!( all_hunks, @@ -2170,10 +2167,7 @@ struct Row10;"#}; let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new(), - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!( all_hunks, vec![( @@ -2189,8 +2183,8 @@ struct Row10;"#}; let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new(), + expanded_hunks_background_highlights(editor, cx), + vec![5..=5] ); assert_eq!( all_hunks, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ca1b24f93c..f84154087b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -449,7 +449,7 @@ pub struct Editor { show_wrap_guides: Option, placeholder_text: Option>, highlight_order: usize, - highlighted_rows: HashMap, Hsla)>>, + highlighted_rows: HashMap, Option)>>, background_highlights: TreeMap, scrollbar_marker_state: ScrollbarMarkerState, nav_history: Option, @@ -9705,7 +9705,7 @@ impl Editor { /// If multiple anchor ranges will produce highlights for the same row, the last range added will be used. pub fn highlight_rows( &mut self, - rows: Range, + rows: RangeInclusive, color: Option, cx: &mut ViewContext, ) { @@ -9716,9 +9716,13 @@ impl Editor { 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)) + .start() + .cmp(&rows.start(), &multi_buffer_snapshot) + .then( + highlight_range + .end() + .cmp(&rows.end(), &multi_buffer_snapshot), + ) }); match color { Some(color) => { @@ -9728,20 +9732,22 @@ impl Editor { }; row_highlights.insert( insert_index, - (post_inc(&mut self.highlight_order), rows, color), + (post_inc(&mut self.highlight_order), rows, Some(color)), ); } - None => { - if let Ok(i) = existing_highlight_index { + 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) => { - if let Some(color) = color { - v.insert(vec![(post_inc(&mut self.highlight_order), rows, color)]); - } + v.insert(vec![(post_inc(&mut self.highlight_order), rows, color)]); } } } @@ -9754,12 +9760,12 @@ impl Editor { /// For a highlight given context type, gets all anchor ranges that will be used for row highlighting. pub fn highlighted_rows( &self, - ) -> Option, &Hsla)>> { + ) -> Option, Option<&Hsla>)>> { Some( self.highlighted_rows .get(&TypeId::of::())? .iter() - .map(|(_, range, color)| (range, color)), + .map(|(_, range, color)| (range, color.as_ref())), ) } @@ -9780,14 +9786,21 @@ impl Editor { .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(); + let start_row = anchor_range.start().to_display_point(&snapshot).row(); + let end_row = anchor_range.end().to_display_point(&snapshot).row(); for row in start_row..=end_row { let used_index = used_highlight_orders.entry(row).or_insert(*highlight_order); if highlight_order >= used_index { *used_index = *highlight_order; - unique_rows.insert(row, *hsla); + match hsla { + Some(hsla) => { + unique_rows.insert(row, *hsla); + } + None => { + unique_rows.remove(&row); + } + } } } unique_rows @@ -11587,6 +11600,12 @@ trait RangeToAnchorExt { impl RangeToAnchorExt for Range { fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range { - snapshot.anchor_after(self.start)..snapshot.anchor_before(self.end) + let start_offset = self.start.to_offset(snapshot); + let end_offset = self.end.to_offset(snapshot); + if start_offset == end_offset { + snapshot.anchor_before(start_offset)..snapshot.anchor_before(end_offset) + } else { + snapshot.anchor_after(self.start)..snapshot.anchor_before(self.end) + } } } diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 06c79bf556..01d0a390da 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -9543,8 +9543,8 @@ async fn test_toggle_hunk_diff(executor: BackgroundExecutor, cx: &mut gpui::Test let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![1..2, 7..8, 9..10], + expanded_hunks_background_highlights(editor, cx), + vec![1..=1, 7..=7, 9..=9], "After expanding, all git additions should be highlighted for Modified (split into added and removed) and Added hunks" ); assert_eq!( @@ -9571,7 +9571,7 @@ async fn test_toggle_hunk_diff(executor: BackgroundExecutor, cx: &mut gpui::Test let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), + expanded_hunks_background_highlights(editor, cx), Vec::new(), "After cancelling in editor, no git highlights should be left" ); @@ -9684,8 +9684,8 @@ async fn test_toggled_diff_base_change( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![9..11, 13..15], + expanded_hunks_background_highlights(editor, cx), + vec![9..=10, 13..=14], "After expanding, all git additions should be highlighted for Modified (split into added and removed) and Added hunks" ); assert_eq!( @@ -9713,7 +9713,7 @@ async fn test_toggled_diff_base_change( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), + expanded_hunks_background_highlights(editor, cx), Vec::new(), "After diff base is changed, old git highlights should be removed" ); @@ -9858,8 +9858,8 @@ async fn test_fold_unfold_diff(executor: BackgroundExecutor, cx: &mut gpui::Test let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![9..11, 13..15, 19..20] + expanded_hunks_background_highlights(editor, cx), + vec![9..=10, 13..=14, 19..=19] ); assert_eq!( all_hunks, @@ -9923,8 +9923,8 @@ async fn test_fold_unfold_diff(executor: BackgroundExecutor, cx: &mut gpui::Test let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![5..6], + expanded_hunks_background_highlights(editor, cx), + vec![0..=0, 5..=5], "Only one hunk is left not folded, its highlight should be visible" ); assert_eq!( @@ -10004,8 +10004,8 @@ async fn test_fold_unfold_diff(executor: BackgroundExecutor, cx: &mut gpui::Test let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![9..11, 13..15, 19..20], + expanded_hunks_background_highlights(editor, cx), + vec![9..=10, 13..=14, 19..=19], "After unfolding, all hunk diffs should be visible again" ); assert_eq!( @@ -10172,10 +10172,7 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext) let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new(), - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!(all_hunks, expected_all_hunks); assert_eq!(all_expanded_hunks, Vec::new()); }); @@ -10190,8 +10187,8 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext) let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![18..19, 33..34], + expanded_hunks_background_highlights(editor, cx), + vec![18..=18, 33..=33], ); assert_eq!(all_hunks, expected_all_hunks_shifted); assert_eq!(all_hunks, all_expanded_hunks); @@ -10205,10 +10202,7 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext) let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new(), - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!(all_hunks, expected_all_hunks); assert_eq!(all_expanded_hunks, Vec::new()); }); @@ -10222,8 +10216,8 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext) let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![18..19, 33..34], + expanded_hunks_background_highlights(editor, cx), + vec![18..=18, 33..=33], ); assert_eq!(all_hunks, expected_all_hunks_shifted); assert_eq!(all_hunks, all_expanded_hunks); @@ -10237,10 +10231,7 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext) let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new(), - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!(all_hunks, expected_all_hunks); assert_eq!(all_expanded_hunks, Vec::new()); }); @@ -10329,8 +10320,8 @@ async fn test_edits_around_toggled_additions( vec![("".to_string(), DiffHunkStatus::Added, 4..7)] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![4..7] + expanded_hunks_background_highlights(editor, cx), + vec![4..=6] ); assert_eq!(all_hunks, all_expanded_hunks); }); @@ -10365,8 +10356,8 @@ async fn test_edits_around_toggled_additions( vec![("".to_string(), DiffHunkStatus::Added, 4..8)] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![4..8], + expanded_hunks_background_highlights(editor, cx), + vec![4..=6], "Edited hunk should have one more line added" ); assert_eq!( @@ -10406,8 +10397,8 @@ async fn test_edits_around_toggled_additions( vec![("".to_string(), DiffHunkStatus::Added, 4..9)] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![4..9], + expanded_hunks_background_highlights(editor, cx), + vec![4..=6], "Edited hunk should have one more line added" ); assert_eq!(all_hunks, all_expanded_hunks); @@ -10446,8 +10437,8 @@ async fn test_edits_around_toggled_additions( vec![("".to_string(), DiffHunkStatus::Added, 4..8)] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![4..8], + expanded_hunks_background_highlights(editor, cx), + vec![4..=6], "Deleting a line should shrint the hunk" ); assert_eq!( @@ -10490,8 +10481,8 @@ async fn test_edits_around_toggled_additions( vec![("".to_string(), DiffHunkStatus::Added, 5..6)] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![5..6] + expanded_hunks_background_highlights(editor, cx), + vec![5..=5] ); assert_eq!(all_hunks, all_expanded_hunks); }); @@ -10533,7 +10524,7 @@ async fn test_edits_around_toggled_additions( ] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), + expanded_hunks_background_highlights(editor, cx), Vec::new(), "Should close all stale expanded addition hunks" ); @@ -10632,10 +10623,7 @@ async fn test_edits_around_toggled_deletions( let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new() - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!( all_hunks, vec![( @@ -10672,7 +10660,7 @@ async fn test_edits_around_toggled_deletions( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), + expanded_hunks_background_highlights(editor, cx), Vec::new(), "Deleted hunks do not highlight current editor's background" ); @@ -10710,10 +10698,7 @@ async fn test_edits_around_toggled_deletions( let snapshot = editor.snapshot(cx); let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); - assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - Vec::new() - ); + assert_eq!(expanded_hunks_background_highlights(editor, cx), Vec::new()); assert_eq!( all_hunks, vec![( @@ -10757,8 +10742,8 @@ async fn test_edits_around_toggled_deletions( )] ); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![7..8], + expanded_hunks_background_highlights(editor, cx), + vec![7..=7], "Modified expanded hunks should display additions and highlight their background" ); assert_eq!(all_hunks, all_expanded_hunks); @@ -10851,8 +10836,8 @@ async fn test_edits_around_toggled_modifications( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![6..7], + expanded_hunks_background_highlights(editor, cx), + vec![6..=6], ); assert_eq!( all_hunks, @@ -10894,8 +10879,8 @@ async fn test_edits_around_toggled_modifications( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![6..9], + expanded_hunks_background_highlights(editor, cx), + vec![6..=6], "Modified hunk should grow highlighted lines on more text additions" ); assert_eq!( @@ -10940,9 +10925,8 @@ async fn test_edits_around_toggled_modifications( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![6..9], - "Modified hunk should grow deleted lines on text deletions above" + expanded_hunks_background_highlights(editor, cx), + vec![6..=8], ); assert_eq!( all_hunks, @@ -10950,7 +10934,8 @@ async fn test_edits_around_toggled_modifications( "const B: u32 = 42;\nconst C: u32 = 42;\n".to_string(), DiffHunkStatus::Modified, 6..9 - )] + )], + "Modified hunk should grow deleted lines on text deletions above" ); assert_eq!(all_hunks, all_expanded_hunks); }); @@ -10984,8 +10969,8 @@ async fn test_edits_around_toggled_modifications( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![6..10], + expanded_hunks_background_highlights(editor, cx), + vec![6..=9], "Modified hunk should grow deleted lines on text modifications above" ); assert_eq!( @@ -11028,8 +11013,8 @@ async fn test_edits_around_toggled_modifications( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![6..9], + expanded_hunks_background_highlights(editor, cx), + vec![6..=8], "Modified hunk should grow shrink lines on modification lines removal" ); assert_eq!( @@ -11069,7 +11054,7 @@ async fn test_edits_around_toggled_modifications( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), + expanded_hunks_background_highlights(editor, cx), Vec::new(), "Modified hunk should turn into a removed one on all modified lines removal" ); @@ -11172,8 +11157,8 @@ async fn test_multiple_expanded_hunks_merge( let all_hunks = editor_hunks(editor, &snapshot, cx); let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx); assert_eq!( - expanded_hunks_background_highlights(editor, &snapshot), - vec![6..7], + expanded_hunks_background_highlights(editor, cx), + vec![6..=6], ); assert_eq!( all_hunks, diff --git a/crates/editor/src/hunk_diff.rs b/crates/editor/src/hunk_diff.rs index dbc0fbaf9e..f2f0a5efc4 100644 --- a/crates/editor/src/hunk_diff.rs +++ b/crates/editor/src/hunk_diff.rs @@ -1,4 +1,7 @@ -use std::{ops::Range, sync::Arc}; +use std::{ + ops::{Range, RangeInclusive}, + sync::Arc, +}; use collections::{hash_map, HashMap, HashSet}; use git::diff::{DiffHunk, DiffHunkStatus}; @@ -14,8 +17,8 @@ use util::{debug_panic, RangeExt}; use crate::{ git::{diff_hunk_to_display, DisplayDiffHunk}, hunks_for_selections, BlockDisposition, BlockId, BlockProperties, BlockStyle, DiffRowHighlight, - Editor, ExpandAllHunkDiffs, RangeToAnchorExt, RevertSelectedHunks, ToDisplayPoint, - ToggleHunkDiff, + Editor, EditorSnapshot, ExpandAllHunkDiffs, RangeToAnchorExt, RevertSelectedHunks, + ToDisplayPoint, ToggleHunkDiff, }; #[derive(Debug, Clone)] @@ -184,7 +187,11 @@ impl Editor { } for removed_rows in highlights_to_remove { - editor.highlight_rows::(removed_rows, None, cx); + editor.highlight_rows::( + to_inclusive_row_range(removed_rows, &snapshot), + None, + cx, + ); } editor.remove_blocks(blocks_to_remove, None, cx); for hunk in hunks_to_expand { @@ -216,9 +223,9 @@ impl Editor { let hunk_end = hunk.multi_buffer_range.end; let buffer = self.buffer().clone(); + let snapshot = self.snapshot(cx); let (diff_base_buffer, deleted_text_lines) = buffer.update(cx, |buffer, cx| { - let snapshot = buffer.snapshot(cx); - let hunk = buffer_diff_hunk(&snapshot, multi_buffer_row_range.clone())?; + let hunk = buffer_diff_hunk(&snapshot.buffer_snapshot, multi_buffer_row_range.clone())?; let mut buffer_ranges = buffer.range_to_buffer_ranges(multi_buffer_row_range, cx); if buffer_ranges.len() == 1 { let (buffer, _, _) = buffer_ranges.pop()?; @@ -256,7 +263,7 @@ impl Editor { } DiffHunkStatus::Added => { self.highlight_rows::( - hunk_start..hunk_end, + to_inclusive_row_range(hunk_start..hunk_end, &snapshot), Some(added_hunk_color(cx)), cx, ); @@ -264,13 +271,16 @@ impl Editor { } DiffHunkStatus::Modified => { self.highlight_rows::( - hunk_start..hunk_end, + to_inclusive_row_range(hunk_start..hunk_end, &snapshot), Some(added_hunk_color(cx)), cx, ); self.insert_deleted_text_block(diff_base_buffer, deleted_text_lines, &hunk, cx) } }; + if hunk_start.cmp(&hunk_end, &multi_buffer_snapshot).is_gt() { + eprintln!("@######################!!!!!!!!!!!!!"); + }; self.expanded_hunks.hunks.insert( block_insert_index, ExpandedHunk { @@ -461,7 +471,11 @@ impl Editor { }); for removed_rows in highlights_to_remove { - editor.highlight_rows::(removed_rows, None, cx); + editor.highlight_rows::( + to_inclusive_row_range(removed_rows, &snapshot), + None, + cx, + ); } editor.remove_blocks(blocks_to_remove, None, cx); @@ -565,7 +579,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), cx); let hunk_related_subscription = cx.on_blur(&editor.focus_handle, |editor, cx| { editor.change_selections(None, cx, |s| { s.try_cancel(); @@ -619,3 +633,18 @@ fn buffer_diff_hunk( } None } + +fn to_inclusive_row_range( + row_range: Range, + snapshot: &EditorSnapshot, +) -> RangeInclusive { + let mut display_row_range = + row_range.start.to_display_point(snapshot)..row_range.end.to_display_point(snapshot); + if display_row_range.end.row() > display_row_range.start.row() { + *display_row_range.end.row_mut() -= 1; + } + let point_range = display_row_range.start.to_point(&snapshot.display_snapshot) + ..display_row_range.end.to_point(&snapshot.display_snapshot); + let new_range = point_range.to_anchors(&snapshot.buffer_snapshot); + new_range.start..=new_range.end +} diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index af1bc75201..bc0c0afb11 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -148,18 +148,31 @@ pub fn expanded_hunks( #[cfg(any(test, feature = "test-support"))] pub fn expanded_hunks_background_highlights( - editor: &Editor, - snapshot: &DisplaySnapshot, -) -> Vec> { - use itertools::Itertools; + editor: &mut Editor, + cx: &mut gpui::WindowContext, +) -> Vec> { + let mut highlights = Vec::new(); - editor - .highlighted_rows::() - .into_iter() - .flatten() - .map(|(range, _)| { - range.start.to_display_point(snapshot).row()..range.end.to_display_point(snapshot).row() - }) - .unique() - .collect() + let mut range_start = 0; + let mut previous_highlighted_row = None; + for (highlighted_row, _) in editor.highlighted_display_rows(collections::HashSet::default(), cx) + { + match previous_highlighted_row { + Some(previous_row) => { + if previous_row + 1 != highlighted_row { + highlights.push(range_start..=previous_row); + range_start = highlighted_row; + } + } + None => { + range_start = highlighted_row; + } + } + previous_highlighted_row = Some(highlighted_row); + } + if let Some(previous_row) = previous_highlighted_row { + highlights.push(range_start..=previous_row); + } + + highlights } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index f47c144580..5e6e51612f 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -120,7 +120,7 @@ impl GoToLine { let anchor = snapshot.buffer_snapshot.anchor_before(point); active_editor.clear_row_highlights::(); active_editor.highlight_rows::( - anchor..anchor, + anchor..=anchor, Some(cx.theme().colors().editor_highlighted_line_background), cx, ); diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index e57f8c56b6..cdaf5fcf20 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -142,7 +142,7 @@ impl OutlineViewDelegate { self.active_editor.update(cx, |active_editor, cx| { active_editor.clear_row_highlights::(); active_editor.highlight_rows::( - outline_item.range.clone(), + outline_item.range.start..=outline_item.range.end, Some(cx.theme().colors().editor_highlighted_line_background), cx, ); @@ -243,7 +243,7 @@ impl PickerDelegate for OutlineViewDelegate { .and_then(|highlights| highlights.into_iter().next().map(|(rows, _)| rows.clone())) { active_editor.change_selections(Some(Autoscroll::center()), cx, |s| { - s.select_ranges([rows.start..rows.start]) + s.select_ranges([*rows.start()..*rows.start()]) }); active_editor.clear_row_highlights::(); active_editor.focus(cx);