77import * as vscode from "vscode" ;
88import { execSync } from "child_process" ;
99import * as shell from "shelljs" ;
10+ import * as path from "path" ;
1011
1112import { workspace , ExtensionContext , WorkspaceFolder , Uri } from "vscode" ;
1213import {
@@ -156,6 +157,60 @@ function configureDebugger(context: ExtensionContext) {
156157 context . subscriptions . push ( disposable ) ;
157158}
158159
160+ function configureTerminalLinkProvider ( context : ExtensionContext ) {
161+ function openUri ( uri : Uri , line : number ) {
162+ vscode . workspace . openTextDocument ( uri ) . then ( document => {
163+ vscode . window . showTextDocument ( document ) . then ( editor => {
164+ const position = new vscode . Position ( line - 1 , 0 ) ;
165+ const selection = new vscode . Selection ( position , position ) ;
166+ editor . revealRange ( selection ) ;
167+ editor . selection = selection ;
168+ } ) ;
169+ } ) ;
170+ }
171+
172+ const disposable = vscode . window . registerTerminalLinkProvider ( {
173+ provideTerminalLinks : ( context : vscode . TerminalLinkContext , token : vscode . CancellationToken ) => {
174+ const regex = / (?: \( (?< app > [ _ a - z ] + ) \d + .\d + .\d + \) ) (?< file > [ _ a - z \/ ] * [ _ a - z ] + .e x ) : (?< line > \d + ) / ;
175+ const matches = context . line . match ( regex ) ;
176+ if ( matches === null ) {
177+ return [ ] ;
178+ }
179+
180+ return [
181+ {
182+ startIndex : matches . index ! ,
183+ length : matches [ 0 ] . length ,
184+ data : {
185+ app : matches . groups ! . app ,
186+ file : matches . groups ! . file ,
187+ line : parseInt ( matches . groups ! . line ) ,
188+ } ,
189+ } ,
190+ ] ;
191+ } ,
192+ handleTerminalLink : ( { data : { app, file, line } } : any ) => {
193+ let umbrellaFile = path . join ( "apps" , app , file ) ;
194+ vscode . workspace . findFiles ( `{${ umbrellaFile } ,${ file } }` ) . then ( uris => {
195+ if ( uris . length === 1 ) {
196+ openUri ( uris [ 0 ] , line ) ;
197+ } else if ( uris . length > 1 ) {
198+ const items = uris . map ( uri => ( { label : uri . toString ( ) , uri } ) ) ;
199+ vscode . window . showQuickPick ( items ) . then ( selection => {
200+ if ( ! selection ) {
201+ return ;
202+ }
203+
204+ openUri ( selection . uri , line ) ;
205+ } ) ;
206+ }
207+ } ) ;
208+ }
209+ } ) ;
210+
211+ context . subscriptions . push ( disposable ) ;
212+ }
213+
159214export function activate ( context : ExtensionContext ) : void {
160215 testElixir ( ) ;
161216 detectConflictingExtension ( "mjmcloug.vscode-elixir" ) ;
@@ -164,6 +219,7 @@ export function activate(context: ExtensionContext): void {
164219
165220 configureCopyDebugInfo ( context ) ;
166221 configureDebugger ( context ) ;
222+ configureTerminalLinkProvider ( context ) ;
167223
168224 const command =
169225 os . platform ( ) == "win32" ? "language_server.bat" : "language_server.sh" ;
0 commit comments