mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
Merge pull request #60219 from xxyy/pn/51032/json-status-bar
Less distracting error message for JSON schema resolution issues
This commit is contained in:
@@ -8,8 +8,8 @@ import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
|
||||
import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature } from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
|
||||
import { hash } from './utils/hash';
|
||||
@@ -22,6 +22,10 @@ namespace SchemaContentChangeNotification {
|
||||
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
|
||||
}
|
||||
|
||||
namespace ForceValidateRequest {
|
||||
export const type: RequestType<string, Diagnostic[], any, any> = new RequestType('json/validate');
|
||||
}
|
||||
|
||||
export interface ISchemaAssociations {
|
||||
[pattern: string]: string[];
|
||||
}
|
||||
@@ -77,6 +81,18 @@ export function activate(context: ExtensionContext) {
|
||||
|
||||
let documentSelector = ['json', 'jsonc'];
|
||||
|
||||
let statusBarItem = window.createStatusBarItem(StatusBarAlignment.Right, 0);
|
||||
statusBarItem.command = '_json.retrySchema';
|
||||
toDispose.push(statusBarItem);
|
||||
|
||||
let showStatusBarItem = (message: string) => {
|
||||
statusBarItem.tooltip = message + '\n' + localize('json.clickToRetry', 'Click to retry.');
|
||||
statusBarItem.text = '$(alert)';
|
||||
statusBarItem.show();
|
||||
};
|
||||
|
||||
let fileSchemaErrors = new Map<string, string>();
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
// Register the server for json documents
|
||||
@@ -89,6 +105,20 @@ export function activate(context: ExtensionContext) {
|
||||
middleware: {
|
||||
workspace: {
|
||||
didChangeConfiguration: () => client.sendNotification(DidChangeConfigurationNotification.type, { settings: getSettings() })
|
||||
},
|
||||
handleDiagnostics: (uri: Uri, diagnostics: Diagnostic[], next: HandleDiagnosticsSignature) => {
|
||||
const schemaErrorIndex = diagnostics.findIndex(candidate => candidate.code === /* SchemaResolveError */ 0x300);
|
||||
if (schemaErrorIndex !== -1) {
|
||||
// Show schema resolution errors in status bar only; ref: #51032
|
||||
const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
|
||||
fileSchemaErrors.set(uri.toString(), schemaResolveDiagnostic.message);
|
||||
showStatusBarItem(schemaResolveDiagnostic.message);
|
||||
diagnostics.splice(schemaErrorIndex, 1);
|
||||
} else {
|
||||
statusBarItem.hide();
|
||||
fileSchemaErrors.delete(uri.toString());
|
||||
}
|
||||
next(uri, diagnostics);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -121,8 +151,32 @@ export function activate(context: ExtensionContext) {
|
||||
client.sendNotification(SchemaContentChangeNotification.type, uri.toString());
|
||||
}
|
||||
};
|
||||
|
||||
let handleActiveEditorChange = (activeEditor?: TextEditor) => {
|
||||
const uriStr = activeEditor && activeEditor.document.uri.toString();
|
||||
if (uriStr && fileSchemaErrors.has(uriStr)) {
|
||||
const message = fileSchemaErrors.get(uriStr)!;
|
||||
showStatusBarItem(message);
|
||||
} else {
|
||||
statusBarItem.hide();
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri)));
|
||||
toDispose.push(workspace.onDidCloseTextDocument(d => handleContentChange(d.uri)));
|
||||
toDispose.push(workspace.onDidCloseTextDocument(d => {
|
||||
handleContentChange(d.uri);
|
||||
fileSchemaErrors.delete(d.uri.toString());
|
||||
}));
|
||||
toDispose.push(window.onDidChangeActiveTextEditor(handleActiveEditorChange));
|
||||
|
||||
let handleRetrySchemaCommand = () => {
|
||||
if (window.activeTextEditor) {
|
||||
client.sendRequest(ForceValidateRequest.type, window.activeTextEditor.document.uri.toString());
|
||||
statusBarItem.text = '$(watch)';
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(commands.registerCommand('_json.retrySchema', handleRetrySchemaCommand));
|
||||
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
|
||||
});
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
"json.format.enable.desc": "Enable/disable default JSON formatter",
|
||||
"json.tracing.desc": "Traces the communication between VS Code and the JSON language server.",
|
||||
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
|
||||
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`."
|
||||
}
|
||||
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
|
||||
"json.clickToRetry": "Click to retry."
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import {
|
||||
createConnection, IConnection,
|
||||
TextDocuments, TextDocument, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, Diagnostic
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
|
||||
@@ -34,6 +34,10 @@ namespace SchemaContentChangeNotification {
|
||||
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
|
||||
}
|
||||
|
||||
namespace ForceValidateRequest {
|
||||
export const type: RequestType<string, Diagnostic[], any, any> = new RequestType('json/validate');
|
||||
}
|
||||
|
||||
// Create a connection for the server
|
||||
const connection: IConnection = createConnection();
|
||||
|
||||
@@ -207,6 +211,21 @@ connection.onNotification(SchemaContentChangeNotification.type, uri => {
|
||||
languageService.resetSchema(uri);
|
||||
});
|
||||
|
||||
// Retry schema validation on all open documents
|
||||
connection.onRequest(ForceValidateRequest.type, uri => {
|
||||
return new Promise<Diagnostic[]>(resolve => {
|
||||
const document = documents.get(uri);
|
||||
if (document) {
|
||||
updateConfiguration();
|
||||
validateTextDocument(document, diagnostics => {
|
||||
resolve(diagnostics);
|
||||
});
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function updateConfiguration() {
|
||||
const languageSettings = {
|
||||
validate: true,
|
||||
@@ -271,10 +290,15 @@ function triggerValidation(textDocument: TextDocument): void {
|
||||
}, validationDelayMs);
|
||||
}
|
||||
|
||||
function validateTextDocument(textDocument: TextDocument): void {
|
||||
function validateTextDocument(textDocument: TextDocument, callback?: (diagnostics: Diagnostic[]) => void): void {
|
||||
const respond = (diagnostics: Diagnostic[]) => {
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
||||
if (callback) {
|
||||
callback(diagnostics);
|
||||
}
|
||||
};
|
||||
if (textDocument.getText().length === 0) {
|
||||
// ignore empty documents
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
|
||||
respond([]); // ignore empty documents
|
||||
return;
|
||||
}
|
||||
const jsonDocument = getJSONDocument(textDocument);
|
||||
@@ -285,8 +309,7 @@ function validateTextDocument(textDocument: TextDocument): void {
|
||||
setTimeout(() => {
|
||||
const currDocument = documents.get(textDocument.uri);
|
||||
if (currDocument && currDocument.version === version) {
|
||||
// Send the computed diagnostics to VSCode.
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
||||
respond(diagnostics); // Send the computed diagnostics to VSCode.
|
||||
}
|
||||
}, 100);
|
||||
}, error => {
|
||||
@@ -405,4 +428,4 @@ connection.onFoldingRanges((params, token) => {
|
||||
});
|
||||
|
||||
// Listen on the connection
|
||||
connection.listen();
|
||||
connection.listen();
|
||||
|
||||
Reference in New Issue
Block a user