Skip to content

Commit 3b29d21

Browse files
authored
Dynamically register markdown completions and document highlights (microsoft#167451)
Fixes microsoft#165920
1 parent 488651b commit 3b29d21

File tree

2 files changed

+47
-35
lines changed

2 files changed

+47
-35
lines changed

extensions/markdown-language-features/server/src/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Disposable } from './util/dispose';
88

99
export type ValidateEnabled = 'ignore' | 'warning' | 'error' | 'hint';
1010

11-
interface Settings {
11+
export interface Settings {
1212
readonly markdown: {
1313
readonly occurrencesHighlight: {
1414
readonly enabled: boolean;

extensions/markdown-language-features/server/src/server.ts

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { CancellationToken, Connection, InitializeParams, InitializeResult, NotebookDocuments, ResponseError, TextDocuments } from 'vscode-languageserver';
6+
import { CancellationToken, CompletionRegistrationOptions, CompletionRequest, Connection, Disposable, DocumentHighlightRegistrationOptions, DocumentHighlightRequest, InitializeParams, InitializeResult, NotebookDocuments, ResponseError, TextDocuments } from 'vscode-languageserver';
77
import { TextDocument } from 'vscode-languageserver-textdocument';
88
import * as lsp from 'vscode-languageserver-types';
99
import * as md from 'vscode-markdown-languageservice';
1010
import { URI } from 'vscode-uri';
1111
import { getLsConfiguration, LsConfiguration } from './config';
12-
import { ConfigurationManager } from './configuration';
12+
import { ConfigurationManager, Settings } from './configuration';
1313
import { registerValidateSupport } from './languageFeatures/diagnostics';
1414
import { LogFunctionLogger } from './logging';
1515
import * as protocol from './protocol';
@@ -77,7 +77,7 @@ export async function startServer(connection: Connection, serverConfig: {
7777
});
7878

7979
registerCompletionsSupport(connection, documents, mdLs, configurationManager);
80-
registerDocumentHightlightSupport(connection, documents, mdLs, configurationManager);
80+
registerDocumentHighlightSupport(connection, documents, mdLs, configurationManager);
8181
registerValidateSupport(connection, workspace, documents, mdLs, configurationManager, serverConfig.logger);
8282

8383
return {
@@ -89,10 +89,8 @@ export async function startServer(connection: Connection, serverConfig: {
8989
workspaceDiagnostics: false,
9090
},
9191
codeActionProvider: { resolveProvider: true },
92-
completionProvider: { triggerCharacters: ['.', '/', '#'] },
9392
definitionProvider: true,
9493
documentLinkProvider: { resolveProvider: true },
95-
documentHighlightProvider: true,
9694
documentSymbolProvider: true,
9795
foldingRangeProvider: true,
9896
referencesProvider: true,
@@ -257,50 +255,57 @@ export async function startServer(connection: Connection, serverConfig: {
257255
connection.listen();
258256
}
259257

258+
function registerDynamicClientFeature(
259+
config: ConfigurationManager,
260+
isEnabled: (settings: Settings | undefined) => boolean,
261+
register: () => Promise<Disposable>,
262+
) {
263+
let registration: Promise<IDisposable> | undefined;
264+
function update() {
265+
const settings = config.getSettings();
266+
if (isEnabled(settings)) {
267+
if (!registration) {
268+
registration = register();
269+
}
270+
} else {
271+
registration?.then(x => x.dispose());
272+
registration = undefined;
273+
}
274+
}
275+
276+
update();
277+
return config.onDidChangeConfiguration(() => update());
278+
}
260279

261280
function registerCompletionsSupport(
262281
connection: Connection,
263282
documents: TextDocuments<md.ITextDocument>,
264283
ls: md.IMdLanguageService,
265284
config: ConfigurationManager,
266285
): IDisposable {
267-
// let registration: Promise<IDisposable> | undefined;
268-
function update() {
269-
// TODO: client still makes the request in this case. Figure our how to properly unregister.
270-
return;
271-
// const settings = config.getSettings();
272-
// if (settings?.markdown.suggest.paths.enabled) {
273-
// if (!registration) {
274-
// registration = connection.client.register(CompletionRequest.type);
275-
// }
276-
// } else {
277-
// registration?.then(x => x.dispose());
278-
// registration = undefined;
279-
// }
280-
}
281-
282286
connection.onCompletion(async (params, token): Promise<lsp.CompletionItem[]> => {
283-
try {
284-
const settings = config.getSettings();
285-
if (!settings?.markdown.suggest.paths.enabled) {
286-
return [];
287-
}
287+
const settings = config.getSettings();
288+
if (!settings?.markdown.suggest.paths.enabled) {
289+
return [];
290+
}
288291

289-
const document = documents.get(params.textDocument.uri);
290-
if (document) {
291-
return await ls.getCompletionItems(document, params.position, params.context!, token);
292-
}
293-
} catch (e) {
294-
console.error(e.stack);
292+
const document = documents.get(params.textDocument.uri);
293+
if (document) {
294+
return ls.getCompletionItems(document, params.position, params.context!, token);
295295
}
296296
return [];
297297
});
298298

299-
update();
300-
return config.onDidChangeConfiguration(() => update());
299+
return registerDynamicClientFeature(config, (settings) => !!settings?.markdown.suggest.paths.enabled, () => {
300+
const registrationOptions: CompletionRegistrationOptions = {
301+
documentSelector: null,
302+
triggerCharacters: ['.', '/', '#'],
303+
};
304+
return connection.client.register(CompletionRequest.type, registrationOptions);
305+
});
301306
}
302307

303-
function registerDocumentHightlightSupport(
308+
function registerDocumentHighlightSupport(
304309
connection: Connection,
305310
documents: TextDocuments<md.ITextDocument>,
306311
mdLs: md.IMdLanguageService,
@@ -319,4 +324,11 @@ function registerDocumentHightlightSupport(
319324

320325
return mdLs!.getDocumentHighlights(document, params.position, token);
321326
});
327+
328+
return registerDynamicClientFeature(configurationManager, (settings) => !!settings?.markdown.occurrencesHighlight.enabled, () => {
329+
const registrationOptions: DocumentHighlightRegistrationOptions = {
330+
documentSelector: null,
331+
};
332+
return connection.client.register(DocumentHighlightRequest.type, registrationOptions);
333+
});
322334
}

0 commit comments

Comments
 (0)