Skip to content

Commit c7cb204

Browse files
authored
Adding level for diagnostic. Modify behavior so new diagnostic only appears on save, not on edit. (#1423)
closes #1405
1 parent 2f2796c commit c7cb204

File tree

3 files changed

+82
-69
lines changed

3 files changed

+82
-69
lines changed

Src/CSharpier.VSCode/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.9.2
2+
- Add option for diagnostic level, default to warning
3+
- Modify behavior of diagnostics so that new ones only appear on file save, not as a user types.
4+
15
## 1.9.1
26
- Add option for disabling diagnostics.
37

Src/CSharpier.VSCode/package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "csharpier-vscode",
33
"displayName": "CSharpier - Code formatter",
44
"description": "Code formatter using csharpier",
5-
"version": "1.9.1",
5+
"version": "1.9.2",
66
"publisher": "csharpier",
77
"author": "CSharpier",
88
"homepage": "https://marketplace.visualstudio.com/items?itemName=csharpier.csharpier-vscode",
@@ -48,6 +48,13 @@
4848
"default": false,
4949
"description": "Enable debug logs."
5050
},
51+
"csharpier.diagnosticsLevel": {
52+
"type": "string",
53+
"enum": ["0", "1", "2", "3"],
54+
"enumItemLabels": ["Error", "Warning", "Information", "Hint"],
55+
"default": "1",
56+
"description": "Determines the severity level of diagnostics if they are enabled."
57+
},
5158
"csharpier.enableDiagnostics": {
5259
"type": "boolean",
5360
"default": true,

Src/CSharpier.VSCode/src/DiagnosticsService.ts

Lines changed: 70 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ export interface CsharpierDiff {
1515
}
1616

1717
export class DiagnosticsService implements vscode.CodeActionProvider, vscode.Disposable {
18-
public static readonly quickFixCodeActionKind =
18+
private static readonly quickFixCodeActionKind =
1919
vscode.CodeActionKind.QuickFix.append(DIAGNOSTICS_ID);
20-
public static metadata: vscode.CodeActionProviderMetadata = {
20+
21+
private static metadata: vscode.CodeActionProviderMetadata = {
2122
providedCodeActionKinds: [DiagnosticsService.quickFixCodeActionKind],
2223
};
2324

@@ -48,87 +49,100 @@ export class DiagnosticsService implements vscode.CodeActionProvider, vscode.Dis
4849
this.codeActionsProvider.dispose();
4950
}
5051

51-
private handleChangeTextDocument(document: vscode.TextDocument): void {
52-
void this.runDiagnostics(document);
53-
}
54-
55-
public async runDiagnostics(document: vscode.TextDocument): Promise<void> {
56-
const shouldRunDiagnostics =
57-
this.documentSelector.some(selector => selector.language === document.languageId) &&
58-
!!vscode.workspace.getWorkspaceFolder(document.uri) &&
59-
(workspace.getConfiguration("csharpier").get<boolean>("enableDiagnostics") ?? true);
60-
if (shouldRunDiagnostics) {
61-
try {
62-
const diff = await this.getDiff(document);
63-
this.updateDiagnostics(document, diff);
64-
} catch (e) {
65-
this.logger.error(`Unable to provide diagnostics: ${(e as Error).message}`);
66-
}
67-
}
68-
}
69-
70-
public updateDiagnostics(document: vscode.TextDocument, diff: CsharpierDiff): void {
71-
const diagnostics = this.getDiagnostics(document, diff);
72-
this.diagnosticCollection.set(document.uri, diagnostics);
73-
}
74-
7552
private registerEditorEvents(): void {
7653
const activeDocument = vscode.window.activeTextEditor?.document;
7754
if (activeDocument) {
7855
void this.runDiagnostics(activeDocument);
7956
}
8057

81-
const onDidChangeTextDocument = vscode.workspace.onDidChangeTextDocument(
82-
(e: vscode.TextDocumentChangeEvent) => {
83-
if (
84-
e.contentChanges.length &&
85-
vscode.window.activeTextEditor?.document === e.document
86-
) {
87-
this.handleChangeTextDocument(e.document);
88-
}
89-
},
90-
);
58+
const onDidChangeTextDocument = vscode.workspace.onDidChangeTextDocument(e => {
59+
if (
60+
e.contentChanges.length &&
61+
vscode.window.activeTextEditor?.document === e.document
62+
) {
63+
// when editing don't pop up any new diagnostics, but if someone cleans up one then allow that update
64+
void this.runDiagnostics(e.document, true);
65+
}
66+
});
9167

92-
const onDidChangeActiveTextEditor = vscode.window.onDidChangeActiveTextEditor(
93-
(editor?: vscode.TextEditor) => {
94-
if (editor) {
95-
void this.runDiagnostics(editor.document);
96-
}
97-
},
98-
);
68+
const onDidSaveTextDocument = vscode.workspace.onDidSaveTextDocument(document => {
69+
if (vscode.window.activeTextEditor?.document === document) {
70+
void this.runDiagnostics(document);
71+
}
72+
});
73+
74+
const onDidChangeActiveTextEditor = vscode.window.onDidChangeActiveTextEditor(editor => {
75+
if (editor) {
76+
void this.runDiagnostics(editor.document);
77+
}
78+
});
9979

10080
this.disposables.push(
10181
onDidChangeTextDocument,
82+
onDidSaveTextDocument,
10283
onDidChangeActiveTextEditor,
10384
this.diagnosticCollection,
10485
);
10586
}
10687

88+
public async runDiagnostics(
89+
document: vscode.TextDocument,
90+
onlyAllowLessDiagnostics = false,
91+
): Promise<void> {
92+
const shouldRunDiagnostics =
93+
this.documentSelector.some(selector => selector.language === document.languageId) &&
94+
!!vscode.workspace.getWorkspaceFolder(document.uri) &&
95+
(workspace.getConfiguration("csharpier").get<boolean>("enableDiagnostics") ?? true);
96+
if (!shouldRunDiagnostics) {
97+
this.diagnosticCollection.set(document.uri, []);
98+
return;
99+
}
100+
101+
try {
102+
const source = document.getText();
103+
const formattedSource =
104+
(await this.formatDocumentProvider.formatDocument(document)) ?? source;
105+
const differences = generateDifferences(source, formattedSource);
106+
const diff = {
107+
source,
108+
formattedSource,
109+
differences,
110+
};
111+
const diagnostics = this.getDiagnostics(document, diff);
112+
if (onlyAllowLessDiagnostics) {
113+
let currentDiagnostics = this.diagnosticCollection.get(document.uri);
114+
let currentCount = !currentDiagnostics ? 0 : currentDiagnostics.length;
115+
if (diagnostics.length >= currentCount) {
116+
return;
117+
}
118+
}
119+
this.diagnosticCollection.set(document.uri, diagnostics);
120+
} catch (e) {
121+
this.logger.error(`Unable to provide diagnostics: ${(e as Error).message}`);
122+
}
123+
}
124+
107125
private getDiagnostics(
108126
document: vscode.TextDocument,
109127
diff: CsharpierDiff,
110128
): vscode.Diagnostic[] {
111129
const diagnostics: vscode.Diagnostic[] = [];
112130
for (const difference of diff.differences) {
113-
const diagnostic = this.getDiagnostic(document, difference);
131+
let range = this.getRange(document, difference);
132+
let message = this.getMessage(difference);
133+
let diagnostic = new vscode.Diagnostic(range, message);
134+
diagnostic.source = DIAGNOSTICS_ID;
135+
diagnostic.code = DIAGNOSTICS_SOURCE_ID;
136+
diagnostic.severity = parseInt(
137+
workspace.getConfiguration("csharpier").get<string>("diagnosticsLevel") ?? "1",
138+
10,
139+
);
114140
this.diagnosticDifferenceMap.set(diagnostic, difference);
115141
diagnostics.push(diagnostic);
116142
}
117143
return diagnostics;
118144
}
119145

120-
private getDiagnostic(
121-
document: vscode.TextDocument,
122-
difference: Difference,
123-
): vscode.Diagnostic {
124-
const range = this.getRange(document, difference);
125-
const message = this.getMessage(difference);
126-
const diagnostic = new vscode.Diagnostic(range, message);
127-
diagnostic.source = DIAGNOSTICS_ID;
128-
diagnostic.code = DIAGNOSTICS_SOURCE_ID;
129-
return diagnostic;
130-
}
131-
132146
private getMessage(difference: Difference): string {
133147
switch (difference.operation) {
134148
case generateDifferences.INSERT:
@@ -154,18 +168,6 @@ export class DiagnosticsService implements vscode.CodeActionProvider, vscode.Dis
154168
return new vscode.Range(start.line, start.character, end.line, end.character);
155169
}
156170

157-
private async getDiff(document: vscode.TextDocument): Promise<CsharpierDiff> {
158-
const source = document.getText();
159-
const formattedSource =
160-
(await this.formatDocumentProvider.formatDocument(document)) ?? source;
161-
const differences = generateDifferences(source, formattedSource);
162-
return {
163-
source,
164-
formattedSource,
165-
differences,
166-
};
167-
}
168-
169171
public provideCodeActions(
170172
document: vscode.TextDocument,
171173
range: vscode.Range | vscode.Selection,

0 commit comments

Comments
 (0)