diff --git a/src/contexts/folding_range.ts b/src/contexts/folding_range.ts index 5173925..1639432 100644 --- a/src/contexts/folding_range.ts +++ b/src/contexts/folding_range.ts @@ -23,6 +23,20 @@ export default class FoldingRangeContext { private static readonly nodeFormat = RegExp('^@(?:(node)|(subsection|unnumberedsubsec|appendixsubsec|subheading)|' + '(section|unnumberedsec|appendixsec|heading)|(chapter|unnumbered|appendix|majorheading|chapheading)) (.*)$'); + private foldingRanges?: FoldingRange[]; + + private nodes = []; + + private commentRange?: Range; + + private headerStart?: number; + + private closingChapter?: number; + + private closingSection?: number; + + private closingSubsection?: number; + /** * Get VSCode folding ranges from the context. */ @@ -38,20 +52,6 @@ export default class FoldingRangeContext { return this.nodes; } - private foldingRanges?: FoldingRange[]; - - private nodes = []; - - private commentRange?: Range; - - private headerStart?: number; - - private closingChapter?: number; - - private closingSection?: number; - - private closingSubsection?: number; - /** * Update folding range context based on document change event. * @@ -71,6 +71,8 @@ export default class FoldingRangeContext { return false; } + constructor(private readonly document: vscode.TextDocument) {} + /** * Calculate and update folding ranges for the document. * @@ -146,8 +148,6 @@ export default class FoldingRangeContext { return true; } - constructor(private readonly document: vscode.TextDocument) {} - private processNode(lineText: string, lineNum: number, lastLineNum: number) { const result = lineText.match(FoldingRangeContext.nodeFormat); if (result === null) return false; diff --git a/src/contexts/preview.ts b/src/contexts/preview.ts index 9294731..0bde310 100644 --- a/src/contexts/preview.ts +++ b/src/contexts/preview.ts @@ -64,6 +64,30 @@ export default class PreviewContext { */ private pendingUpdate = false; + private get imageTransformer(): Optional> { + if (!Options.displayImage) return undefined; + const pathName = path.dirname(this.document.fileName); + return src => { + const srcUri = vscode.Uri.file(pathName + '/' + src); + // To display images in webviews, image URIs in HTML should be converted to VSCode-recognizable ones. + return this.panel.webview.asWebviewUri(srcUri).toString(); + }; + } + + private get script() { + if (!Options.enableCodeLens) return undefined; + return "window.addEventListener('message', event => {" + + "const message = event.data;" + + "switch (message.command) {" + + "case 'goto':" + + "window.location.hash = message.value;" + + // We may want to scroll to the same node again. + "history.pushState('', '', window.location.pathname);" + + "break;" + + "}" + + "})"; + } + close() { this.disposables.forEach(event => event.dispose()); this.panel.dispose(); @@ -108,30 +132,6 @@ export default class PreviewContext { this.updateWebview(); } - private get imageTransformer(): Optional> { - if (!Options.displayImage) return undefined; - const pathName = path.dirname(this.document.fileName); - return src => { - const srcUri = vscode.Uri.file(pathName + '/' + src); - // To display images in webviews, image URIs in HTML should be converted to VSCode-recognizable ones. - return this.panel.webview.asWebviewUri(srcUri).toString(); - }; - } - - private get script() { - if (!Options.enableCodeLens) return undefined; - return "window.addEventListener('message', event => {" + - "const message = event.data;" + - "switch (message.command) {" + - "case 'goto':" + - "window.location.hash = message.value;" + - // We may want to scroll to the same node again. - "history.pushState('', '', window.location.pathname);" + - "break;" + - "}" + - "})"; - } - private updateTitle() { const updating = this.updating ? '(Updating) ' : ''; const fileName = path.basename(this.document.fileName); diff --git a/src/indicator.ts b/src/indicator.ts index 8e00734..f02994f 100644 --- a/src/indicator.ts +++ b/src/indicator.ts @@ -9,17 +9,28 @@ import * as vscode from 'vscode'; import Options from './options'; import { exec } from './utils/misc'; +/** + * Shows whether GNU Texinfo is properly installed and configured. + */ export default class Indicator implements vscode.Disposable { private static singleton?: Indicator; - private statusBarItem: vscode.StatusBarItem; - static async click() { await Indicator.instance.updateStatus(); Indicator.instance.refresh(vscode.window.activeTextEditor); } + static onTextEditorChange(editor?: vscode.TextEditor) { + Indicator.instance.refresh(editor); + } + + static get instance() { + return this.singleton ??= new Indicator(); + } + + private statusBarItem: vscode.StatusBarItem; + private refresh(editor?: vscode.TextEditor) { if (editor === undefined || editor.document.languageId != 'texinfo') { this.statusBarItem.hide(); @@ -28,7 +39,7 @@ export default class Indicator implements vscode.Disposable { } } - async updateStatus() { + private async updateStatus() { const output = await exec(Options.makeinfo, ['--version'], Options.maxSize); const result = output.data?.match(/\(GNU texinfo\) (.*)\n/); let tooltip = '', icon: string, version = ''; @@ -49,14 +60,6 @@ export default class Indicator implements vscode.Disposable { this.statusBarItem.command = 'texinfo.indicator.click'; } - static onTextEditorChange(editor?: vscode.TextEditor) { - Indicator.instance.refresh(editor); - } - - static get instance() { - return this.singleton ??= new Indicator(); - } - private constructor() { this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); this.updateStatus().then(() => this.refresh(vscode.window.activeTextEditor)); diff --git a/src/logger.ts b/src/logger.ts index 18eaf64..c7c18be 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -29,12 +29,12 @@ export default class Logger implements vscode.Disposable { private outputChannel: vscode.OutputChannel; + private constructor() { + this.outputChannel = vscode.window.createOutputChannel('Texinfo'); + } + dispose() { Logger.instance.outputChannel.dispose(); Logger.singleton = undefined; } - - private constructor() { - this.outputChannel = vscode.window.createOutputChannel('Texinfo'); - } } diff --git a/src/options.ts b/src/options.ts index 29d9e24..942c9da 100644 --- a/src/options.ts +++ b/src/options.ts @@ -74,10 +74,6 @@ export default class Options implements vscode.Disposable { private readonly configuration: vscode.WorkspaceConfiguration; - private constructor(section: string) { - this.configuration = vscode.workspace.getConfiguration(section); - } - private getString(section: string) { return this.configuration.get(section, ''); } @@ -90,6 +86,10 @@ export default class Options implements vscode.Disposable { return this.configuration.get(section, 0); } + private constructor(section: string) { + this.configuration = vscode.workspace.getConfiguration(section); + } + dispose() { Options.singleton = undefined; } diff --git a/src/utils/converter.ts b/src/utils/converter.ts index 184bf2f..530ae74 100644 --- a/src/utils/converter.ts +++ b/src/utils/converter.ts @@ -38,10 +38,7 @@ export default class Converter { constructor(private readonly path: string) {} - async convertToHtml( - imgTransformer?: Operator, - insertScript?: string, - ) { + async convertToHtml(imgTransformer?: Operator, insertScript?: string) { const options = ['-o', '-', '--no-split', '--html', `--error-limit=${Options.errorLimit}`]; Options.noHeaders && options.push('--no-headers'); Options.force && options.push('--force');