5
5
6
6
import * as resources from 'vs/base/common/resources' ;
7
7
import * as dom from 'vs/base/browser/dom' ;
8
- import { IAction , Action , Separator } from 'vs/base/common/actions' ;
9
- import { IDebugService , IBreakpoint , CONTEXT_BREAKPOINTS_FOCUSED , State , DEBUG_SCHEME , IFunctionBreakpoint , IExceptionBreakpoint , IEnablement , BREAKPOINT_EDITOR_CONTRIBUTION_ID , IBreakpointEditorContribution , IDebugModel , IDataBreakpoint , BREAKPOINTS_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug' ;
8
+ import { IAction } from 'vs/base/common/actions' ;
9
+ import { IDebugService , IBreakpoint , CONTEXT_BREAKPOINTS_FOCUSED , State , DEBUG_SCHEME , IFunctionBreakpoint , IExceptionBreakpoint , IEnablement , IDebugModel , IDataBreakpoint , BREAKPOINTS_VIEW_ID , CONTEXT_BREAKPOINT_ITEM_TYPE , CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION , CONTEXT_BREAKPOINTS_EXIST , CONTEXT_DEBUGGERS_AVAILABLE , CONTEXT_IN_DEBUG_MODE , IBaseBreakpoint , IBreakpointEditorContribution , BREAKPOINT_EDITOR_CONTRIBUTION_ID } from 'vs/workbench/contrib/debug/common/debug' ;
10
10
import { ExceptionBreakpoint , FunctionBreakpoint , Breakpoint , DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel' ;
11
- import { RemoveBreakpointAction , EnableAllBreakpointsAction , DisableAllBreakpointsAction , ReapplyBreakpointsAction } from 'vs/workbench/contrib/debug/browser/debugActions' ;
12
11
import { IContextMenuService , IContextViewService } from 'vs/platform/contextview/browser/contextView' ;
13
12
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
14
13
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
@@ -23,12 +22,11 @@ import { KeyCode } from 'vs/base/common/keyCodes';
23
22
import { WorkbenchList , ListResourceNavigator } from 'vs/platform/list/browser/listService' ;
24
23
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet' ;
25
24
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler' ;
26
- import { isCodeEditor } from 'vs/editor/browser/editorBrowser' ;
27
25
import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
28
26
import { IEditorService , SIDE_GROUP , ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService' ;
29
27
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane' ;
30
28
import { ILabelService } from 'vs/platform/label/common/label' ;
31
- import { IContextKeyService , ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey' ;
29
+ import { IContextKeyService , ContextKeyEqualsExpr , IContextKey , ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey' ;
32
30
import { Gesture } from 'vs/base/browser/touch' ;
33
31
import { IViewDescriptorService } from 'vs/workbench/common/views' ;
34
32
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor' ;
@@ -37,9 +35,11 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
37
35
import { Orientation } from 'vs/base/browser/ui/splitview/splitview' ;
38
36
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget' ;
39
37
import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons' ;
40
- import { registerAction2 , Action2 , MenuId , MenuItemAction } from 'vs/platform/actions/common/actions' ;
38
+ import { registerAction2 , Action2 , MenuId , IMenu , IMenuService } from 'vs/platform/actions/common/actions' ;
41
39
import { localize } from 'vs/nls' ;
42
40
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions' ;
41
+ import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem' ;
42
+ import { isCodeEditor } from 'vs/editor/browser/editorBrowser' ;
43
43
44
44
const $ = dom . $ ;
45
45
@@ -64,6 +64,9 @@ export class BreakpointsView extends ViewPane {
64
64
private list ! : WorkbenchList < BreakpointItem > ;
65
65
private needsRefresh = false ;
66
66
private ignoreLayout = false ;
67
+ private menu : IMenu ;
68
+ private breakpointItemType : IContextKey < string | undefined > ;
69
+ private exceptionBreakpointSupportsCondition : IContextKey < boolean > ;
67
70
68
71
constructor (
69
72
options : IViewletViewOptions ,
@@ -80,10 +83,21 @@ export class BreakpointsView extends ViewPane {
80
83
@IOpenerService openerService : IOpenerService ,
81
84
@ITelemetryService telemetryService : ITelemetryService ,
82
85
@ILabelService private readonly labelService : ILabelService ,
86
+ @IMenuService menuService : IMenuService
83
87
) {
84
88
super ( options , keybindingService , contextMenuService , configurationService , contextKeyService , viewDescriptorService , instantiationService , openerService , themeService , telemetryService ) ;
85
89
90
+ this . menu = menuService . createMenu ( MenuId . DebugBreakpointsContext , contextKeyService ) ;
91
+ this . _register ( this . menu ) ;
92
+ this . breakpointItemType = CONTEXT_BREAKPOINT_ITEM_TYPE . bindTo ( contextKeyService ) ;
93
+ this . exceptionBreakpointSupportsCondition = CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION . bindTo ( contextKeyService ) ;
86
94
this . _register ( this . debugService . getModel ( ) . onDidChangeBreakpoints ( ( ) => this . onBreakpointsChange ( ) ) ) ;
95
+ this . _register ( this . debugService . getViewModel ( ) . onDidSelectBreakpoint ( breakpoint => {
96
+ if ( breakpoint ) {
97
+ // Only react when a new breakpoint is selected - to reduce refresh, since other times a refresh is not needed
98
+ this . onBreakpointsChange ( ) ;
99
+ }
100
+ } ) ) ;
87
101
}
88
102
89
103
public renderBody ( container : HTMLElement ) : void {
@@ -140,7 +154,6 @@ export class BreakpointsView extends ViewPane {
140
154
if ( e . browserEvent instanceof MouseEvent && e . browserEvent . detail === 2 && e . element instanceof FunctionBreakpoint && e . element !== this . debugService . getViewModel ( ) . getSelectedBreakpoint ( ) ) {
141
155
// double click
142
156
this . debugService . getViewModel ( ) . setSelectedBreakpoint ( e . element ) ;
143
- this . onBreakpointsChange ( ) ;
144
157
}
145
158
} ) ) ;
146
159
@@ -183,60 +196,20 @@ export class BreakpointsView extends ViewPane {
183
196
}
184
197
185
198
private onListContextMenu ( e : IListContextMenuEvent < IEnablement > ) : void {
186
- if ( ! e . element ) {
187
- return ;
188
- }
189
-
190
- const actions : IAction [ ] = [ ] ;
191
199
const element = e . element ;
200
+ const type = element instanceof Breakpoint ? 'breakpoint' : element instanceof ExceptionBreakpoint ? 'exceptionBreakpoint' :
201
+ element instanceof FunctionBreakpoint ? 'functionBreakpoint' : element instanceof DataBreakpoint ? 'dataBreakpoint' : undefined ;
202
+ this . breakpointItemType . set ( type ) ;
203
+ this . exceptionBreakpointSupportsCondition . set ( element instanceof ExceptionBreakpoint && element . supportsCondition ) ;
192
204
193
- if ( element instanceof ExceptionBreakpoint ) {
194
- if ( element . supportsCondition ) {
195
- actions . push ( new Action ( 'workbench.action.debug.editExceptionBreakpointCondition' , localize ( 'editCondition' , "Edit Condition" ) , '' , true , async ( ) => {
196
- this . debugService . getViewModel ( ) . setSelectedBreakpoint ( element ) ;
197
- this . onBreakpointsChange ( ) ;
198
- } ) ) ;
199
- }
200
- } else {
201
- const breakpointType = element instanceof Breakpoint && element . logMessage ? localize ( 'Logpoint' , "Logpoint" ) : localize ( 'Breakpoint' , "Breakpoint" ) ;
202
- if ( element instanceof Breakpoint || element instanceof FunctionBreakpoint ) {
203
- actions . push ( new Action ( 'workbench.action.debug.openEditorAndEditBreakpoint' , localize ( 'editBreakpoint' , "Edit {0}..." , breakpointType ) , '' , true , async ( ) => {
204
- if ( element instanceof Breakpoint ) {
205
- const editor = await openBreakpointSource ( element , false , false , true , this . debugService , this . editorService ) ;
206
- if ( editor ) {
207
- const codeEditor = editor . getControl ( ) ;
208
- if ( isCodeEditor ( codeEditor ) ) {
209
- codeEditor . getContribution < IBreakpointEditorContribution > ( BREAKPOINT_EDITOR_CONTRIBUTION_ID ) . showBreakpointWidget ( element . lineNumber , element . column ) ;
210
- }
211
- }
212
- } else {
213
- this . debugService . getViewModel ( ) . setSelectedBreakpoint ( element ) ;
214
- this . onBreakpointsChange ( ) ;
215
- }
216
- } ) ) ;
217
- actions . push ( new Separator ( ) ) ;
218
- }
219
-
220
-
221
- actions . push ( new RemoveBreakpointAction ( RemoveBreakpointAction . ID , localize ( 'removeBreakpoint' , "Remove {0}" , breakpointType ) , this . debugService ) ) ;
222
-
223
- if ( this . debugService . getModel ( ) . getBreakpoints ( ) . length + this . debugService . getModel ( ) . getFunctionBreakpoints ( ) . length >= 1 ) {
224
- actions . push ( this . instantiationService . createInstance ( MenuItemAction , removeAllBreakpointsCommand , undefined , { } ) ) ;
225
- actions . push ( new Separator ( ) ) ;
226
-
227
- actions . push ( new EnableAllBreakpointsAction ( EnableAllBreakpointsAction . ID , EnableAllBreakpointsAction . LABEL , this . debugService , this . keybindingService ) ) ;
228
- actions . push ( new DisableAllBreakpointsAction ( DisableAllBreakpointsAction . ID , DisableAllBreakpointsAction . LABEL , this . debugService , this . keybindingService ) ) ;
229
- }
230
-
231
- actions . push ( new Separator ( ) ) ;
232
- actions . push ( new ReapplyBreakpointsAction ( ReapplyBreakpointsAction . ID , ReapplyBreakpointsAction . LABEL , this . debugService , this . keybindingService ) ) ;
233
- }
205
+ const actions : IAction [ ] = [ ] ;
206
+ const actionsDisposable = createAndFillInContextMenuActions ( this . menu , { arg : e . element , shouldForwardArgs : false } , actions ) ;
234
207
235
208
this . contextMenuService . showContextMenu ( {
236
209
getAnchor : ( ) => e . anchor ,
237
210
getActions : ( ) => actions ,
238
211
getActionsContext : ( ) => element ,
239
- onHide : ( ) => dispose ( actions )
212
+ onHide : ( ) => dispose ( actionsDisposable )
240
213
} ) ;
241
214
}
242
215
@@ -933,21 +906,60 @@ registerAction2(class extends Action2 {
933
906
}
934
907
} ) ;
935
908
936
- export const removeAllBreakpointsCommand = {
937
- id : 'workbench.debug.viewlet.action.removeAllBreakpoints' ,
938
- title : localize ( 'removeAllBreakpoints' , "Remove All Breakpoints" ) ,
939
- f1 : true ,
940
- icon : icons . breakpointsRemoveAll ,
941
- menu : [ {
942
- id : MenuId . ViewTitle ,
943
- group : 'navigation' ,
944
- order : 30 ,
945
- when : ContextKeyEqualsExpr . create ( 'view' , BREAKPOINTS_VIEW_ID )
946
- } ]
947
- } ;
948
909
registerAction2 ( class extends Action2 {
949
910
constructor ( ) {
950
- super ( removeAllBreakpointsCommand ) ;
911
+ super ( {
912
+ id : 'workbench.debug.viewlet.action.removeBreakpoint' ,
913
+ title : localize ( 'removeBreakpoint' , "Remove Breakpoint" ) ,
914
+ menu : [ {
915
+ id : MenuId . DebugBreakpointsContext ,
916
+ group : '3_modification' ,
917
+ order : 10 ,
918
+ when : CONTEXT_BREAKPOINT_ITEM_TYPE . notEqualsTo ( 'exceptionBreakpoint' )
919
+ } ]
920
+ } ) ;
921
+ }
922
+
923
+ async run ( accessor : ServicesAccessor , breakpoint : IBaseBreakpoint ) : Promise < void > {
924
+ const debugService = accessor . get ( IDebugService ) ;
925
+ if ( breakpoint instanceof Breakpoint ) {
926
+ await debugService . removeBreakpoints ( breakpoint . getId ( ) ) ;
927
+ } else if ( breakpoint instanceof FunctionBreakpoint ) {
928
+ await debugService . removeFunctionBreakpoints ( breakpoint . getId ( ) ) ;
929
+ } else if ( breakpoint instanceof DataBreakpoint ) {
930
+ await debugService . removeDataBreakpoints ( breakpoint . getId ( ) ) ;
931
+ }
932
+ }
933
+ } ) ;
934
+
935
+ registerAction2 ( class extends Action2 {
936
+ constructor ( ) {
937
+ super ( {
938
+ id : 'workbench.debug.viewlet.action.removeAllBreakpoints' ,
939
+ title : {
940
+ original : 'Remove All Breakpoints' ,
941
+ value : localize ( 'removeAllBreakpoints' , "Remove All Breakpoints" ) ,
942
+ mnemonicedTitle : localize ( { key : 'miRemoveAllBreakpoints' , comment : [ '&& denotes a mnemonic' ] } , "Remove &&All Breakpoints" )
943
+ } ,
944
+ f1 : true ,
945
+ icon : icons . breakpointsRemoveAll ,
946
+ menu : [ {
947
+ id : MenuId . ViewTitle ,
948
+ group : 'navigation' ,
949
+ order : 30 ,
950
+ when : ContextKeyEqualsExpr . create ( 'view' , BREAKPOINTS_VIEW_ID )
951
+ } , {
952
+ id : MenuId . DebugBreakpointsContext ,
953
+ group : '3_modification' ,
954
+ order : 20 ,
955
+ when : ContextKeyExpr . and ( CONTEXT_BREAKPOINTS_EXIST , CONTEXT_BREAKPOINT_ITEM_TYPE . notEqualsTo ( 'exceptionBreakpoint' ) )
956
+ } , {
957
+ id : MenuId . MenubarDebugMenu ,
958
+ group : '5_breakpoints' ,
959
+ order : 3 ,
960
+ when : CONTEXT_DEBUGGERS_AVAILABLE
961
+ } ]
962
+ } ) ;
951
963
}
952
964
953
965
run ( accessor : ServicesAccessor ) : void {
@@ -957,3 +969,140 @@ registerAction2(class extends Action2 {
957
969
debugService . removeDataBreakpoints ( ) ;
958
970
}
959
971
} ) ;
972
+
973
+ registerAction2 ( class extends Action2 {
974
+ constructor ( ) {
975
+ super ( {
976
+ id : 'workbench.debug.viewlet.action.enableAllBreakpoints' ,
977
+ title : {
978
+ original : '' ,
979
+ value : localize ( 'enableAllBreakpoints' , "Enable All Breakpoints" ) ,
980
+ mnemonicedTitle : localize ( { key : 'miEnableAllBreakpoints' , comment : [ '&& denotes a mnemonic' ] } , "&&Enable All Breakpoints" ) ,
981
+ } ,
982
+ f1 : true ,
983
+ precondition : CONTEXT_DEBUGGERS_AVAILABLE ,
984
+ menu : [ {
985
+ id : MenuId . DebugBreakpointsContext ,
986
+ group : 'z_commands' ,
987
+ order : 10 ,
988
+ when : ContextKeyExpr . and ( CONTEXT_BREAKPOINTS_EXIST , CONTEXT_BREAKPOINT_ITEM_TYPE . notEqualsTo ( 'exceptionBreakpoint' ) )
989
+ } , {
990
+ id : MenuId . MenubarDebugMenu ,
991
+ group : '5_breakpoints' ,
992
+ order : 1 ,
993
+ when : CONTEXT_DEBUGGERS_AVAILABLE
994
+ } ]
995
+ } ) ;
996
+ }
997
+
998
+ async run ( accessor : ServicesAccessor ) : Promise < void > {
999
+ const debugService = accessor . get ( IDebugService ) ;
1000
+ await debugService . enableOrDisableBreakpoints ( true ) ;
1001
+ }
1002
+ } ) ;
1003
+
1004
+ registerAction2 ( class extends Action2 {
1005
+ constructor ( ) {
1006
+ super ( {
1007
+ id : 'workbench.debug.viewlet.action.disableAllBreakpoints' ,
1008
+ title : {
1009
+ original : 'Disable All Breakpoints' ,
1010
+ value : localize ( 'disableAllBreakpoints' , "Disable All Breakpoints" ) ,
1011
+ mnemonicedTitle : localize ( { key : 'miDisableAllBreakpoints' , comment : [ '&& denotes a mnemonic' ] } , "Disable A&&ll Breakpoints" )
1012
+ } ,
1013
+ f1 : true ,
1014
+ precondition : CONTEXT_DEBUGGERS_AVAILABLE ,
1015
+ menu : [ {
1016
+ id : MenuId . DebugBreakpointsContext ,
1017
+ group : 'z_commands' ,
1018
+ order : 20 ,
1019
+ when : ContextKeyExpr . and ( CONTEXT_BREAKPOINTS_EXIST , CONTEXT_BREAKPOINT_ITEM_TYPE . notEqualsTo ( 'exceptionBreakpoint' ) )
1020
+ } , {
1021
+ id : MenuId . MenubarDebugMenu ,
1022
+ group : '5_breakpoints' ,
1023
+ order : 2 ,
1024
+
1025
+ when : CONTEXT_DEBUGGERS_AVAILABLE
1026
+ } ]
1027
+ } ) ;
1028
+ }
1029
+
1030
+ async run ( accessor : ServicesAccessor ) : Promise < void > {
1031
+ const debugService = accessor . get ( IDebugService ) ;
1032
+ await debugService . enableOrDisableBreakpoints ( false ) ;
1033
+ }
1034
+ } ) ;
1035
+
1036
+ registerAction2 ( class extends Action2 {
1037
+ constructor ( ) {
1038
+ super ( {
1039
+ id : 'workbench.debug.viewlet.action.reapplyBreakpointsAction' ,
1040
+ title : localize ( 'reapplyAllBreakpoints' , "Reapply All Breakpoints" ) ,
1041
+ f1 : true ,
1042
+ precondition : CONTEXT_IN_DEBUG_MODE ,
1043
+ menu : [ {
1044
+ id : MenuId . DebugBreakpointsContext ,
1045
+ group : 'z_commands' ,
1046
+ order : 30 ,
1047
+ when : ContextKeyExpr . and ( CONTEXT_BREAKPOINTS_EXIST , CONTEXT_BREAKPOINT_ITEM_TYPE . notEqualsTo ( 'exceptionBreakpoint' ) )
1048
+ } ]
1049
+ } ) ;
1050
+ }
1051
+
1052
+ async run ( accessor : ServicesAccessor ) : Promise < void > {
1053
+ const debugService = accessor . get ( IDebugService ) ;
1054
+ await debugService . setBreakpointsActivated ( true ) ;
1055
+ }
1056
+ } ) ;
1057
+
1058
+ registerAction2 ( class extends Action2 {
1059
+ constructor ( ) {
1060
+ super ( {
1061
+ id : 'workbench.action.debug.editExceptionBreakpointCondition' ,
1062
+ title : localize ( 'editCondition' , "Edit Condition" ) ,
1063
+ menu : [ {
1064
+ id : MenuId . DebugBreakpointsContext ,
1065
+ group : 'navigation' ,
1066
+ order : 10 ,
1067
+ when : CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION
1068
+ } ]
1069
+ } ) ;
1070
+ }
1071
+
1072
+ async run ( accessor : ServicesAccessor , breakpoint : ExceptionBreakpoint ) : Promise < void > {
1073
+ const debugService = accessor . get ( IDebugService ) ;
1074
+ debugService . getViewModel ( ) . setSelectedBreakpoint ( breakpoint ) ;
1075
+ }
1076
+ } ) ;
1077
+
1078
+
1079
+ registerAction2 ( class extends Action2 {
1080
+ constructor ( ) {
1081
+ super ( {
1082
+ id : 'debug.editBreakpoint' ,
1083
+ title : localize ( 'editBreakpoint' , "Edit Breakpoint..." ) ,
1084
+ menu : [ {
1085
+ id : MenuId . DebugBreakpointsContext ,
1086
+ group : 'navigation' ,
1087
+ order : 10 ,
1088
+ when : ContextKeyExpr . or ( CONTEXT_BREAKPOINT_ITEM_TYPE . isEqualTo ( 'breakpoint' ) , CONTEXT_BREAKPOINT_ITEM_TYPE . isEqualTo ( 'functionBreakpoint' ) )
1089
+ } ]
1090
+ } ) ;
1091
+ }
1092
+
1093
+ async run ( accessor : ServicesAccessor , breakpoint : ExceptionBreakpoint ) : Promise < void > {
1094
+ const debugService = accessor . get ( IDebugService ) ;
1095
+ const editorService = accessor . get ( IEditorService ) ;
1096
+ if ( breakpoint instanceof Breakpoint ) {
1097
+ const editor = await openBreakpointSource ( breakpoint , false , false , true , debugService , editorService ) ;
1098
+ if ( editor ) {
1099
+ const codeEditor = editor . getControl ( ) ;
1100
+ if ( isCodeEditor ( codeEditor ) ) {
1101
+ codeEditor . getContribution < IBreakpointEditorContribution > ( BREAKPOINT_EDITOR_CONTRIBUTION_ID ) . showBreakpointWidget ( breakpoint . lineNumber , breakpoint . column ) ;
1102
+ }
1103
+ }
1104
+ } else {
1105
+ debugService . getViewModel ( ) . setSelectedBreakpoint ( breakpoint ) ;
1106
+ }
1107
+ }
1108
+ } ) ;
0 commit comments