Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically register markdown completions and document highlights #167451

Merged
merged 1 commit into from Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -8,7 +8,7 @@ import { Disposable } from './util/dispose';

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

interface Settings {
export interface Settings {
readonly markdown: {
readonly occurrencesHighlight: {
readonly enabled: boolean;
Expand Down
80 changes: 46 additions & 34 deletions extensions/markdown-language-features/server/src/server.ts
Expand Up @@ -3,13 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

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

registerCompletionsSupport(connection, documents, mdLs, configurationManager);
registerDocumentHightlightSupport(connection, documents, mdLs, configurationManager);
registerDocumentHighlightSupport(connection, documents, mdLs, configurationManager);
registerValidateSupport(connection, workspace, documents, mdLs, configurationManager, serverConfig.logger);

return {
Expand All @@ -89,10 +89,8 @@ export async function startServer(connection: Connection, serverConfig: {
workspaceDiagnostics: false,
},
codeActionProvider: { resolveProvider: true },
completionProvider: { triggerCharacters: ['.', '/', '#'] },
definitionProvider: true,
documentLinkProvider: { resolveProvider: true },
documentHighlightProvider: true,
documentSymbolProvider: true,
foldingRangeProvider: true,
referencesProvider: true,
Expand Down Expand Up @@ -257,50 +255,57 @@ export async function startServer(connection: Connection, serverConfig: {
connection.listen();
}

function registerDynamicClientFeature(
config: ConfigurationManager,
isEnabled: (settings: Settings | undefined) => boolean,
register: () => Promise<Disposable>,
) {
let registration: Promise<IDisposable> | undefined;
function update() {
const settings = config.getSettings();
if (isEnabled(settings)) {
if (!registration) {
registration = register();
}
} else {
registration?.then(x => x.dispose());
registration = undefined;
}
}

update();
return config.onDidChangeConfiguration(() => update());
}

function registerCompletionsSupport(
connection: Connection,
documents: TextDocuments<md.ITextDocument>,
ls: md.IMdLanguageService,
config: ConfigurationManager,
): IDisposable {
// let registration: Promise<IDisposable> | undefined;
function update() {
// TODO: client still makes the request in this case. Figure our how to properly unregister.
return;
// const settings = config.getSettings();
// if (settings?.markdown.suggest.paths.enabled) {
// if (!registration) {
// registration = connection.client.register(CompletionRequest.type);
// }
// } else {
// registration?.then(x => x.dispose());
// registration = undefined;
// }
}

connection.onCompletion(async (params, token): Promise<lsp.CompletionItem[]> => {
try {
const settings = config.getSettings();
if (!settings?.markdown.suggest.paths.enabled) {
return [];
}
const settings = config.getSettings();
if (!settings?.markdown.suggest.paths.enabled) {
return [];
}

const document = documents.get(params.textDocument.uri);
if (document) {
return await ls.getCompletionItems(document, params.position, params.context!, token);
}
} catch (e) {
console.error(e.stack);
const document = documents.get(params.textDocument.uri);
if (document) {
return ls.getCompletionItems(document, params.position, params.context!, token);
}
return [];
});

update();
return config.onDidChangeConfiguration(() => update());
return registerDynamicClientFeature(config, (settings) => !!settings?.markdown.suggest.paths.enabled, () => {
const registrationOptions: CompletionRegistrationOptions = {
documentSelector: null,
triggerCharacters: ['.', '/', '#'],
};
return connection.client.register(CompletionRequest.type, registrationOptions);
});
}

function registerDocumentHightlightSupport(
function registerDocumentHighlightSupport(
connection: Connection,
documents: TextDocuments<md.ITextDocument>,
mdLs: md.IMdLanguageService,
Expand All @@ -319,4 +324,11 @@ function registerDocumentHightlightSupport(

return mdLs!.getDocumentHighlights(document, params.position, token);
});

return registerDynamicClientFeature(configurationManager, (settings) => !!settings?.markdown.occurrencesHighlight.enabled, () => {
const registrationOptions: DocumentHighlightRegistrationOptions = {
documentSelector: null,
};
return connection.client.register(DocumentHighlightRequest.type, registrationOptions);
});
}