@@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
7
7
import { Disposable } from 'vs/base/common/lifecycle' ;
8
8
import { IWorkbenchContribution } from 'vs/workbench/common/contributions' ;
9
9
import { ICommandService } from 'vs/platform/commands/common/commands' ;
10
- import { QuickPickItem , IQuickInputService } from 'vs/platform/quickinput/common/quickInput' ;
10
+ import { QuickPickItem , IQuickInputService , IQuickInputButton } from 'vs/platform/quickinput/common/quickInput' ;
11
11
import { once } from 'vs/base/common/functional' ;
12
12
import { IProductService } from 'vs/platform/product/common/productService' ;
13
13
import { Action2 , MenuRegistry , registerAction2 } from 'vs/platform/actions/common/actions' ;
@@ -22,6 +22,10 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
22
22
import { ContextKeyExpr , IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
23
23
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions' ;
24
24
import { IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement' ;
25
+ import { ThemeIcon } from 'vs/base/common/themables' ;
26
+ import { infoIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons' ;
27
+ import { IOpenerService } from 'vs/platform/opener/common/opener' ;
28
+ import { URI } from 'vs/base/common/uri' ;
25
29
26
30
const STATUSBAR_REMOTEINDICATOR_CONTRIBUTION = 'statusBar/remoteIndicator' ;
27
31
@@ -49,6 +53,10 @@ interface RemoteExtensionMetadata {
49
53
installed : boolean ;
50
54
dependencies : string [ ] ;
51
55
isPlatformCompatible : boolean ;
56
+ helpLink : string ;
57
+ startConnectLabel : string ;
58
+ startCommand : string ;
59
+ priority : number ;
52
60
}
53
61
54
62
export class RemoteStartEntry extends Disposable implements IWorkbenchContribution {
@@ -66,16 +74,29 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
66
74
@IWorkbenchExtensionEnablementService private readonly extensionEnablementService : IWorkbenchExtensionEnablementService ,
67
75
@IExtensionGalleryService private readonly extensionGalleryService : IExtensionGalleryService ,
68
76
@ITelemetryService private readonly telemetryService : ITelemetryService ,
69
- @IContextKeyService private readonly contextKeyService : IContextKeyService ) {
77
+ @IContextKeyService private readonly contextKeyService : IContextKeyService ,
78
+ @IOpenerService private readonly openerService : IOpenerService ) {
70
79
71
80
super ( ) ;
72
81
const enable = this . extensionGalleryService . isEnabled ( ) && ( this . productService . remoteExtensionTips ?? false ) && this . productService . quality !== 'stable' ;
73
82
registerConfiguration ( enable ) ;
74
83
const remoteExtensionTips = { ...this . productService . remoteExtensionTips , ...this . productService . virtualWorkspaceExtensionTips } ;
75
- this . remoteExtensionMetadata = Object . values ( remoteExtensionTips ) . filter ( value => value . showInStartEntry === true ) . map ( value => {
76
- return { id : value . extensionId , installed : false , friendlyName : value . friendlyName , remoteCommands : [ ] , isPlatformCompatible : false , dependencies : [ ] } ;
84
+ this . remoteExtensionMetadata = Object . values ( remoteExtensionTips ) . filter ( value => value . startEntry !== undefined ) . map ( value => {
85
+ return {
86
+ id : value . extensionId ,
87
+ installed : false ,
88
+ friendlyName : value . friendlyName ,
89
+ remoteCommands : [ ] ,
90
+ isPlatformCompatible : false ,
91
+ dependencies : [ ] ,
92
+ helpLink : value . startEntry ?. helpLink ?? '' ,
93
+ startConnectLabel : value . startEntry ?. startConnectLabel ?? '' ,
94
+ startCommand : value . startEntry ?. startCommand ?? '' ,
95
+ priority : value . startEntry ?. priority ?? 10
96
+ } ;
77
97
} ) ;
78
98
99
+ this . remoteExtensionMetadata . sort ( ( ext1 , ext2 ) => ext1 . priority - ext2 . priority ) ;
79
100
this . registerActions ( ) ;
80
101
this . registerListeners ( ) ;
81
102
}
@@ -220,8 +241,12 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
220
241
}
221
242
}
222
243
else if ( ! metadata . installed && metadata . isPlatformCompatible ) {
223
- const label = nls . localize ( 'remote.startActions.connectTo' , 'Connect to {0}... ' , metadata . friendlyName ) ;
224
- notInstalledItems . push ( { type : 'item' , id : metadata . id , label : label } ) ;
244
+ const label = metadata . startConnectLabel ;
245
+ const buttons : IQuickInputButton [ ] = [ {
246
+ iconClass : ThemeIcon . asClassName ( infoIcon ) ,
247
+ tooltip : nls . localize ( 'remote.startActions.help' , "Learn More" )
248
+ } ] ;
249
+ notInstalledItems . push ( { type : 'item' , id : metadata . id , label : label , buttons : buttons } ) ;
225
250
}
226
251
}
227
252
@@ -232,7 +257,7 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
232
257
} ;
233
258
234
259
const quickPick = this . quickInputService . createQuickPick ( ) ;
235
- quickPick . placeholder = nls . localize ( 'remote.startActions.quickPickPlaceholder' , 'Select an option to connect to a Remote Window ' ) ;
260
+ quickPick . placeholder = nls . localize ( 'remote.startActions.quickPickPlaceholder' , 'Select an option to connect' ) ;
236
261
quickPick . items = await computeItems ( ) ;
237
262
quickPick . sortByLabel = false ;
238
263
quickPick . canSelectMany = false ;
@@ -258,11 +283,10 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
258
283
} ) ;
259
284
260
285
this . telemetryService . publicLog2 < RemoteStartActionEvent , RemoteStartActionClassification > ( 'remoteStartList.ActionExecuted' , { command : 'workbench.extensions.installExtension' , remoteExtensionId : selectedItem } ) ;
261
- const commands = await this . getRemoteCommands ( selectedItem ) ;
262
-
263
- await this . extensionService . activateByEvent ( `onCommand:${ commands [ 0 ] } ` ) ;
264
286
265
- const command = commands [ 0 ] . command ;
287
+ const commands = await this . getRemoteCommands ( selectedItem ) ;
288
+ const command = ( commands . find ( value => value . command === remoteExtension . startCommand ) ?? commands [ 0 ] ) . command ;
289
+ await this . extensionService . activateByEvent ( `onCommand:${ command } ` ) ;
266
290
this . commandService . executeCommand ( command ) ;
267
291
268
292
this . telemetryService . publicLog2 < RemoteStartActionEvent , RemoteStartActionClassification > ( 'remoteStartList.ActionExecuted' , { command : command , remoteExtensionId : selectedItem } ) ;
@@ -274,6 +298,12 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
274
298
quickPick . dispose ( ) ;
275
299
}
276
300
} ) ;
301
+ once ( quickPick . onDidTriggerItemButton ) ( async ( e ) => {
302
+ const remoteExtension = this . remoteExtensionMetadata . find ( value => ExtensionIdentifier . equals ( value . id , e . item . id ) ) ;
303
+ if ( remoteExtension ) {
304
+ await this . openerService . open ( URI . parse ( remoteExtension . helpLink ) ) ;
305
+ }
306
+ } ) ;
277
307
quickPick . onDidHide ( ( ) => quickPick . dispose ( ) ) ;
278
308
quickPick . show ( ) ;
279
309
}
0 commit comments