From 3ecb2a5b037a27967d80e4225f208d41b9e87815 Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 12 Aug 2021 01:23:04 +0800 Subject: [PATCH] Refactor code. --- src/context_mapping.ts | 4 +-- src/contexts/document.ts | 4 +-- src/contexts/document_symbol.ts | 19 ++++++----- src/contexts/folding_range.ts | 27 +++++++++++----- src/contexts/preview.ts | 26 +++++++++------ src/diagnosis.ts | 13 +++++--- src/global_context.ts | 43 ++++++++++++++++--------- src/indicator.ts | 23 ++++++++------ src/logger.ts | 10 +++--- src/options.ts | 4 +-- src/providers/code_lens.ts | 16 ++++++---- src/providers/completion_item.ts | 54 ++++++++++++++------------------ src/providers/document_symbol.ts | 4 +-- src/providers/folding_range.ts | 4 +-- src/utils/converter.ts | 11 ++++--- src/utils/misc.ts | 5 +-- 16 files changed, 156 insertions(+), 111 deletions(-) diff --git a/src/context_mapping.ts b/src/context_mapping.ts index 368708c..b446b98 100644 --- a/src/context_mapping.ts +++ b/src/context_mapping.ts @@ -28,8 +28,8 @@ import { prompt } from './utils/misc'; * Manage mappings between Texinfo documents and corresponding * document-specific contexts. */ -export default class ContextMapping implements vscode.Disposable { - +export default class ContextMapping implements vscode.Disposable +{ /** * Get context of a Texinfo document. Create one if not exists. * diff --git a/src/contexts/document.ts b/src/contexts/document.ts index 8a6b91a..03cf39b 100644 --- a/src/contexts/document.ts +++ b/src/contexts/document.ts @@ -28,8 +28,8 @@ import PreviewContext from './preview'; /** * Holds all contexts for a Texinfo document. */ -export default class DocumentContext { - +export default class DocumentContext +{ readonly foldingRange = new FoldingRangeContext(this); readonly documentSymbol = new DocumentSymbolContext(this); diff --git a/src/contexts/document_symbol.ts b/src/contexts/document_symbol.ts index bd730e2..a92f7c1 100644 --- a/src/contexts/document_symbol.ts +++ b/src/contexts/document_symbol.ts @@ -27,8 +27,8 @@ import { FoldingRange, Optional } from '../utils/types'; /** * Context for symbols in a Texinfo document. */ -export default class DocumentSymbolContext { - +export default class DocumentSymbolContext +{ get documentSymbols() { return this._documentSymbols ??= this._calculcateDocumentSymbols(); } @@ -63,11 +63,16 @@ function foldingRangeToSymbols( const symbols = []; for (let idx = start; idx < end; ++idx) { const node = ranges[idx]; - if (node === undefined) continue; - const range = lineNumToRange(idx, node.end); - const selectionRange = lineNumToRange(idx); - const symbol = new vscode.DocumentSymbol('@' + node.name, node.detail, - vscode.SymbolKind.String, range, selectionRange); + if (node === undefined) { + continue; + } + const symbol = new vscode.DocumentSymbol( + '@' + node.name, + node.detail, + vscode.SymbolKind.String, + lineNumToRange(idx, node.end), // full range + lineNumToRange(idx), // selection range + ); symbol.children = foldingRangeToSymbols(ranges, idx + 1, node.end); symbols.push(symbol); idx = node.end; diff --git a/src/contexts/folding_range.ts b/src/contexts/folding_range.ts index 7da9710..9023c29 100644 --- a/src/contexts/folding_range.ts +++ b/src/contexts/folding_range.ts @@ -30,8 +30,8 @@ import DocumentContext from './document'; * Actually, more than folding ranges (e.g. code lens) is handled within * this context, so perhaps we should use another name... */ -export default class FoldingRangeContext { - +export default class FoldingRangeContext +{ /** * Get VSCode folding ranges from the context. */ @@ -129,7 +129,9 @@ export default class FoldingRangeContext { let verbatim = false; for (let idx = lastLine; idx >= 0; --idx) { const line = this._document.lineAt(idx).text.trimLeft(); - if (!line.startsWith('@')) continue; + if (!line.startsWith('@')) { + continue; + } if (!verbatim) { if (line === '@bye') { lastLine = idx; @@ -139,7 +141,9 @@ export default class FoldingRangeContext { this._clearTemporaries(); continue; } - if (this._processComment(line, idx)) continue; + if (this._processComment(line, idx)) { + continue; + } } // Process block. if (line.startsWith('@end ')) { @@ -151,9 +155,13 @@ export default class FoldingRangeContext { closingBlocks.push({ name: name, line: idx }); continue; } - if (!verbatim && this._processNode(line, idx, lastLine)) continue; + if (!verbatim && this._processNode(line, idx, lastLine)) { + continue; + } const closingBlock = closingBlocks.pop(); - if (closingBlock === undefined) continue; + if (closingBlock === undefined) { + continue; + } const name = closingBlock.name; if (line.substring(1, name.length + 2).trim() === name) { this._addRange(idx, closingBlock.line, { name: name }); @@ -165,8 +173,11 @@ export default class FoldingRangeContext { } } if (this._commentRange !== undefined) { - this._addRange(this._commentRange.start, this._commentRange.end, - { kind: vscode.FoldingRangeKind.Comment }); + this._addRange( + this._commentRange.start, + this._commentRange.end, + { kind: vscode.FoldingRangeKind.Comment }, + ); } return this._foldingRanges; } diff --git a/src/contexts/preview.ts b/src/contexts/preview.ts index 4bd2dbb..514bc5b 100644 --- a/src/contexts/preview.ts +++ b/src/contexts/preview.ts @@ -28,8 +28,8 @@ import { getNodeHtmlRef, prompt } from '../utils/misc'; /** * Stores information of a Texinfo document preview. */ -export default class PreviewContext { - +export default class PreviewContext +{ close() { this._disposables.forEach(event => event.dispose()); this._panel.dispose(); @@ -57,11 +57,16 @@ export default class PreviewContext { // Inform the user that the preview is updating, when `makeinfo` // takes too long. setTimeout(() => this._updating && this._updateTitle(), 500); - const initFile = this._globalContext.path + '/ext/html-preview.pm'; - const converter = new Converter(this._document.fileName, initFile, - this._globalContext.options, this._logger); - const { data, error } = await converter - .toHTML(path => this._webview.asWebviewUri(path), this._script); + const converter = new Converter( + this._document.fileName, + this._globalContext.path + '/ext/html-preview.pm', + this._globalContext.options, + this._logger, + ); + const { data, error } = await converter.toHTML( + path => this._webview.asWebviewUri(path), + this._script, + ); if (error) { this._logger.log(error); this._diagnosis.update(this._document, error); @@ -86,8 +91,11 @@ export default class PreviewContext { retainContextWhenHidden: true, enableScripts: true, }; - this._panel = vscode.window.createWebviewPanel('texinfo.preview', '', - vscode.ViewColumn.Beside, options); + this._panel = vscode.window.createWebviewPanel( + 'texinfo.preview', '', + vscode.ViewColumn.Beside, + options, + ); this._webview = this._panel.webview; this._disposables.push(this._panel.onDidDispose(() => this.close())); this._updateTitle(); diff --git a/src/diagnosis.ts b/src/diagnosis.ts index 80b5698..7172adf 100644 --- a/src/diagnosis.ts +++ b/src/diagnosis.ts @@ -26,8 +26,8 @@ import { isDefined } from './utils/types'; /** * Manage diagnostic information of Texinfo documents. */ -export default class Diagnosis implements vscode.Disposable { - +export default class Diagnosis implements vscode.Disposable +{ /** * Remove a document's diagnostic entry from the collection. * @@ -68,10 +68,13 @@ export default class Diagnosis implements vscode.Disposable { */ function logToDiagnostic(lineText: string) { const lineNum = parseInt(lineText) - 1; - // Ignore error that does not correspond a line in document. - if (isNaN(lineNum)) return undefined; + // Ignore error that does not correspond to a line in document. + if (isNaN(lineNum)) { + return undefined; + } const message = lineText.substring(lineNum.toString().length + 2); const severity = message.startsWith('warning:') - ? vscode.DiagnosticSeverity.Warning : undefined; + ? vscode.DiagnosticSeverity.Warning + : undefined; return new vscode.Diagnostic(lineNumToRange(lineNum), message, severity); } diff --git a/src/global_context.ts b/src/global_context.ts index 1228627..6c9064e 100644 --- a/src/global_context.ts +++ b/src/global_context.ts @@ -33,14 +33,14 @@ import FoldingRangeProvider from './providers/folding_range'; /** * Manage extension-level global-scope contexts. */ -export default class GlobalContext { - +export default class GlobalContext +{ readonly contextMapping = new ContextMapping(this); readonly diagnosis = new Diagnosis; readonly indicator = new Indicator(this); readonly logger = new Logger; - readonly path = this.context.extensionPath; + readonly path = this._context.extensionPath; /** * Note: `Options`' no singleton. @@ -52,22 +52,35 @@ export default class GlobalContext { } subscribe(...items: vscode.Disposable[]) { - this.context.subscriptions.push(...items); + this._context.subscriptions.push(...items); } - constructor(private readonly context: vscode.ExtensionContext) { + constructor(private readonly _context: vscode.ExtensionContext) { this.subscribe( - this.contextMapping, this.diagnosis, this.indicator, this.logger, - vscode.languages.registerCodeLensProvider('texinfo', - new CodeLensProvider(this)), - vscode.languages.registerCompletionItemProvider('texinfo', - new CompletionItemProvider(this), '@'), - vscode.languages.registerDocumentSymbolProvider('texinfo', - new DocumentSymbolProvider(this)), - vscode.languages.registerFoldingRangeProvider('texinfo', - new FoldingRangeProvider(this)), + this.contextMapping, + this.diagnosis, + this.indicator, + this.logger, + vscode.languages.registerCodeLensProvider( + 'texinfo', + new CodeLensProvider(this), + ), + vscode.languages.registerCompletionItemProvider( + 'texinfo', + new CompletionItemProvider(this), + '@', + ), + vscode.languages.registerDocumentSymbolProvider( + 'texinfo', + new DocumentSymbolProvider(this), + ), + vscode.languages.registerFoldingRangeProvider( + 'texinfo', + new FoldingRangeProvider(this), + ), vscode.workspace.onDidChangeConfiguration( - () => this._options = undefined), + () => this._options = undefined, + ), ); } diff --git a/src/indicator.ts b/src/indicator.ts index ed8ee39..35f0b28 100644 --- a/src/indicator.ts +++ b/src/indicator.ts @@ -26,8 +26,8 @@ import { exec } from './utils/misc'; /** * Shows whether GNU Texinfo is properly installed and configured. */ -export default class Indicator implements vscode.Disposable { - +export default class Indicator implements vscode.Disposable +{ get canDisplayPreview() { return this._canDisplayPreview; } @@ -36,12 +36,15 @@ export default class Indicator implements vscode.Disposable { this._statusBarItem.dispose(); } - constructor(private readonly globalContext: GlobalContext) { - globalContext.subscribe( - vscode.commands.registerCommand('texinfo.indicator.click', - this._click.bind(this)), + constructor(private readonly _globalContext: GlobalContext) { + _globalContext.subscribe( + vscode.commands.registerCommand( + 'texinfo.indicator.click', + this._click.bind(this), + ), vscode.window.onDidChangeActiveTextEditor( - this._refresh.bind(this)), + this._refresh.bind(this), + ), ); this._updateStatus() .then(() => this._refresh(vscode.window.activeTextEditor)); @@ -78,9 +81,9 @@ export default class Indicator implements vscode.Disposable { * by checking `makeinfo --version`. */ private async _updateStatus() { - const options = this.globalContext.options; - const output = await exec(options.makeinfo, ['--version'], - options.maxSize); + const options = this._globalContext.options; + const output + = await exec(options.makeinfo, ['--version'], options.maxSize); const result = output.data?.match(/\(GNU texinfo\) (.*)\n/); let tooltip = '', icon: string, version = ''; if (result && result[1]) { diff --git a/src/logger.ts b/src/logger.ts index 6c43abe..d2c9151 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -24,11 +24,13 @@ import * as vscode from 'vscode'; /** * Logger which prints message to VSCode output channel. */ -export default class Logger implements vscode.Disposable { - +export default class Logger implements vscode.Disposable +{ log(message: string) { - const dateTime = new Date() - .toLocaleString(undefined, { hour12: false }); + const dateTime = new Date().toLocaleString( + undefined, + { hour12: false } + ); this._outputChannel.appendLine(`[ ${dateTime} ]\n${message}`); } diff --git a/src/options.ts b/src/options.ts index cb181cc..565c475 100644 --- a/src/options.ts +++ b/src/options.ts @@ -26,8 +26,8 @@ import * as vscode from 'vscode'; * * See the `contributes.configuration` entry in package.json for details. */ -export default class Options { - +export default class Options +{ get enableSnippets() { return this._getBoolean('completion.enableSnippets'); } diff --git a/src/providers/code_lens.ts b/src/providers/code_lens.ts index bf39c52..420ae35 100644 --- a/src/providers/code_lens.ts +++ b/src/providers/code_lens.ts @@ -25,13 +25,17 @@ import GlobalContext from '../global_context'; /** * Provide code lenses for Texinfo document. */ -export default class CodeLensProvider implements vscode.CodeLensProvider { - +export default class CodeLensProvider implements vscode.CodeLensProvider +{ provideCodeLenses(document: vscode.TextDocument) { - if (!this._globalContext.options.enableCodeLens) return undefined; - if (!this._globalContext.indicator.canDisplayPreview) return undefined; - return this._globalContext.contextMapping.getDocumentContext(document) - .foldingRange.nodeValues; + if (!this._globalContext.options.enableCodeLens) { + return undefined; + } + if (!this._globalContext.indicator.canDisplayPreview) { + return undefined; + } + return this._globalContext.contextMapping + .getDocumentContext(document).foldingRange.nodeValues; } constructor(private readonly _globalContext: GlobalContext) {} diff --git a/src/providers/completion_item.ts b/src/providers/completion_item.ts index a4390b7..277fc1b 100644 --- a/src/providers/completion_item.ts +++ b/src/providers/completion_item.ts @@ -32,15 +32,16 @@ export default class CompletionItemProvider /** * Full list of completion items. * - * Note: Descriptions of completion items for @-commands are excerpted from - * the GNU Texinfo manual - * ({@link https://www.gnu.org/software/texinfo/manual/texinfo }), - * which is licensed under the GNU Free Documentation License, version 1.3. + * Note: Descriptions of completion items for @-commands + * are excerpted from the [GNU Texinfo manual], which is licensed under the + * GNU Free Documentation License, version 1.3. * * According to GFDL, this usage is considered "aggregation with - * independent work", which means that GFDL applies to lines 48-367 of this - * file, while the remainder is under GPL like other source code files of - * the project. + * independent work", which means that GFDL applies to lines 50-1117 of + * this file, while the remainder is under GPL like other source code files + * of the project. + * + * [GNU Texinfo manual]: https://gnu.org/software/texinfo/manual/texinfo */ private _getCompletionItems() { const enableSnippets = this._oldOptions.enableSnippets; @@ -159,10 +160,6 @@ export default class CompletionItemProvider 'Center the line of text following the command', 'text-line', ), - ...lineCommand('centerchap', - 'Like @chapter, but centers the chapter title', - 'text-line', - ), ...lineCommand('chapheading', 'Print an unnumbered chapter-like heading', 'title', @@ -245,11 +242,6 @@ export default class CompletionItemProvider 'Define a new index, print entries in a roman font', 'index-name', ), - ...lineCommand('definfoenclose', - 'Create a new command for Info that marks text by enclosing ' + - 'it in strings that precede and follow the text.', - 'newcmd', 'before', 'after', - ), ...lineCommandX('defivar', 'Format a description for an instance variable ' + 'in object-oriented programming', @@ -612,10 +604,6 @@ export default class CompletionItemProvider 'Indicate text that is a URL', 1, 'URL', ), - ...braceCommand('inforef', - 'Make a cross-reference to an Info file', - 3, 'node-name', 'entry-name', 'info-file-name', - ), ...braceCommand('inlinefmt', 'Insert text only if the output format is fmt', 2, 'fmt', 'text', @@ -820,10 +808,6 @@ export default class CompletionItemProvider 'any special text', 1, 'node', 'entry', 'node-title', 'info-node', 'manual', ), - command('refill', - 'Refill and indent the paragraph after all the ' + - 'other processing has been done', - ), command('registeredsymbol', 'Generate the legal symbol, "®"', { hasEmptyBrace: true }, @@ -1153,12 +1137,18 @@ export default class CompletionItemProvider // Triggered in the middle of a word. if (context.triggerKind === vscode.CompletionTriggerKind.Invoke) { const wordRange = document.getWordRangeAtPosition(position); - if (wordRange === undefined) return undefined; + if (wordRange === undefined) { + return undefined; + } // Normalize position so that it can be treated as // triggered by '@' character. - position = wordRange.start; - const pos = new vscode.Range(position.translate(0, -1), position); - if (document.getText(pos) !== '@') return undefined; + const charBeforeWord = new vscode.Range( + wordRange.start.translate(0, -1), + wordRange.start, + ); + if (document.getText(charBeforeWord) !== '@') { + return undefined; + } } // Check whether options has changed. const newOptions = this._globalContext.options; @@ -1168,9 +1158,11 @@ export default class CompletionItemProvider } if (position.character === 1) return this._getCompletionItems(); // Check whether the '@' character is escaped. - const pos = new vscode.Range( - position.translate(0, -2), position.translate(0, -1)); - if (document.getText(pos) === '@') { + const secondCharBeforeWord = new vscode.Range( + position.translate(0, -2), + position.translate(0, -1) + ); + if (document.getText(secondCharBeforeWord) === '@') { return undefined; } else { return this._getCompletionItems(); diff --git a/src/providers/document_symbol.ts b/src/providers/document_symbol.ts index ce94642..f3ca4cb 100644 --- a/src/providers/document_symbol.ts +++ b/src/providers/document_symbol.ts @@ -29,8 +29,8 @@ export default class DocumentSymbolProvider implements vscode.DocumentSymbolProvider { provideDocumentSymbols(document: vscode.TextDocument) { - return this._globalContext.contextMapping.getDocumentContext(document) - .documentSymbol.documentSymbols; + return this._globalContext.contextMapping + .getDocumentContext(document).documentSymbol.documentSymbols; } constructor(private readonly _globalContext: GlobalContext) {} diff --git a/src/providers/folding_range.ts b/src/providers/folding_range.ts index 73a80ce..515d1d6 100644 --- a/src/providers/folding_range.ts +++ b/src/providers/folding_range.ts @@ -29,8 +29,8 @@ export default class FoldingRangeProvider implements vscode.FoldingRangeProvider { provideFoldingRanges(document: vscode.TextDocument) { - return this._globalContext.contextMapping.getDocumentContext(document) - .foldingRange.foldingRanges; + return this._globalContext.contextMapping + .getDocumentContext(document).foldingRange.foldingRanges; } constructor(private readonly _globalContext: GlobalContext) {} diff --git a/src/utils/converter.ts b/src/utils/converter.ts index 88a4caa..c7ec4f9 100644 --- a/src/utils/converter.ts +++ b/src/utils/converter.ts @@ -29,8 +29,8 @@ import { Operator } from './types'; /** * Converter which converts file from Texinfo to other formats. */ -export default class Converter { - +export default class Converter +{ async toHTML(imgTransformer: Operator, insertScript?: string) { const pathUri = vscode.Uri.file(path.dirname(this._path)); const newPath = imgTransformer(pathUri).toString() + '/'; @@ -49,8 +49,11 @@ export default class Converter { this._addIncludePaths(this._options.includePaths, options); this._defineVariables(this._options.variables, options); this._includeCustomCSS(this._options.customCSS, options); - return await exec(this._options.makeinfo, options.concat(this._path), - this._options.maxSize); + return await exec( + this._options.makeinfo, + options.concat(this._path), + this._options.maxSize, + ); } constructor( diff --git a/src/utils/misc.ts b/src/utils/misc.ts index 7a4ef62..f7fa82f 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -112,6 +112,7 @@ export function getNodeHtmlRef(nodeName: string) { .join('')) .join('-'); const firstCharCode = result.charCodeAt(0); - return isAlpha(firstCharCode) ? result : 'g_t_00' - + firstCharCode.toString(16) + result.substring(1); + return isAlpha(firstCharCode) + ? result + : 'g_t_00' + firstCharCode.toString(16) + result.substring(1); }