Make markdown extension points dynamic

For #67574

Blocked by #67958
This commit is contained in:
Matt Bierner
2019-02-05 17:44:57 -08:00
parent 8f10101dd4
commit 038e8d3904
5 changed files with 72 additions and 11 deletions

View File

@@ -5,6 +5,8 @@
import * as vscode from 'vscode';
import * as path from 'path';
import { Disposable } from './util/dispose';
import * as arrays from './util/arrays';
const resolveExtensionResource = (extension: vscode.Extension<any>, resourcePath: string): vscode.Uri => {
return vscode.Uri.file(path.join(extension.extensionPath, resourcePath))
@@ -29,7 +31,7 @@ export interface MarkdownContributions {
readonly previewScripts: ReadonlyArray<vscode.Uri>;
readonly previewStyles: ReadonlyArray<vscode.Uri>;
readonly previewResourceRoots: ReadonlyArray<vscode.Uri>;
readonly markdownItPlugins: ReadonlyArray<Thenable<(md: any) => any>>;
readonly markdownItPlugins: Map<string, Thenable<(md: any) => any>>;
}
export namespace MarkdownContributions {
@@ -37,7 +39,7 @@ export namespace MarkdownContributions {
previewScripts: [],
previewStyles: [],
previewResourceRoots: [],
markdownItPlugins: []
markdownItPlugins: new Map()
};
export function merge(a: MarkdownContributions, b: MarkdownContributions): MarkdownContributions {
@@ -45,10 +47,21 @@ export namespace MarkdownContributions {
previewScripts: [...a.previewScripts, ...b.previewScripts],
previewStyles: [...a.previewStyles, ...b.previewStyles],
previewResourceRoots: [...a.previewResourceRoots, ...b.previewResourceRoots],
markdownItPlugins: [...a.markdownItPlugins, ...b.markdownItPlugins],
markdownItPlugins: new Map([...a.markdownItPlugins.entries(), ...b.markdownItPlugins.entries()]),
};
}
function uriEqual(a: vscode.Uri, b: vscode.Uri): boolean {
return a.toString() === b.toString();
}
export function equal(a: MarkdownContributions, b: MarkdownContributions): boolean {
return arrays.equals(a.previewScripts, b.previewScripts, uriEqual)
&& arrays.equals(a.previewStyles, b.previewStyles, uriEqual)
&& arrays.equals(a.previewResourceRoots, b.previewResourceRoots, uriEqual)
&& arrays.equals(Array.from(a.markdownItPlugins.keys()), Array.from(b.markdownItPlugins.keys()));
}
export function fromExtension(
extension: vscode.Extension<any>
): MarkdownContributions {
@@ -69,7 +82,7 @@ export namespace MarkdownContributions {
previewScripts: scripts,
previewStyles: styles,
previewResourceRoots,
markdownItPlugins: plugins ? [plugins] : []
markdownItPlugins: plugins ? new Map([[extension.id, plugins]]) : new Map()
};
}
@@ -106,23 +119,42 @@ export namespace MarkdownContributions {
export interface MarkdownContributionProvider {
readonly extensionPath: string;
readonly contributions: MarkdownContributions;
readonly onContributionsChanged: vscode.Event<this>;
}
class VSCodeExtensionMarkdownContributionProvider implements MarkdownContributionProvider {
class VSCodeExtensionMarkdownContributionProvider extends Disposable implements MarkdownContributionProvider {
private _contributions?: MarkdownContributions;
public constructor(
public readonly extensionPath: string,
) { }
) {
super();
vscode.extensions.onDidChange(() => {
const currentContributions = this.getCurrentContributions();
const existingContributions = this._contributions || MarkdownContributions.Empty;
if (!MarkdownContributions.equal(existingContributions, currentContributions)) {
this._contributions = currentContributions;
this._onContributionsChanged.fire(this);
}
}, undefined, this._disposables);
}
private readonly _onContributionsChanged = new vscode.EventEmitter<this>();
public readonly onContributionsChanged = this._onContributionsChanged.event;
public get contributions(): MarkdownContributions {
if (!this._contributions) {
this._contributions = vscode.extensions.all.reduce(
(contributions, extension) => MarkdownContributions.merge(contributions, MarkdownContributions.fromExtension(extension)),
MarkdownContributions.Empty);
this._contributions = this.getCurrentContributions();
}
return this._contributions;
}
private getCurrentContributions(): MarkdownContributions {
return vscode.extensions.all
.map(MarkdownContributions.fromExtension)
.reduce(MarkdownContributions.merge, MarkdownContributions.Empty);
}
}
export function getMarkdownExtensionContributions(context: vscode.ExtensionContext): MarkdownContributionProvider {