From 897597da8365475c00dec14bcba2c22dd067dcb9 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Mon, 16 Jun 2025 20:54:52 +0800 Subject: [PATCH 1/8] Revert "build: bump source-lsp version to 0.1.8 (#15)" This reverts commit abc9b3247cbbc1a8c2347bddc6dde5c3407f0625. --- scripts/lsp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/lsp.js b/scripts/lsp.js index 1930ba6..b376fc7 100644 --- a/scripts/lsp.js +++ b/scripts/lsp.js @@ -22,7 +22,7 @@ async function main() { async function downloadLsp() { const outputFolder = getOutputDir(); - const version = "0.1.8"; + const version = "0.1.4"; const lspFilename = "source-lsp.js"; const url = `https://github.com/source-academy/source-lsp/releases/download/v${version}/${lspFilename}`; // const url = `https://github.com/source-academy/source-lsp/releases/latest/download/${lspFilename}`; From 24fe90e72817ea7cd07873e2771f9b08f60928d6 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Tue, 17 Jun 2025 12:24:43 +0800 Subject: [PATCH 2/8] Use documentChangeEvent to check for any changes faster --- scripts/lsp.js | 2 +- src/utils/editor.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/lsp.js b/scripts/lsp.js index b376fc7..1930ba6 100644 --- a/scripts/lsp.js +++ b/scripts/lsp.js @@ -22,7 +22,7 @@ async function main() { async function downloadLsp() { const outputFolder = getOutputDir(); - const version = "0.1.4"; + const version = "0.1.8"; const lspFilename = "source-lsp.js"; const url = `https://github.com/source-academy/source-lsp/releases/download/v${version}/${lspFilename}`; // const url = `https://github.com/source-academy/source-lsp/releases/latest/download/${lspFilename}`; diff --git a/src/utils/editor.ts b/src/utils/editor.ts index 95a7d30..6a3fd62 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -73,7 +73,11 @@ export class Editor { ].join("\n"); await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)).then( - () => null, + (value) => { + if (value.toString() !== contents) { + console.log("editor code changed while offline") + } + }, async () => { self.log(`Opening file failed, creating at ${filePath}`); await vscode.workspace.fs.writeFile( @@ -94,12 +98,12 @@ export class Editor { vscode.commands.executeCommand("editor.fold"); self.editor = editor; - vscode.workspace.onDidChangeTextDocument(() => { + vscode.workspace.onDidChangeTextDocument((e: vscode.TextDocumentChangeEvent) => { if (!self.onChangeCallback) { return; } const text = editor.document.getText(); - if (self.code === text) { + if (e.contentChanges.length === 0) { self.log(`EXTENSION: Editor's code did not change, ignoring`); return; } @@ -109,7 +113,7 @@ export class Editor { ); return; } - self.log(`EXTENSION: Editor's code changed! ${text}`); + self.log(`EXTENSION: Editor's code changed!`); self.onChangeCallback(self); self.code = text; }); From fca7b3692ea5aa3ed705791ee5287a9681161756 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Tue, 17 Jun 2025 12:38:25 +0800 Subject: [PATCH 3/8] prompt user to pick local or server --- src/utils/editor.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/utils/editor.ts b/src/utils/editor.ts index 6a3fd62..a269862 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -71,11 +71,27 @@ export class Editor { "// END PREPEND", initialCode, ].join("\n"); + self.log(contents) await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)).then( (value) => { if (value.toString() !== contents) { - console.log("editor code changed while offline") + self.log("EXTENSION: Conflict detected between local and remote, prompting user to choose one") + vscode.window + .showInformationMessage( + "The program on file differs from the one on the Source Academy servers." + + "Which program should we use? (Note that picking one will overwrite the other)", + "Local", "Server") + .then(async answer => { + // By default the code displayed is the local one + if (answer === "Server") { + await vscode.workspace.fs.writeFile( + uri, + new TextEncoder().encode(contents), + ); + } + }) + } }, async () => { From dbf466084a319d7600d526db4c68380f0dbbe34c Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Tue, 17 Jun 2025 12:47:01 +0800 Subject: [PATCH 4/8] Changed logs --- src/utils/editor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/editor.ts b/src/utils/editor.ts index a269862..43cd5a7 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -71,7 +71,6 @@ export class Editor { "// END PREPEND", initialCode, ].join("\n"); - self.log(contents) await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)).then( (value) => { @@ -85,6 +84,7 @@ export class Editor { .then(async answer => { // By default the code displayed is the local one if (answer === "Server") { + self.log('EXTENSION: Saving program from server to file') await vscode.workspace.fs.writeFile( uri, new TextEncoder().encode(contents), From 634958ad519f4cddb2f2e3b35b5172048e9457e4 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Fri, 20 Jun 2025 17:03:03 +0800 Subject: [PATCH 5/8] Implemented message passing for chapter-selection --- package.json | 2 +- src/commands/showPanel.tsx | 9 +++++++++ src/utils/editor.ts | 29 +++++++++++++++++------------ src/utils/messages.ts | 11 +++++++++++ 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 442792d..b19d949 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "properties": { "source-academy.frontendBaseUrl": { "type": "string", - "default": "https://frontend.cloud.heyzec.dedyn.io", + "default": "http://localhost:8000", "description": "URL to the Source Academy frontend" } } diff --git a/src/commands/showPanel.tsx b/src/commands/showPanel.tsx index a390108..d930626 100644 --- a/src/commands/showPanel.tsx +++ b/src/commands/showPanel.tsx @@ -85,6 +85,15 @@ async function handleMessage( sendToFrontend(panel, message); }); break; + case MessageTypeNames.ChangeChapter: { + const info = context.globalState.get("info") ?? {}; + const uri = vscode.Uri.file(Editor.getFilePath(message.assessmentName, message.questionId)).toString(); + + _.set(info, `["${uri}"].chapter`, message.chapter ?? 1); + context.globalState.update("info", info); + client.sendRequest("source/publishInfo", info); + break; + } // case MessageTypeNames.Text: // if (!activeEditor) { // console.log("ERROR: activeEditor is not set"); diff --git a/src/utils/editor.ts b/src/utils/editor.ts index 43cd5a7..2952a7c 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -37,18 +37,7 @@ export class Editor { return this.editor?.document.getText(); } - // TODO: This method is too loaded, it's not obvious it also shows the editor - static async create( - workspaceLocation: VscWorkspaceLocation, - assessmentName: string, - questionId: number, - prepend: string = "", - initialCode: string = "", - ): Promise { - const self = new Editor(workspaceLocation, assessmentName, questionId); - self.assessmentName = assessmentName; - self.questionId = questionId; - + static getFilePath(assessmentName: string, questionId: number): string { let workspaceFolder = config.workspaceFolder; if (!workspaceFolder) { workspaceFolder = path.join(os.homedir(), ".sourceacademy"); @@ -62,6 +51,22 @@ export class Editor { `${assessmentName}_${questionId}.js`, ); + return filePath + } + + // TODO: This method is too loaded, it's not obvious it also shows the editor + static async create( + workspaceLocation: VscWorkspaceLocation, + assessmentName: string, + questionId: number, + prepend: string = "", + initialCode: string = "", + ): Promise { + const self = new Editor(workspaceLocation, assessmentName, questionId); + self.assessmentName = assessmentName; + self.questionId = questionId; + + const filePath = this.getFilePath(assessmentName, questionId); const uri = vscode.Uri.file(filePath); self.uri = uri.toString(); diff --git a/src/utils/messages.ts b/src/utils/messages.ts index e2a6d36..9b5088f 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -40,6 +40,17 @@ const Messages = createMessages({ EvalEditor: (workspaceLocation: VscWorkspaceLocation) => ({ workspaceLocation: workspaceLocation, }), + ChangeChapter: ( + assessmentName: string, + questionId: number, + chapter: number, + variant: string + ) => ({ + assessmentName, + questionId, + chapter, + variant + }) }); export default Messages; From 9517c538b89efba5fba75277e7855d4a9c583eb0 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Sat, 21 Jun 2025 17:09:14 +0800 Subject: [PATCH 6/8] added warning for selecting variants --- src/commands/showPanel.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/commands/showPanel.tsx b/src/commands/showPanel.tsx index d930626..970e2db 100644 --- a/src/commands/showPanel.tsx +++ b/src/commands/showPanel.tsx @@ -92,6 +92,13 @@ async function handleMessage( _.set(info, `["${uri}"].chapter`, message.chapter ?? 1); context.globalState.update("info", info); client.sendRequest("source/publishInfo", info); + + if (message.variant !== "default") { + vscode.window.showInformationMessage(`The Language Server does not support any variants, the + Language Server will use Source ยง${message.chapter}, but it is not guaranteed to be accurate.`) + } + + break; } // case MessageTypeNames.Text: From c0a92eb938a588aa9b70b245e6965b0e184d4239 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Sat, 21 Jun 2025 17:11:35 +0800 Subject: [PATCH 7/8] revert frontend url --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b19d949..442792d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "properties": { "source-academy.frontendBaseUrl": { "type": "string", - "default": "http://localhost:8000", + "default": "https://frontend.cloud.heyzec.dedyn.io", "description": "URL to the Source Academy frontend" } } From 86aaf21eb25917322ff237fa855f5ef03f9725a9 Mon Sep 17 00:00:00 2001 From: mug1wara26 Date: Thu, 26 Jun 2025 18:50:13 +0800 Subject: [PATCH 8/8] fix merge issues --- src/utils/editor.ts | 66 +------------------------------------------ src/utils/messages.ts | 6 ++-- 2 files changed, 4 insertions(+), 68 deletions(-) diff --git a/src/utils/editor.ts b/src/utils/editor.ts index a92708d..9a5740d 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -38,37 +38,14 @@ export class Editor { return this.editor?.document.getText(); } -<<<<<<< chapter-selection static getFilePath(assessmentName: string, questionId: number): string { - let workspaceFolder = config.workspaceFolder; - if (!workspaceFolder) { - workspaceFolder = path.join(os.homedir(), ".sourceacademy"); - // TODO: Prompt the user to make this folder the default, and then set back to the config store. - } else if (!path.isAbsolute(workspaceFolder)) { - workspaceFolder = path.join(os.homedir(), workspaceFolder); - } -======= - // TODO: This method is too loaded, it's not obvious it also shows the editor - static async create( - workspaceLocation: VscWorkspaceLocation, - assessmentName: string, - questionId: number, - prepend: string = "", - initialCode: string = "", - ): Promise { - const self = new Editor(workspaceLocation, assessmentName, questionId); - self.assessmentName = assessmentName; - self.questionId = questionId; - const workspaceFolder = canonicaliseLocation(config.workspaceFolder); ->>>>>>> main - const filePath = path.join( workspaceFolder, `${assessmentName}_${questionId}.js`, ); - return filePath + return filePath; } // TODO: This method is too loaded, it's not obvious it also shows the editor @@ -100,18 +77,6 @@ export class Editor { await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)).then( (value) => { if (value.toString() !== contents) { -<<<<<<< chapter-selection - self.log("EXTENSION: Conflict detected between local and remote, prompting user to choose one") - vscode.window - .showInformationMessage( - "The program on file differs from the one on the Source Academy servers." + - "Which program should we use? (Note that picking one will overwrite the other)", - "Local", "Server") - .then(async answer => { - // By default the code displayed is the local one - if (answer === "Server") { - self.log('EXTENSION: Saving program from server to file') -======= self.log( "EXTENSION: Conflict detected between local and remote, prompting user to choose one", ); @@ -128,16 +93,10 @@ export class Editor { // By default the code displayed is the local one if (answer === "Yes") { self.log("EXTENSION: Saving program from server to file"); ->>>>>>> main await vscode.workspace.fs.writeFile( uri, new TextEncoder().encode(contents), ); -<<<<<<< chapter-selection - } - }) - -======= } else if (answer === undefined) { // Modal cancelled const message = Messages.Text( @@ -147,7 +106,6 @@ export class Editor { sendToFrontendWrapped(message); } }); ->>>>>>> main } }, async () => { @@ -171,27 +129,6 @@ export class Editor { vscode.commands.executeCommand("editor.fold"); self.editor = editor; -<<<<<<< chapter-selection - vscode.workspace.onDidChangeTextDocument((e: vscode.TextDocumentChangeEvent) => { - if (!self.onChangeCallback) { - return; - } - const text = editor.document.getText(); - if (e.contentChanges.length === 0) { - self.log(`EXTENSION: Editor's code did not change, ignoring`); - return; - } - if (Date.now() - self.replaceTime < 1000) { - self.log( - `EXTENSION: Ignoring change event, ${Date.now() - self.replaceTime}ms since last replace`, - ); - return; - } - self.log(`EXTENSION: Editor's code changed!`); - self.onChangeCallback(self); - self.code = text; - }); -======= vscode.workspace.onDidChangeTextDocument( (e: vscode.TextDocumentChangeEvent) => { if (!self.onChangeCallback) { @@ -213,7 +150,6 @@ export class Editor { self.code = text; }, ); ->>>>>>> main return self; } diff --git a/src/utils/messages.ts b/src/utils/messages.ts index b136195..29b15fc 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -52,13 +52,13 @@ const Messages = createMessages({ assessmentName: string, questionId: number, chapter: number, - variant: string + variant: string, ) => ({ assessmentName, questionId, chapter, - variant - }) + variant, + }), NotifyAssessmentsOverview: ( assessmentOverviews: VscAssessmentOverview[], courseId: number,