Skip to content

Commit

Permalink
Add middleware to intercept diagnostics from the server
Browse files Browse the repository at this point in the history
Clients may want to inspect diagnostics received from the server
before letting VS Code handle and display them. It is not possible to
use onNotification because the existing handler will be replaced.
Thus, we need to introduce a new middleware for the language client
to route the server's textDocument/publishDiagnostics notification
to. This will allow the client can do what it needs to do before then
forwarding it off to VS Code.

Signed-off-by: Remy Suen <remy.suen@gmail.com>
  • Loading branch information
rcjsuen committed Mar 18, 2018
1 parent 6501c8f commit 2a3f054
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
13 changes: 13 additions & 0 deletions client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ export interface _Middleware {
willSaveWaitUntil?: NextSignature<TextDocumentWillSaveEvent, Thenable<VTextEdit[]>>;
didSave?: NextSignature<TextDocument, void>;
didClose?: NextSignature<TextDocument, void>;
publishDiagnostics?: NextSignature<PublishDiagnosticsParams, void>;

provideCompletionItem?: (this: void, document: TextDocument, position: VPosition, context: VCompletionContext, token: CancellationToken, next: ProvideCompletionItemsSignature) => ProviderResult<VCompletionItem[] | VCompletionList>;
resolveCompletionItem?: (this: void, item: VCompletionItem, token: CancellationToken, next: ResolveCompletionItemSignature) => ProviderResult<VCompletionItem>;
Expand Down Expand Up @@ -2740,6 +2741,18 @@ export abstract class BaseLanguageClient {
}

private handleDiagnostics(params: PublishDiagnosticsParams) {
if (!this._diagnostics) {
return;
}
let middleware = this.clientOptions.middleware!.publishDiagnostics;
if (middleware) {
middleware(params, (params) => this.setDiagnostics(params));
} else {
this.setDiagnostics(params);
}
}

private setDiagnostics(params: PublishDiagnosticsParams) {
if (!this._diagnostics) {
return;
}
Expand Down
17 changes: 14 additions & 3 deletions client/src/test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import * as assert from 'assert';
import * as lsclient from '../main';
import * as path from 'path';
import { PublishDiagnosticsParams } from '../main';

suite('Client integration', () => {

Expand All @@ -17,7 +18,19 @@ suite('Client integration', () => {
debug: { module: serverModule, transport: lsclient.TransportKind.ipc, options: { execArgv: ['--nolazy', '--inspect=6014'] } }
};
let documentSelector: lsclient.DocumentSelector = ['css'];
let clientOptions: lsclient.LanguageClientOptions = { documentSelector, synchronize: {}, initializationOptions: {} };
let clientOptions: lsclient.LanguageClientOptions = {
documentSelector, synchronize: {}, initializationOptions: {},
middleware: {
publishDiagnostics: (params: PublishDiagnosticsParams, next) => {
assert.equal(params.uri, "uri:/test.ts");
assert.ok(Array.isArray(params.diagnostics));
assert.equal(params.diagnostics.length, 0);
next(params);
disposable.dispose();
done();
}
}
};
let client = new lsclient.LanguageClient('css', 'Test Language Server', serverOptions, clientOptions);
let disposable = client.start();

Expand All @@ -36,8 +49,6 @@ suite('Client integration', () => {
}
};
assert.deepEqual(client.initializeResult, expected);
disposable.dispose();
done();
} catch (e) {
disposable.dispose();
done(e);
Expand Down
3 changes: 3 additions & 0 deletions client/src/test/servers/testInitializeResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ connection.onInitialize((params: InitializeParams): any => {
return { capabilities, customResults: { "hello": "world" } };
});

connection.onInitialized(() => {
connection.sendDiagnostics({ uri: "uri:/test.ts", diagnostics: [] });
});

// Listen on the connection
connection.listen();

0 comments on commit 2a3f054

Please sign in to comment.