Refactor code.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
b3b9644af0
commit
3ecb2a5b03
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = <vscode.DocumentSymbol[]>[];
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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<vscode.Uri>, 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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue