Update
This commit is contained in:
parent
4cbbcdfd4d
commit
c52c7b5924
|
@ -35,7 +35,7 @@ See `File -> Preferences -> Settings -> Extensions -> Texinfo` for details. The
|
|||
|
||||
## Notes
|
||||
|
||||
* If syntax highlighting is not satisfactory, try another color theme where keyword/operator colors are distinct (e.g. Solarized Light/Dark, Monokai).
|
||||
* If syntax highlighting is not satisfactory, try another color theme (e.g. Solarized Light/Dark, Monokai) where keyword/operator colors are distinct.
|
||||
* Preview content is updated on document save rather than document change.
|
||||
* For macOS users: Preinstalled GNU Texinfo distribution is very old. Use a latest one instead. This can be easily done by `brew install texinfo` and change extension setting `texinfo.makeinfo` value.
|
||||
|
||||
|
|
|
@ -44,9 +44,9 @@
|
|||
}
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz",
|
||||
"integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==",
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.0.tgz",
|
||||
"integrity": "sha512-+cIGPCBdLCzqxdtwppswP+zTsH9BOIGzAeKfBIbtb4gW/giMlfMwP0HUSFfhzh20f9u8uZ8hOp62+4GPquTbwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
|
@ -74,9 +74,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.10.tgz",
|
||||
"integrity": "sha512-yV1nWZPlMFpoXyoknm4S56y2nlTAuFYaJuQtYRAOU7xA/FJ9RY0Xm7QOkaYMMmr8ESdHIuUb6oQgR/0+2NqlyA==",
|
||||
"version": "14.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.2.tgz",
|
||||
"integrity": "sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/vscode": {
|
||||
|
@ -169,9 +169,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.5",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
|
||||
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
|
@ -403,13 +403,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "7.11.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.11.0.tgz",
|
||||
"integrity": "sha512-G9+qtYVCHaDi1ZuWzBsOWo2wSwd70TXnU6UHA3cTYHp7gCTXZcpggWFoUVAMRarg68qtPoNfFbzPh+VdOgmwmw==",
|
||||
"version": "7.12.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.0.tgz",
|
||||
"integrity": "sha512-n5pEU27DRxCSlOhJ2rO57GDLcNsxO0LPpAbpFdh7xmcDmjmlGUfoyrsB3I7yYdQXO5N3gkSTiDrPSPNFiiirXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@eslint/eslintrc": "^0.1.3",
|
||||
"@eslint/eslintrc": "^0.2.0",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "texinfo",
|
||||
"displayName": "Texinfo Language Support",
|
||||
"description": "Syntax highlighting, code completion and preview support for Texinfo.",
|
||||
"description": "Syntax highlighting, code completion, folding and preview support for Texinfo.",
|
||||
"version": "0.1.0",
|
||||
"author": {
|
||||
"name": "CismonX",
|
||||
|
@ -15,12 +15,12 @@
|
|||
},
|
||||
"icon": "assets/texinfo.png",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.11.10",
|
||||
"@types/node": "^14.14.2",
|
||||
"@types/vscode": "^1.50.0",
|
||||
"@typescript-eslint/eslint-plugin": "^3.8.0",
|
||||
"@typescript-eslint/parser": "^3.8.0",
|
||||
"cson": "^7.20.0",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint": "^7.12.0",
|
||||
"language-texinfo": "^1.0.0",
|
||||
"typescript": "^4.0.3"
|
||||
},
|
||||
|
@ -128,7 +128,7 @@
|
|||
"type": "integer",
|
||||
"default": 100,
|
||||
"minimum": 0,
|
||||
"markdownDescription": "Max tolerated number of errors when trying to display preview.\n\nThis corresponds to the `--error-limit=NUM` option of `makeinfo`."
|
||||
"markdownDescription": "Max number of errors before quit when trying to display preview.\n\nThis corresponds to the `--error-limit=NUM` option of `makeinfo`."
|
||||
},
|
||||
"texinfo.preview.force": {
|
||||
"type": "boolean",
|
||||
|
|
|
@ -17,7 +17,6 @@ export default class Converter {
|
|||
* Convert a Texinfo document to HTML.
|
||||
*
|
||||
* @param path Path to the Texinfo document.
|
||||
* @returns HTML code, or `undefined` if conversion fails.
|
||||
*/
|
||||
static async convertToHtml(path: string) {
|
||||
return await new Converter().convert(path);
|
||||
|
|
|
@ -32,7 +32,7 @@ export default class Document {
|
|||
static update(event: vscode.TextDocumentChangeEvent) {
|
||||
const documentContext = Document.get(event.document);
|
||||
if (documentContext?.foldingRange.update(event.contentChanges)) {
|
||||
documentContext.symbol.update(documentContext.foldingRange.values);
|
||||
documentContext.symbol.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,18 +14,10 @@ export default class Logger {
|
|||
|
||||
private static singleton?: Logger;
|
||||
|
||||
private static get instance() {
|
||||
static get instance() {
|
||||
return Logger.singleton ??= new Logger();
|
||||
}
|
||||
|
||||
static log(message: string) {
|
||||
Logger.instance.log(message);
|
||||
}
|
||||
|
||||
static show() {
|
||||
Logger.instance.show();
|
||||
}
|
||||
|
||||
static destroy() {
|
||||
Logger.instance.outputChannel.dispose();
|
||||
Logger.singleton = undefined;
|
||||
|
@ -37,12 +29,12 @@ export default class Logger {
|
|||
this.outputChannel = vscode.window.createOutputChannel('Texinfo');
|
||||
}
|
||||
|
||||
private log(message: string) {
|
||||
log(message: string) {
|
||||
const dateTime = new Date().toLocaleString(undefined, { hour12: false });
|
||||
this.outputChannel.appendLine(`[ ${dateTime} ]:\n${message}`);
|
||||
this.outputChannel.appendLine(`[ ${dateTime} ]\n${message}`);
|
||||
}
|
||||
|
||||
private show() {
|
||||
show() {
|
||||
this.outputChannel.show(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ export default class Preview {
|
|||
private pendingUpdate = false;
|
||||
|
||||
constructor(private readonly documentContext: Document) {
|
||||
this.panel = vscode.window.createWebviewPanel('texinfo.preview', '', vscode.ViewColumn.Beside);
|
||||
this.panel = vscode.window.createWebviewPanel('texinfo.preview', '', vscode.ViewColumn.Beside,
|
||||
{ enableFindWidget: true, retainContextWhenHidden: true });
|
||||
this.disposables.push(this.panel.onDidDispose(() => this.close()));
|
||||
this.updateTitle();
|
||||
this.updateWebview();
|
||||
|
|
|
@ -29,53 +29,47 @@ export class DocumentSymbolContext {
|
|||
|
||||
private symbols?: vscode.DocumentSymbol[];
|
||||
|
||||
private foldingRanges?: FoldingRange[];
|
||||
private foldingRanges?: readonly FoldingRange[];
|
||||
|
||||
get values() {
|
||||
return this.symbols ??= this.calculcateDocumentSymbols();
|
||||
}
|
||||
|
||||
update(foldingRanges: FoldingRange[]) {
|
||||
this.foldingRanges = foldingRanges;
|
||||
clear() {
|
||||
this.foldingRanges = undefined;
|
||||
this.symbols = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate (very limited) document symbols based on folding ranges.
|
||||
* Calculate document symbols based on folding ranges.
|
||||
*/
|
||||
private calculcateDocumentSymbols() {
|
||||
this.symbols = [];
|
||||
if (this.foldingRanges === undefined) {
|
||||
this.foldingRanges = this.documentContext.foldingRange.values;
|
||||
}
|
||||
const ranges = Array<RangeNode>(this.document.lineCount);
|
||||
this.foldingRanges.forEach(range => {
|
||||
if (range.kind !== undefined) return;
|
||||
ranges[range.start] = range;
|
||||
});
|
||||
return this.symbols = this.rangeToSymbols(ranges, 0, ranges.length);
|
||||
}
|
||||
|
||||
private rangeToSymbols(ranges: RangeNode[], start: number, end: number) {
|
||||
const symbols = <vscode.DocumentSymbol[]>[];
|
||||
for (let idx = start; idx < end; ++idx) {
|
||||
const node = ranges[idx];
|
||||
if (node === undefined) continue;
|
||||
const startPosition = new vscode.Position(idx, 0);
|
||||
const endFirstLine = new vscode.Position(idx, Number.MAX_SAFE_INTEGER);
|
||||
const endLastLine = new vscode.Position(node.end, Number.MAX_SAFE_INTEGER);
|
||||
const range = new vscode.Range(startPosition, endLastLine);
|
||||
const selectionRange = new vscode.Range(startPosition, endFirstLine);
|
||||
const symbol = new vscode.DocumentSymbol('@' + node.name, node.detail,
|
||||
vscode.SymbolKind.String, range, selectionRange);
|
||||
symbol.children = this.rangeToSymbols(ranges, idx + 1, node.end);
|
||||
symbols.push(symbol);
|
||||
idx = node.end;
|
||||
}
|
||||
return symbols;
|
||||
(this.foldingRanges ??= this.documentContext.foldingRange.values)
|
||||
.forEach(range => range.kind ?? (ranges[range.start] = range));
|
||||
return this.symbols = foldingRangeToSymbols(ranges, 0, ranges.length);
|
||||
}
|
||||
|
||||
constructor(private readonly documentContext: Document) {}
|
||||
}
|
||||
|
||||
type RangeNode = Optional<FoldingRange>;
|
||||
|
||||
function foldingRangeToSymbols(ranges: readonly RangeNode[], start: number, end: number) {
|
||||
const symbols = <vscode.DocumentSymbol[]>[];
|
||||
for (let idx = start; idx < end; ++idx) {
|
||||
const node = ranges[idx];
|
||||
if (node === undefined) continue;
|
||||
const startPosition = new vscode.Position(idx, 0);
|
||||
const endFirstLine = new vscode.Position(idx, Number.MAX_SAFE_INTEGER);
|
||||
const endLastLine = new vscode.Position(node.end, Number.MAX_SAFE_INTEGER);
|
||||
const range = new vscode.Range(startPosition, endLastLine);
|
||||
const selectionRange = new vscode.Range(startPosition, endFirstLine);
|
||||
const symbol = new vscode.DocumentSymbol('@' + node.name, node.detail,
|
||||
vscode.SymbolKind.String, range, selectionRange);
|
||||
symbol.children = foldingRangeToSymbols(ranges, idx + 1, node.end);
|
||||
symbols.push(symbol);
|
||||
idx = node.end;
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
|
11
src/utils.ts
11
src/utils.ts
|
@ -8,7 +8,6 @@
|
|||
import * as child_process from 'child_process';
|
||||
import * as htmlparser from 'node-html-parser';
|
||||
import * as vscode from 'vscode';
|
||||
import Logger from './logger';
|
||||
|
||||
/**
|
||||
* Open a prompt with two buttons, "Confirm" and "Cancel", and wait for user action.
|
||||
|
@ -32,14 +31,12 @@ export async function prompt(message: string, confirm: string, error = false) {
|
|||
* @returns The output data, or `undefined` if execution fails.
|
||||
*/
|
||||
export function exec(path: string, args: string[], maxBuffer: number) {
|
||||
return new Promise<Optional<string>>(resolve => {
|
||||
return new Promise<ExecResult>(resolve => {
|
||||
child_process.execFile(path, args, { maxBuffer: maxBuffer }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
Logger.log(stderr ? stderr : error.message);
|
||||
resolve(undefined);
|
||||
resolve({ error: stderr ? stderr : error.message });
|
||||
} else {
|
||||
stderr && Logger.log(stderr);
|
||||
resolve(stdout);
|
||||
resolve({ data: stdout, error: stderr });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -65,4 +62,6 @@ export function transformHtmlImageUri(htmlCode: string, transformer: (src: strin
|
|||
|
||||
export type Optional<T> = T | undefined;
|
||||
|
||||
export type ExecResult = { data?: string, error: string };
|
||||
|
||||
export type Range = { start: number, end: number };
|
||||
|
|
Loading…
Reference in New Issue