mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
JSON formatting often fails at first. Fixes #71652
This commit is contained in:
@@ -10,8 +10,8 @@ import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError } from 'vscode-languageclient';
|
||||
import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, ProviderResult, TextEdit, Range, Disposable } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams, DocumentRangeFormattingRequest } from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
|
||||
import { hash } from './utils/hash';
|
||||
@@ -65,6 +65,8 @@ export function activate(context: ExtensionContext) {
|
||||
|
||||
let toDispose = context.subscriptions;
|
||||
|
||||
let rangeFormatting: Disposable | undefined = undefined;
|
||||
|
||||
let packageInfo = getPackageInfo(context);
|
||||
telemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||
|
||||
@@ -101,7 +103,8 @@ export function activate(context: ExtensionContext) {
|
||||
// Register the server for json documents
|
||||
documentSelector,
|
||||
initializationOptions: {
|
||||
handledSchemaProtocols: ['file'] // language server only loads file-URI. Fetching schemas with other protocols ('http'...) are made on the client.
|
||||
handledSchemaProtocols: ['file'], // language server only loads file-URI. Fetching schemas with other protocols ('http'...) are made on the client.
|
||||
provideFormatter: false // tell the server to not provide formatting capability and ignore the `json.format.enable` setting.
|
||||
},
|
||||
synchronize: {
|
||||
// Synchronize the setting section 'json' to the server
|
||||
@@ -224,10 +227,13 @@ export function activate(context: ExtensionContext) {
|
||||
extensions.onDidChange(_ => {
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
|
||||
});
|
||||
|
||||
// manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652.
|
||||
updateFormatterRegistration();
|
||||
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
|
||||
toDispose.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration('html.format.enable') && updateFormatterRegistration()));
|
||||
});
|
||||
|
||||
|
||||
|
||||
let languageConfiguration: LanguageConfiguration = {
|
||||
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/,
|
||||
indentationRules: {
|
||||
@@ -237,8 +243,35 @@ export function activate(context: ExtensionContext) {
|
||||
};
|
||||
languages.setLanguageConfiguration('json', languageConfiguration);
|
||||
languages.setLanguageConfiguration('jsonc', languageConfiguration);
|
||||
|
||||
function updateFormatterRegistration() {
|
||||
const formatEnabled = workspace.getConfiguration().get('json.format.enable');
|
||||
if (!formatEnabled && rangeFormatting) {
|
||||
rangeFormatting.dispose();
|
||||
rangeFormatting = undefined;
|
||||
} else if (formatEnabled && !rangeFormatting) {
|
||||
rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, {
|
||||
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
|
||||
let params: DocumentRangeFormattingParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
range: client.code2ProtocolConverter.asRange(range),
|
||||
options: client.code2ProtocolConverter.asFormattingOptions(options)
|
||||
};
|
||||
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
|
||||
client.protocol2CodeConverter.asTextEdits,
|
||||
(error) => {
|
||||
client.logFailedRequest(DocumentRangeFormattingRequest.type, error);
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function deactivate(): Promise<any> {
|
||||
return telemetryReporter ? telemetryReporter.dispose() : Promise.resolve(null);
|
||||
}
|
||||
@@ -286,7 +319,6 @@ function getSettings(): Settings {
|
||||
proxyStrictSSL: httpSettings.get('proxyStrictSSL')
|
||||
},
|
||||
json: {
|
||||
format: workspace.getConfiguration('json').get('format'),
|
||||
schemas: [],
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ The JSON Language server provides language-specific smarts for editing, validati
|
||||
|
||||
The JSON language server supports requests on documents of language id `json` and `jsonc`.
|
||||
- `json` documents are parsed and validated following the [JSON specification](https://tools.ietf.org/html/rfc7159).
|
||||
- `jsonc` documents additionally accept single line (`//`) and multi-line comments (`/* ... */`) and accepts trailing commas. JSONC is a VSCode specific file format, intended for VSCode configuration files, without any aspirations to define a new common file format.
|
||||
- `jsonc` documents additionally accept single line (`//`) and multi-line comments (`/* ... */`). JSONC is a VSCode specific file format, intended for VSCode configuration files, without any aspirations to define a new common file format.
|
||||
|
||||
The server implements the following capabilities of the language server protocol:
|
||||
|
||||
@@ -40,6 +40,13 @@ The JSON language server has the following dependencies on the client's capabili
|
||||
|
||||
## Configuration
|
||||
|
||||
### Initialization options
|
||||
|
||||
The client can send the following initialization options to the server:
|
||||
|
||||
- `provideFormatter: boolean | undefined`. If defined, the value defines wheter the server provides the `documentRangeFormattingProvider` capability on initialization. If undefined, the setting `json.format.enable` is used to determined wheter formatting is provided. The formatter will then be registered through dynamic registration. If the client does not support dynamic registration, no formatter will be available.
|
||||
- `handledSchemaProtocols`: The URI schemas handles by the server. See section `Schema configuration` below.
|
||||
|
||||
### Settings
|
||||
|
||||
Clients may send a `workspace/didChangeConfiguration` notification to notify the server of settings changes.
|
||||
@@ -51,7 +58,7 @@ The server supports the following settings:
|
||||
|
||||
- json
|
||||
- `format`
|
||||
- `enable`: Whether the server should register the formatting support. This option is only applicable if the client supports *dynamicRegistration* for *rangeFormatting*
|
||||
- `enable`: Whether the server should register the formatting support. This option is only applicable if the client supports *dynamicRegistration* for *rangeFormatting* and `initializationOptions.provideFormatter` is not defined.
|
||||
- `schema`: Configures association of file names to schema URL or schemas and/or associations of schema URL to schema content.
|
||||
- `fileMatch`: an array or file names or paths (separated by `/`). `*` can be used as a wildcard.
|
||||
- `url`: The URL of the schema, optional when also a schema is provided.
|
||||
|
||||
@@ -114,7 +114,7 @@ const documents: TextDocuments = new TextDocuments();
|
||||
documents.listen(connection);
|
||||
|
||||
let clientSnippetSupport = false;
|
||||
let clientDynamicRegisterSupport = false;
|
||||
let dynamicFormatterRegistration = false;
|
||||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let hierarchicalDocumentSymbolSupport = false;
|
||||
|
||||
@@ -144,7 +144,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
}
|
||||
|
||||
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
|
||||
clientDynamicRegisterSupport = getClientCapability('workspace.rangeFormatting.dynamicRegistration', false);
|
||||
dynamicFormatterRegistration = getClientCapability('workspace.rangeFormatting.dynamicRegistration', false) && (params.initializationOptions.provideFormatter === undefined);
|
||||
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
|
||||
const capabilities: ServerCapabilities = {
|
||||
@@ -156,7 +156,8 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
documentRangeFormattingProvider: false,
|
||||
colorProvider: {},
|
||||
foldingRangeProvider: true,
|
||||
selectionRangeProvider: true
|
||||
selectionRangeProvider: true,
|
||||
documentFormattingProvider: params.initializationOptions.provideFormatter === true
|
||||
};
|
||||
|
||||
return { capabilities };
|
||||
@@ -195,7 +196,7 @@ connection.onDidChangeConfiguration((change) => {
|
||||
updateConfiguration();
|
||||
|
||||
// dynamically enable & disable the formatter
|
||||
if (clientDynamicRegisterSupport) {
|
||||
if (dynamicFormatterRegistration) {
|
||||
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
|
||||
if (enableFormatter) {
|
||||
if (!formatterRegistration) {
|
||||
|
||||
Reference in New Issue
Block a user