This repository has been archived by the owner on Jul 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 651
/
goLiveErrors.ts
98 lines (86 loc) · 3.01 KB
/
goLiveErrors.ts
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
'use strict';
import vscode = require('vscode');
import { byteOffsetAt, getBinPath, getToolsEnvVars } from './util';
import cp = require('child_process');
import path = require('path');
import { promptForMissingTool } from './goInstallTools';
import { errorDiagnosticCollection } from './goMain';
// Interface for settings configuration for adding and removing tags
interface GoLiveErrorsConfig {
delay: number;
enabled: boolean;
}
let runner;
export function goLiveErrorsEnabled() {
let goConfig = <GoLiveErrorsConfig>vscode.workspace.getConfiguration('go')['liveErrors'];
if (goConfig === null || goConfig === undefined || !goConfig.enabled) {
return false;
}
let files = vscode.workspace.getConfiguration('files');
let autoSave = files['autoSave'];
let autoSaveDelay = files['autoSaveDelay'];
if (autoSave !== null && autoSave !== undefined &&
autoSave === 'afterDelay' && autoSaveDelay < goConfig.delay * 1.5) {
return false;
}
return goConfig.enabled;
}
// parseLiveFile runs the gotype command in live mode to check for any syntactic or
// semantic errors and reports them immediately
export function parseLiveFile(e: vscode.TextDocumentChangeEvent) {
if (e.document.isUntitled) {
return;
}
if (e.document.languageId !== 'go') {
return;
}
if (!goLiveErrorsEnabled()) {
return;
}
if (runner != null) {
clearTimeout(runner);
}
runner = setTimeout(function(){
processFile(e);
runner = null;
}, vscode.workspace.getConfiguration('go')['liveErrors']['delay']);
}
// processFile does the actual work once the timeout has fired
function processFile(e: vscode.TextDocumentChangeEvent) {
let gotypeLive = getBinPath('gotype-live');
let fileContents = e.document.getText();
let fileName = e.document.fileName;
let args = ['-e', '-a', '-lf=' + fileName, path.dirname(fileName)];
let env = getToolsEnvVars();
let p = cp.execFile(gotypeLive, args, {env}, (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('gotype-live');
return;
}
errorDiagnosticCollection.clear();
if (err) {
// we want to take the error path here because the command we are calling
// returns a non-zero exit status if the checks fail
let diagnosticMap: Map<string, vscode.Diagnostic[]> = new Map();
stderr.split('\n').forEach(error => {
if (error === null || error.length === 0) {
return;
}
// extract the line, column and error message from the gotype output
let [_, file, line, column, message] = /^(.+):(\d+):(\d+):\s+(.+)/.exec(error);
let range = new vscode.Range(+line - 1, +column, +line - 1, +column);
let diagnostic = new vscode.Diagnostic(range, message, vscode.DiagnosticSeverity.Error);
let diagnostics = diagnosticMap.get(file);
if (!diagnostics) {
diagnostics = [];
}
diagnostics.push(diagnostic);
diagnosticMap.set(file, diagnostics);
});
diagnosticMap.forEach((diagnostics, file) => {
errorDiagnosticCollection.set(vscode.Uri.parse('file://' + file), diagnostics);
});
}
});
p.stdin.end(fileContents);
}