Skip to content

Commit c0218ec

Browse files
committed
Added back file picker for competitive companion
1 parent 51ae67a commit c0218ec

File tree

2 files changed

+55
-33
lines changed

2 files changed

+55
-33
lines changed

src/extension/utils/asyncQueue.ts

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/extension/utils/competitiveCompanion.ts

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,50 @@ import * as v from "valibot";
66

77
import { ProblemSchema } from "~shared/schemas";
88
import type JudgeViewProvider from "~extension/providers/JudgeViewProvider";
9-
import { AsyncQueue } from "./asyncQueue";
109

1110
type Problem = v.InferOutput<typeof ProblemSchema>;
1211

12+
/**
13+
* Queue that processes problems sequentially as they arrive from Competitive Companion.
14+
* Gathers workspace files once before processing a batch of problems.
15+
*/
16+
class ProblemQueue {
17+
private queue: Problem[] = [];
18+
private processing = false;
19+
20+
constructor(private processor: (problem: Problem, files: vscode.Uri[]) => Promise<void>) {}
21+
22+
enqueue(problem: Problem): void {
23+
this.queue.push(problem);
24+
void this.processNext();
25+
}
26+
27+
private async processNext(): Promise<void> {
28+
if (this.processing || this.queue.length === 0) return;
29+
30+
this.processing = true;
31+
const files = await gatherWorkspaceFiles();
32+
while (this.queue.length > 0) {
33+
const problem = this.queue.shift()!;
34+
await this.processor(problem, files);
35+
}
36+
this.processing = false;
37+
}
38+
}
39+
1340
// Module state
1441
let server: http.Server | undefined;
1542
let statusBarItem: vscode.StatusBarItem | undefined;
1643

1744
/**
18-
* Shows a QuickPick to let the user select a target file for testcases.
45+
* Shows a QuickPick to let the user select a target file for testcases,
46+
* with the files provided.
1947
*/
2048
async function promptForTargetFile(
2149
problem: Problem,
2250
workspaceRoot: string,
23-
defaultValue: string
51+
defaultValue: string,
52+
files: vscode.Uri[]
2453
): Promise<string> {
2554
const config = vscode.workspace.getConfiguration("fastolympiccoding");
2655
const includePattern = config.get<string>("includePattern")!;
@@ -32,10 +61,15 @@ async function promptForTargetFile(
3261
description: path.parse(path.relative(workspaceRoot, file.fsPath)).dir,
3362
}));
3463

64+
const options = files.map((file) => ({
65+
label: path.parse(file.fsPath).base,
66+
description: path.parse(path.relative(workspaceRoot, file.fsPath)).dir,
67+
}));
68+
3569
const pick = vscode.window.createQuickPick();
3670
pick.title = `Testcases for "${problem.name}"`;
3771
pick.placeholder = "Full file path to put testcases onto";
38-
pick.value = defaultValue;
72+
pick.items = options;
3973
pick.ignoreFocusOut = true;
4074
pick.items = items;
4175
pick.show();
@@ -53,7 +87,11 @@ async function promptForTargetFile(
5387
/**
5488
* Processes a single problem received from Competitive Companion.
5589
*/
56-
async function processProblem(problem: Problem, judge: JudgeViewProvider): Promise<void> {
90+
async function processProblem(
91+
problem: Problem,
92+
judge: JudgeViewProvider,
93+
files: vscode.Uri[]
94+
): Promise<void> {
5795
const activeFile = vscode.window.activeTextEditor?.document.fileName;
5896
const workspaceRoot = vscode.workspace.workspaceFolders?.at(0)?.uri.fsPath ?? "";
5997
const config = vscode.workspace.getConfiguration("fastolympiccoding");
@@ -66,7 +104,7 @@ async function processProblem(problem: Problem, judge: JudgeViewProvider): Promi
66104
let relativePath = isSingleProblem && activeFile ? path.relative(workspaceRoot, activeFile) : "";
67105

68106
if (needsPrompt) {
69-
relativePath = await promptForTargetFile(problem, workspaceRoot, relativePath);
107+
relativePath = await promptForTargetFile(problem, workspaceRoot, relativePath, files);
70108
}
71109

72110
if (relativePath === "") {
@@ -85,11 +123,21 @@ async function processProblem(problem: Problem, judge: JudgeViewProvider): Promi
85123
}
86124
}
87125

126+
/**
127+
* Gather files using VSCode's API with include and exclude patterns from settings.
128+
*/
129+
async function gatherWorkspaceFiles(): Promise<vscode.Uri[]> {
130+
const config = vscode.workspace.getConfiguration("fastolympiccoding");
131+
const includePattern = config.get<string>("includePattern")!;
132+
const excludePattern = config.get<string>("excludePattern")!;
133+
return vscode.workspace.findFiles(includePattern, excludePattern);
134+
}
135+
88136
/**
89137
* Creates the request handler for the Competitive Companion HTTP server.
90138
*/
91139
function createRequestHandler(judge: JudgeViewProvider): http.RequestListener {
92-
const problemQueue = new AsyncQueue<Problem>((problem) => processProblem(problem, judge));
140+
const problemQueue = new ProblemQueue((problem, files) => processProblem(problem, judge, files));
93141

94142
return (req, res) => {
95143
if (req.method !== "POST") {

0 commit comments

Comments
 (0)