Skip to content

Commit cdb46d0

Browse files
authored
feat: Support open preview page through Code Lens and context menu (#338)
1 parent e6cd998 commit cdb46d0

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

package.json

+4
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
{
226226
"command": "leetcode.showSolution",
227227
"group": "leetcode@3"
228+
},
229+
{
230+
"command": "leetcode.previewProblem",
231+
"group": "leetcode@4"
228232
}
229233
]
230234
},

src/codelens/CustomCodeLensProvider.ts

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ export class CustomCodeLensProvider implements vscode.CodeLensProvider {
3232
command: "leetcode.showSolution",
3333
arguments: [document.uri],
3434
}),
35+
new vscode.CodeLens(range, {
36+
title: "Preview",
37+
command: "leetcode.previewProblem",
38+
arguments: [document.uri],
39+
}),
3540
];
3641
}
3742
}

src/commands/show.ts

+28-3
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,45 @@ import * as fse from "fs-extra";
55
import * as path from "path";
66
import * as unescapeJS from "unescape-js";
77
import * as vscode from "vscode";
8+
import { explorerNodeManager } from "../explorer/explorerNodeManager";
89
import { LeetCodeNode } from "../explorer/LeetCodeNode";
910
import { leetCodeChannel } from "../leetCodeChannel";
1011
import { leetCodeExecutor } from "../leetCodeExecutor";
1112
import { leetCodeManager } from "../leetCodeManager";
1213
import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared";
14+
import { getNodeIdFromFile } from "../utils/problemUtils";
1315
import { DialogOptions, DialogType, openSettingsEditor, promptForOpenOutputChannel, promptForSignIn, promptHintMessage } from "../utils/uiUtils";
1416
import { selectWorkspaceFolder } from "../utils/workspaceUtils";
1517
import * as wsl from "../utils/wslUtils";
1618
import { leetCodePreviewProvider } from "../webview/leetCodePreviewProvider";
1719
import { leetCodeSolutionProvider } from "../webview/leetCodeSolutionProvider";
1820
import * as list from "./list";
1921

20-
export async function previewProblem(node: IProblem, isSideMode: boolean = false): Promise<void> {
21-
const descString: string = await leetCodeExecutor.getDescription(node);
22+
export async function previewProblem(input: IProblem | vscode.Uri, isSideMode: boolean = false): Promise<void> {
23+
let node: LeetCodeNode;
24+
if (input instanceof LeetCodeNode) {
25+
node = input;
26+
} else if (input instanceof vscode.Uri) {
27+
const activeFilePath: string = input.fsPath;
28+
const id: string = await getNodeIdFromFile(activeFilePath);
29+
if (!id) {
30+
vscode.window.showErrorMessage(`Failed to resolve the problem id from file: ${activeFilePath}.`);
31+
return;
32+
}
33+
const cachedNode: LeetCodeNode | undefined = explorerNodeManager.getNodeById(id);
34+
if (!cachedNode) {
35+
vscode.window.showErrorMessage(`Failed to resolve the problem with id: ${id}.`);
36+
return;
37+
}
38+
node = cachedNode;
39+
// Move the preview page aside if it's triggered from Code Lens
40+
isSideMode = true;
41+
} else {
42+
vscode.window.showErrorMessage("Invalid input to fetch the preview data.");
43+
return;
44+
}
45+
46+
const descString: string = await leetCodeExecutor.getDescription(node.id);
2247
leetCodePreviewProvider.show(descString, node, isSideMode);
2348
}
2449

@@ -54,7 +79,7 @@ export async function showSolution(input: LeetCodeNode | vscode.Uri): Promise<vo
5479
} else if (input instanceof vscode.Uri) {
5580
problemInput = `"${input.fsPath}"`;
5681
} else {
57-
vscode.window.showErrorMessage("Invalid input to fetch the solution data");
82+
vscode.window.showErrorMessage("Invalid input to fetch the solution data.");
5883
return;
5984
}
6085

src/leetCodeExecutor.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ class LeetCodeExecutor implements Disposable {
112112
return solution;
113113
}
114114

115-
public async getDescription(problemNode: IProblem): Promise<string> {
116-
return await this.executeCommandWithProgressEx("Fetching problem description...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-x"]);
115+
public async getDescription(problemNodeId: string): Promise<string> {
116+
return await this.executeCommandWithProgressEx("Fetching problem description...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNodeId, "-x"]);
117117
}
118118

119119
public async listSessions(): Promise<string> {

src/utils/problemUtils.ts

+17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4+
import * as fse from "fs-extra";
45
import * as _ from "lodash";
6+
import * as path from "path";
57
import { IProblem, langExt } from "../shared";
68

79
export function genFileExt(language: string): string {
@@ -17,3 +19,18 @@ export function genFileName(node: IProblem, language: string): string {
1719
const ext: string = genFileExt(language);
1820
return `${node.id}.${slug}.${ext}`;
1921
}
22+
23+
export async function getNodeIdFromFile(fsPath: string): Promise<string> {
24+
const fileContent: string = await fse.readFile(fsPath, "utf8");
25+
let id: string = "";
26+
const matchResults: RegExpMatchArray | null = fileContent.match(/@lc.+id=(.+?) /);
27+
if (matchResults && matchResults.length === 2) {
28+
id = matchResults[1];
29+
}
30+
// Try to get id from file name if getting from comments failed
31+
if (!id) {
32+
id = path.basename(fsPath).split(".")[0];
33+
}
34+
35+
return id;
36+
}

0 commit comments

Comments
 (0)