Refactor code.
This commit is contained in:
parent
ff4bac1951
commit
13415c5e39
|
@ -94,21 +94,17 @@ export class CompletionItemProvider implements vscode.CompletionItemProvider {
|
||||||
token: vscode.CancellationToken,
|
token: vscode.CancellationToken,
|
||||||
context: vscode.CompletionContext,
|
context: vscode.CompletionContext,
|
||||||
) {
|
) {
|
||||||
|
// Triggered in the middle of a word.
|
||||||
if (context.triggerKind === vscode.CompletionTriggerKind.Invoke) {
|
if (context.triggerKind === vscode.CompletionTriggerKind.Invoke) {
|
||||||
const wordRange = document.getWordRangeAtPosition(position);
|
const wordRange = document.getWordRangeAtPosition(position);
|
||||||
if (wordRange === undefined) {
|
if (wordRange === undefined) return undefined;
|
||||||
return undefined;
|
// Normalize position so that it can be treated as triggered by '@' character.
|
||||||
}
|
|
||||||
position = wordRange.start;
|
position = wordRange.start;
|
||||||
if (document.getText(new vscode.Range(position.translate(0, -1), position)) !== '@') {
|
if (document.getText(new vscode.Range(position.translate(0, -1), position)) !== '@') return undefined;
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (position.character === 1) {
|
|
||||||
return this.completionItems;
|
|
||||||
}
|
}
|
||||||
|
if (position.character === 1) return this.completionItems;
|
||||||
|
// Check whether the '@' character is escaped.
|
||||||
if (document.getText(new vscode.Range(position.translate(0, -2), position.translate(0, -1))) === '@') {
|
if (document.getText(new vscode.Range(position.translate(0, -2), position.translate(0, -1))) === '@') {
|
||||||
// The '@' character is escaped.
|
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
return this.completionItems;
|
return this.completionItems;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* document.ts
|
||||||
|
*
|
||||||
|
* @author CismonX <admin@cismon.net>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { FoldingRangeContext } from './folding';
|
||||||
|
import Preview from './preview';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages context and events for a document.
|
||||||
|
*/
|
||||||
|
export default class Document {
|
||||||
|
|
||||||
|
private static readonly map = new Map<vscode.TextDocument, Document>();
|
||||||
|
|
||||||
|
static of(document: vscode.TextDocument) {
|
||||||
|
let documentContext = Document.map.get(document);
|
||||||
|
if (documentContext === undefined) {
|
||||||
|
Document.map.set(document, documentContext = new Document(document));
|
||||||
|
}
|
||||||
|
return documentContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get(document: vscode.TextDocument) {
|
||||||
|
return document.languageId === 'texinfo' ? Document.of(document) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static update(event: vscode.TextDocumentChangeEvent) {
|
||||||
|
const documentContext = Document.get(event.document);
|
||||||
|
documentContext?.foldingRange.update(event.contentChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
static save(document: vscode.TextDocument) {
|
||||||
|
const documentContext = Document.get(document);
|
||||||
|
documentContext?.preview?.updateWebview();
|
||||||
|
}
|
||||||
|
|
||||||
|
static close(document: vscode.TextDocument) {
|
||||||
|
Document.map.get(document)?.preview?.close();
|
||||||
|
Document.map.delete(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
static clear() {
|
||||||
|
Document.map.forEach(document => document.preview?.close());
|
||||||
|
Document.map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly foldingRange = new FoldingRangeContext(this.document);
|
||||||
|
|
||||||
|
private preview?: Preview;
|
||||||
|
|
||||||
|
initPreview() {
|
||||||
|
return this.preview ??= new Preview(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
closePreview() {
|
||||||
|
this.preview = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(readonly document: vscode.TextDocument) {}
|
||||||
|
}
|
|
@ -6,20 +6,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
import Document from './document';
|
||||||
import Options from './options';
|
import Options from './options';
|
||||||
import Preview from './preview';
|
import Preview from './preview';
|
||||||
import { CompletionItemProvider } from './completion';
|
import { CompletionItemProvider } from './completion';
|
||||||
import { FoldingRangeProvider, FoldingRangeContext } from './folding';
|
import { FoldingRangeProvider } from './folding';
|
||||||
|
|
||||||
export function activate(context: vscode.ExtensionContext) {
|
export function activate(context: vscode.ExtensionContext) {
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
vscode.workspace.onDidSaveTextDocument(Preview.update),
|
vscode.workspace.onDidOpenTextDocument(Document.of),
|
||||||
vscode.workspace.onDidCloseTextDocument((document) => {
|
vscode.workspace.onDidChangeTextDocument(Document.update),
|
||||||
Preview.close(document);
|
vscode.workspace.onDidSaveTextDocument(Document.save),
|
||||||
FoldingRangeContext.close(document);
|
vscode.workspace.onDidCloseTextDocument(Document.close),
|
||||||
}),
|
|
||||||
vscode.workspace.onDidOpenTextDocument(FoldingRangeContext.open),
|
|
||||||
vscode.workspace.onDidChangeTextDocument(FoldingRangeContext.update),
|
|
||||||
vscode.commands.registerTextEditorCommand('texinfo.showPreview', Preview.show),
|
vscode.commands.registerTextEditorCommand('texinfo.showPreview', Preview.show),
|
||||||
vscode.languages.registerCompletionItemProvider('texinfo', new CompletionItemProvider(), '@'),
|
vscode.languages.registerCompletionItemProvider('texinfo', new CompletionItemProvider(), '@'),
|
||||||
vscode.languages.registerFoldingRangeProvider('texinfo', new FoldingRangeProvider()),
|
vscode.languages.registerFoldingRangeProvider('texinfo', new FoldingRangeProvider()),
|
||||||
|
@ -27,7 +25,6 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deactivate() {
|
export function deactivate() {
|
||||||
Preview.clear();
|
Document.clear();
|
||||||
Options.clear();
|
Options.clear();
|
||||||
FoldingRangeContext.clear();
|
|
||||||
}
|
}
|
||||||
|
|
137
src/folding.ts
137
src/folding.ts
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
import Document from './document';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide folding range info for Texinfo documents.
|
* Provide folding range info for Texinfo documents.
|
||||||
|
@ -13,7 +14,7 @@ import * as vscode from 'vscode';
|
||||||
export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
|
export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
|
||||||
|
|
||||||
provideFoldingRanges(document: vscode.TextDocument) {
|
provideFoldingRanges(document: vscode.TextDocument) {
|
||||||
return FoldingRangeContext.get(document).values;
|
return Document.of(document).foldingRange.values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,53 +23,6 @@ export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
|
||||||
*/
|
*/
|
||||||
export class FoldingRangeContext {
|
export class FoldingRangeContext {
|
||||||
|
|
||||||
private static readonly map = new Map<vscode.TextDocument, FoldingRangeContext>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize folding range context for a document.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
*/
|
|
||||||
static open(document: vscode.TextDocument) {
|
|
||||||
document.languageId === 'texinfo' && FoldingRangeContext.get(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get existing folding range context of a document, or create one if not exist.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
*/
|
|
||||||
static get(document: vscode.TextDocument) {
|
|
||||||
return FoldingRangeContext.map.get(document) ?? new FoldingRangeContext(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the folding range context of a document based on its change event.
|
|
||||||
*
|
|
||||||
* @param event Change event of a document.
|
|
||||||
*/
|
|
||||||
static update(event: vscode.TextDocumentChangeEvent) {
|
|
||||||
if (event.document.languageId === 'texinfo') {
|
|
||||||
FoldingRangeContext.get(event.document).update(event.contentChanges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the folding range context of a document.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
*/
|
|
||||||
static close(document: vscode.TextDocument) {
|
|
||||||
FoldingRangeContext.map.delete(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy all existing folding range contexts.
|
|
||||||
*/
|
|
||||||
static clear() {
|
|
||||||
FoldingRangeContext.map.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get VSCode folding ranges from the context.
|
* Get VSCode folding ranges from the context.
|
||||||
*/
|
*/
|
||||||
|
@ -76,14 +30,28 @@ export class FoldingRangeContext {
|
||||||
return this.foldingRanges ?? (this.foldingRanges = this.calculateFoldingRanges());
|
return this.foldingRanges ?? (this.foldingRanges = this.calculateFoldingRanges());
|
||||||
}
|
}
|
||||||
|
|
||||||
private foldingRanges?: vscode.FoldingRange[];
|
private foldingRanges?: FoldingRange[];
|
||||||
|
|
||||||
private commentRange?: { start: number, end: number };
|
private commentRange?: { start: number, end: number };
|
||||||
|
|
||||||
private headerStart?: number;
|
private headerStart?: number;
|
||||||
|
|
||||||
private constructor(private readonly document: vscode.TextDocument) {
|
/**
|
||||||
FoldingRangeContext.map.set(document, this);
|
* Update folding range context based on document change event.
|
||||||
|
*
|
||||||
|
* @param events Events describing the changes in the document.
|
||||||
|
*/
|
||||||
|
update(events: readonly vscode.TextDocumentContentChangeEvent[]) {
|
||||||
|
if (this.foldingRanges === undefined) return false;
|
||||||
|
for (const event of events) {
|
||||||
|
const updatedLines = event.text.split(this.document.eol === vscode.EndOfLine.LF ? '\n' : '\r\n').length;
|
||||||
|
// Clear cached folding range when line count changes.
|
||||||
|
if (updatedLines !== 1 || event.range.start.line !== event.range.end.line) {
|
||||||
|
this.foldingRanges = undefined;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,41 +61,34 @@ export class FoldingRangeContext {
|
||||||
* @param end Ending line number.
|
* @param end Ending line number.
|
||||||
*/
|
*/
|
||||||
private calculateFoldingRanges() {
|
private calculateFoldingRanges() {
|
||||||
|
this.foldingRanges = [];
|
||||||
this.headerStart = undefined;
|
this.headerStart = undefined;
|
||||||
const closingBlocks = <{ name: string, line: number }[]>[];
|
const closingBlocks = <{ name: string, line: number }[]>[];
|
||||||
let verbatim = false;
|
let verbatim = false;
|
||||||
for (let idx = this.document.lineCount - 1; idx >= 0; --idx) {
|
for (let idx = this.document.lineCount - 1; idx >= 0; --idx) {
|
||||||
const line = this.document.lineAt(idx).text;
|
const line = this.document.lineAt(idx).text;
|
||||||
if (!line.startsWith('@')) {
|
if (!line.startsWith('@')) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!verbatim) {
|
if (!verbatim) {
|
||||||
if (line === '@bye') {
|
if (line === '@bye') {
|
||||||
// Abort anything after `@bye`.
|
// Abort anything after `@bye`.
|
||||||
this.foldingRanges = undefined;
|
this.foldingRanges = [];
|
||||||
this.commentRange = undefined;
|
this.commentRange = undefined;
|
||||||
this.headerStart = undefined;
|
this.headerStart = undefined;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (this.processComment(line, idx)) {
|
if (this.processComment(line, idx)) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Process block.
|
// Process block.
|
||||||
if (line.startsWith('@end ')) {
|
if (line.startsWith('@end ')) {
|
||||||
if (verbatim) {
|
if (verbatim) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const name = line.substring(5);
|
const name = line.substring(5);
|
||||||
name === 'verbatim' && (verbatim = true);
|
name === 'verbatim' && (verbatim = true);
|
||||||
closingBlocks.push({ name: name, line: idx });
|
closingBlocks.push({ name: name, line: idx });
|
||||||
} else {
|
} else {
|
||||||
const closingBlock = closingBlocks.pop();
|
const closingBlock = closingBlocks.pop();
|
||||||
if (closingBlock === undefined) {
|
if (closingBlock === undefined) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (line.substring(1, closingBlock.name.length + 2).trim() === closingBlock.name) {
|
if (line.substring(1, closingBlock.name.length + 2).trim() === closingBlock.name) {
|
||||||
this.insertRange(idx, closingBlock.line);
|
this.addRange(idx, closingBlock.line, { name: closingBlock.name });
|
||||||
// If `verbatim == true` goes here, this line must be the `@verbatim` line.
|
// If `verbatim == true` goes here, this line must be the `@verbatim` line.
|
||||||
verbatim = false;
|
verbatim = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,24 +96,18 @@ export class FoldingRangeContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.commentRange !== undefined) {
|
|
||||||
this.insertRange(this.commentRange.start, this.commentRange.end, vscode.FoldingRangeKind.Comment);
|
|
||||||
this.commentRange = undefined;
|
|
||||||
}
|
|
||||||
return this.foldingRanges;
|
return this.foldingRanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
private processComment(lineText: string, lineNum: number) {
|
private processComment(lineText: string, lineNum: number) {
|
||||||
if (lineText.startsWith('@c')) {
|
if (lineText.startsWith('@c')) {
|
||||||
if (!lineText.startsWith(' ', 2) && !lineText.startsWith('omment ', 2)) {
|
if (!lineText.startsWith(' ', 2) && !lineText.startsWith('omment ', 2)) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check for opening/closing header.
|
// Check for opening/closing header.
|
||||||
if (lineText.startsWith('%**', lineText[2] === ' ' ? 3 : 9)) {
|
if (lineText.startsWith('%**', lineText[2] === ' ' ? 3 : 9)) {
|
||||||
if (this.headerStart === undefined) {
|
if (this.headerStart === undefined) {
|
||||||
this.headerStart = lineNum;
|
this.headerStart = lineNum;
|
||||||
} else {
|
} else {
|
||||||
this.insertRange(lineNum, this.headerStart);
|
this.addRange(lineNum, this.headerStart, { kind: vscode.FoldingRangeKind.Region });
|
||||||
this.headerStart = undefined;
|
this.headerStart = undefined;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -161,34 +116,28 @@ export class FoldingRangeContext {
|
||||||
this.commentRange = { start: lineNum, end: lineNum };
|
this.commentRange = { start: lineNum, end: lineNum };
|
||||||
} else if (this.commentRange.start - 1 === lineNum) {
|
} else if (this.commentRange.start - 1 === lineNum) {
|
||||||
this.commentRange.start = lineNum;
|
this.commentRange.start = lineNum;
|
||||||
} else {
|
|
||||||
this.insertRange(this.commentRange.start, this.commentRange.end, vscode.FoldingRangeKind.Comment);
|
|
||||||
this.commentRange = { start: lineNum, end: lineNum };
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (this.commentRange !== undefined) {
|
||||||
|
this.addRange(this.commentRange.start, this.commentRange.end, { kind: vscode.FoldingRangeKind.Comment });
|
||||||
|
this.commentRange = undefined;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private insertRange(start: number, end: number, kind?: vscode.FoldingRangeKind) {
|
private addRange(start: number, end: number, extraArgs: { name?: string, kind?: vscode.FoldingRangeKind }) {
|
||||||
(this.foldingRanges ?? (this.foldingRanges = [])).push(new vscode.FoldingRange(start, end, kind));
|
(this.foldingRanges ??= []).push(new FoldingRange(extraArgs.name ?? '', start, end, extraArgs.kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
constructor(private readonly document: vscode.TextDocument) {}
|
||||||
* Update folding range context based on document change event.
|
}
|
||||||
*
|
|
||||||
* @param events Events describing the changes in the document.
|
/**
|
||||||
*/
|
* VSCode folding range with name.
|
||||||
private update(events: readonly vscode.TextDocumentContentChangeEvent[]) {
|
*/
|
||||||
if (this.foldingRanges === undefined) {
|
export class FoldingRange extends vscode.FoldingRange {
|
||||||
return;
|
|
||||||
}
|
constructor(readonly name: string, start: number, end: number, kind?: vscode.FoldingRangeKind) {
|
||||||
for (const event of events) {
|
super(start, end, kind);
|
||||||
const updatedLines = event.text.split(this.document.eol === vscode.EndOfLine.LF ? '\n' : '\r\n').length;
|
|
||||||
// Clear folding range buffer when line count changes.
|
|
||||||
if (updatedLines !== 1 || event.range.start.line !== event.range.end.line) {
|
|
||||||
this.foldingRanges = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default class Options {
|
||||||
private static singleton?: Options;
|
private static singleton?: Options;
|
||||||
|
|
||||||
private static get instance() {
|
private static get instance() {
|
||||||
return Options.singleton ?? (Options.singleton = new Options('texinfo'));
|
return Options.singleton ??= new Options('texinfo');
|
||||||
}
|
}
|
||||||
|
|
||||||
static clear() {
|
static clear() {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import Converter from './converter';
|
import Converter from './converter';
|
||||||
|
import Document from './document';
|
||||||
import Options from './options';
|
import Options from './options';
|
||||||
import * as utils from './utils';
|
import * as utils from './utils';
|
||||||
|
|
||||||
|
@ -16,8 +17,6 @@ import * as utils from './utils';
|
||||||
*/
|
*/
|
||||||
export default class Preview {
|
export default class Preview {
|
||||||
|
|
||||||
private static readonly map = new Map<vscode.TextDocument, Preview>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create (if not yet created) and show preview for a Texinfo document.
|
* Create (if not yet created) and show preview for a Texinfo document.
|
||||||
*
|
*
|
||||||
|
@ -25,47 +24,18 @@ export default class Preview {
|
||||||
*/
|
*/
|
||||||
static async show(editor: vscode.TextEditor) {
|
static async show(editor: vscode.TextEditor) {
|
||||||
const document = editor.document;
|
const document = editor.document;
|
||||||
if (document.isUntitled) {
|
const documentContext = Document.get(document);
|
||||||
if (!await utils.prompt('Save this document to display preview.', 'Save')) {
|
if (documentContext === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (!await document.save()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(Preview.map.get(document) ?? new Preview(document)).panel.reveal();
|
if (document.isUntitled) {
|
||||||
|
if (!await utils.prompt('Save this document to display preview.', 'Save')) return;
|
||||||
|
if (!await document.save()) return;
|
||||||
|
}
|
||||||
|
documentContext.initPreview().panel.reveal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private readonly document = this.documentContext.document;
|
||||||
* If the document has a corresponding Texinfo preview, update the preview.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
*/
|
|
||||||
static update(document: vscode.TextDocument) {
|
|
||||||
Preview.getByDocument(document)?.updateWebview();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the document has a corresponding Texinfo preview, close the preview.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
*/
|
|
||||||
static close(document: vscode.TextDocument) {
|
|
||||||
Preview.getByDocument(document)?.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
static clear() {
|
|
||||||
Preview.map.forEach((preview) => preview.destroy());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get associated preview instance of the given document.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
*/
|
|
||||||
private static getByDocument(document: vscode.TextDocument) {
|
|
||||||
return document.languageId !== 'texinfo' ? undefined : Preview.map.get(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly panel: vscode.WebviewPanel;
|
private readonly panel: vscode.WebviewPanel;
|
||||||
|
|
||||||
|
@ -81,10 +51,9 @@ export default class Preview {
|
||||||
*/
|
*/
|
||||||
private pendingUpdate = false;
|
private pendingUpdate = false;
|
||||||
|
|
||||||
private constructor(private readonly document: vscode.TextDocument) {
|
constructor(private readonly documentContext: Document) {
|
||||||
this.panel = vscode.window.createWebviewPanel('texinfo.preview', '', vscode.ViewColumn.Beside);
|
this.panel = vscode.window.createWebviewPanel('texinfo.preview', '', vscode.ViewColumn.Beside);
|
||||||
this.disposables.push(this.panel.onDidDispose(() => this.destroy()));
|
this.disposables.push(this.panel.onDidDispose(() => this.close()));
|
||||||
Preview.map.set(document, this);
|
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,13 +63,13 @@ export default class Preview {
|
||||||
this.panel.title = `${updating}Preview ${fileName}`;
|
this.panel.title = `${updating}Preview ${fileName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private destroy() {
|
close() {
|
||||||
this.disposables.forEach((event) => event.dispose());
|
this.disposables.forEach(event => event.dispose());
|
||||||
this.panel.dispose();
|
this.panel.dispose();
|
||||||
Preview.map.delete(this.document);
|
this.documentContext.closePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateWebview() {
|
async updateWebview() {
|
||||||
if (this.updating) {
|
if (this.updating) {
|
||||||
this.pendingUpdate = true;
|
this.pendingUpdate = true;
|
||||||
return;
|
return;
|
||||||
|
@ -116,7 +85,7 @@ export default class Preview {
|
||||||
if (Options.displayImage) {
|
if (Options.displayImage) {
|
||||||
const pathName = path.dirname(this.document.fileName);
|
const pathName = path.dirname(this.document.fileName);
|
||||||
// To display images in webviews, image URIs in HTML should be converted to VSCode-recognizable ones.
|
// To display images in webviews, image URIs in HTML should be converted to VSCode-recognizable ones.
|
||||||
htmlCode = utils.transformHtmlImageUri(htmlCode, (src) => {
|
htmlCode = utils.transformHtmlImageUri(htmlCode, src => {
|
||||||
const srcUri = vscode.Uri.file(pathName + '/' + src);
|
const srcUri = vscode.Uri.file(pathName + '/' + src);
|
||||||
return this.panel.webview.asWebviewUri(srcUri).toString();
|
return this.panel.webview.asWebviewUri(srcUri).toString();
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,7 @@ export async function prompt(message: string, confirm: string) {
|
||||||
* @returns The output data, or `undefined` if execution fails.
|
* @returns The output data, or `undefined` if execution fails.
|
||||||
*/
|
*/
|
||||||
export function exec(path: string, args: string[], maxBuffer: number) {
|
export function exec(path: string, args: string[], maxBuffer: number) {
|
||||||
return new Promise<string | undefined>((resolve) => {
|
return new Promise<string | undefined>(resolve => {
|
||||||
child_process.execFile(path, args, { maxBuffer: maxBuffer }, (error, stdout, stderr) => {
|
child_process.execFile(path, args, { maxBuffer: maxBuffer }, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(stderr ? stderr : error);
|
console.error(stderr ? stderr : error);
|
||||||
|
@ -52,7 +52,7 @@ export function exec(path: string, args: string[], maxBuffer: number) {
|
||||||
export function transformHtmlImageUri(htmlCode: string, transformer: (src: string) => string) {
|
export function transformHtmlImageUri(htmlCode: string, transformer: (src: string) => string) {
|
||||||
const dom = htmlparser.parse(htmlCode);
|
const dom = htmlparser.parse(htmlCode);
|
||||||
const elements = dom.querySelectorAll('img');
|
const elements = dom.querySelectorAll('img');
|
||||||
elements.forEach((element) => {
|
elements.forEach(element => {
|
||||||
const src = element.getAttribute('src');
|
const src = element.getAttribute('src');
|
||||||
src && element.setAttribute('src', transformer(src));
|
src && element.setAttribute('src', transformer(src));
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue