Skip to content

Commit

Permalink
Top voted solution webview (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vigilans authored and jdneo committed Mar 13, 2019
1 parent 9164acb commit 9b33df0
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 29 deletions.
60 changes: 57 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 22 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@
"dark": "resources/dark/search.svg"
}
},
{
"command": "leetcode.showSolution",
"title": "Show Top Voted Solution",
"category": "LeetCode"
},
{
"command": "leetcode.testSolution",
"title": "Test in LeetCode",
Expand Down Expand Up @@ -171,6 +176,12 @@
"when": "view == leetCodeExplorer && viewItem == problem",
"group": "leetcode@1"
},
{

"command": "leetcode.showSolution",
"when": "view == leetCodeExplorer && viewItem == problem",
"group": "leetcode@1"
},
{
"command": "leetcode.previewProblem",
"when": "view == leetCodeExplorer && viewItem == problem",
Expand All @@ -182,6 +193,11 @@
"command": "leetcode.showProblem",
"when": "never"
},
{

"command": "leetcode.showSolution",
"when": "never"
},
{
"command": "leetcode.previewProblem",
"when": "never"
Expand Down Expand Up @@ -288,7 +304,9 @@
},
"devDependencies": {
"@types/fs-extra": "5.0.0",
"@types/highlight.js": "^9.12.3",
"@types/lodash.kebabcase": "^4.1.5",
"@types/markdown-it": "0.0.7",
"@types/mocha": "^2.2.42",
"@types/node": "^7.0.43",
"@types/require-from-string": "^1.2.0",
Expand All @@ -298,8 +316,10 @@
},
"dependencies": {
"fs-extra": "^6.0.1",
"vsc-leetcode-cli": "2.6.2",
"highlight.js": "^9.15.6",
"lodash.kebabcase": "^4.1.1",
"require-from-string": "^2.0.2"
"markdown-it": "^8.4.2",
"require-from-string": "^2.0.2",
"vsc-leetcode-cli": "2.6.2"
}
}
69 changes: 49 additions & 20 deletions src/commands/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { LeetCodeNode } from "../explorer/LeetCodeNode";
import { leetCodeChannel } from "../leetCodeChannel";
import { leetCodeExecutor } from "../leetCodeExecutor";
import { leetCodeManager } from "../leetCodeManager";
import { leetCodeSolutionProvider } from "../leetCodeSolutionProvider";
import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared";
import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils";
import { selectWorkspaceFolder } from "../utils/workspaceUtils";
Expand Down Expand Up @@ -39,18 +40,60 @@ export async function searchProblem(): Promise<void> {
await showProblemInternal(choice.value);
}

async function showProblemInternal(node: IProblem): Promise<void> {
export async function showSolution(node?: LeetCodeNode): Promise<void> {
if (!node) {
return;
}
const language: string | undefined = await fetchProblemLanguage();
if (!language) {
return;
}
try {
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
let defaultLanguage: string | undefined = leetCodeConfig.get<string>("defaultLanguage");
if (defaultLanguage && languages.indexOf(defaultLanguage) < 0) {
defaultLanguage = undefined;
let solution: string = await leetCodeExecutor.showSolution(node, language);
// remove backslash in espaced \'...\'(generated by leetcode's database)
solution = solution.replace(/\\'/g, "'");
await leetCodeSolutionProvider.show(solution, node);
} catch (error) {
await promptForOpenOutputChannel("Failed to fetch the top voted solution. Please open the output channel for details.", DialogType.error);
}
}

// SUGGESTION: group config retriving into one file
async function fetchProblemLanguage(): Promise<string | undefined> {
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
let defaultLanguage: string | undefined = leetCodeConfig.get<string>("defaultLanguage");
if (defaultLanguage && languages.indexOf(defaultLanguage) < 0) {
defaultLanguage = undefined;
}
const language: string | undefined = defaultLanguage || await vscode.window.showQuickPick(languages, { placeHolder: "Select the language you want to use" });
// fire-and-forget default language query
(async (): Promise<void> => {
if (!defaultLanguage && leetCodeConfig.get<boolean>("showSetDefaultLanguageHint")) {
const choice: vscode.MessageItem | undefined = await vscode.window.showInformationMessage(
`Would you like to set '${language}' as your default language?`,
DialogOptions.yes,
DialogOptions.no,
DialogOptions.never,
);
if (choice === DialogOptions.yes) {
leetCodeConfig.update("defaultLanguage", language, true /* UserSetting */);
} else if (choice === DialogOptions.never) {
leetCodeConfig.update("showSetDefaultLanguageHint", false, true /* UserSetting */);
}
}
const language: string | undefined = defaultLanguage || await vscode.window.showQuickPick(languages, { placeHolder: "Select the language you want to use" });
})();
return language;
}

async function showProblemInternal(node: IProblem): Promise<void> {
try {
const language: string | undefined = await fetchProblemLanguage();
if (!language) {
return;
}

// SUGGESTION: group config retriving into one file
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
let outDir: string = await selectWorkspaceFolder();
let relativePath: string = (leetCodeConfig.get<string>("outputFolder") || "").trim();
const matchResult: RegExpMatchArray | null = relativePath.match(/\$\{(.*?)\}/);
Expand All @@ -69,20 +112,6 @@ async function showProblemInternal(node: IProblem): Promise<void> {
const originFilePath: string = await leetCodeExecutor.showProblem(node, language, outDir);
const filePath: string = wsl.useWsl() ? await wsl.toWinPath(originFilePath) : originFilePath;
await vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false });

if (!defaultLanguage && leetCodeConfig.get<boolean>("showSetDefaultLanguageHint")) {
const choice: vscode.MessageItem | undefined = await vscode.window.showInformationMessage(
`Would you like to set '${language}' as your default language?`,
DialogOptions.yes,
DialogOptions.no,
DialogOptions.never,
);
if (choice === DialogOptions.yes) {
leetCodeConfig.update("defaultLanguage", language, true /* UserSetting */);
} else if (choice === DialogOptions.never) {
leetCodeConfig.update("showSetDefaultLanguageHint", false, true /* UserSetting */);
}
}
} catch (error) {
await promptForOpenOutputChannel("Failed to show the problem. Please open the output channel for details.", DialogType.error);
}
Expand Down
4 changes: 4 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { leetCodeExecutor } from "./leetCodeExecutor";
import { leetCodeManager } from "./leetCodeManager";
import { leetCodePreviewProvider } from "./leetCodePreviewProvider";
import { leetCodeResultProvider } from "./leetCodeResultProvider";
import { leetCodeSolutionProvider } from "./leetCodeSolutionProvider";
import { leetCodeStatusBarItem } from "./leetCodeStatusBarItem";

export async function activate(context: vscode.ExtensionContext): Promise<void> {
Expand All @@ -32,12 +33,14 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
const leetCodeTreeDataProvider: LeetCodeTreeDataProvider = new LeetCodeTreeDataProvider(context);
leetCodePreviewProvider.initialize(context);
leetCodeResultProvider.initialize(context);
leetCodeSolutionProvider.initialize(context);

context.subscriptions.push(
leetCodeStatusBarItem,
leetCodeChannel,
leetCodePreviewProvider,
leetCodeResultProvider,
leetCodeSolutionProvider,
vscode.window.createTreeView("leetCodeExplorer", { treeDataProvider: leetCodeTreeDataProvider, showCollapseAll: true }),
vscode.languages.registerCodeLensProvider({ scheme: "file" }, codeLensProvider),
vscode.commands.registerCommand("leetcode.deleteCache", () => cache.deleteCache()),
Expand All @@ -49,6 +52,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => leetCodePreviewProvider.preview(node)),
vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(node)),
vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem()),
vscode.commands.registerCommand("leetcode.showSolution", (node: LeetCodeNode) => show.showSolution(node)),
vscode.commands.registerCommand("leetcode.refreshExplorer", () => leetCodeTreeDataProvider.refresh()),
vscode.commands.registerCommand("leetcode.testSolution", (uri?: vscode.Uri) => test.testSolution(uri)),
vscode.commands.registerCommand("leetcode.submitSolution", (uri?: vscode.Uri) => submit.submitSolution(uri)),
Expand Down
15 changes: 11 additions & 4 deletions src/leetCodeExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ class LeetCodeExecutor {
}
return false;
}
try { // Check company plugin
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", "company"]);
} catch (error) { // Download company plugin and activate
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-i", "company"]);
for (const plugin of ["company", "solution.discuss"]) {
try { // Check plugin
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
} catch (error) { // Download plugin and activate
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-i", plugin]);
}
}
return true;
}
Expand Down Expand Up @@ -87,6 +89,11 @@ class LeetCodeExecutor {
return filePath;
}

public async showSolution(problemNode: IProblem, language: string): Promise<string> {
const solution: string = await this.executeCommandWithProgressEx("Fetching top voted solution from discussions...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "--solution", "-l", language]);
return solution;
}

public async getDescription(problemNode: IProblem): Promise<string> {
return await this.executeCommandWithProgressEx("Fetching problem description...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-x"]);
}
Expand Down
Loading

0 comments on commit 9b33df0

Please sign in to comment.