@@ -7,22 +7,23 @@ use editor::{
7
7
Direction , Editor , EditorEvent , MultiBuffer , ToPoint ,
8
8
} ;
9
9
use gpui:: {
10
- prelude:: * , AnyElement , AnyView , App , Entity , EventEmitter , FocusHandle , Focusable ,
10
+ prelude:: * , Action , AnyElement , AnyView , App , Entity , EventEmitter , FocusHandle , Focusable ,
11
11
SharedString , Subscription , Task , WeakEntity , Window ,
12
12
} ;
13
- use language:: { Capability , DiskState , OffsetRangeExt } ;
13
+ use language:: { Capability , DiskState , OffsetRangeExt , Point } ;
14
14
use multi_buffer:: PathKey ;
15
15
use project:: { Project , ProjectPath } ;
16
16
use std:: {
17
17
any:: { Any , TypeId } ,
18
18
ops:: Range ,
19
19
sync:: Arc ,
20
20
} ;
21
- use ui:: { prelude:: * , IconButtonShape , Tooltip } ;
21
+ use ui:: { prelude:: * , IconButtonShape , KeyBinding , Tooltip } ;
22
22
use workspace:: {
23
23
item:: { BreadcrumbText , ItemEvent , TabContentParams } ,
24
24
searchable:: SearchableItemHandle ,
25
- Item , ItemHandle , ItemNavHistory , ToolbarItemLocation , Workspace ,
25
+ Item , ItemHandle , ItemNavHistory , ToolbarItemEvent , ToolbarItemLocation , ToolbarItemView ,
26
+ Workspace ,
26
27
} ;
27
28
28
29
pub struct AssistantDiff {
@@ -78,6 +79,7 @@ impl AssistantDiff {
78
79
is_created_file,
79
80
line_height,
80
81
_editor : & Entity < Editor > ,
82
+ window : & mut Window ,
81
83
cx : & mut App | {
82
84
render_diff_hunk_controls (
83
85
row,
@@ -86,6 +88,7 @@ impl AssistantDiff {
86
88
is_created_file,
87
89
line_height,
88
90
& assistant_diff,
91
+ window,
89
92
cx,
90
93
)
91
94
}
@@ -253,6 +256,18 @@ impl AssistantDiff {
253
256
} )
254
257
}
255
258
259
+ fn reject_all ( & mut self , _: & crate :: RejectAll , window : & mut Window , cx : & mut Context < Self > ) {
260
+ self . editor . update ( cx, |editor, cx| {
261
+ let max_point = editor. buffer ( ) . read ( cx) . read ( cx) . max_point ( ) ;
262
+ editor. restore_hunks_in_ranges ( vec ! [ Point :: zero( ) ..max_point] , window, cx)
263
+ } )
264
+ }
265
+
266
+ fn keep_all ( & mut self , _: & crate :: KeepAll , _window : & mut Window , cx : & mut Context < Self > ) {
267
+ self . thread
268
+ . update ( cx, |thread, cx| thread. keep_all_edits ( cx) ) ;
269
+ }
270
+
256
271
fn review_diff_hunks (
257
272
& mut self ,
258
273
hunk_ranges : Vec < Range < editor:: Anchor > > ,
@@ -465,6 +480,8 @@ impl Render for AssistantDiff {
465
480
} )
466
481
. on_action ( cx. listener ( Self :: toggle_keep) )
467
482
. on_action ( cx. listener ( Self :: reject) )
483
+ . on_action ( cx. listener ( Self :: reject_all) )
484
+ . on_action ( cx. listener ( Self :: keep_all) )
468
485
. bg ( cx. theme ( ) . colors ( ) . editor_background )
469
486
. flex ( )
470
487
. items_center ( )
@@ -482,6 +499,7 @@ fn render_diff_hunk_controls(
482
499
is_created_file : bool ,
483
500
line_height : Pixels ,
484
501
assistant_diff : & Entity < AssistantDiff > ,
502
+ window : & mut Window ,
485
503
cx : & mut App ,
486
504
) -> AnyElement {
487
505
let editor = assistant_diff. read ( cx) . editor . clone ( ) ;
@@ -501,55 +519,67 @@ fn render_diff_hunk_controls(
501
519
. shadow_md ( )
502
520
. children ( if status. has_secondary_hunk ( ) {
503
521
vec ! [
504
- Button :: new( ( "keep" , row as u64 ) , "Keep" )
522
+ Button :: new( "reject" , "Reject" )
523
+ . key_binding( KeyBinding :: for_action_in(
524
+ & crate :: Reject ,
525
+ & editor. read( cx) . focus_handle( cx) ,
526
+ window,
527
+ cx,
528
+ ) )
505
529
. tooltip( {
506
530
let focus_handle = editor. focus_handle( cx) ;
507
531
move |window, cx| {
508
532
Tooltip :: for_action_in(
509
- "Keep Hunk" ,
510
- & crate :: ToggleKeep ,
533
+ "Reject Hunk" ,
534
+ & crate :: Reject ,
511
535
& focus_handle,
512
536
window,
513
537
cx,
514
538
)
515
539
}
516
540
} )
517
541
. on_click( {
518
- let assistant_diff = assistant_diff. clone( ) ;
519
- move |_event, _window, cx| {
520
- assistant_diff. update( cx, |diff, cx| {
521
- diff. review_diff_hunks(
522
- vec![ hunk_range. start..hunk_range. start] ,
523
- true ,
524
- cx,
525
- ) ;
542
+ let editor = editor. clone( ) ;
543
+ move |_event, window, cx| {
544
+ editor. update( cx, |editor, cx| {
545
+ let snapshot = editor. snapshot( window, cx) ;
546
+ let point = hunk_range. start. to_point( & snapshot. buffer_snapshot) ;
547
+ editor. restore_hunks_in_ranges( vec![ point..point] , window, cx) ;
526
548
} ) ;
527
549
}
528
- } ) ,
529
- Button :: new( "reject" , "Reject" )
550
+ } )
551
+ . disabled( is_created_file) ,
552
+ Button :: new( ( "keep" , row as u64 ) , "Keep" )
553
+ . key_binding( KeyBinding :: for_action_in(
554
+ & crate :: ToggleKeep ,
555
+ & editor. read( cx) . focus_handle( cx) ,
556
+ window,
557
+ cx,
558
+ ) )
530
559
. tooltip( {
531
560
let focus_handle = editor. focus_handle( cx) ;
532
561
move |window, cx| {
533
562
Tooltip :: for_action_in(
534
- "Reject Hunk" ,
535
- & crate :: Reject ,
563
+ "Keep Hunk" ,
564
+ & crate :: ToggleKeep ,
536
565
& focus_handle,
537
566
window,
538
567
cx,
539
568
)
540
569
}
541
570
} )
542
571
. on_click( {
543
- let editor = editor. clone( ) ;
544
- move |_event, window, cx| {
545
- editor. update( cx, |editor, cx| {
546
- let snapshot = editor. snapshot( window, cx) ;
547
- let point = hunk_range. start. to_point( & snapshot. buffer_snapshot) ;
548
- editor. restore_hunks_in_ranges( vec![ point..point] , window, cx) ;
572
+ let assistant_diff = assistant_diff. clone( ) ;
573
+ move |_event, _window, cx| {
574
+ assistant_diff. update( cx, |diff, cx| {
575
+ diff. review_diff_hunks(
576
+ vec![ hunk_range. start..hunk_range. start] ,
577
+ true ,
578
+ cx,
579
+ ) ;
549
580
} ) ;
550
581
}
551
- } )
552
- . disabled( is_created_file) ,
582
+ } ) ,
553
583
]
554
584
} else {
555
585
vec ! [ Button :: new( ( "review" , row as u64 ) , "Review" )
@@ -663,3 +693,89 @@ impl editor::Addon for AssistantDiffAddon {
663
693
key_context. add ( "assistant_diff" ) ;
664
694
}
665
695
}
696
+
697
+ pub struct AssistantDiffToolbar {
698
+ assistant_diff : Option < WeakEntity < AssistantDiff > > ,
699
+ _workspace : WeakEntity < Workspace > ,
700
+ }
701
+
702
+ impl AssistantDiffToolbar {
703
+ pub fn new ( workspace : & Workspace , _: & mut Context < Self > ) -> Self {
704
+ Self {
705
+ assistant_diff : None ,
706
+ _workspace : workspace. weak_handle ( ) ,
707
+ }
708
+ }
709
+
710
+ fn assistant_diff ( & self , _: & App ) -> Option < Entity < AssistantDiff > > {
711
+ self . assistant_diff . as_ref ( ) ?. upgrade ( )
712
+ }
713
+
714
+ fn dispatch_action ( & self , action : & dyn Action , window : & mut Window , cx : & mut Context < Self > ) {
715
+ if let Some ( assistant_diff) = self . assistant_diff ( cx) {
716
+ assistant_diff. focus_handle ( cx) . focus ( window) ;
717
+ }
718
+ let action = action. boxed_clone ( ) ;
719
+ cx. defer ( move |cx| {
720
+ cx. dispatch_action ( action. as_ref ( ) ) ;
721
+ } )
722
+ }
723
+ }
724
+
725
+ impl EventEmitter < ToolbarItemEvent > for AssistantDiffToolbar { }
726
+
727
+ impl ToolbarItemView for AssistantDiffToolbar {
728
+ fn set_active_pane_item (
729
+ & mut self ,
730
+ active_pane_item : Option < & dyn ItemHandle > ,
731
+ _: & mut Window ,
732
+ cx : & mut Context < Self > ,
733
+ ) -> ToolbarItemLocation {
734
+ self . assistant_diff = active_pane_item
735
+ . and_then ( |item| item. act_as :: < AssistantDiff > ( cx) )
736
+ . map ( |entity| entity. downgrade ( ) ) ;
737
+ if self . assistant_diff . is_some ( ) {
738
+ ToolbarItemLocation :: PrimaryRight
739
+ } else {
740
+ ToolbarItemLocation :: Hidden
741
+ }
742
+ }
743
+
744
+ fn pane_focus_update (
745
+ & mut self ,
746
+ _pane_focused : bool ,
747
+ _window : & mut Window ,
748
+ _cx : & mut Context < Self > ,
749
+ ) {
750
+ }
751
+ }
752
+
753
+ impl Render for AssistantDiffToolbar {
754
+ fn render ( & mut self , _: & mut Window , cx : & mut Context < Self > ) -> impl IntoElement {
755
+ if self . assistant_diff ( cx) . is_none ( ) {
756
+ return div ( ) ;
757
+ }
758
+
759
+ h_group_xl ( )
760
+ . my_neg_1 ( )
761
+ . items_center ( )
762
+ . py_1 ( )
763
+ . pl_2 ( )
764
+ . pr_1 ( )
765
+ . flex_wrap ( )
766
+ . justify_between ( )
767
+ . child (
768
+ h_group_sm ( )
769
+ . child (
770
+ Button :: new ( "reject-all" , "Reject All" ) . on_click ( cx. listener (
771
+ |this, _, window, cx| {
772
+ this. dispatch_action ( & crate :: RejectAll , window, cx)
773
+ } ,
774
+ ) ) ,
775
+ )
776
+ . child ( Button :: new ( "keep-all" , "Keep All" ) . on_click ( cx. listener (
777
+ |this, _, window, cx| this. dispatch_action ( & crate :: KeepAll , window, cx) ,
778
+ ) ) ) ,
779
+ )
780
+ }
781
+ }
0 commit comments