Skip to content

Commit 47c6845

Browse files
authored
Link stack traces to relevant files (#152)
1 parent 2fc0dad commit 47c6845

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

src/extension.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import * as vscode from "vscode";
88
import { execSync } from "child_process";
99
import * as shell from "shelljs";
10+
import * as path from "path";
1011

1112
import { workspace, ExtensionContext, WorkspaceFolder, Uri } from "vscode";
1213
import {
@@ -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]+.ex):(?<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+
159214
export 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

Comments
 (0)