From a6a8d79d8612425dff6ad02dcc14ef99cfdf914e Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Thu, 13 Feb 2025 14:38:20 -0500 Subject: [PATCH] Rework hunk controls (#24814) - Remove prev hunk arrow - Replace next hunk arrow with "Skip" labelled button - New "Stage"/"Unstage" labelled button cc @iamnbutler Release Notes: - N/A --------- Co-authored-by: Nate Co-authored-by: Nate Butler --- crates/editor/src/editor.rs | 4 +- crates/editor/src/element.rs | 101 ++++++++++++++++++----------------- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index dbc9b0616fc233b33e1b1c4678baeb3b74363ddb..a61ffbcf30d25490605cc053ecae18a5555d38b0 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6975,10 +6975,10 @@ impl Editor { cx: &mut Context, ) { let selections = self.selections.all(cx).into_iter().map(|s| s.range()); - self.revert_hunks_in_ranges(selections, window, cx); + self.discard_hunks_in_ranges(selections, window, cx); } - fn revert_hunks_in_ranges( + fn discard_hunks_in_ranges( &mut self, ranges: impl Iterator>, window: &mut Window, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 46d33a9c98ef5bd05e5fcd44de55bee9a00777c6..9c00adff34b18fc0a1c617cfc6be46a3327414f8 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -18,10 +18,10 @@ use crate::{ BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint, DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, FocusedBlock, GoToHunk, - GoToPrevHunk, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor, - InlineCompletion, JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, - RevertSelectedHunks, RowExt, RowRangeExt, SelectPhase, Selection, SoftWrap, - StickyHeaderExcerpt, ToPoint, ToggleFold, CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT, + GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor, InlineCompletion, + JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, RevertSelectedHunks, RowExt, + RowRangeExt, SelectPhase, Selection, SoftWrap, StickyHeaderExcerpt, ToPoint, ToggleFold, + ToggleStagedSelectedDiffHunks, CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT, GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, }; use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus}; @@ -33,8 +33,8 @@ use gpui::{ anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, pattern_slash, point, px, quad, relative, size, svg, transparent_black, Action, AnyElement, App, AvailableSpace, Axis, Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, - CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _, - FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length, + CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable, FontId, + GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement, @@ -4166,13 +4166,16 @@ impl EditorElement { let y = display_row_range.start.as_f32() * line_height + text_hitbox.bounds.top() - scroll_pixel_position.y; - let x = text_hitbox.bounds.right() - px(100.); + let x = text_hitbox.bounds.right() + - rems(6.).to_pixels(window.rem_size()) + - px(33.); let mut element = diff_hunk_controls( display_row_range.start.0, multi_buffer_range.clone(), line_height, &editor, + window, cx, ); element.prepaint_as_root( @@ -8916,8 +8919,13 @@ fn diff_hunk_controls( hunk_range: Range, line_height: Pixels, editor: &Entity, + _window: &mut Window, cx: &mut App, ) -> AnyElement { + let stage = editor.update(cx, |editor, cx| { + let snapshot = editor.buffer.read(cx).snapshot(cx); + editor.has_stageable_diff_hunks_in_ranges(&[hunk_range.start..hunk_range.start], &snapshot) + }); h_flex() .h(line_height) .mr_1() @@ -8930,39 +8938,15 @@ fn diff_hunk_controls( .bg(cx.theme().colors().editor_background) .gap_1() .child( - IconButton::new(("next-hunk", row as u64), IconName::ArrowDown) + IconButton::new(("discard-hunk", row as u64), IconName::Undo) .shape(IconButtonShape::Square) .icon_size(IconSize::Small) - // .disabled(!has_multiple_hunks) - .tooltip({ - let focus_handle = editor.focus_handle(cx); - move |window, cx| { - Tooltip::for_action_in("Next Hunk", &GoToHunk, &focus_handle, window, cx) - } - }) - .on_click({ - let editor = editor.clone(); - move |_event, window, cx| { - editor.update(cx, |editor, cx| { - let snapshot = editor.snapshot(window, cx); - let position = hunk_range.end.to_point(&snapshot.buffer_snapshot); - editor.go_to_hunk_after_position(&snapshot, position, window, cx); - editor.expand_selected_diff_hunks(cx); - }); - } - }), - ) - .child( - IconButton::new(("prev-hunk", row as u64), IconName::ArrowUp) - .shape(IconButtonShape::Square) - .icon_size(IconSize::Small) - // .disabled(!has_multiple_hunks) .tooltip({ let focus_handle = editor.focus_handle(cx); move |window, cx| { Tooltip::for_action_in( - "Previous Hunk", - &GoToPrevHunk, + "Discard Hunk", + &RevertSelectedHunks, &focus_handle, window, cx, @@ -8975,26 +8959,18 @@ fn diff_hunk_controls( editor.update(cx, |editor, cx| { let snapshot = editor.snapshot(window, cx); let point = hunk_range.start.to_point(&snapshot.buffer_snapshot); - editor.go_to_hunk_before_position(&snapshot, point, window, cx); - editor.expand_selected_diff_hunks(cx); + editor.discard_hunks_in_ranges([point..point].into_iter(), window, cx); }); } }), ) .child( - IconButton::new("discard", IconName::Undo) - .shape(IconButtonShape::Square) - .icon_size(IconSize::Small) + Button::new(("skip-hunk", row as u64), "Skip") + .label_size(LabelSize::Small) .tooltip({ let focus_handle = editor.focus_handle(cx); move |window, cx| { - Tooltip::for_action_in( - "Discard Hunk", - &RevertSelectedHunks, - &focus_handle, - window, - cx, - ) + Tooltip::for_action_in("Skip Hunk", &GoToHunk, &focus_handle, window, cx) } }) .on_click({ @@ -9002,11 +8978,40 @@ fn diff_hunk_controls( move |_event, window, cx| { editor.update(cx, |editor, cx| { let snapshot = editor.snapshot(window, cx); - let point = hunk_range.start.to_point(&snapshot.buffer_snapshot); - editor.revert_hunks_in_ranges([point..point].into_iter(), window, cx); + let position = hunk_range.end.to_point(&snapshot.buffer_snapshot); + editor.go_to_hunk_after_position(&snapshot, position, window, cx); + editor.expand_selected_diff_hunks(cx); }); } }), ) + .child( + Button::new( + ("stage-unstage-hunk", row as u64), + if stage { "Stage" } else { "Unstage" }, + ) + .label_size(LabelSize::Small) + .tooltip({ + let focus_handle = editor.focus_handle(cx); + move |window, cx| { + Tooltip::for_action_in( + if stage { "Stage Hunk" } else { "Unstage Hunk" }, + &ToggleStagedSelectedDiffHunks, + &focus_handle, + window, + cx, + ) + } + }) + .on_click({ + let editor = editor.clone(); + move |_event, _window, cx| { + editor.update(cx, |editor, cx| { + editor + .stage_or_unstage_diff_hunks(&[hunk_range.start..hunk_range.start], cx); + }); + } + }), + ) .into_any_element() }