Refactor code.

This commit is contained in:
CismonX 2021-04-22 17:07:13 +08:00
parent 165bf9f583
commit d5b84cdd7b
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
11 changed files with 52 additions and 22 deletions

View File

@ -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

View File

@ -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<vscode.TextDocument, DocumentContext>();
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();
}

View File

@ -48,7 +48,9 @@ export default class DocumentSymbolContext {
*/
private calculcateDocumentSymbols() {
const ranges = Array<Optional<FoldingRange>>(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);
}
}

View File

@ -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') {

View File

@ -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 => {" +

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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');
}

View File

@ -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() {

View File

@ -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<ExecResult>(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<ExecResult>(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 })));
}
/**