diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index bc843f9df6a7a..ba008995582c9 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -13603,20 +13603,24 @@ fn test_wrap_with_prefix() { ); } +fn is_hunk_selected(hunk: &MultiBufferDiffHunk, selections: &[Selection]) -> bool { + let mut buffer_rows_for_selections = selections.iter().map(|selection| { + let start = MultiBufferRow(selection.start.row); + let end = MultiBufferRow(selection.end.row); + start..end + }); + + buffer_rows_for_selections.any(|range| does_selection_touch_hunk(&range, hunk)) +} + fn hunks_for_selections( multi_buffer_snapshot: &MultiBufferSnapshot, selections: &[Selection], ) -> Vec { let buffer_rows_for_selections = selections.iter().map(|selection| { - let head = selection.head(); - let tail = selection.tail(); - let start = MultiBufferRow(tail.to_point(multi_buffer_snapshot).row); - let end = MultiBufferRow(head.to_point(multi_buffer_snapshot).row); - if start > end { - end..start - } else { - start..end - } + let start = MultiBufferRow(selection.start.to_point(multi_buffer_snapshot).row); + let end = MultiBufferRow(selection.end.to_point(multi_buffer_snapshot).row); + start..end }); hunks_for_rows(buffer_rows_for_selections, multi_buffer_snapshot) @@ -13633,19 +13637,8 @@ pub fn hunks_for_rows( let query_rows = selected_multi_buffer_rows.start..selected_multi_buffer_rows.end.next_row(); for hunk in multi_buffer_snapshot.git_diff_hunks_in_range(query_rows.clone()) { - // Deleted hunk is an empty row range, no caret can be placed there and Zed allows to revert it - // when the caret is just above or just below the deleted hunk. - let allow_adjacent = hunk_status(&hunk) == DiffHunkStatus::Removed; - let related_to_selection = if allow_adjacent { - hunk.row_range.overlaps(&query_rows) - || hunk.row_range.start == query_rows.end - || hunk.row_range.end == query_rows.start - } else { - // `selected_multi_buffer_rows` are inclusive (e.g. [2..2] means 2nd row is selected) - // `hunk.row_range` is exclusive (e.g. [2..3] means 2nd row is selected) - hunk.row_range.overlaps(&selected_multi_buffer_rows) - || selected_multi_buffer_rows.end == hunk.row_range.start - }; + let related_to_selection = + does_selection_touch_hunk(&selected_multi_buffer_rows, &hunk); if related_to_selection { if !processed_buffer_rows .entry(hunk.buffer_id) @@ -13662,6 +13655,26 @@ pub fn hunks_for_rows( hunks } +fn does_selection_touch_hunk( + selected_multi_buffer_rows: &Range, + hunk: &MultiBufferDiffHunk, +) -> bool { + let query_rows = selected_multi_buffer_rows.start..selected_multi_buffer_rows.end.next_row(); + // Deleted hunk is an empty row range, no caret can be placed there and Zed allows to revert it + // when the caret is just above or just below the deleted hunk. + let allow_adjacent = hunk_status(hunk) == DiffHunkStatus::Removed; + if allow_adjacent { + hunk.row_range.overlaps(&query_rows) + || hunk.row_range.start == query_rows.end + || hunk.row_range.end == query_rows.start + } else { + // `selected_multi_buffer_rows` are inclusive (e.g. [2..2] means 2nd row is selected) + // `hunk.row_range` is exclusive (e.g. [2..3] means 2nd row is selected) + hunk.row_range.overlaps(selected_multi_buffer_rows) + || selected_multi_buffer_rows.end == hunk.row_range.start + } +} + pub trait CollaborationHub { fn collaborators<'a>(&self, cx: &'a AppContext) -> &'a HashMap; fn user_participant_indices<'a>( diff --git a/crates/editor/src/hunk_diff.rs b/crates/editor/src/hunk_diff.rs index 0e9fbc0ab37dc..902aef33057e6 100644 --- a/crates/editor/src/hunk_diff.rs +++ b/crates/editor/src/hunk_diff.rs @@ -16,10 +16,11 @@ use util::RangeExt; use workspace::Item; use crate::{ - editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, ApplyAllDiffHunks, - ApplySelectedDiffHunks, BlockPlacement, BlockProperties, BlockStyle, CustomBlockId, - DiffRowHighlight, DisplayRow, DisplaySnapshot, Editor, EditorElement, ExpandAllHunkDiffs, - GoToHunk, GoToPrevHunk, RevertSelectedHunks, ToDisplayPoint, ToggleHunkDiff, + editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, is_hunk_selected, + ApplyAllDiffHunks, ApplySelectedDiffHunks, BlockPlacement, BlockProperties, BlockStyle, + CustomBlockId, DiffRowHighlight, DisplayRow, DisplaySnapshot, Editor, EditorElement, + ExpandAllHunkDiffs, GoToHunk, GoToPrevHunk, RevertSelectedHunks, ToDisplayPoint, + ToggleHunkDiff, }; #[derive(Debug, Clone)] @@ -373,12 +374,8 @@ impl Editor { _: &ApplySelectedDiffHunks, cx: &mut ViewContext, ) { - dbg!("apply_selected_diff_hunks"); let snapshot = self.buffer.read(cx).snapshot(cx); - let hunks = dbg!(hunks_for_selections( - &snapshot, - &self.selections.disjoint_anchors() - )); + let hunks = hunks_for_selections(&snapshot, &self.selections.disjoint_anchors()); self.transact(cx, |editor, cx| { if hunks.is_empty() { @@ -390,7 +387,6 @@ impl Editor { let mut ranges_by_buffer = HashMap::default(); for hunk in hunks { - dbg!(&hunk); if let Some(buffer) = editor.buffer.read(cx).buffer(hunk.buffer_id) { ranges_by_buffer .entry(buffer.clone()) @@ -440,15 +436,14 @@ impl Editor { let hunk = hunk.clone(); move |cx| { - let hunk_controls_menu_handle = - editor.read(cx).hunk_controls_menu_handle.clone(); - let is_first_hunk = editor - .read(cx) - .expanded_hunks - .hunks - .first() - .map(|first_hunk| first_hunk.hunk_range == hunk.multi_buffer_range) - .unwrap_or(false); + let is_hunk_selected = editor.update(&mut **cx, |editor, cx| { + let snapshot = editor.buffer.read(cx).snapshot(cx); + if let Some(hunk) = to_diff_hunk(&hunk, &snapshot) { + is_hunk_selected(&hunk, &editor.selections.all(cx)) + } else { + false + } + }); let focus_handle = editor.focus_handle(cx); @@ -561,7 +556,7 @@ impl Editor { } } }); - if is_first_hunk { + if is_hunk_selected { button.key_binding(KeyBinding::for_action_in( &RevertSelectedHunks, &focus_handle, @@ -588,7 +583,7 @@ impl Editor { }); } }); - if is_first_hunk { + if is_hunk_selected { button.key_binding(KeyBinding::for_action_in( &ApplySelectedDiffHunks, &focus_handle,