@@ -28,6 +28,7 @@ import { TerminalQuickFix, TerminalQuickFixType, toMenuItems } from 'vs/workbenc
2828import { ITerminalQuickFixProviderSelector , ITerminalQuickFixService } from 'vs/workbench/contrib/terminal/common/terminal' ;
2929import { ITerminalQuickFixOptions , IResolvedExtensionOptions , IUnresolvedExtensionOptions , ITerminalCommandSelector , ITerminalQuickFix , IInternalOptions , ITerminalQuickFixCommandAction , ITerminalQuickFixOpenerAction } from 'vs/platform/terminal/common/xterm/terminalQuickFix' ;
3030import { getLinesForCommand } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability' ;
31+ import { IAnchor } from 'vs/base/browser/ui/contextview/contextview' ;
3132
3233const quickFixTelemetryTitle = 'terminal/quick-fix' ;
3334type QuickFixResultTelemetryEvent = {
@@ -45,6 +46,7 @@ type QuickFixClassification = {
4546const quickFixSelectors = [ DecorationSelector . QuickFix , DecorationSelector . LightBulb , DecorationSelector . Codicon , DecorationSelector . CommandDecoration , DecorationSelector . XtermDecoration ] ;
4647
4748export interface ITerminalQuickFixAddon {
49+ showMenu ( ) : void ;
4850 onDidRequestRerunCommand : Event < { command : string ; addNewLine ?: boolean } > ;
4951 /**
5052 * Registers a listener on onCommandFinished scoped to a particular command or regular
@@ -68,6 +70,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
6870 private _fixesShown : boolean = false ;
6971 private _expectedCommands : string [ ] | undefined ;
7072 private _fixId : string | undefined ;
73+ private _currentRenderContext : { quickFixes : ITerminalAction [ ] ; anchor : IAnchor ; parentElement : HTMLElement } | undefined ;
7174
7275 constructor (
7376 private readonly _aliases : string [ ] [ ] | undefined ,
@@ -105,8 +108,31 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
105108 }
106109
107110 showMenu ( ) : void {
111+ if ( ! this . _currentRenderContext ) {
112+ return ;
113+ }
108114 this . _fixesShown = true ;
109- this . _decoration ?. element ?. click ( ) ;
115+ // TODO: What's documentation do? Need a vscode command?
116+ const actions = this . _currentRenderContext . quickFixes . map ( f => new TerminalQuickFix ( f , f . class || TerminalQuickFixType . Command , f . source , f . label ) ) ;
117+ const documentation = this . _currentRenderContext . quickFixes . map ( f => { return { id : f . source , title : f . label , tooltip : f . source } ; } ) ;
118+ const actionSet = {
119+ // TODO: Documentation and actions are separate?
120+ documentation,
121+ allActions : actions ,
122+ hasAutoFix : false ,
123+ validActions : actions ,
124+ dispose : ( ) => { }
125+ } as ActionSet < TerminalQuickFix > ;
126+ const delegate = {
127+ onSelect : async ( fix : TerminalQuickFix ) => {
128+ fix . action ?. run ( ) ;
129+ this . _actionWidgetService . hide ( ) ;
130+ } ,
131+ onHide : ( ) => {
132+ this . _terminal ?. focus ( ) ;
133+ } ,
134+ } ;
135+ this . _actionWidgetService . show ( 'quickFixWidget' , toMenuItems ( actionSet . validActions , true ) , delegate , this . _currentRenderContext . anchor , this . _currentRenderContext . parentElement ) ;
110136 }
111137
112138 registerCommandSelector ( selector : ITerminalCommandSelector ) : void {
@@ -251,42 +277,23 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
251277 e . classList . add ( ...quickFixSelectors ) ;
252278 updateLayout ( this . _configurationService , e ) ;
253279 this . _audioCueService . playAudioCue ( AudioCue . terminalQuickFix ) ;
254- this . _register ( dom . addDisposableListener ( e , dom . EventType . CLICK , ( ) => {
255- const rect = e . getBoundingClientRect ( ) ;
256- const anchor = {
257- x : rect . x ,
258- y : rect . y ,
259- width : rect . width ,
260- height : rect . height
261- } ;
262- // TODO: What's documentation do? Need a vscode command?
263- const actions = fixes . map ( f => new TerminalQuickFix ( f , f . class || TerminalQuickFixType . Command , f . source , f . label ) ) ;
264- const documentation = fixes . map ( f => { return { id : f . source , title : f . label , tooltip : f . source } ; } ) ;
265- const actionSet = {
266- // TODO: Documentation and actions are separate?
267- documentation,
268- allActions : actions ,
269- hasAutoFix : false ,
270- validActions : actions ,
271- dispose : ( ) => { }
272- } as ActionSet < TerminalQuickFix > ;
280+ const rect = e . getBoundingClientRect ( ) ;
281+ const anchor = {
282+ x : rect . x ,
283+ y : rect . y ,
284+ width : rect . width ,
285+ height : rect . height
286+ } ;
273287
274- const parentElement = e . parentElement ?. parentElement ?. parentElement ?. parentElement ;
275- if ( ! parentElement ) {
276- return ;
277- }
278- const delegate = {
279- onSelect : async ( fix : TerminalQuickFix ) => {
280- fix . action ?. run ( ) ;
281- this . _actionWidgetService . hide ( ) ;
282- } ,
283- onHide : ( ) => {
284- this . _terminal ?. focus ( ) ;
285- } ,
286- } ;
287- this . _actionWidgetService . show ( 'quickFixWidget' , toMenuItems ( actionSet . validActions , true ) , delegate , anchor , parentElement ) ;
288- } ) ) ;
288+ const parentElement = e . parentElement ?. parentElement ?. parentElement ?. parentElement ;
289+ if ( ! parentElement ) {
290+ return ;
291+ }
292+
293+ this . _currentRenderContext = { quickFixes : fixes , anchor, parentElement } ;
294+ this . _register ( dom . addDisposableListener ( e , dom . EventType . CLICK , ( ) => this . showMenu ( ) ) ) ;
289295 } ) ;
296+ decoration . onDispose ( ( ) => this . _currentRenderContext = undefined ) ;
290297 }
291298}
292299
0 commit comments