From c52c7b5924ac20ae8149a88d564f4caa9f8c83d8 Mon Sep 17 00:00:00 2001 From: CismonX Date: Sat, 24 Oct 2020 23:50:20 +0800 Subject: [PATCH] Update --- README.md | 2 +- package-lock.json | 26 ++++++++++----------- package.json | 8 +++---- src/converter.ts | 1 - src/document.ts | 2 +- src/logger.ts | 16 ++++--------- src/preview.ts | 3 ++- src/symbol.ts | 58 +++++++++++++++++++++-------------------------- src/utils.ts | 11 ++++----- 9 files changed, 56 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 7e2a512..1ef469b 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/package-lock.json b/package-lock.json index 27617ac..b9b978e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 77ab7a0..09a72a6 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/converter.ts b/src/converter.ts index a7f74e4..e35a161 100644 --- a/src/converter.ts +++ b/src/converter.ts @@ -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); diff --git a/src/document.ts b/src/document.ts index 56bcd72..786ed76 100644 --- a/src/document.ts +++ b/src/document.ts @@ -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(); } } diff --git a/src/logger.ts b/src/logger.ts index c8d9896..0364d43 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -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); } } diff --git a/src/preview.ts b/src/preview.ts index f325b23..82f38ed 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -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(); diff --git a/src/symbol.ts b/src/symbol.ts index d6e2624..aa6e124 100644 --- a/src/symbol.ts +++ b/src/symbol.ts @@ -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(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 = []; - 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; + +function foldingRangeToSymbols(ranges: readonly RangeNode[], start: number, end: number) { + const symbols = []; + 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; +} diff --git a/src/utils.ts b/src/utils.ts index e33c956..60d0c1d 100644 --- a/src/utils.ts +++ b/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>(resolve => { + return new Promise(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 | undefined; +export type ExecResult = { data?: string, error: string }; + export type Range = { start: number, end: number };