Skip to content

Commit

Permalink
Use selected hunk over first hunk for apply/discard
Browse files Browse the repository at this point in the history
Co-Authored-By: Max <[email protected]>
  • Loading branch information
rtfeldman and maxbrunsfeld committed Nov 21, 2024
1 parent 0deaf3b commit 44db64a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 43 deletions.
57 changes: 35 additions & 22 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13603,20 +13603,24 @@ fn test_wrap_with_prefix() {
);
}

fn is_hunk_selected(hunk: &MultiBufferDiffHunk, selections: &[Selection<Point>]) -> 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<Anchor>],
) -> Vec<MultiBufferDiffHunk> {
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)
Expand All @@ -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)
Expand All @@ -13662,6 +13655,26 @@ pub fn hunks_for_rows(
hunks
}

fn does_selection_touch_hunk(
selected_multi_buffer_rows: &Range<MultiBufferRow>,
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<PeerId, Collaborator>;
fn user_participant_indices<'a>(
Expand Down
37 changes: 16 additions & 21 deletions crates/editor/src/hunk_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -373,12 +374,8 @@ impl Editor {
_: &ApplySelectedDiffHunks,
cx: &mut ViewContext<Self>,
) {
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() {
Expand All @@ -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())
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -561,7 +556,7 @@ impl Editor {
}
}
});
if is_first_hunk {
if is_hunk_selected {
button.key_binding(KeyBinding::for_action_in(
&RevertSelectedHunks,
&focus_handle,
Expand All @@ -588,7 +583,7 @@ impl Editor {
});
}
});
if is_first_hunk {
if is_hunk_selected {
button.key_binding(KeyBinding::for_action_in(
&ApplySelectedDiffHunks,
&focus_handle,
Expand Down

0 comments on commit 44db64a

Please sign in to comment.