2
2
// Licensed under the MIT license.
3
3
4
4
import * as fse from "fs-extra" ;
5
+ import * as path from "path" ;
5
6
import * as vscode from "vscode" ;
6
7
import { LeetCodeNode } from "../explorer/LeetCodeNode" ;
8
+ import { leetCodeChannel } from "../leetCodeChannel" ;
7
9
import { leetCodeExecutor } from "../leetCodeExecutor" ;
8
10
import { leetCodeManager } from "../leetCodeManager" ;
9
11
import { IProblem , IQuickItemEx , languages , ProblemState } from "../shared" ;
@@ -16,15 +18,15 @@ export async function showProblem(node?: LeetCodeNode): Promise<void> {
16
18
if ( ! node ) {
17
19
return ;
18
20
}
19
- await showProblemInternal ( node . id ) ;
21
+ await showProblemInternal ( node ) ;
20
22
}
21
23
22
24
export async function searchProblem ( ) : Promise < void > {
23
25
if ( ! leetCodeManager . getUser ( ) ) {
24
26
promptForSignIn ( ) ;
25
27
return ;
26
28
}
27
- const choice : IQuickItemEx < string > | undefined = await vscode . window . showQuickPick (
29
+ const choice : IQuickItemEx < IProblem > | undefined = await vscode . window . showQuickPick (
28
30
parseProblemsToPicks ( list . listProblems ( ) ) ,
29
31
{
30
32
matchOnDetail : true ,
@@ -37,7 +39,7 @@ export async function searchProblem(): Promise<void> {
37
39
await showProblemInternal ( choice . value ) ;
38
40
}
39
41
40
- async function showProblemInternal ( id : string ) : Promise < void > {
42
+ async function showProblemInternal ( node : IProblem ) : Promise < void > {
41
43
try {
42
44
const leetCodeConfig : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "leetcode" ) ;
43
45
let defaultLanguage : string | undefined = leetCodeConfig . get < string > ( "defaultLanguage" ) ;
@@ -49,9 +51,21 @@ async function showProblemInternal(id: string): Promise<void> {
49
51
return ;
50
52
}
51
53
52
- const outDir : string = await selectWorkspaceFolder ( ) ;
54
+ let outDir : string = await selectWorkspaceFolder ( ) ;
55
+ let relativePath : string = ( leetCodeConfig . get < string > ( "outputFolder" ) || "" ) . trim ( ) ;
56
+ const matchResult : RegExpMatchArray | null = relativePath . match ( / \$ \{ ( .* ?) \} / ) ;
57
+ if ( matchResult ) {
58
+ const resolvedPath : string | undefined = await resolveRelativePath ( matchResult [ 1 ] . toLocaleLowerCase ( ) , node , language ) ;
59
+ if ( ! resolvedPath ) {
60
+ leetCodeChannel . appendLine ( "Showing problem canceled by user." ) ;
61
+ return ;
62
+ }
63
+ relativePath = resolvedPath ;
64
+ }
65
+
66
+ outDir = path . join ( outDir , relativePath ) ;
53
67
await fse . ensureDir ( outDir ) ;
54
- const result : string = await leetCodeExecutor . showProblem ( id , language , outDir ) ;
68
+ const result : string = await leetCodeExecutor . showProblem ( node . id , language , outDir ) ;
55
69
const reg : RegExp = / \* S o u r c e C o d e : \s * ( .* ) / ;
56
70
const match : RegExpMatchArray | null = result . match ( reg ) ;
57
71
if ( match && match . length >= 2 ) {
@@ -76,17 +90,17 @@ async function showProblemInternal(id: string): Promise<void> {
76
90
}
77
91
}
78
92
} catch ( error ) {
79
- await promptForOpenOutputChannel ( "Failed to fetch the problem information . Please open the output channel for details." , DialogType . error ) ;
93
+ await promptForOpenOutputChannel ( "Failed to show the problem. Please open the output channel for details." , DialogType . error ) ;
80
94
}
81
95
}
82
96
83
- async function parseProblemsToPicks ( p : Promise < IProblem [ ] > ) : Promise < Array < IQuickItemEx < string > > > {
84
- return new Promise ( async ( resolve : ( res : Array < IQuickItemEx < string > > ) => void ) : Promise < void > => {
85
- const picks : Array < IQuickItemEx < string > > = ( await p ) . map ( ( problem : IProblem ) => Object . assign ( { } , {
97
+ async function parseProblemsToPicks ( p : Promise < IProblem [ ] > ) : Promise < Array < IQuickItemEx < IProblem > > > {
98
+ return new Promise ( async ( resolve : ( res : Array < IQuickItemEx < IProblem > > ) => void ) : Promise < void > => {
99
+ const picks : Array < IQuickItemEx < IProblem > > = ( await p ) . map ( ( problem : IProblem ) => Object . assign ( { } , {
86
100
label : `${ parseProblemDecorator ( problem . state , problem . locked ) } ${ problem . id } .${ problem . name } ` ,
87
101
description : "" ,
88
102
detail : `AC rate: ${ problem . passRate } , Difficulty: ${ problem . difficulty } ` ,
89
- value : problem . id ,
103
+ value : problem ,
90
104
} ) ) ;
91
105
resolve ( picks ) ;
92
106
} ) ;
@@ -102,3 +116,28 @@ function parseProblemDecorator(state: ProblemState, locked: boolean): string {
102
116
return locked ? "$(lock) " : "" ;
103
117
}
104
118
}
119
+
120
+ async function resolveRelativePath ( value : string , node : IProblem , selectedLanguage : string ) : Promise < string | undefined > {
121
+ switch ( value ) {
122
+ case "tag" :
123
+ if ( node . tags . length === 1 ) {
124
+ return node . tags [ 0 ] ;
125
+ }
126
+ return await vscode . window . showQuickPick (
127
+ node . tags ,
128
+ {
129
+ matchOnDetail : true ,
130
+ placeHolder : "Multiple tags available, please select one" ,
131
+ ignoreFocusOut : true ,
132
+ } ,
133
+ ) ;
134
+ case "language" :
135
+ return selectedLanguage ;
136
+ case "difficulty" :
137
+ return node . difficulty ;
138
+ default :
139
+ const errorMsg : string = `The config '${ value } ' is not supported.` ;
140
+ leetCodeChannel . appendLine ( errorMsg ) ;
141
+ throw new Error ( errorMsg ) ;
142
+ }
143
+ }
0 commit comments