Refactor code.
This commit is contained in:
parent
165bf9f583
commit
d5b84cdd7b
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,9 +68,10 @@ export default class FoldingRangeContext {
|
|||
}
|
||||
|
||||
clear() {
|
||||
if (!this.contentMayChange) return;
|
||||
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') {
|
||||
|
|
|
@ -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 => {" +
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 })));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue