diff --git a/src/extension.ts b/src/extension.ts index 8a0f48f..f76451b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,6 +7,7 @@ import * as vscode from 'vscode'; import Document from './document'; +import Logger from './logger'; import Options from './options'; import Preview from './preview'; import { CompletionItemProvider } from './completion'; @@ -28,5 +29,6 @@ export function activate(context: vscode.ExtensionContext) { export function deactivate() { Document.clear(); + Logger.destroy(); Options.clear(); } diff --git a/src/logger.ts b/src/logger.ts new file mode 100644 index 0000000..c8d9896 --- /dev/null +++ b/src/logger.ts @@ -0,0 +1,48 @@ +/** + * logger.ts + * + * @author CismonX + * @license MIT + */ + +import * as vscode from 'vscode'; + +/** + * Logger which prints message to VSCode output channel. + */ +export default class Logger { + + private static singleton?: Logger; + + private 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; + } + + private outputChannel: vscode.OutputChannel; + + private constructor() { + this.outputChannel = vscode.window.createOutputChannel('Texinfo'); + } + + private log(message: string) { + const dateTime = new Date().toLocaleString(undefined, { hour12: false }); + this.outputChannel.appendLine(`[ ${dateTime} ]:\n${message}`); + } + + private show() { + this.outputChannel.show(true); + } +} diff --git a/src/preview.ts b/src/preview.ts index 5dd24d4..3df7c61 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -80,7 +80,8 @@ export default class Preview { let htmlCode = await Converter.convertToHtml(this.document.fileName); if (htmlCode === undefined) { - vscode.window.showErrorMessage(`Failed to show preview for ${this.document.fileName}.`); + prompt(`Failed to show preview for ${this.document.fileName}.`, 'Show log', true) + .then(result => result && Logger.show()); } else { if (Options.displayImage) { const pathName = path.dirname(this.document.fileName); diff --git a/src/utils.ts b/src/utils.ts index d68fb3b..4d3d8b2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,16 +8,19 @@ 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. * * @param message The message to be displayed on the prompt. * @param confirm Text to be displayed on the "Confirm" button. + * @param error Whether the prompt is shown as an error message. Default false. * @returns Whether the user clicked the "Confirm" button. */ -export async function prompt(message: string, confirm: string) { - return confirm === await vscode.window.showInformationMessage(message, confirm, 'Cancel'); +export async function prompt(message: string, confirm: string, error = false) { + const func = error ? vscode.window.showErrorMessage : vscode.window.showInformationMessage; + return confirm === await func(message, confirm, 'Cancel'); } /** @@ -32,10 +35,10 @@ export function exec(path: string, args: string[], maxBuffer: number) { return new Promise(resolve => { child_process.execFile(path, args, { maxBuffer: maxBuffer }, (error, stdout, stderr) => { if (error) { - console.error(stderr ? stderr : error); + Logger.log(stderr ? stderr : error.message); resolve(undefined); } else { - stderr && console.log(stderr); + stderr && Logger.log(stderr); resolve(stdout); } });