Skip to content

Commit 5d5ea15

Browse files
authored
Allow passing in custom workspace/parser to markdown server (microsoft#160429)
For microsoft#159805 This splits the markdown server into two main functions: - `startVsCodeServer` which assumes the client can implement all the functionality of VS Code. It is not specific to VS Code however, the client just need to implement the custom messages that VS Code does - `startServer` which lets you pass in your own implementation of the parser and workspace. A consumer of the server can then use this to have their own custom server implementation, which might use normal node apis to read files
1 parent a844e8a commit 5d5ea15

File tree

5 files changed

+49
-26
lines changed

5 files changed

+49
-26
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { BrowserMessageReader, BrowserMessageWriter, createConnection } from 'vscode-languageserver/browser';
7-
import { startServer } from '../server';
7+
import { startVsCodeServer } from '../server';
88

99
declare let self: any;
1010

@@ -13,4 +13,4 @@ const messageWriter = new BrowserMessageWriter(self);
1313

1414
const connection = createConnection(messageReader, messageWriter);
1515

16-
startServer(connection);
16+
startVsCodeServer(connection);

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { disposeAll } from 'vscode-markdown-languageservice/out/util/dispose';
99
import { Disposable } from 'vscode-notebook-renderer/events';
1010
import { URI } from 'vscode-uri';
1111
import { ConfigurationManager, ValidateEnabled } from '../configuration';
12-
import { VsCodeClientWorkspace } from '../workspace';
1312

1413
const defaultDiagnosticOptions: md.DiagnosticOptions = {
1514
validateFileLinks: md.DiagnosticLevel.ignore,
@@ -45,7 +44,7 @@ function getDiagnosticsOptions(config: ConfigurationManager): md.DiagnosticOptio
4544

4645
export function registerValidateSupport(
4746
connection: Connection,
48-
workspace: VsCodeClientWorkspace,
47+
workspace: md.IWorkspace,
4948
ls: md.IMdLanguageService,
5049
config: ConfigurationManager,
5150
logger: md.ILogger,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Connection, createConnection } from 'vscode-languageserver/node';
7-
import { startServer } from '../server';
7+
import { startVsCodeServer } from '../server';
88

99
// Create a connection for the server.
1010
const connection: Connection = createConnection();
@@ -16,4 +16,4 @@ process.on('unhandledRejection', (e: any) => {
1616
connection.console.error(`Unhandled exception ${e}`);
1717
});
1818

19-
startServer(connection);
19+
startVsCodeServer(connection);

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

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,65 @@ const localize = nls.loadMessageBundle();
2222
interface MdServerInitializationOptions extends LsConfiguration { }
2323

2424
const organizeLinkDefKind = 'source.organizeLinkDefinitions';
25-
export async function startServer(connection: Connection) {
25+
26+
export async function startVsCodeServer(connection: Connection) {
27+
const logger = new LogFunctionLogger(connection.console.log.bind(connection.console));
28+
29+
const parser = new class implements md.IMdParser {
30+
slugifier = md.githubSlugifier;
31+
32+
tokenize(document: md.ITextDocument): Promise<md.Token[]> {
33+
return connection.sendRequest(protocol.parse, { uri: document.uri.toString() });
34+
}
35+
};
36+
2637
const documents = new TextDocuments(TextDocument);
2738
const notebooks = new NotebookDocuments(documents);
2839

29-
const configurationManager = new ConfigurationManager(connection);
40+
const workspaceFactory: WorkspaceFactory = ({ connection, config, workspaceFolders }) => {
41+
const workspace = new VsCodeClientWorkspace(connection, config, documents, notebooks, logger);
42+
workspace.workspaceFolders = (workspaceFolders ?? []).map(x => URI.parse(x.uri));
43+
return workspace;
44+
};
3045

31-
let mdLs: md.IMdLanguageService | undefined;
32-
let workspace: VsCodeClientWorkspace | undefined;
46+
return startServer(connection, { documents, notebooks, logger, parser, workspaceFactory });
47+
}
3348

34-
connection.onInitialize((params: InitializeParams): InitializeResult => {
35-
const parser = new class implements md.IMdParser {
36-
slugifier = md.githubSlugifier;
49+
type WorkspaceFactory = (config: {
50+
connection: Connection;
51+
config: LsConfiguration;
52+
workspaceFolders?: lsp.WorkspaceFolder[] | null;
53+
}) => md.IWorkspace;
54+
55+
export async function startServer(connection: Connection, serverConfig: {
56+
documents: TextDocuments<md.ITextDocument>;
57+
notebooks?: NotebookDocuments<md.ITextDocument>;
58+
logger: md.ILogger;
59+
parser: md.IMdParser;
60+
workspaceFactory: WorkspaceFactory;
61+
}) {
62+
const { documents, notebooks } = serverConfig;
3763

38-
async tokenize(document: md.ITextDocument): Promise<md.Token[]> {
39-
return await connection.sendRequest(protocol.parse, { uri: document.uri.toString() });
40-
}
41-
};
64+
let mdLs: md.IMdLanguageService | undefined;
4265

66+
connection.onInitialize((params: InitializeParams): InitializeResult => {
4367
const initOptions = params.initializationOptions as MdServerInitializationOptions | undefined;
4468
const config = getLsConfiguration(initOptions ?? {});
4569

46-
const logger = new LogFunctionLogger(connection.console.log.bind(connection.console));
47-
workspace = new VsCodeClientWorkspace(connection, config, documents, notebooks, logger);
70+
const configurationManager = new ConfigurationManager(connection);
71+
72+
const workspace = serverConfig.workspaceFactory({ connection, config, workspaceFolders: params.workspaceFolders });
4873
mdLs = md.createLanguageService({
4974
workspace,
50-
parser,
51-
logger,
75+
parser: serverConfig.parser,
76+
logger: serverConfig.logger,
5277
markdownFileExtensions: config.markdownFileExtensions,
5378
excludePaths: config.excludePaths,
5479
});
5580

5681
registerCompletionsSupport(connection, documents, mdLs, configurationManager);
57-
registerValidateSupport(connection, workspace, mdLs, configurationManager, logger);
82+
registerValidateSupport(connection, workspace, mdLs, configurationManager, serverConfig.logger);
5883

59-
workspace.workspaceFolders = (params.workspaceFolders ?? []).map(x => URI.parse(x.uri));
6084
return {
6185
capabilities: {
6286
diagnosticProvider: {
@@ -212,14 +236,14 @@ export async function startServer(connection: Connection) {
212236
}));
213237

214238
documents.listen(connection);
215-
notebooks.listen(connection);
239+
notebooks?.listen(connection);
216240
connection.listen();
217241
}
218242

219243

220244
function registerCompletionsSupport(
221245
connection: Connection,
222-
documents: TextDocuments<TextDocument>,
246+
documents: TextDocuments<md.ITextDocument>,
223247
ls: md.IMdLanguageService,
224248
config: ConfigurationManager,
225249
): IDisposable {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { URI, Utils } from 'vscode-uri';
88
import { LsConfiguration } from '../config';
99

1010
export function looksLikeMarkdownPath(config: LsConfiguration, resolvedHrefPath: URI) {
11-
return config.markdownFileExtensions.includes(Utils.extname(URI.from(resolvedHrefPath)).toLowerCase().replace('.', ''));
11+
return config.markdownFileExtensions.includes(Utils.extname(resolvedHrefPath).toLowerCase().replace('.', ''));
1212
}
1313

1414
export function isMarkdownFile(document: TextDocument) {

0 commit comments

Comments
 (0)