import { CancellationToken , commands , Position , ProviderResult , Range , TerminalLink , TerminalLinkContext , TerminalLinkProvider , Uri , window } from "vscode" ; import { resolveSourceUri } from "./languageServerPlugin" ; export class JavaTerminalLinkProvder implements TerminalLinkProvider < IJavaTerminalLink > { param context param token return public provideTerminalLinks ( context , _token ) { if ( context . terminal . name !== "Java Debug Console" && context . terminal . name !== "Java Process Console" ) { return [ ] ; } const regex = new RegExp ( "(\\sat\\s+)([\\w$\\.]+\\/)?(([\\w$]+\\.)+[<\\w$>]+)\\(([\\w-$]+\\.java:\\d+)\\)" ) ; const result = regex . exec ( context . line ) ; if ( result && result . length ) { const stackTrace = `${ result [ 2 ] || "" }${ result [ 3 ] }(${ result [ 5 ] })` ; const sourceLineNumber = Number ( result [ 5 ] . split ( ":" ) [ 1 ] ) ; return [ { startIndex : result . index + result [ 1 ] . length , length : stackTrace . length , methodName : result [ 3 ] , stackTrace , lineNumber : sourceLineNumber , } ] ; } return [ ] ; } /**
     * Handle an activated terminal link.
     */ public async handleTerminalLink ( link ) { const uri = await resolveSourceUri ( link . stackTrace ) ; if ( uri ) { const lineNumber = Math . max ( link . lineNumber - 1 , 0 ) ; window . showTextDocument ( Uri . parse ( uri ) , { preserveFocus : true , selection : new Range ( new Position ( lineNumber , 0 ) , new Position ( lineNumber , 0 ) ) , } ) ; } else { const fullyQualifiedName = link . methodName . substring ( 0 , link . methodName . lastIndexOf ( "." ) ) ; const className = fullyQualifiedName . substring ( fullyQualifiedName . lastIndexOf ( "." ) + 1 ) ; commands . executeCommand ( "workbench.action.quickOpen" , "#" + className ) ; } } } interface IJavaTerminalLink extends TerminalLink { methodName : string ; stackTrace : string ; lineNumber : number ; }