import * as _ from "lodash" ; import * as path from "path" ; import { TextEditor , window } from "vscode" ; import { IMainClassOption } from "./languageServerPlugin" ; const defaultLabelFormatter = ( option ) => { return option . mainClass ; } ; type Formatter = ( option : IMainClassOption ) => string ; class MainClassPicker { private cache : { [ key ] : number ; } = { } ; public async showQuickPick ( options , placeHolder ) ; public async showQuickPick ( options , placeHolder , labelFormatter ) ; public async showQuickPick ( options , placeHolder , autoPick ) ; public async showQuickPick ( options , placeHolder , parameter3 ? , parameter4 ? ) { let labelFormatter = defaultLabelFormatter ; let autoPick = true ; if ( typeof parameter3 === "function" ) { labelFormatter = parameter3 ; } else if ( typeof parameter3 === "boolean" ) { autoPick = parameter3 ; } if ( typeof parameter4 === "boolean" ) { autoPick = parameter4 ; } if ( ! options || ! options . length ) { return undefined ; } else if ( autoPick && options . length === 1 ) { return options [ 0 ] ; } const pickItems = options . map ( ( option ) => { return { label : labelFormatter ( option ) , description : option . filePath ? path . basename ( option . filePath ) : "" , detail : option . projectName ? `Project: ${ option . projectName }` : "" , data : option , } ; } ) ; const selected = await window . showQuickPick ( pickItems , { placeHolder } ) ; if ( selected ) { return selected . data ; } return undefined ; } public async showQuickPickWithRecentlyUsed ( options , placeHolder ) ; public async showQuickPickWithRecentlyUsed ( options , placeHolder , labelFormatter ) ; public async showQuickPickWithRecentlyUsed ( options , placeHolder , autoPick ) ; public async showQuickPickWithRecentlyUsed ( options , placeHolder , parameter3 ? , parameter4 ? ) { let labelFormatter = defaultLabelFormatter ; let autoPick = true ; if ( typeof parameter3 === "function" ) { labelFormatter = parameter3 ; } else if ( typeof parameter3 === "boolean" ) { autoPick = parameter3 ; } if ( typeof parameter4 === "boolean" ) { autoPick = parameter4 ; } if ( ! options || ! options . length ) { return undefined ; } else if ( autoPick && options . length === 1 ) { return options [ 0 ] ; } options . sort ( ( a , b ) => { return this . getMRUTimestamp ( b ) - this . getMRUTimestamp ( a ) ; } ) ; const mostRecentlyUsedOption = ( options . length && this . contains ( options [ 0 ] ) ) ? options [ 0 ] : undefined ; const isMostRecentlyUsed = ( option ) : boolean => { return ! ! mostRecentlyUsedOption && mostRecentlyUsedOption . mainClass === option . mainClass && mostRecentlyUsedOption . projectName === option . projectName ; } ; const isFromActiveEditor = ( option ) : boolean => { const activeEditor = window . activeTextEditor ; const currentActiveFile = _ . get ( activeEditor , "document.uri.fsPath" ) ; if ( option . filePath && currentActiveFile ) { return path . relative ( option . filePath , currentActiveFile ) === "" ; } return false ; } ; const isPrivileged = ( option ) : boolean => { return isMostRecentlyUsed ( option ) || isFromActiveEditor ( option ) ; } ; const adjustedOptions = [ ] ; options . forEach ( ( option ) => { if ( isPrivileged ( option ) ) { adjustedOptions . push ( option ) ; } } ) ; options . forEach ( ( option ) => { if ( ! isPrivileged ( option ) ) { adjustedOptions . push ( option ) ; } } ) ; const pickItems = adjustedOptions . map ( ( option ) => { const adjustedDetail = [ ] ; if ( isMostRecentlyUsed ( option ) ) { adjustedDetail . push ( "$(clock) recently used" ) ; } if ( isFromActiveEditor ( option ) && option . filePath ) { adjustedDetail . push ( `$(file-text) active editor (${ path . basename ( option . filePath ) })` ) ; } if ( option . projectName ) { adjustedDetail . push ( `Project: ${ option . projectName }` ) ; } const detail = adjustedDetail . join ( ", " ) ; return { label : labelFormatter ? labelFormatter ( option ) : defaultLabelFormatter ( option ) , description : option . filePath ? path . basename ( option . filePath ) : "" , detail , data : option , } ; } ) ; const selected = await window . showQuickPick ( pickItems , { placeHolder } ) ; if ( selected ) { this . updateMRUTimestamp ( selected . data ) ; return selected . data ; } return undefined ; } param options param autoPick public isAutoPicked ( options , autoPick ? ) { const shouldAutoPick = ( autoPick === undefined ? true : ! ! autoPick ) ; if ( ! options || ! options . length ) { return true ; } else if ( shouldAutoPick && options . length === 1 ) { return true ; } return false ; } private getMRUTimestamp ( mainClassOption ) { return this . cache [ this . getKey ( mainClassOption ) ] || 0 ; } private updateMRUTimestamp ( mainClassOption ) { this . cache [ this . getKey ( mainClassOption ) ] = Date . now ( ) ; } private contains ( mainClassOption ) { return Boolean ( this . cache [ this . getKey ( mainClassOption ) ] ) ; } private getKey ( mainClassOption ) { return mainClassOption . mainClass + "|" + mainClassOption . projectName ; } } export const mainClassPicker = new MainClassPicker ( ) ;