1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
"use strict";
import { runInNewContext } from "vm";
import * as path from "path";
/*
Modified code from https://github.com/hdevalke/rust-test-lens/
*/
import {
CancellationToken,
CodeLens,
CodeLensProvider,
Event,
EventEmitter,
Range,
TextDocument,
DebugConfiguration,
} from "vscode";
/*
This is not good enough. I think I have to let the language server make the lenses. Also I can't tell when the debug button is pressed, so users can end up pressing the button multiple times.
Would also be neat to see how many tests have failed since last, and also press a button to run all tests in the workspace.
*/
export class RunnableCodeLensProvider implements CodeLensProvider {
constructor(private _onDidChange: EventEmitter<void>) { }
public async provideCodeLenses(
doc: TextDocument,
token: CancellationToken
): Promise<CodeLens[]> {
if (token.isCancellationRequested) {
return [];
}
let lenses: CodeLens[] = this.testMethodLenses(doc);
return lenses;
}
get onDidChangeCodeLenses(): Event<void> {
return this._onDidChange.event;
}
public updateArgs() {
}
private testMethodLenses(doc: TextDocument) {
const text = doc.getText();
const reTest = /\@\(?test\)?/g;
const reFnTest = /\s*\w+\s*::\s*proc\s*\s*\(/g;
const rePackageName = /package\s+\w+/g;
var testMatch: RegExpExecArray | null = null;
let lenses: CodeLens[] = [];
while ((testMatch = reTest.exec(text)) !== null) {
reFnTest.lastIndex = reTest.lastIndex;
const fnMatch = reFnTest.exec(text);
if (fnMatch === null) {
continue;
}
const pkgMatch = rePackageName.exec(text);
if (pkgMatch === null) {
continue;
}
const fn = fnMatch[0].split(":")[0];
const pkg = pkgMatch[0].split(" ")[1];
if (fn && fn[0]) {
const debugCodelens = this.makeDebugLens(reTest.lastIndex, testMatch[0].length, pkg, fn.trim(), doc);
if (debugCodelens !== undefined) {
lenses.push(debugCodelens);
}
const runCodelens = this.makeRunLens(reTest.lastIndex, testMatch[0].length, pkg, fn.trim(), doc);
if (runCodelens !== undefined) {
lenses.push(runCodelens);
}
}
}
return lenses;
}
private makeDebugLens(index: number, length: number, pkg:string, fn: string, doc: TextDocument) {
const startIdx = index - length;
const start = doc.positionAt(startIdx);
const end = doc.positionAt(index);
const range = new Range(start, end);
return new CodeLens(range, {
title: "Debug",
command: "ols.runDebugTest",
tooltip: "Debug",
arguments: [{
function: fn,
cwd: path.dirname(doc.uri.fsPath),
pkg: pkg
}]
});
}
private makeRunLens(index: number, length: number, pkg: string, fn: string, doc: TextDocument): any | undefined {
const startIdx = index - length;
const start = doc.positionAt(startIdx);
const end = doc.positionAt(index);
const range = new Range(start, end);
return new CodeLens(range, {
title: "Run",
command: "ols.runTest",
tooltip: "Run",
arguments: [{
function: fn,
cwd: path.dirname(doc.uri.fsPath),
pkg: pkg
}]
});
}
}
|