Revert "Styling for Apply/Discard buttons (#21017)"
This reverts commit 884748038e
.
This commit is contained in:
parent
6dbe2ef10c
commit
64708527e7
9 changed files with 291 additions and 409 deletions
|
@ -522,7 +522,7 @@
|
||||||
{
|
{
|
||||||
"context": "ProposedChangesEditor",
|
"context": "ProposedChangesEditor",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"ctrl-shift-y": "editor::ApplySelectedDiffHunks",
|
"ctrl-shift-y": "editor::ApplyDiffHunk",
|
||||||
"ctrl-alt-a": "editor::ApplyAllDiffHunks"
|
"ctrl-alt-a": "editor::ApplyAllDiffHunks"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -562,7 +562,7 @@
|
||||||
{
|
{
|
||||||
"context": "ProposedChangesEditor",
|
"context": "ProposedChangesEditor",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"cmd-shift-y": "editor::ApplySelectedDiffHunks",
|
"cmd-shift-y": "editor::ApplyDiffHunk",
|
||||||
"cmd-shift-a": "editor::ApplyAllDiffHunks"
|
"cmd-shift-a": "editor::ApplyAllDiffHunks"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -209,7 +209,7 @@ gpui::actions!(
|
||||||
AddSelectionAbove,
|
AddSelectionAbove,
|
||||||
AddSelectionBelow,
|
AddSelectionBelow,
|
||||||
ApplyAllDiffHunks,
|
ApplyAllDiffHunks,
|
||||||
ApplySelectedDiffHunks,
|
ApplyDiffHunk,
|
||||||
Backspace,
|
Backspace,
|
||||||
Cancel,
|
Cancel,
|
||||||
CancelLanguageServerWork,
|
CancelLanguageServerWork,
|
||||||
|
|
|
@ -99,8 +99,7 @@ use language::{
|
||||||
use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange};
|
use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange};
|
||||||
use linked_editing_ranges::refresh_linked_ranges;
|
use linked_editing_ranges::refresh_linked_ranges;
|
||||||
pub use proposed_changes_editor::{
|
pub use proposed_changes_editor::{
|
||||||
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesToolbar,
|
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,
|
||||||
ProposedChangesToolbarControls,
|
|
||||||
};
|
};
|
||||||
use similar::{ChangeTag, TextDiff};
|
use similar::{ChangeTag, TextDiff};
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
|
@ -161,7 +160,7 @@ use theme::{
|
||||||
};
|
};
|
||||||
use ui::{
|
use ui::{
|
||||||
h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize,
|
h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize,
|
||||||
ListItem, Popover, Tooltip,
|
ListItem, Popover, PopoverMenuHandle, Tooltip,
|
||||||
};
|
};
|
||||||
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
|
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||||
use workspace::item::{ItemHandle, PreviewTabsSettings};
|
use workspace::item::{ItemHandle, PreviewTabsSettings};
|
||||||
|
@ -591,6 +590,7 @@ pub struct Editor {
|
||||||
nav_history: Option<ItemNavHistory>,
|
nav_history: Option<ItemNavHistory>,
|
||||||
context_menu: RwLock<Option<ContextMenu>>,
|
context_menu: RwLock<Option<ContextMenu>>,
|
||||||
mouse_context_menu: Option<MouseContextMenu>,
|
mouse_context_menu: Option<MouseContextMenu>,
|
||||||
|
hunk_controls_menu_handle: PopoverMenuHandle<ui::ContextMenu>,
|
||||||
completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
|
completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
|
||||||
signature_help_state: SignatureHelpState,
|
signature_help_state: SignatureHelpState,
|
||||||
auto_signature_help: Option<bool>,
|
auto_signature_help: Option<bool>,
|
||||||
|
@ -2112,6 +2112,7 @@ impl Editor {
|
||||||
nav_history: None,
|
nav_history: None,
|
||||||
context_menu: RwLock::new(None),
|
context_menu: RwLock::new(None),
|
||||||
mouse_context_menu: None,
|
mouse_context_menu: None,
|
||||||
|
hunk_controls_menu_handle: PopoverMenuHandle::default(),
|
||||||
completion_tasks: Default::default(),
|
completion_tasks: Default::default(),
|
||||||
signature_help_state: SignatureHelpState::default(),
|
signature_help_state: SignatureHelpState::default(),
|
||||||
auto_signature_help: None,
|
auto_signature_help: None,
|
||||||
|
@ -13557,24 +13558,20 @@ 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(
|
fn hunks_for_selections(
|
||||||
multi_buffer_snapshot: &MultiBufferSnapshot,
|
multi_buffer_snapshot: &MultiBufferSnapshot,
|
||||||
selections: &[Selection<Anchor>],
|
selections: &[Selection<Anchor>],
|
||||||
) -> Vec<MultiBufferDiffHunk> {
|
) -> Vec<MultiBufferDiffHunk> {
|
||||||
let buffer_rows_for_selections = selections.iter().map(|selection| {
|
let buffer_rows_for_selections = selections.iter().map(|selection| {
|
||||||
let start = MultiBufferRow(selection.start.to_point(multi_buffer_snapshot).row);
|
let head = selection.head();
|
||||||
let end = MultiBufferRow(selection.end.to_point(multi_buffer_snapshot).row);
|
let tail = selection.tail();
|
||||||
start..end
|
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
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
hunks_for_rows(buffer_rows_for_selections, multi_buffer_snapshot)
|
hunks_for_rows(buffer_rows_for_selections, multi_buffer_snapshot)
|
||||||
|
@ -13591,8 +13588,19 @@ pub fn hunks_for_rows(
|
||||||
let query_rows =
|
let query_rows =
|
||||||
selected_multi_buffer_rows.start..selected_multi_buffer_rows.end.next_row();
|
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()) {
|
for hunk in multi_buffer_snapshot.git_diff_hunks_in_range(query_rows.clone()) {
|
||||||
let related_to_selection =
|
// Deleted hunk is an empty row range, no caret can be placed there and Zed allows to revert it
|
||||||
does_selection_touch_hunk(&selected_multi_buffer_rows, &hunk);
|
// 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
|
||||||
|
};
|
||||||
if related_to_selection {
|
if related_to_selection {
|
||||||
if !processed_buffer_rows
|
if !processed_buffer_rows
|
||||||
.entry(hunk.buffer_id)
|
.entry(hunk.buffer_id)
|
||||||
|
@ -13609,26 +13617,6 @@ pub fn hunks_for_rows(
|
||||||
hunks
|
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 {
|
pub trait CollaborationHub {
|
||||||
fn collaborators<'a>(&self, cx: &'a AppContext) -> &'a HashMap<PeerId, Collaborator>;
|
fn collaborators<'a>(&self, cx: &'a AppContext) -> &'a HashMap<PeerId, Collaborator>;
|
||||||
fn user_participant_indices<'a>(
|
fn user_participant_indices<'a>(
|
||||||
|
|
|
@ -12552,7 +12552,7 @@ async fn test_edits_around_expanded_insertion_hunks(
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
cx.assert_diff_hunks(
|
cx.assert_diff_hunks(
|
||||||
r#"
|
r#"
|
||||||
- use some::mod1;
|
use some::mod1;
|
||||||
- use some::mod2;
|
- use some::mod2;
|
||||||
-
|
-
|
||||||
- const A: u32 = 42;
|
- const A: u32 = 42;
|
||||||
|
|
|
@ -2509,7 +2509,6 @@ impl EditorElement {
|
||||||
element,
|
element,
|
||||||
available_space: size(AvailableSpace::MinContent, element_size.height.into()),
|
available_space: size(AvailableSpace::MinContent, element_size.height.into()),
|
||||||
style: BlockStyle::Fixed,
|
style: BlockStyle::Fixed,
|
||||||
is_zero_height: block.height() == 0,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (row, block) in non_fixed_blocks {
|
for (row, block) in non_fixed_blocks {
|
||||||
|
@ -2556,7 +2555,6 @@ impl EditorElement {
|
||||||
element,
|
element,
|
||||||
available_space: size(width.into(), element_size.height.into()),
|
available_space: size(width.into(), element_size.height.into()),
|
||||||
style,
|
style,
|
||||||
is_zero_height: block.height() == 0,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2604,7 +2602,6 @@ impl EditorElement {
|
||||||
element,
|
element,
|
||||||
available_space: size(width, element_size.height.into()),
|
available_space: size(width, element_size.height.into()),
|
||||||
style,
|
style,
|
||||||
is_zero_height: block.height() == 0,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3950,23 +3947,8 @@ impl EditorElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_blocks(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
|
fn paint_blocks(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
|
||||||
cx.paint_layer(layout.text_hitbox.bounds, |cx| {
|
for mut block in layout.blocks.drain(..) {
|
||||||
layout.blocks.retain_mut(|block| {
|
block.element.paint(cx);
|
||||||
if !block.is_zero_height {
|
|
||||||
block.element.paint(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.is_zero_height
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Paint all the zero-height blocks in a higher layer (if there were any remaining to paint).
|
|
||||||
if !layout.blocks.is_empty() {
|
|
||||||
cx.paint_layer(layout.text_hitbox.bounds, |cx| {
|
|
||||||
for mut block in layout.blocks.drain(..) {
|
|
||||||
block.element.paint(cx);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6029,7 +6011,6 @@ struct BlockLayout {
|
||||||
element: AnyElement,
|
element: AnyElement,
|
||||||
available_space: Size<AvailableSpace>,
|
available_space: Size<AvailableSpace>,
|
||||||
style: BlockStyle,
|
style: BlockStyle,
|
||||||
is_zero_height: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_line(
|
fn layout_line(
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use collections::{hash_map, HashMap, HashSet};
|
use collections::{hash_map, HashMap, HashSet};
|
||||||
use git::diff::DiffHunkStatus;
|
use git::diff::DiffHunkStatus;
|
||||||
use gpui::{
|
use gpui::{Action, AnchorCorner, AppContext, CursorStyle, Hsla, Model, MouseButton, Task, View};
|
||||||
AppContext, ClickEvent, CursorStyle, FocusableView, Hsla, Model, MouseButton, Task, View,
|
|
||||||
};
|
|
||||||
use language::{Buffer, BufferId, Point};
|
use language::{Buffer, BufferId, Point};
|
||||||
use multi_buffer::{
|
use multi_buffer::{
|
||||||
Anchor, AnchorRangeExt, ExcerptRange, MultiBuffer, MultiBufferDiffHunk, MultiBufferRow,
|
Anchor, AnchorRangeExt, ExcerptRange, MultiBuffer, MultiBufferDiffHunk, MultiBufferRow,
|
||||||
|
@ -11,18 +9,17 @@ use multi_buffer::{
|
||||||
use std::{ops::Range, sync::Arc};
|
use std::{ops::Range, sync::Arc};
|
||||||
use text::OffsetRangeExt;
|
use text::OffsetRangeExt;
|
||||||
use ui::{
|
use ui::{
|
||||||
prelude::*, ActiveTheme, IconButtonShape, InteractiveElement, IntoElement, KeyBinding,
|
prelude::*, ActiveTheme, ContextMenu, IconButtonShape, InteractiveElement, IntoElement,
|
||||||
ParentElement, Styled, TintColor, Tooltip, ViewContext, VisualContext,
|
ParentElement, PopoverMenu, Styled, Tooltip, ViewContext, VisualContext,
|
||||||
};
|
};
|
||||||
use util::RangeExt;
|
use util::RangeExt;
|
||||||
use workspace::Item;
|
use workspace::Item;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, is_hunk_selected,
|
editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, ApplyAllDiffHunks,
|
||||||
ApplyAllDiffHunks, ApplySelectedDiffHunks, BlockPlacement, BlockProperties, BlockStyle,
|
ApplyDiffHunk, BlockPlacement, BlockProperties, BlockStyle, CustomBlockId, DiffRowHighlight,
|
||||||
CustomBlockId, DiffRowHighlight, DisplayRow, DisplaySnapshot, Editor, EditorElement,
|
DisplayRow, DisplaySnapshot, Editor, EditorElement, ExpandAllHunkDiffs, GoToHunk, GoToPrevHunk,
|
||||||
ExpandAllHunkDiffs, GoToHunk, GoToPrevHunk, RevertSelectedHunks, ToDisplayPoint,
|
RevertFile, RevertSelectedHunks, ToDisplayPoint, ToggleHunkDiff,
|
||||||
ToggleHunkDiff,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -60,6 +57,7 @@ pub enum DisplayDiffHunk {
|
||||||
Folded {
|
Folded {
|
||||||
display_row: DisplayRow,
|
display_row: DisplayRow,
|
||||||
},
|
},
|
||||||
|
|
||||||
Unfolded {
|
Unfolded {
|
||||||
diff_base_byte_range: Range<usize>,
|
diff_base_byte_range: Range<usize>,
|
||||||
display_row_range: Range<DisplayRow>,
|
display_row_range: Range<DisplayRow>,
|
||||||
|
@ -373,35 +371,26 @@ impl Editor {
|
||||||
|
|
||||||
pub(crate) fn apply_selected_diff_hunks(
|
pub(crate) fn apply_selected_diff_hunks(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &ApplySelectedDiffHunks,
|
_: &ApplyDiffHunk,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let hunks = hunks_for_selections(&snapshot, &self.selections.disjoint_anchors());
|
let hunks = hunks_for_selections(&snapshot, &self.selections.disjoint_anchors());
|
||||||
|
let mut ranges_by_buffer = HashMap::default();
|
||||||
self.transact(cx, |editor, cx| {
|
self.transact(cx, |editor, cx| {
|
||||||
if hunks.is_empty() {
|
for hunk in hunks {
|
||||||
// If there are no selected hunks, e.g. because we're using the keybinding with nothing selected, apply the first hunk.
|
if let Some(buffer) = editor.buffer.read(cx).buffer(hunk.buffer_id) {
|
||||||
if let Some(first_hunk) = editor.expanded_hunks.hunks.first() {
|
ranges_by_buffer
|
||||||
editor.apply_diff_hunks_in_range(first_hunk.hunk_range.clone(), cx);
|
.entry(buffer.clone())
|
||||||
|
.or_insert_with(Vec::new)
|
||||||
|
.push(hunk.buffer_range.to_offset(buffer.read(cx)));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
let mut ranges_by_buffer = HashMap::default();
|
|
||||||
|
|
||||||
for hunk in hunks {
|
for (buffer, ranges) in ranges_by_buffer {
|
||||||
if let Some(buffer) = editor.buffer.read(cx).buffer(hunk.buffer_id) {
|
buffer.update(cx, |buffer, cx| {
|
||||||
ranges_by_buffer
|
buffer.merge_into_base(ranges, cx);
|
||||||
.entry(buffer.clone())
|
});
|
||||||
.or_insert_with(Vec::new)
|
|
||||||
.push(hunk.buffer_range.to_offset(buffer.read(cx)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (buffer, ranges) in ranges_by_buffer {
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
|
||||||
buffer.merge_into_base(ranges, cx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -423,238 +412,246 @@ impl Editor {
|
||||||
buffer.read(cx).diff_base_buffer().is_some()
|
buffer.read(cx).diff_base_buffer().is_some()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let border_color = cx.theme().colors().border_variant;
|
||||||
|
let bg_color = cx.theme().colors().editor_background;
|
||||||
|
let gutter_color = match hunk.status {
|
||||||
|
DiffHunkStatus::Added => cx.theme().status().created,
|
||||||
|
DiffHunkStatus::Modified => cx.theme().status().modified,
|
||||||
|
DiffHunkStatus::Removed => cx.theme().status().deleted,
|
||||||
|
};
|
||||||
|
|
||||||
BlockProperties {
|
BlockProperties {
|
||||||
placement: BlockPlacement::Above(hunk.multi_buffer_range.start),
|
placement: BlockPlacement::Above(hunk.multi_buffer_range.start),
|
||||||
height: 0,
|
height: 1,
|
||||||
style: BlockStyle::Sticky,
|
style: BlockStyle::Sticky,
|
||||||
priority: 1,
|
priority: 0,
|
||||||
render: Arc::new({
|
render: Arc::new({
|
||||||
let editor = cx.view().clone();
|
let editor = cx.view().clone();
|
||||||
let hunk = hunk.clone();
|
let hunk = hunk.clone();
|
||||||
|
|
||||||
move |cx| {
|
move |cx| {
|
||||||
let is_hunk_selected = editor.update(&mut **cx, |editor, cx| {
|
let hunk_controls_menu_handle =
|
||||||
let snapshot = editor.buffer.read(cx).snapshot(cx);
|
editor.read(cx).hunk_controls_menu_handle.clone();
|
||||||
let selections = &editor.selections.all::<Point>(cx);
|
|
||||||
|
|
||||||
if editor.focus_handle(cx).is_focused(cx) && !selections.is_empty() {
|
|
||||||
if let Some(hunk) = to_diff_hunk(&hunk, &snapshot) {
|
|
||||||
is_hunk_selected(&hunk, selections)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If we have no cursor, or aren't focused, then default to the first hunk
|
|
||||||
// because that's what the keyboard shortcuts do.
|
|
||||||
editor
|
|
||||||
.expanded_hunks
|
|
||||||
.hunks
|
|
||||||
.first()
|
|
||||||
.map(|first_hunk| first_hunk.hunk_range == hunk.multi_buffer_range)
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let focus_handle = editor.focus_handle(cx);
|
|
||||||
|
|
||||||
let handle_discard_click = {
|
|
||||||
let editor = editor.clone();
|
|
||||||
let hunk = hunk.clone();
|
|
||||||
move |_event: &ClickEvent, cx: &mut WindowContext| {
|
|
||||||
let multi_buffer = editor.read(cx).buffer().clone();
|
|
||||||
let multi_buffer_snapshot = multi_buffer.read(cx).snapshot(cx);
|
|
||||||
let mut revert_changes = HashMap::default();
|
|
||||||
if let Some(hunk) =
|
|
||||||
crate::hunk_diff::to_diff_hunk(&hunk, &multi_buffer_snapshot)
|
|
||||||
{
|
|
||||||
Editor::prepare_revert_change(
|
|
||||||
&mut revert_changes,
|
|
||||||
&multi_buffer,
|
|
||||||
&hunk,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if !revert_changes.is_empty() {
|
|
||||||
editor.update(cx, |editor, cx| editor.revert(revert_changes, cx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let handle_apply_click = {
|
|
||||||
let editor = editor.clone();
|
|
||||||
let hunk = hunk.clone();
|
|
||||||
move |_event: &ClickEvent, cx: &mut WindowContext| {
|
|
||||||
editor.update(cx, |editor, cx| {
|
|
||||||
editor
|
|
||||||
.apply_diff_hunks_in_range(hunk.multi_buffer_range.clone(), cx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let discard_key_binding =
|
|
||||||
KeyBinding::for_action_in(&RevertSelectedHunks, &focus_handle, cx);
|
|
||||||
|
|
||||||
let discard_tooltip = {
|
|
||||||
let focus_handle = editor.focus_handle(cx);
|
|
||||||
move |cx: &mut WindowContext| {
|
|
||||||
Tooltip::for_action_in(
|
|
||||||
"Discard Hunk",
|
|
||||||
&RevertSelectedHunks,
|
|
||||||
&focus_handle,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(cx.block_id)
|
.id(cx.block_id)
|
||||||
.pr_5()
|
.block_mouse_down()
|
||||||
|
.h(cx.line_height())
|
||||||
.w_full()
|
.w_full()
|
||||||
.justify_end()
|
.border_t_1()
|
||||||
|
.border_color(border_color)
|
||||||
|
.bg(bg_color)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.id("gutter-strip")
|
||||||
|
.w(EditorElement::diff_hunk_strip_width(cx.line_height()))
|
||||||
|
.h_full()
|
||||||
|
.bg(gutter_color)
|
||||||
|
.cursor(CursorStyle::PointingHand)
|
||||||
|
.on_click({
|
||||||
|
let editor = editor.clone();
|
||||||
|
let hunk = hunk.clone();
|
||||||
|
move |_event, cx| {
|
||||||
|
editor.update(cx, |editor, cx| {
|
||||||
|
editor.toggle_hovered_hunk(&hunk, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.h(cx.line_height())
|
.px_6()
|
||||||
.gap_1()
|
.size_full()
|
||||||
.px_1()
|
.justify_end()
|
||||||
.pb_1()
|
.child(
|
||||||
.border_x_1()
|
h_flex()
|
||||||
.border_b_1()
|
.gap_1()
|
||||||
.border_color(cx.theme().colors().border_variant)
|
.when(!is_branch_buffer, |row| {
|
||||||
.rounded_b_lg()
|
row.child(
|
||||||
.bg(cx.theme().colors().editor_background)
|
IconButton::new("next-hunk", IconName::ArrowDown)
|
||||||
.shadow(smallvec::smallvec![gpui::BoxShadow {
|
.shape(IconButtonShape::Square)
|
||||||
color: gpui::hsla(0.0, 0.0, 0.0, 0.1),
|
.icon_size(IconSize::Small)
|
||||||
blur_radius: px(1.0),
|
.tooltip({
|
||||||
spread_radius: px(1.0),
|
let focus_handle = editor.focus_handle(cx);
|
||||||
offset: gpui::point(px(0.), px(1.0)),
|
move |cx| {
|
||||||
}])
|
Tooltip::for_action_in(
|
||||||
.when(!is_branch_buffer, |row| {
|
"Next Hunk",
|
||||||
row.child(
|
&GoToHunk,
|
||||||
IconButton::new("next-hunk", IconName::ArrowDown)
|
&focus_handle,
|
||||||
.shape(IconButtonShape::Square)
|
cx,
|
||||||
.icon_size(IconSize::Small)
|
)
|
||||||
.tooltip({
|
}
|
||||||
let focus_handle = editor.focus_handle(cx);
|
})
|
||||||
move |cx| {
|
.on_click({
|
||||||
Tooltip::for_action_in(
|
let editor = editor.clone();
|
||||||
"Next Hunk",
|
let hunk = hunk.clone();
|
||||||
&GoToHunk,
|
move |_event, cx| {
|
||||||
&focus_handle.clone(),
|
editor.update(cx, |editor, cx| {
|
||||||
cx,
|
editor.go_to_subsequent_hunk(
|
||||||
)
|
hunk.multi_buffer_range.end,
|
||||||
}
|
cx,
|
||||||
})
|
);
|
||||||
.on_click({
|
});
|
||||||
let editor = editor.clone();
|
}
|
||||||
let hunk = hunk.clone();
|
}),
|
||||||
move |_event, cx| {
|
)
|
||||||
editor.update(cx, |editor, cx| {
|
.child(
|
||||||
editor.go_to_subsequent_hunk(
|
IconButton::new("prev-hunk", IconName::ArrowUp)
|
||||||
hunk.multi_buffer_range.end,
|
.shape(IconButtonShape::Square)
|
||||||
cx,
|
.icon_size(IconSize::Small)
|
||||||
);
|
.tooltip({
|
||||||
});
|
let focus_handle = editor.focus_handle(cx);
|
||||||
}
|
move |cx| {
|
||||||
}),
|
Tooltip::for_action_in(
|
||||||
)
|
"Previous Hunk",
|
||||||
.child(
|
&GoToPrevHunk,
|
||||||
IconButton::new("prev-hunk", IconName::ArrowUp)
|
&focus_handle,
|
||||||
.shape(IconButtonShape::Square)
|
cx,
|
||||||
.icon_size(IconSize::Small)
|
)
|
||||||
.tooltip({
|
}
|
||||||
let focus_handle = editor.focus_handle(cx);
|
})
|
||||||
move |cx| {
|
.on_click({
|
||||||
Tooltip::for_action_in(
|
let editor = editor.clone();
|
||||||
"Previous Hunk",
|
let hunk = hunk.clone();
|
||||||
&GoToPrevHunk,
|
move |_event, cx| {
|
||||||
&focus_handle,
|
editor.update(cx, |editor, cx| {
|
||||||
cx,
|
editor.go_to_preceding_hunk(
|
||||||
)
|
hunk.multi_buffer_range.start,
|
||||||
}
|
cx,
|
||||||
})
|
);
|
||||||
.on_click({
|
});
|
||||||
let editor = editor.clone();
|
}
|
||||||
let hunk = hunk.clone();
|
}),
|
||||||
move |_event, cx| {
|
)
|
||||||
editor.update(cx, |editor, cx| {
|
})
|
||||||
editor.go_to_preceding_hunk(
|
.child(
|
||||||
hunk.multi_buffer_range.start,
|
IconButton::new("discard", IconName::Undo)
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.child(if is_branch_buffer {
|
|
||||||
if is_hunk_selected {
|
|
||||||
Button::new("discard", "Discard")
|
|
||||||
.style(ButtonStyle::Tinted(TintColor::Negative))
|
|
||||||
.label_size(LabelSize::Small)
|
|
||||||
.key_binding(discard_key_binding)
|
|
||||||
.on_click(handle_discard_click.clone())
|
|
||||||
.into_any_element()
|
|
||||||
} else {
|
|
||||||
IconButton::new("discard", IconName::Close)
|
|
||||||
.style(ButtonStyle::Tinted(TintColor::Negative))
|
|
||||||
.shape(IconButtonShape::Square)
|
|
||||||
.icon_size(IconSize::XSmall)
|
|
||||||
.tooltip(discard_tooltip.clone())
|
|
||||||
.on_click(handle_discard_click.clone())
|
|
||||||
.into_any_element()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if is_hunk_selected {
|
|
||||||
Button::new("undo", "Undo")
|
|
||||||
.style(ButtonStyle::Tinted(TintColor::Negative))
|
|
||||||
.label_size(LabelSize::Small)
|
|
||||||
.key_binding(discard_key_binding)
|
|
||||||
.on_click(handle_discard_click.clone())
|
|
||||||
.into_any_element()
|
|
||||||
} else {
|
|
||||||
IconButton::new("undo", IconName::Undo)
|
|
||||||
.shape(IconButtonShape::Square)
|
|
||||||
.icon_size(IconSize::Small)
|
|
||||||
.tooltip(discard_tooltip.clone())
|
|
||||||
.on_click(handle_discard_click.clone())
|
|
||||||
.into_any_element()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.when(is_branch_buffer, |this| {
|
|
||||||
this.child({
|
|
||||||
let button = Button::new("apply", "Apply")
|
|
||||||
.style(ButtonStyle::Tinted(TintColor::Positive))
|
|
||||||
.label_size(LabelSize::Small)
|
|
||||||
.key_binding(KeyBinding::for_action_in(
|
|
||||||
&ApplySelectedDiffHunks,
|
|
||||||
&focus_handle,
|
|
||||||
cx,
|
|
||||||
))
|
|
||||||
.on_click(handle_apply_click.clone())
|
|
||||||
.into_any_element();
|
|
||||||
if is_hunk_selected {
|
|
||||||
button
|
|
||||||
} else {
|
|
||||||
IconButton::new("apply", IconName::Check)
|
|
||||||
.style(ButtonStyle::Tinted(TintColor::Positive))
|
|
||||||
.shape(IconButtonShape::Square)
|
.shape(IconButtonShape::Square)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::Small)
|
||||||
.tooltip({
|
.tooltip({
|
||||||
let focus_handle = editor.focus_handle(cx);
|
let focus_handle = editor.focus_handle(cx);
|
||||||
move |cx| {
|
move |cx| {
|
||||||
Tooltip::for_action_in(
|
Tooltip::for_action_in(
|
||||||
"Apply Hunk",
|
"Discard Hunk",
|
||||||
&ApplySelectedDiffHunks,
|
&RevertSelectedHunks,
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on_click(handle_apply_click.clone())
|
.on_click({
|
||||||
.into_any_element()
|
let editor = editor.clone();
|
||||||
}
|
let hunk = hunk.clone();
|
||||||
})
|
move |_event, cx| {
|
||||||
})
|
let multi_buffer =
|
||||||
|
editor.read(cx).buffer().clone();
|
||||||
|
let multi_buffer_snapshot =
|
||||||
|
multi_buffer.read(cx).snapshot(cx);
|
||||||
|
let mut revert_changes = HashMap::default();
|
||||||
|
if let Some(hunk) =
|
||||||
|
crate::hunk_diff::to_diff_hunk(
|
||||||
|
&hunk,
|
||||||
|
&multi_buffer_snapshot,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Editor::prepare_revert_change(
|
||||||
|
&mut revert_changes,
|
||||||
|
&multi_buffer,
|
||||||
|
&hunk,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !revert_changes.is_empty() {
|
||||||
|
editor.update(cx, |editor, cx| {
|
||||||
|
editor.revert(revert_changes, cx)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.map(|this| {
|
||||||
|
if is_branch_buffer {
|
||||||
|
this.child(
|
||||||
|
IconButton::new("apply", IconName::Check)
|
||||||
|
.shape(IconButtonShape::Square)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.tooltip({
|
||||||
|
let focus_handle =
|
||||||
|
editor.focus_handle(cx);
|
||||||
|
move |cx| {
|
||||||
|
Tooltip::for_action_in(
|
||||||
|
"Apply Hunk",
|
||||||
|
&ApplyDiffHunk,
|
||||||
|
&focus_handle,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on_click({
|
||||||
|
let editor = editor.clone();
|
||||||
|
let hunk = hunk.clone();
|
||||||
|
move |_event, cx| {
|
||||||
|
editor.update(cx, |editor, cx| {
|
||||||
|
editor
|
||||||
|
.apply_diff_hunks_in_range(
|
||||||
|
hunk.multi_buffer_range
|
||||||
|
.clone(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this.child({
|
||||||
|
let focus = editor.focus_handle(cx);
|
||||||
|
PopoverMenu::new("hunk-controls-dropdown")
|
||||||
|
.trigger(
|
||||||
|
IconButton::new(
|
||||||
|
"toggle_editor_selections_icon",
|
||||||
|
IconName::EllipsisVertical,
|
||||||
|
)
|
||||||
|
.shape(IconButtonShape::Square)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.selected(
|
||||||
|
hunk_controls_menu_handle
|
||||||
|
.is_deployed(),
|
||||||
|
)
|
||||||
|
.when(
|
||||||
|
!hunk_controls_menu_handle
|
||||||
|
.is_deployed(),
|
||||||
|
|this| {
|
||||||
|
this.tooltip(|cx| {
|
||||||
|
Tooltip::text(
|
||||||
|
"Hunk Controls",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.anchor(AnchorCorner::TopRight)
|
||||||
|
.with_handle(hunk_controls_menu_handle)
|
||||||
|
.menu(move |cx| {
|
||||||
|
let focus = focus.clone();
|
||||||
|
let menu = ContextMenu::build(
|
||||||
|
cx,
|
||||||
|
move |menu, _| {
|
||||||
|
menu.context(focus.clone())
|
||||||
|
.action(
|
||||||
|
"Discard All Hunks",
|
||||||
|
RevertFile
|
||||||
|
.boxed_clone(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Some(menu)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.when(!is_branch_buffer, |div| {
|
.when(!is_branch_buffer, |div| {
|
||||||
div.child(
|
div.child(
|
||||||
IconButton::new("collapse", IconName::Close)
|
IconButton::new("collapse", IconName::Close)
|
||||||
|
@ -710,7 +707,7 @@ impl Editor {
|
||||||
placement: BlockPlacement::Above(hunk.multi_buffer_range.start),
|
placement: BlockPlacement::Above(hunk.multi_buffer_range.start),
|
||||||
height,
|
height,
|
||||||
style: BlockStyle::Flex,
|
style: BlockStyle::Flex,
|
||||||
priority: 1,
|
priority: 0,
|
||||||
render: Arc::new(move |cx| {
|
render: Arc::new(move |cx| {
|
||||||
let width = EditorElement::diff_hunk_strip_width(cx.line_height());
|
let width = EditorElement::diff_hunk_strip_width(cx.line_height());
|
||||||
let gutter_dimensions = editor.read(cx.context).gutter_dimensions;
|
let gutter_dimensions = editor.read(cx.context).gutter_dimensions;
|
||||||
|
|
|
@ -5,11 +5,10 @@ use gpui::{AppContext, EventEmitter, FocusableView, Model, Render, Subscription,
|
||||||
use language::{Buffer, BufferEvent, Capability};
|
use language::{Buffer, BufferEvent, Capability};
|
||||||
use multi_buffer::{ExcerptRange, MultiBuffer};
|
use multi_buffer::{ExcerptRange, MultiBuffer};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use settings::Settings;
|
|
||||||
use smol::stream::StreamExt;
|
use smol::stream::StreamExt;
|
||||||
use std::{any::TypeId, ops::Range, rc::Rc, time::Duration};
|
use std::{any::TypeId, ops::Range, rc::Rc, time::Duration};
|
||||||
use text::ToOffset;
|
use text::ToOffset;
|
||||||
use ui::{prelude::*, KeyBinding};
|
use ui::{prelude::*, ButtonLike, KeyBinding};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
searchable::SearchableItemHandle, Item, ItemHandle as _, ToolbarItemEvent, ToolbarItemLocation,
|
searchable::SearchableItemHandle, Item, ItemHandle as _, ToolbarItemEvent, ToolbarItemLocation,
|
||||||
ToolbarItemView, Workspace,
|
ToolbarItemView, Workspace,
|
||||||
|
@ -35,11 +34,7 @@ struct BufferEntry {
|
||||||
_subscription: Subscription,
|
_subscription: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ProposedChangesToolbarControls {
|
pub struct ProposedChangesEditorToolbar {
|
||||||
current_editor: Option<View<ProposedChangesEditor>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ProposedChangesToolbar {
|
|
||||||
current_editor: Option<View<ProposedChangesEditor>>,
|
current_editor: Option<View<ProposedChangesEditor>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,10 +228,6 @@ impl ProposedChangesEditor {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_changes_accepted(&self) -> bool {
|
|
||||||
false // In the future, we plan to compute this based on the current state of patches.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for ProposedChangesEditor {
|
impl Render for ProposedChangesEditor {
|
||||||
|
@ -260,11 +251,7 @@ impl Item for ProposedChangesEditor {
|
||||||
type Event = EditorEvent;
|
type Event = EditorEvent;
|
||||||
|
|
||||||
fn tab_icon(&self, _cx: &ui::WindowContext) -> Option<Icon> {
|
fn tab_icon(&self, _cx: &ui::WindowContext) -> Option<Icon> {
|
||||||
if self.all_changes_accepted() {
|
Some(Icon::new(IconName::Diff))
|
||||||
Some(Icon::new(IconName::Check).color(Color::Success))
|
|
||||||
} else {
|
|
||||||
Some(Icon::new(IconName::ZedAssistant))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
|
fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
|
||||||
|
@ -330,7 +317,7 @@ impl Item for ProposedChangesEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProposedChangesToolbarControls {
|
impl ProposedChangesEditorToolbar {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_editor: None,
|
current_editor: None,
|
||||||
|
@ -346,97 +333,28 @@ impl ProposedChangesToolbarControls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for ProposedChangesToolbarControls {
|
impl Render for ProposedChangesEditorToolbar {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
if let Some(editor) = &self.current_editor {
|
let button_like = ButtonLike::new("apply-changes").child(Label::new("Apply All"));
|
||||||
let focus_handle = editor.focus_handle(cx);
|
|
||||||
let action = &ApplyAllDiffHunks;
|
|
||||||
let keybinding = KeyBinding::for_action_in(action, &focus_handle, cx);
|
|
||||||
|
|
||||||
let editor = editor.read(cx);
|
match &self.current_editor {
|
||||||
|
Some(editor) => {
|
||||||
|
let focus_handle = editor.focus_handle(cx);
|
||||||
|
let keybinding = KeyBinding::for_action_in(&ApplyAllDiffHunks, &focus_handle, cx)
|
||||||
|
.map(|binding| binding.into_any_element());
|
||||||
|
|
||||||
let apply_all_button = if editor.all_changes_accepted() {
|
button_like.children(keybinding).on_click({
|
||||||
None
|
move |_event, cx| focus_handle.dispatch_action(&ApplyAllDiffHunks, cx)
|
||||||
} else {
|
})
|
||||||
Some(
|
}
|
||||||
Button::new("apply-changes", "Apply All")
|
None => button_like.disabled(true),
|
||||||
.style(ButtonStyle::Filled)
|
|
||||||
.key_binding(keybinding)
|
|
||||||
.on_click(move |_event, cx| focus_handle.dispatch_action(action, cx)),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
h_flex()
|
|
||||||
.gap_1()
|
|
||||||
.children([apply_all_button].into_iter().flatten())
|
|
||||||
.into_any_element()
|
|
||||||
} else {
|
|
||||||
gpui::Empty.into_any_element()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter<ToolbarItemEvent> for ProposedChangesToolbarControls {}
|
impl EventEmitter<ToolbarItemEvent> for ProposedChangesEditorToolbar {}
|
||||||
|
|
||||||
impl ToolbarItemView for ProposedChangesToolbarControls {
|
impl ToolbarItemView for ProposedChangesEditorToolbar {
|
||||||
fn set_active_pane_item(
|
|
||||||
&mut self,
|
|
||||||
active_pane_item: Option<&dyn workspace::ItemHandle>,
|
|
||||||
_cx: &mut ViewContext<Self>,
|
|
||||||
) -> workspace::ToolbarItemLocation {
|
|
||||||
self.current_editor =
|
|
||||||
active_pane_item.and_then(|item| item.downcast::<ProposedChangesEditor>());
|
|
||||||
self.get_toolbar_item_location()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProposedChangesToolbar {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
current_editor: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_toolbar_item_location(&self) -> ToolbarItemLocation {
|
|
||||||
if self.current_editor.is_some() {
|
|
||||||
ToolbarItemLocation::PrimaryLeft
|
|
||||||
} else {
|
|
||||||
ToolbarItemLocation::Hidden
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Render for ProposedChangesToolbar {
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
|
||||||
if let Some(editor) = &self.current_editor {
|
|
||||||
let editor = editor.read(cx);
|
|
||||||
let all_changes_accepted = editor.all_changes_accepted();
|
|
||||||
let icon = if all_changes_accepted {
|
|
||||||
Icon::new(IconName::Check).color(Color::Success)
|
|
||||||
} else {
|
|
||||||
Icon::new(IconName::ZedAssistant)
|
|
||||||
};
|
|
||||||
|
|
||||||
h_flex()
|
|
||||||
.gap_2p5()
|
|
||||||
.font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
|
|
||||||
.child(icon.size(IconSize::Small))
|
|
||||||
.child(
|
|
||||||
Label::new(editor.title.clone())
|
|
||||||
.color(Color::Muted)
|
|
||||||
.single_line()
|
|
||||||
.strikethrough(all_changes_accepted),
|
|
||||||
)
|
|
||||||
.into_any_element()
|
|
||||||
} else {
|
|
||||||
gpui::Empty.into_any_element()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventEmitter<ToolbarItemEvent> for ProposedChangesToolbar {}
|
|
||||||
|
|
||||||
impl ToolbarItemView for ProposedChangesToolbar {
|
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn workspace::ItemHandle>,
|
active_pane_item: Option<&dyn workspace::ItemHandle>,
|
||||||
|
|
|
@ -17,8 +17,8 @@ use breadcrumbs::Breadcrumbs;
|
||||||
use client::{zed_urls, ZED_URL_SCHEME};
|
use client::{zed_urls, ZED_URL_SCHEME};
|
||||||
use collections::VecDeque;
|
use collections::VecDeque;
|
||||||
use command_palette_hooks::CommandPaletteFilter;
|
use command_palette_hooks::CommandPaletteFilter;
|
||||||
|
use editor::ProposedChangesEditorToolbar;
|
||||||
use editor::{scroll::Autoscroll, Editor, MultiBuffer};
|
use editor::{scroll::Autoscroll, Editor, MultiBuffer};
|
||||||
use editor::{ProposedChangesToolbar, ProposedChangesToolbarControls};
|
|
||||||
use feature_flags::FeatureFlagAppExt;
|
use feature_flags::FeatureFlagAppExt;
|
||||||
use futures::{channel::mpsc, select_biased, StreamExt};
|
use futures::{channel::mpsc, select_biased, StreamExt};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -644,10 +644,8 @@ fn initialize_pane(workspace: &Workspace, pane: &View<Pane>, cx: &mut ViewContex
|
||||||
let buffer_search_bar = cx.new_view(search::BufferSearchBar::new);
|
let buffer_search_bar = cx.new_view(search::BufferSearchBar::new);
|
||||||
toolbar.add_item(buffer_search_bar.clone(), cx);
|
toolbar.add_item(buffer_search_bar.clone(), cx);
|
||||||
|
|
||||||
let proposed_changes_bar = cx.new_view(|_| ProposedChangesToolbar::new());
|
let proposed_change_bar = cx.new_view(|_| ProposedChangesEditorToolbar::new());
|
||||||
toolbar.add_item(proposed_changes_bar, cx);
|
toolbar.add_item(proposed_change_bar, cx);
|
||||||
let proposed_changes_controls = cx.new_view(|_| ProposedChangesToolbarControls::new());
|
|
||||||
toolbar.add_item(proposed_changes_controls, cx);
|
|
||||||
let quick_action_bar =
|
let quick_action_bar =
|
||||||
cx.new_view(|cx| QuickActionBar::new(buffer_search_bar, workspace, cx));
|
cx.new_view(|cx| QuickActionBar::new(buffer_search_bar, workspace, cx));
|
||||||
toolbar.add_item(quick_action_bar, cx);
|
toolbar.add_item(quick_action_bar, cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue