From d5b84cdd7b2c0a66b8695ee1262634a0342a44d2 Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 22 Apr 2021 17:07:13 +0800 Subject: [PATCH] Refactor code. --- scripts/package.sh | 2 +- src/context_mapping.ts | 12 +++++++++--- src/contexts/document_symbol.ts | 4 +++- src/contexts/folding_range.ts | 11 ++++++----- src/contexts/preview.ts | 3 +++ src/diagnosis.ts | 13 ++++++++++++- src/global_context.ts | 6 +----- src/indicator.ts | 13 ++++++++++++- src/logger.ts | 2 +- src/providers/completion_item.ts | 2 +- src/utils/misc.ts | 6 +++--- 11 files changed, 52 insertions(+), 22 deletions(-) diff --git a/scripts/package.sh b/scripts/package.sh index 5aebea9..c615f0c 100755 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -19,7 +19,7 @@ minify-xml --output extension.vsixmanifest{,} cd extension # Minify JSON files. json -j0 -I -e "$PACKAGE_JSON_CLEANUP_JS" -f package.json -json5 -o package.json{,} +sed -i '' -e '2d' package.json json5 -o language-configuration.json{,} # Remove comments from Markdown files. sed -i '' -e '1,8d' README.md CHANGELOG.md diff --git a/src/context_mapping.ts b/src/context_mapping.ts index 17ad7ce..f2c902b 100644 --- a/src/context_mapping.ts +++ b/src/context_mapping.ts @@ -29,6 +29,12 @@ import { prompt } from './utils/misc'; */ export default class ContextMapping implements vscode.Disposable { + /** + * Get context of a Texinfo document. Create one if not exists. + * + * @param document + * @returns + */ getDocumentContext(document: vscode.TextDocument) { let documentContext = this.map.get(document); if (documentContext === undefined) { @@ -54,7 +60,7 @@ export default class ContextMapping implements vscode.Disposable { private readonly map = new Map(); - private getDocumentContextIfExist(document: vscode.TextDocument) { + private tryGetDocumentContext(document: vscode.TextDocument) { return document.languageId === 'texinfo' ? this.getDocumentContext(document) : undefined; } @@ -74,14 +80,14 @@ export default class ContextMapping implements vscode.Disposable { } private onDocumentSave(document: vscode.TextDocument) { - const documentContext = this.getDocumentContextIfExist(document); + const documentContext = this.tryGetDocumentContext(document); if (documentContext === undefined) return; documentContext.foldingRange.clear(); documentContext.getPreview()?.updateWebview(); } private onDocumentUpdate(event: vscode.TextDocumentChangeEvent) { - const documentContext = this.getDocumentContextIfExist(event.document); + const documentContext = this.tryGetDocumentContext(event.document); if (documentContext?.foldingRange.update(event.contentChanges)) { documentContext.documentSymbol.clear(); } diff --git a/src/contexts/document_symbol.ts b/src/contexts/document_symbol.ts index ee70a0f..78139df 100644 --- a/src/contexts/document_symbol.ts +++ b/src/contexts/document_symbol.ts @@ -48,7 +48,9 @@ export default class DocumentSymbolContext { */ private calculcateDocumentSymbols() { const ranges = Array>(this.document.lineCount); - this.documentContext.foldingRange.foldingRanges.forEach(range => range.kind ?? (ranges[range.start] = range)); + this.documentContext.foldingRange.foldingRanges + .filter(range => range.kind === undefined) + .forEach(range => ranges[range.start] = range); return foldingRangeToSymbols(ranges, 0, ranges.length); } } diff --git a/src/contexts/folding_range.ts b/src/contexts/folding_range.ts index d383d25..ddb7553 100644 --- a/src/contexts/folding_range.ts +++ b/src/contexts/folding_range.ts @@ -55,10 +55,10 @@ export default class FoldingRangeContext { update(events: readonly vscode.TextDocumentContentChangeEvent[]) { this.contentMayChange = true; if (this._foldingRanges === undefined) return false; + const eol = this.document.eol === vscode.EndOfLine.LF ? '\n' : '\r\n'; 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) { + if (event.text.split(eol).length !== 1 || event.range.start.line !== event.range.end.line) { this._foldingRanges = undefined; this.nodes = []; return true; @@ -68,8 +68,9 @@ export default class FoldingRangeContext { } clear() { - if (!this.contentMayChange) return; - this._foldingRanges = undefined; + if (this.contentMayChange) { + this._foldingRanges = undefined; + } } constructor(private readonly documentContext: DocumentContext) {} @@ -117,7 +118,7 @@ export default class FoldingRangeContext { let lastLine = this.document.lineCount - 1; let verbatim = false; for (let idx = lastLine; idx >= 0; --idx) { - const line = this.document.lineAt(idx).text; + const line = this.document.lineAt(idx).text.trimLeft(); if (!line.startsWith('@')) continue; if (!verbatim) { if (line === '@bye') { diff --git a/src/contexts/preview.ts b/src/contexts/preview.ts index ad36f4d..60c83ae 100644 --- a/src/contexts/preview.ts +++ b/src/contexts/preview.ts @@ -114,6 +114,9 @@ export default class PreviewContext { }; } + /** + * Generate script used for jumping to the corresponding location of preview with code lens. + */ private get script() { if (!this.globalContext.options.enableCodeLens) return undefined; return "window.addEventListener('message', event => {" + diff --git a/src/diagnosis.ts b/src/diagnosis.ts index f349657..4e254a1 100644 --- a/src/diagnosis.ts +++ b/src/diagnosis.ts @@ -28,6 +28,11 @@ import { isDefined } from './utils/types'; */ export default class Diagnosis implements vscode.Disposable { + /** + * Remove a document's diagnostic entry from the collection. + * + * @param document + */ delete(document: vscode.TextDocument) { this.diagnostics.delete(document.uri); } @@ -54,9 +59,15 @@ export default class Diagnosis implements vscode.Disposable { private readonly diagnostics = vscode.languages.createDiagnosticCollection('texinfo'); } +/** + * Convert a `makeinfo` error log line to a VSCode `Diagnostic` object. + * + * @param lineText + * @returns + */ function logLineToDiagnostic(lineText: string) { const lineNum = parseInt(lineText) - 1; - // Ignore error that does not correspond a line. + // Ignore error that does not correspond 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; diff --git a/src/global_context.ts b/src/global_context.ts index ef5342a..18e9f93 100644 --- a/src/global_context.ts +++ b/src/global_context.ts @@ -60,13 +60,9 @@ export default class GlobalContext { 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.refreshOptions), + vscode.workspace.onDidChangeConfiguration(() => this._options = undefined), ); } private _options?: Options; - - private refreshOptions() { - this._options = undefined; - } } diff --git a/src/indicator.ts b/src/indicator.ts index b5560a5..286626b 100644 --- a/src/indicator.ts +++ b/src/indicator.ts @@ -46,13 +46,21 @@ export default class Indicator implements vscode.Disposable { private _canDisplayPreview = false; - private statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); + private readonly statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); + /** + * Calls when the status bar item is clicked. + */ private async click() { await this.updateStatus(); this.refresh(vscode.window.activeTextEditor); } + /** + * Refresh the show/hide status of the indicator based on given editor. + * + * @param editor + */ private refresh(editor?: vscode.TextEditor) { if (editor?.document.languageId === 'texinfo') { this.statusBarItem.show(); @@ -61,6 +69,9 @@ export default class Indicator implements vscode.Disposable { } } + /** + * Update the installation status of GNU Texinfo, by checking `makeinfo --version`. + */ private async updateStatus() { const options = this.globalContext.options; const output = await exec(options.makeinfo, ['--version'], options.maxSize); diff --git a/src/logger.ts b/src/logger.ts index fb47d0d..1bce94c 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -39,5 +39,5 @@ export default class Logger implements vscode.Disposable { this.outputChannel.dispose(); } - private outputChannel = vscode.window.createOutputChannel('Texinfo'); + private readonly outputChannel = vscode.window.createOutputChannel('Texinfo'); } diff --git a/src/providers/completion_item.ts b/src/providers/completion_item.ts index 0b1a0cf..0241e94 100644 --- a/src/providers/completion_item.ts +++ b/src/providers/completion_item.ts @@ -36,7 +36,7 @@ export default class CompletionItemProvider implements vscode.CompletionItemProv * 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-398 of this file, while the remainder + * which means that GFDL applies to lines 46-365 of this file, while the remainder * is under GPL like other source code files of the project. */ private get completionItems() { diff --git a/src/utils/misc.ts b/src/utils/misc.ts index 26ba645..31082c3 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -32,9 +32,9 @@ import { ExecResult } from './types'; * @returns The output data, or `undefined` if execution fails. */ export function exec(path: string, args: string[], maxBuffer: number) { - return new Promise(resolve => child_process.execFile(path, args, { maxBuffer: maxBuffer }, - (error, stdout, stderr) => resolve( - error ? { error: stderr ? stderr : error.message } : { data: stdout, error: stderr }))); + return new Promise(resolve => child_process.execFile(path, args, + { env: { LC_MESSAGES: 'en_US' }, maxBuffer: maxBuffer }, (error, stdout, stderr) => + resolve(error ? { error: stderr ? stderr : error.message } : { data: stdout, error: stderr }))); } /**