@@ -14,6 +14,7 @@ import * as commands from "./commands";
1414import * as lsPlugin from "./languageServerPlugin" ;
1515import { addMoreHelpfulVMArgs , detectLaunchCommandStyle , validateRuntime } from "./launchCommand" ;
1616import { logger , Type } from "./logger" ;
17+ import { mainClassPicker } from "./mainClassPicker" ;
1718import { resolveJavaProcess } from "./processPicker" ;
1819import * as utility from "./utility" ;
1920
@@ -26,7 +27,6 @@ const platformName = platformNameMappings[process.platform];
2627
2728export class JavaDebugConfigurationProvider implements vscode . DebugConfigurationProvider {
2829 private isUserSettingsDirty : boolean = true ;
29- private debugHistory : MostRecentlyUsedHistory = new MostRecentlyUsedHistory ( ) ;
3030 constructor ( ) {
3131 vscode . workspace . onDidChangeConfiguration ( ( event ) => {
3232 if ( event . affectsConfiguration ( "java.debug" ) ) {
@@ -331,11 +331,8 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
331331 const currentFile = config . mainClass || _ . get ( vscode . window . activeTextEditor , "document.uri.fsPath" ) ;
332332 if ( currentFile ) {
333333 const mainEntries = await lsPlugin . resolveMainMethod ( vscode . Uri . file ( currentFile ) ) ;
334- if ( mainEntries . length === 1 ) {
335- return mainEntries [ 0 ] ;
336- } else if ( mainEntries . length > 1 ) {
337- return this . showMainClassQuickPick ( this . formatMainClassOptions ( mainEntries ) ,
338- `Please select a main class you want to run.` ) ;
334+ if ( mainEntries . length ) {
335+ return mainClassPicker . showQuickPick ( mainEntries , "Please select a main class you want to run." ) ;
339336 }
340337 }
341338
@@ -384,9 +381,8 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
384381 anchor : anchor . FAILED_TO_RESOLVE_CLASSPATH ,
385382 } , "Fix" ) ;
386383 if ( answer === "Fix" ) {
387- const pickItems : IMainClassQuickPickItem [ ] = this . formatMainClassOptions ( validationResponse . proposals ) ;
388- const selectedFix : lsPlugin . IMainClassOption =
389- await this . showMainClassQuickPick ( pickItems , "Please select main class<project name>." , false ) ;
384+ const selectedFix = await mainClassPicker . showQuickPick ( validationResponse . proposals ,
385+ "Please select main class<project name>." , false ) ;
390386 if ( selectedFix ) {
391387 sendInfo ( null , {
392388 fix : "yes" ,
@@ -445,92 +441,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
445441 } ) ;
446442 }
447443
448- const pickItems : IMainClassQuickPickItem [ ] = this . formatRecentlyUsedMainClassOptions ( res ) ;
449- const selected = await this . showMainClassQuickPick ( pickItems , hintMessage || "Select main class<project name>" ) ;
450- if ( selected ) {
451- this . debugHistory . updateMRUTimestamp ( selected ) ;
452- }
453-
454- return selected ;
455- }
456-
457- private async showMainClassQuickPick ( pickItems : IMainClassQuickPickItem [ ] , quickPickHintMessage : string , autoPick : boolean = true ) :
458- Promise < lsPlugin . IMainClassOption | undefined > {
459- // return undefined when the user cancels QuickPick by pressing ESC.
460- const selected = ( pickItems . length === 1 && autoPick ) ?
461- pickItems [ 0 ] : await vscode . window . showQuickPick ( pickItems , { placeHolder : quickPickHintMessage } ) ;
462-
463- return selected && selected . item ;
464- }
465-
466- private formatRecentlyUsedMainClassOptions ( options : lsPlugin . IMainClassOption [ ] ) : IMainClassQuickPickItem [ ] {
467- // Sort the Main Class options with the recently used timestamp.
468- options . sort ( ( a : lsPlugin . IMainClassOption , b : lsPlugin . IMainClassOption ) => {
469- return this . debugHistory . getMRUTimestamp ( b ) - this . debugHistory . getMRUTimestamp ( a ) ;
470- } ) ;
471-
472- const mostRecentlyUsedOption : lsPlugin . IMainClassOption = ( options . length && this . debugHistory . contains ( options [ 0 ] ) ) ? options [ 0 ] : undefined ;
473- const isMostRecentlyUsed = ( option : lsPlugin . IMainClassOption ) : boolean => {
474- return mostRecentlyUsedOption
475- && mostRecentlyUsedOption . mainClass === option . mainClass
476- && mostRecentlyUsedOption . projectName === option . projectName ;
477- } ;
478- const isFromActiveEditor = ( option : lsPlugin . IMainClassOption ) : boolean => {
479- const activeEditor : vscode . TextEditor = vscode . window . activeTextEditor ;
480- const currentActiveFile : string = _ . get ( activeEditor , "document.uri.fsPath" ) ;
481- return option . filePath && currentActiveFile && path . relative ( option . filePath , currentActiveFile ) === "" ;
482- } ;
483- const isPrivileged = ( option : lsPlugin . IMainClassOption ) : boolean => {
484- return isMostRecentlyUsed ( option ) || isFromActiveEditor ( option ) ;
485- } ;
486-
487- // Show the most recently used Main Class as the first one,
488- // then the Main Class from Active Editor as second,
489- // finally other Main Class.
490- const adjustedOptions : lsPlugin . IMainClassOption [ ] = [ ] ;
491- options . forEach ( ( option : lsPlugin . IMainClassOption ) => {
492- if ( isPrivileged ( option ) ) {
493- adjustedOptions . push ( option ) ;
494- }
495- } ) ;
496- options . forEach ( ( option : lsPlugin . IMainClassOption ) => {
497- if ( ! isPrivileged ( option ) ) {
498- adjustedOptions . push ( option ) ;
499- }
500- } ) ;
501-
502- const pickItems : IMainClassQuickPickItem [ ] = this . formatMainClassOptions ( adjustedOptions ) ;
503- pickItems . forEach ( ( pickItem : IMainClassQuickPickItem ) => {
504- const adjustedDetail = [ ] ;
505- if ( isMostRecentlyUsed ( pickItem . item ) ) {
506- adjustedDetail . push ( "$(clock) recently used" ) ;
507- }
508-
509- if ( isFromActiveEditor ( pickItem . item ) ) {
510- adjustedDetail . push ( `$(file-text) active editor (${ path . basename ( pickItem . item . filePath ) } )` ) ;
511- }
512-
513- pickItem . detail = adjustedDetail . join ( ", " ) ;
514- } ) ;
515-
516- return pickItems ;
517- }
518-
519- private formatMainClassOptions ( options : lsPlugin . IMainClassOption [ ] ) : IMainClassQuickPickItem [ ] {
520- return options . map ( ( item ) => {
521- let label = item . mainClass ;
522- const description = item . filePath ? path . basename ( item . filePath ) : "" ;
523- if ( item . projectName ) {
524- label += `<${ item . projectName } >` ;
525- }
526-
527- return {
528- label,
529- description,
530- detail : null ,
531- item,
532- } ;
533- } ) ;
444+ return mainClassPicker . showQuickPickWithRecentlyUsed ( res , hintMessage || "Select main class<project name>" ) ;
534445 }
535446}
536447
@@ -595,27 +506,3 @@ function convertLogLevel(commonLogLevel: string) {
595506 return "FINE" ;
596507 }
597508}
598-
599- export interface IMainClassQuickPickItem extends vscode . QuickPickItem {
600- item : lsPlugin . IMainClassOption ;
601- }
602-
603- class MostRecentlyUsedHistory {
604- private cache : { [ key : string ] : number } = { } ;
605-
606- public getMRUTimestamp ( mainClassOption : lsPlugin . IMainClassOption ) : number {
607- return this . cache [ this . getKey ( mainClassOption ) ] || 0 ;
608- }
609-
610- public updateMRUTimestamp ( mainClassOption : lsPlugin . IMainClassOption ) : void {
611- this . cache [ this . getKey ( mainClassOption ) ] = Date . now ( ) ;
612- }
613-
614- public contains ( mainClassOption : lsPlugin . IMainClassOption ) : boolean {
615- return Boolean ( this . cache [ this . getKey ( mainClassOption ) ] ) ;
616- }
617-
618- private getKey ( mainClassOption : lsPlugin . IMainClassOption ) : string {
619- return mainClassOption . mainClass + "|" + mainClassOption . projectName ;
620- }
621- }
0 commit comments