mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-24 20:26:08 +00:00
Move MD references, rename, and definition support to md LS (#155127)
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
"name": "Attach",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 7675,
|
||||
"port": 7692,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceFolder}/out/**/*.js"]
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"vscode-languageserver": "^8.0.2-next.5`",
|
||||
"vscode-languageserver-textdocument": "^1.0.5",
|
||||
"vscode-languageserver-types": "^3.17.1",
|
||||
"vscode-markdown-languageservice": "^0.0.0-alpha.5",
|
||||
"vscode-markdown-languageservice": "^0.0.0-alpha.8",
|
||||
"vscode-uri": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
24
extensions/markdown-language-features/server/src/config.ts
Normal file
24
extensions/markdown-language-features/server/src/config.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export interface LsConfiguration {
|
||||
/**
|
||||
* List of file extensions should be considered as markdown.
|
||||
*
|
||||
* These should not include the leading `.`.
|
||||
*/
|
||||
readonly markdownFileExtensions: readonly string[];
|
||||
}
|
||||
|
||||
const defaultConfig: LsConfiguration = {
|
||||
markdownFileExtensions: ['md'],
|
||||
};
|
||||
|
||||
export function getLsConfiguration(overrides: Partial<LsConfiguration>): LsConfiguration {
|
||||
return {
|
||||
...defaultConfig,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
@@ -5,13 +5,14 @@
|
||||
|
||||
import { RequestType } from 'vscode-languageserver';
|
||||
import * as md from 'vscode-markdown-languageservice';
|
||||
import * as lsp from 'vscode-languageserver-types';
|
||||
|
||||
// From server
|
||||
export const parseRequestType: RequestType<{ uri: string }, md.Token[], any> = new RequestType('markdown/parse');
|
||||
|
||||
export const readFileRequestType: RequestType<{ uri: string }, number[], any> = new RequestType('markdown/readFile');
|
||||
|
||||
export const statFileRequestType: RequestType<{ uri: string }, md.FileStat | undefined, any> = new RequestType('markdown/statFile');
|
||||
|
||||
export const readDirectoryRequestType: RequestType<{ uri: string }, [string, md.FileStat][], any> = new RequestType('markdown/readDirectory');
|
||||
|
||||
export const findFilesRequestTypes: RequestType<{}, string[], any> = new RequestType('markdown/findFiles');
|
||||
|
||||
// To server
|
||||
export const getReferencesToFileInWorkspace = new RequestType<{ uri: string }, lsp.Location[], any>('markdown/getReferencesToFileInWorkspace');
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Connection, InitializeParams, InitializeResult, NotebookDocuments, TextDocuments } from 'vscode-languageserver';
|
||||
import { CancellationToken, Connection, InitializeParams, InitializeResult, NotebookDocuments, 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 } from './config';
|
||||
import { LogFunctionLogger } from './logging';
|
||||
import { parseRequestType } from './protocol';
|
||||
import * as protocol from './protocol';
|
||||
import { VsCodeClientWorkspace } from './workspace';
|
||||
|
||||
export async function startServer(connection: Connection) {
|
||||
@@ -17,13 +18,36 @@ export async function startServer(connection: Connection) {
|
||||
const notebooks = new NotebookDocuments(documents);
|
||||
|
||||
connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
const parser = new class implements md.IMdParser {
|
||||
slugifier = md.githubSlugifier;
|
||||
|
||||
async tokenize(document: md.ITextDocument): Promise<md.Token[]> {
|
||||
return await connection.sendRequest(protocol.parseRequestType, { uri: document.uri.toString() });
|
||||
}
|
||||
};
|
||||
|
||||
const config = getLsConfiguration({
|
||||
markdownFileExtensions: params.initializationOptions.markdownFileExtensions,
|
||||
});
|
||||
|
||||
const workspace = new VsCodeClientWorkspace(connection, config, documents, notebooks);
|
||||
const logger = new LogFunctionLogger(connection.console.log.bind(connection.console));
|
||||
provider = md.createLanguageService({
|
||||
workspace,
|
||||
parser,
|
||||
logger,
|
||||
markdownFileExtensions: config.markdownFileExtensions,
|
||||
});
|
||||
|
||||
workspace.workspaceFolders = (params.workspaceFolders ?? []).map(x => URI.parse(x.uri));
|
||||
return {
|
||||
capabilities: {
|
||||
completionProvider: { triggerCharacters: ['.', '/', '#'] },
|
||||
definitionProvider: true,
|
||||
documentLinkProvider: { resolveProvider: true },
|
||||
documentSymbolProvider: true,
|
||||
completionProvider: { triggerCharacters: ['.', '/', '#'] },
|
||||
foldingRangeProvider: true,
|
||||
renameProvider: { prepareProvider: true, },
|
||||
selectionRangeProvider: true,
|
||||
workspaceSymbolProvider: true,
|
||||
workspace: {
|
||||
@@ -36,23 +60,14 @@ export async function startServer(connection: Connection) {
|
||||
};
|
||||
});
|
||||
|
||||
const parser = new class implements md.IMdParser {
|
||||
slugifier = md.githubSlugifier;
|
||||
|
||||
async tokenize(document: md.ITextDocument): Promise<md.Token[]> {
|
||||
return await connection.sendRequest(parseRequestType, { uri: document.uri.toString() });
|
||||
}
|
||||
};
|
||||
|
||||
const workspace = new VsCodeClientWorkspace(connection, documents, notebooks);
|
||||
const logger = new LogFunctionLogger(connection.console.log.bind(connection.console));
|
||||
const provider = md.createLanguageService({ workspace, parser, logger });
|
||||
let provider: md.IMdLanguageService | undefined;
|
||||
|
||||
connection.onDocumentLinks(async (params, token): Promise<lsp.DocumentLink[]> => {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider.getDocumentLinks(document, token);
|
||||
return await provider!.getDocumentLinks(document, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
@@ -62,7 +77,7 @@ export async function startServer(connection: Connection) {
|
||||
|
||||
connection.onDocumentLinkResolve(async (link, token): Promise<lsp.DocumentLink | undefined> => {
|
||||
try {
|
||||
return await provider.resolveDocumentLink(link, token);
|
||||
return await provider!.resolveDocumentLink(link, token);
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
@@ -73,7 +88,7 @@ export async function startServer(connection: Connection) {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider.getDocumentSymbols(document, token);
|
||||
return await provider!.getDocumentSymbols(document, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
@@ -85,7 +100,7 @@ export async function startServer(connection: Connection) {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider.getFoldingRanges(document, token);
|
||||
return await provider!.getFoldingRanges(document, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
@@ -97,7 +112,7 @@ export async function startServer(connection: Connection) {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider.getSelectionRanges(document, params.positions, token);
|
||||
return await provider!.getSelectionRanges(document, params.positions, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
@@ -107,7 +122,7 @@ export async function startServer(connection: Connection) {
|
||||
|
||||
connection.onWorkspaceSymbol(async (params, token): Promise<lsp.WorkspaceSymbol[]> => {
|
||||
try {
|
||||
return await provider.getWorkspaceSymbols(params.query, token);
|
||||
return await provider!.getWorkspaceSymbols(params.query, token);
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
@@ -118,7 +133,7 @@ export async function startServer(connection: Connection) {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider.getCompletionItems(document, params.position, params.context!, token);
|
||||
return await provider!.getCompletionItems(document, params.position, params.context!, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
@@ -126,6 +141,65 @@ export async function startServer(connection: Connection) {
|
||||
return [];
|
||||
});
|
||||
|
||||
connection.onReferences(async (params, token): Promise<lsp.Location[]> => {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider!.getReferences(document, params.position, params.context, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
connection.onDefinition(async (params, token): Promise<lsp.Definition | undefined> => {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider!.getDefinition(document, params.position, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
connection.onPrepareRename(async (params, token) => {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return await provider!.prepareRename(document, params.position, token);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
connection.onRenameRequest(async (params, token) => {
|
||||
try {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
const edit = await provider!.getRenameEdit(document, params.position, params.newName, token);
|
||||
console.log(JSON.stringify(edit));
|
||||
return edit;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
connection.onRequest(protocol.getReferencesToFileInWorkspace, (async (params: { uri: string }, token: CancellationToken) => {
|
||||
try {
|
||||
return await provider!.getFileReferences(URI.parse(params.uri), token);
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
||||
return undefined;
|
||||
}));
|
||||
|
||||
documents.listen(connection);
|
||||
notebooks.listen(connection);
|
||||
connection.listen();
|
||||
|
||||
@@ -4,24 +4,13 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import * as URI from 'vscode-uri';
|
||||
import { URI, Utils } from 'vscode-uri';
|
||||
import { LsConfiguration } from '../config';
|
||||
|
||||
const markdownFileExtensions = Object.freeze<string[]>([
|
||||
'.md',
|
||||
'.mkd',
|
||||
'.mdwn',
|
||||
'.mdown',
|
||||
'.markdown',
|
||||
'.markdn',
|
||||
'.mdtxt',
|
||||
'.mdtext',
|
||||
'.workbook',
|
||||
]);
|
||||
|
||||
export function looksLikeMarkdownPath(resolvedHrefPath: URI.URI) {
|
||||
return markdownFileExtensions.includes(URI.Utils.extname(URI.URI.from(resolvedHrefPath)).toLowerCase());
|
||||
export function looksLikeMarkdownPath(config: LsConfiguration, resolvedHrefPath: URI) {
|
||||
return config.markdownFileExtensions.includes(Utils.extname(URI.from(resolvedHrefPath)).toLowerCase().replace('.', ''));
|
||||
}
|
||||
|
||||
export function isMarkdownDocument(document: TextDocument): boolean {
|
||||
export function isMarkdownFile(document: TextDocument) {
|
||||
return document.languageId === 'markdown';
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import * as md from 'vscode-markdown-languageservice';
|
||||
import { ContainingDocumentContext } from 'vscode-markdown-languageservice/out/workspace';
|
||||
import { URI } from 'vscode-uri';
|
||||
import { LsConfiguration } from './config';
|
||||
import * as protocol from './protocol';
|
||||
import { coalesce } from './util/arrays';
|
||||
import { isMarkdownDocument, looksLikeMarkdownPath } from './util/file';
|
||||
import { isMarkdownFile, looksLikeMarkdownPath } from './util/file';
|
||||
import { Limiter } from './util/limiter';
|
||||
import { ResourceMap } from './util/resourceMap';
|
||||
import { Schemes } from './util/schemes';
|
||||
@@ -34,6 +35,7 @@ export class VsCodeClientWorkspace implements md.IWorkspace {
|
||||
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly config: LsConfiguration,
|
||||
private readonly documents: TextDocuments<TextDocument>,
|
||||
private readonly notebooks: NotebookDocuments<TextDocument>,
|
||||
) {
|
||||
@@ -141,7 +143,7 @@ export class VsCodeClientWorkspace implements md.IWorkspace {
|
||||
return matchingDocument;
|
||||
}
|
||||
|
||||
if (!looksLikeMarkdownPath(resource)) {
|
||||
if (!looksLikeMarkdownPath(this.config, resource)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -182,6 +184,6 @@ export class VsCodeClientWorkspace implements md.IWorkspace {
|
||||
}
|
||||
|
||||
private isRelevantMarkdownDocument(doc: TextDocument) {
|
||||
return isMarkdownDocument(doc) && URI.parse(doc.uri).scheme !== 'vscode-bulkeditpreview';
|
||||
return isMarkdownFile(doc) && URI.parse(doc.uri).scheme !== 'vscode-bulkeditpreview';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ vscode-languageserver@^8.0.2-next.5`:
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "3.17.2-next.6"
|
||||
|
||||
vscode-markdown-languageservice@^0.0.0-alpha.5:
|
||||
version "0.0.0-alpha.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.0.0-alpha.5.tgz#fb3042f3ee79589606154c19b15565541337bceb"
|
||||
integrity sha512-vy8UVa1jtm3CwkifRn3fEWM710JC4AYEECNd5KQthSCoFSfT5pOshJNFWs5yzBeVrohiy4deOdhSrfbDMg/Hyg==
|
||||
vscode-markdown-languageservice@^0.0.0-alpha.8:
|
||||
version "0.0.0-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.0.0-alpha.8.tgz#05d4f86cf0514fd71479847eef742fcc8cdbe87f"
|
||||
integrity sha512-si8weZsY4LtyonyZwxpFYk8WucRFiKJisErNTt1HDjUCglSDIZqsMNuMIcz3t0nVNfG0LrpdMFVLGhmET5D71Q==
|
||||
dependencies:
|
||||
vscode-languageserver-textdocument "^1.0.5"
|
||||
vscode-languageserver-types "^3.17.1"
|
||||
|
||||
Reference in New Issue
Block a user