Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,15 @@ The resulting workflow can look like Grant's 🥳
- [contributing](https://github.com/bhoov/manim-notebook/blob/main/CONTRIBUTING.md)

- [wiki](https://github.com/bhoov/manim-notebook/wiki)

<br /><br />

## Troubleshooting

If you encounter an issue, search for some related keywords first in the [issues](https://github.com/bhoov/manim-notebook/issues). If you can't find anything, feel free to open a new issue. To analyze the problem, we need a **log file** from you:

- Reload the VSCode window. This is important for us such that only important log messages are included in the log file and not unrelated ones.
- Open the command palette `Ctrl+Shift+P` (or `Cmd+Shift+P`). Use the command `Developer: Set Log Level...`, click on `Manim Notebook` and set the log level to `Trace`.
- Now reproduce the issue, e.g. by running a command that causes the problem.
- Open the command palette again and use the command `Manim Notebook: Open Log File`.
- Attach the log file to your GitHub issue. To do so, right-click on the opened log file header (the tab pane that shows the filename at the top of the editor) and select `Reveal In File Explorer` (or `Reveal in Finder`). Then drag and drop the file into the GitHub issue text field.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
"command": "manim-notebook.clearScene",
"title": "Remove all objects from scene",
"category": "Manim Notebook"
},
{
"command": "manim-notebook.openLogFile",
"title": "Open Log File",
"category": "Manim Notebook"
}
],
"keybindings": [
Expand Down
43 changes: 42 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ManimCell } from './manimCell';
import { ManimCellRanges } from './manimCellRanges';
import { previewCode } from './previewCode';
import { startScene, exitScene } from './startStopScene';
import { loggerName } from './logger';
import Logger from './logger';

export function activate(context: vscode.ExtensionContext) {

Expand Down Expand Up @@ -40,14 +42,22 @@ export function activate(context: vscode.ExtensionContext) {
}
);

const openLogFileCommand = vscode.commands.registerCommand(
'manim-notebook.openLogFile', async () => {
openLogFile(context);
});

context.subscriptions.push(
previewManimCellCommand,
previewSelectionCommand,
startSceneCommand,
exitSceneCommand,
clearSceneCommand
clearSceneCommand,
openLogFileCommand
);
registerManimCellProviders(context);

Logger.info("Manim Notebook activated");
}

export function deactivate() { }
Expand Down Expand Up @@ -167,3 +177,34 @@ function registerManimCellProviders(context: vscode.ExtensionContext) {
manimCell.applyCellDecorations(window.activeTextEditor);
}
}

/**
* Opens the Manim Notebook log file in a new editor.
*
* @param context The extension context.
*/
function openLogFile(context: vscode.ExtensionContext) {
const logFilePath = vscode.Uri.joinPath(context.logUri, `${loggerName}.log`);
vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Opening Manim Notebook log file...",
cancellable: false
}, async (progressIndicator, token) => {
await new Promise<void>(async (resolve) => {
try {
const doc = await vscode.workspace.openTextDocument(logFilePath);
await vscode.window.showTextDocument(doc);
} catch {
vscode.window.showErrorMessage("Could not open Manim Notebook log file");
} finally {
resolve();
}

// I've also tried to open the log file in the OS browser,
// but didn't get it to work via:
// commands.executeCommand("revealFileInOS", logFilePath);
// For a sample usage, see this:
// https://github.com/microsoft/vscode/blob/9de080f7cbcec77de4ef3e0d27fbf9fd335d3fba/extensions/typescript-language-features/src/typescriptServiceClient.ts#L580-L586
});
});
}
79 changes: 79 additions & 0 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { window } from 'vscode';
import * as path from 'path';

export const loggerName = 'Manim Notebook';
const logger = window.createOutputChannel(loggerName, { log: true });

export default class Logger {

public static trace(message: string) {
logger.trace(`${Logger.getFormattedCallerInformation()} ${message}`);
}

public static debug(message: string) {
logger.debug(`${Logger.getFormattedCallerInformation()} ${message}`);
}

public static info(message: string) {
logger.info(`${Logger.getFormattedCallerInformation()} ${message}`);
}

public static warn(message: string) {
logger.warn(`${Logger.getFormattedCallerInformation()} ${message}`);
}

public static error(message: string) {
logger.error(`${Logger.getFormattedCallerInformation()} ${message}`);
}

/**
* Returns formatted caller information in the form of
* "[filename] [methodname]".
*
* It works by creating a stack trace and extracting the file name from the
* third line of the stack trace, e.g.
*
* Error:
* at Logger.getCurrentFileName (manim-notebook/out/logger.js:32:19)
* at Logger.info (manim-notebook/out/logger.js:46:39)
* at activate (manim-notebook/out/extension.js:37:21)
* ...
*
* where "extension.js" is the file that called the logger method
* and "activate" is the respective method.
*/
private static getFormattedCallerInformation(): string {
const error = new Error();
const stack = error.stack;

const unknownString = "[unknown] [unknown]";

if (!stack) {
return unknownString;
}

const stackLines = stack.split('\n');
if (stackLines.length < 4) {
return unknownString;
}

const callerLine = stackLines[3];
if (!callerLine) {
return unknownString;
}

const methodMatch = callerLine.match(/at (\w+) \(/);
let methodName = 'unknown';
if (methodMatch && methodMatch[1]) {
methodName = methodMatch[1];
}

const fileMatch = callerLine.match(/\((.*):\d+:\d+\)/);
let fileName = 'unknown';
if (fileMatch && fileMatch[1]) {
fileName = path.basename(fileMatch[1]);
}

return `[${fileName}] [${methodName}]`;
}
}