Extract workspaceContents to own file

This commit is contained in:
Matt Bierner
2022-03-29 14:52:38 -07:00
parent 2783263582
commit 3ce5c78cb9
8 changed files with 175 additions and 145 deletions

View File

@@ -5,7 +5,8 @@
import * as vscode from 'vscode';
import { MarkdownEngine } from '../markdownEngine';
import { SkinnyTextDocument, TableOfContents, TocEntry } from '../tableOfContentsProvider';
import { TableOfContents, TocEntry } from '../tableOfContentsProvider';
import { SkinnyTextDocument } from '../workspaceContents';
interface MarkdownSymbol {
readonly level: number;

View File

@@ -4,129 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { SkinnyTextDocument, SkinnyTextLine } from '../tableOfContentsProvider';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { Lazy, lazy } from '../util/lazy';
import { SkinnyTextDocument, MdWorkspaceContents } from '../workspaceContents';
import { MdDocumentSymbolProvider } from './documentSymbolProvider';
export interface WorkspaceMarkdownDocumentProvider {
getAllMarkdownDocuments(): Thenable<Iterable<SkinnyTextDocument>>;
readonly onDidChangeMarkdownDocument: vscode.Event<SkinnyTextDocument>;
readonly onDidCreateMarkdownDocument: vscode.Event<SkinnyTextDocument>;
readonly onDidDeleteMarkdownDocument: vscode.Event<vscode.Uri>;
}
class VSCodeWorkspaceMarkdownDocumentProvider extends Disposable implements WorkspaceMarkdownDocumentProvider {
private readonly _onDidChangeMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<SkinnyTextDocument>());
private readonly _onDidCreateMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<SkinnyTextDocument>());
private readonly _onDidDeleteMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<vscode.Uri>());
private _watcher: vscode.FileSystemWatcher | undefined;
private readonly utf8Decoder = new TextDecoder('utf-8');
/**
* Reads and parses all .md documents in the workspace.
* Files are processed in batches, to keep the number of open files small.
*
* @returns Array of processed .md files.
*/
async getAllMarkdownDocuments(): Promise<SkinnyTextDocument[]> {
const maxConcurrent = 20;
const docList: SkinnyTextDocument[] = [];
const resources = await vscode.workspace.findFiles('**/*.md', '**/node_modules/**');
for (let i = 0; i < resources.length; i += maxConcurrent) {
const resourceBatch = resources.slice(i, i + maxConcurrent);
const documentBatch = (await Promise.all(resourceBatch.map(x => this.getMarkdownDocument(x)))).filter((doc) => !!doc) as SkinnyTextDocument[];
docList.push(...documentBatch);
}
return docList;
}
public get onDidChangeMarkdownDocument() {
this.ensureWatcher();
return this._onDidChangeMarkdownDocumentEmitter.event;
}
public get onDidCreateMarkdownDocument() {
this.ensureWatcher();
return this._onDidCreateMarkdownDocumentEmitter.event;
}
public get onDidDeleteMarkdownDocument() {
this.ensureWatcher();
return this._onDidDeleteMarkdownDocumentEmitter.event;
}
private ensureWatcher(): void {
if (this._watcher) {
return;
}
this._watcher = this._register(vscode.workspace.createFileSystemWatcher('**/*.md'));
this._register(this._watcher.onDidChange(async resource => {
const document = await this.getMarkdownDocument(resource);
if (document) {
this._onDidChangeMarkdownDocumentEmitter.fire(document);
}
}));
this._register(this._watcher.onDidCreate(async resource => {
const document = await this.getMarkdownDocument(resource);
if (document) {
this._onDidCreateMarkdownDocumentEmitter.fire(document);
}
}));
this._register(this._watcher.onDidDelete(resource => {
this._onDidDeleteMarkdownDocumentEmitter.fire(resource);
}));
this._register(vscode.workspace.onDidChangeTextDocument(e => {
if (isMarkdownFile(e.document)) {
this._onDidChangeMarkdownDocumentEmitter.fire(e.document);
}
}));
}
private async getMarkdownDocument(resource: vscode.Uri): Promise<SkinnyTextDocument | undefined> {
const matchingDocument = vscode.workspace.textDocuments.find((doc) => doc.uri.toString() === resource.toString());
if (matchingDocument) {
return matchingDocument;
}
const bytes = await vscode.workspace.fs.readFile(resource);
// We assume that markdown is in UTF-8
const text = this.utf8Decoder.decode(bytes);
const lines: SkinnyTextLine[] = [];
const parts = text.split(/(\r?\n)/);
const lineCount = Math.floor(parts.length / 2) + 1;
for (let line = 0; line < lineCount; line++) {
lines.push({
text: parts[line * 2]
});
}
return {
uri: resource,
version: 0,
lineCount: lineCount,
lineAt: (index) => {
return lines[index];
},
getText: () => {
return text;
}
};
}
}
export class MdWorkspaceSymbolProvider extends Disposable implements vscode.WorkspaceSymbolProvider {
@@ -135,7 +17,7 @@ export class MdWorkspaceSymbolProvider extends Disposable implements vscode.Work
public constructor(
private _symbolProvider: MdDocumentSymbolProvider,
private _workspaceMarkdownDocumentProvider: WorkspaceMarkdownDocumentProvider = new VSCodeWorkspaceMarkdownDocumentProvider()
private _workspaceMarkdownDocumentProvider: MdWorkspaceContents,
) {
super();
}