@@ -7,13 +7,15 @@ import * as dom from 'vs/base/browser/dom';
7
7
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar' ;
8
8
import 'vs/base/browser/ui/codicons/codiconStyles' ; // The codicon symbol styles are defined here and must be loaded
9
9
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview' ;
10
+ import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel' ;
10
11
import { IListEvent , IListMouseEvent , IListRenderer } from 'vs/base/browser/ui/list/list' ;
11
12
import { List } from 'vs/base/browser/ui/list/listWidget' ;
12
13
import { IAction } from 'vs/base/common/actions' ;
13
14
import { Codicon } from 'vs/base/common/codicons' ;
14
15
import { ResolvedKeybinding } from 'vs/base/common/keybindings' ;
15
16
import { Lazy } from 'vs/base/common/lazy' ;
16
17
import { Disposable , DisposableStore , IDisposable , MutableDisposable } from 'vs/base/common/lifecycle' ;
18
+ import { OS } from 'vs/base/common/platform' ;
17
19
import 'vs/css!./media/action' ;
18
20
import { ICodeEditor } from 'vs/editor/browser/editorBrowser' ;
19
21
import { IEditorContribution } from 'vs/editor/common/editorCommon' ;
@@ -28,7 +30,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
28
30
import { IContextKey , IContextKeyService , RawContextKey } from 'vs/platform/contextkey/common/contextkey' ;
29
31
import { IContextViewService } from 'vs/platform/contextview/browser/contextView' ;
30
32
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
31
- import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem' ;
32
33
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
33
34
34
35
export const Context = {
@@ -78,34 +79,36 @@ type ICodeActionMenuItem = CodeActionListItemCodeAction | CodeActionListItemHead
78
79
79
80
interface ICodeActionMenuTemplateData {
80
81
readonly container : HTMLElement ;
81
- readonly text : HTMLElement ;
82
82
readonly icon : HTMLElement ;
83
+ readonly text : HTMLElement ;
84
+ readonly keybinding : KeybindingLabel ;
83
85
}
84
86
85
87
class CodeActionItemRenderer implements IListRenderer < CodeActionListItemCodeAction , ICodeActionMenuTemplateData > {
86
88
constructor (
89
+ private readonly keybindingResolver : CodeActionKeybindingResolver ,
87
90
@IKeybindingService private readonly keybindingService : IKeybindingService ,
88
91
) { }
89
92
90
93
get templateId ( ) : string { return CodeActionListItemKind . CodeAction ; }
91
94
92
95
renderTemplate ( container : HTMLElement ) : ICodeActionMenuTemplateData {
93
- const iconContainer = document . createElement ( 'div' ) ;
94
- iconContainer . className = 'icon-container' ;
95
- container . append ( iconContainer ) ;
96
+ container . classList . add ( 'code-action' ) ;
96
97
97
98
const icon = document . createElement ( 'div' ) ;
98
- iconContainer . append ( icon ) ;
99
+ icon . className = 'icon' ;
100
+ container . append ( icon ) ;
99
101
100
102
const text = document . createElement ( 'span' ) ;
103
+ text . className = 'title' ;
101
104
container . append ( text ) ;
102
105
103
- return { container, icon, text } ;
106
+ const keybinding = new KeybindingLabel ( container , OS ) ;
107
+
108
+ return { container, icon, text, keybinding } ;
104
109
}
105
110
106
111
renderElement ( element : CodeActionListItemCodeAction , _index : number , data : ICodeActionMenuTemplateData ) : void {
107
- data . text . textContent = stripNewlines ( element . action . action . title ) ;
108
-
109
112
// Icons and Label modification based on group
110
113
const kind = element . action . action . kind ? new CodeActionKind ( element . action . action . kind ) : CodeActionKind . None ;
111
114
if ( CodeActionKind . SurroundWith . contains ( kind ) ) {
@@ -123,6 +126,16 @@ class CodeActionItemRenderer implements IListRenderer<CodeActionListItemCodeActi
123
126
data . icon . style . color = `var(--vscode-editorLightBulb-foreground)` ;
124
127
}
125
128
129
+ data . text . textContent = stripNewlines ( element . action . action . title ) ;
130
+
131
+ const binding = this . keybindingResolver . getResolver ( ) ( element . action . action ) ;
132
+ data . keybinding . set ( binding ) ;
133
+ if ( ! binding ) {
134
+ dom . hide ( data . keybinding . element ) ;
135
+ } else {
136
+ dom . show ( data . keybinding . element ) ;
137
+ }
138
+
126
139
// Check if action has disabled reason
127
140
if ( element . action . action . disabled ) {
128
141
data . container . title = element . action . action . disabled ;
@@ -157,7 +170,7 @@ class HeaderRenderer implements IListRenderer<CodeActionListItemHeader, HeaderTe
157
170
get templateId ( ) : string { return CodeActionListItemKind . Header ; }
158
171
159
172
renderTemplate ( container : HTMLElement ) : HeaderTemplateData {
160
- container . classList . add ( 'group-header' , 'option-disabled' ) ;
173
+ container . classList . add ( 'group-header' ) ;
161
174
162
175
const text = document . createElement ( 'span' ) ;
163
176
container . append ( text ) ;
@@ -203,10 +216,11 @@ class CodeActionList extends Disposable {
203
216
getHeight : element => element . kind === CodeActionListItemKind . Header ? this . headerLineHeight : this . codeActionLineHeight ,
204
217
getTemplateId : element => element . kind ,
205
218
} , [
206
- new CodeActionItemRenderer ( keybindingService ) ,
219
+ new CodeActionItemRenderer ( new CodeActionKeybindingResolver ( keybindingService ) , keybindingService ) ,
207
220
new HeaderRenderer ( ) ,
208
221
] , {
209
222
keyboardSupport : false ,
223
+ mouseSupport : false ,
210
224
accessibilityProvider : {
211
225
getAriaLabel : element => {
212
226
if ( element . kind === CodeActionListItemKind . CodeAction ) {
@@ -251,9 +265,10 @@ class CodeActionList extends Disposable {
251
265
const itemWidths : number [ ] = this . allMenuItems . map ( ( _ , index ) : number => {
252
266
const element = document . getElementById ( this . list . getElementID ( index ) ) ;
253
267
if ( element ) {
254
- const textPadding = 10 ;
255
- const iconPadding = 10 ;
256
- return [ ...element . children ] . reduce ( ( p , c ) => p + c . clientWidth , 0 ) + ( textPadding * 2 ) + iconPadding ;
268
+ element . style . width = 'auto' ;
269
+ const width = element . getBoundingClientRect ( ) . width ;
270
+ element . style . width = '' ;
271
+ return width ;
257
272
}
258
273
return 0 ;
259
274
} ) ;
@@ -672,15 +687,13 @@ export class CodeActionKeybindingResolver {
672
687
] ;
673
688
674
689
constructor (
675
- private readonly _keybindingProvider : {
676
- getKeybindings ( ) : readonly ResolvedKeybindingItem [ ] ;
677
- } ,
690
+ private readonly keybindingService : IKeybindingService ,
678
691
) { }
679
692
680
693
public getResolver ( ) : ( action : CodeAction ) => ResolvedKeybinding | undefined {
681
694
// Lazy since we may not actually ever read the value
682
695
const allCodeActionBindings = new Lazy < readonly ResolveCodeActionKeybinding [ ] > ( ( ) =>
683
- this . _keybindingProvider . getKeybindings ( )
696
+ this . keybindingService . getKeybindings ( )
684
697
. filter ( item => CodeActionKeybindingResolver . codeActionCommands . indexOf ( item . command ! ) >= 0 )
685
698
. filter ( item => item . resolvedKeybinding )
686
699
. map ( ( item ) : ResolveCodeActionKeybinding => {
0 commit comments