|
1 | 1 | import * as vscode from "vscode"; |
2 | 2 | import { isDefined } from "./helpers.ts"; |
3 | 3 | import { isPortAvailable, findAvailablePort } from "./portUtils.ts"; |
4 | | -import { getExecutableName, escapeJuliaCode } from "./platformUtils.ts"; |
| 4 | +import { getExecutableName } from "./platformUtils.ts"; |
5 | 5 |
|
6 | 6 | /** |
7 | 7 | * Parse Julia executable path to extract command and arguments |
@@ -156,29 +156,34 @@ export class PlutoServerTaskManager { |
156 | 156 |
|
157 | 157 | // Julia script that runs `jh auth env` and writes output to file |
158 | 158 | const jhCommand = getExecutableName("jh"); |
| 159 | + // Pass the auth file path via environment variable to avoid any escaping issues |
159 | 160 | const juliaScript = ` |
160 | | -try |
161 | | - output = read(\`${jhCommand} auth env\`, String) |
162 | | - open("${authOutputUri.fsPath}", "w") do io |
163 | | - write(io, output) |
164 | | - end |
| 161 | + s = string; auth_path = ENV[s(:VSCODE_PLUTO_AUTH_FILE)] |
| 162 | +try output = read(\`${jhCommand} auth env\`, String) |
| 163 | + open(io -> write(io, output), auth_path, s(:w)) |
165 | 164 | catch e |
166 | | - # Command failed or not found - write empty file to signal completion |
167 | | - open("${authOutputUri.fsPath}", "w") do io |
168 | | - write(io, "") |
169 | | - end |
170 | | -end; try read(\`${jhCommand} auth refresh\`, String) catch; end |
171 | | -`.trim(); |
| 165 | + open(io -> write(io, s()), auth_path, s(:w)) |
| 166 | +end |
| 167 | +try read(\`${jhCommand} auth refresh\`, String) |
| 168 | +catch e; |
| 169 | +end` |
| 170 | + .replaceAll("\n", ";") |
| 171 | + .trim(); |
172 | 172 |
|
173 | 173 | // Create task to run the Julia script |
174 | 174 | const authTaskDefinition: vscode.TaskDefinition = { |
175 | 175 | type: "pluto-auth-setup", |
176 | 176 | }; |
177 | 177 |
|
178 | | - const authExecution = new vscode.ShellExecution(defaultJulia, [ |
179 | | - "-e", |
180 | | - escapeJuliaCode(juliaScript), |
181 | | - ]); |
| 178 | + const authExecution = new vscode.ShellExecution( |
| 179 | + defaultJulia, |
| 180 | + ["-e", juliaScript], |
| 181 | + { |
| 182 | + env: { |
| 183 | + VSCODE_PLUTO_AUTH_FILE: authOutputUri.fsPath, |
| 184 | + }, |
| 185 | + } |
| 186 | + ); |
182 | 187 |
|
183 | 188 | const authTask = new vscode.Task( |
184 | 189 | authTaskDefinition, |
@@ -262,13 +267,8 @@ end; try read(\`${jhCommand} auth refresh\`, String) catch; end |
262 | 267 | const { command, args: baseArgs } = parseJuliaExecutable(executablePath); |
263 | 268 |
|
264 | 269 | // Build Julia command arguments |
265 | | - const plutoCode = `using Pluto; Pluto.run(port=${this.actualPort}; require_secret_for_open_links=false, require_secret_for_access=false, launch_browser=false)`; |
266 | | - const juliaArgs = [ |
267 | | - `+${juliaVersion}`, |
268 | | - ...baseArgs, |
269 | | - "-e", |
270 | | - escapeJuliaCode(plutoCode), |
271 | | - ]; |
| 270 | + const plutoCode = `import Pkg;s = string;Pkg.activate(mkpath(joinpath(Pkg.depots1(), s(:environments), s(:vscode_pluto_notebook), string(VERSION))));using Pluto; Pluto.run(port=${this.actualPort}; require_secret_for_open_links=false, require_secret_for_access=false, launch_browser=false)`; |
| 271 | + const juliaArgs = [`+${juliaVersion}`, ...baseArgs, "-e", plutoCode]; |
272 | 272 |
|
273 | 273 | console.log( |
274 | 274 | `[PlutoServerTask] Resolved command: ${command} ${juliaArgs.join(" ")}` |
@@ -306,12 +306,20 @@ end; try read(\`${jhCommand} auth refresh\`, String) catch; end |
306 | 306 | const juliaupTask = new vscode.Task( |
307 | 307 | juliaupTaskDefinition, |
308 | 308 | vscode.TaskScope.Workspace, |
309 | | - `Install Julia ${juliaVersion}`, |
| 309 | + `Pluto Server (port ${this.actualPort})`, |
310 | 310 | "pluto-notebook", |
311 | 311 | juliaupExecution, |
312 | 312 | [] |
313 | 313 | ); |
314 | 314 | juliaupTask.isBackground = false; |
| 315 | + juliaupTask.presentationOptions = { |
| 316 | + reveal: vscode.TaskRevealKind.Always, |
| 317 | + panel: vscode.TaskPanelKind.Shared, |
| 318 | + showReuseMessage: false, |
| 319 | + clear: false, |
| 320 | + focus: false, |
| 321 | + echo: true, |
| 322 | + }; |
315 | 323 |
|
316 | 324 | const juliaupTaskExecution = await vscode.tasks.executeTask(juliaupTask); |
317 | 325 | await new Promise<void>((resolve, reject) => { |
@@ -358,23 +366,39 @@ end; try read(\`${jhCommand} auth refresh\`, String) catch; end |
358 | 366 | }; |
359 | 367 |
|
360 | 368 | // Create an envrionment for the SERVER where Pluto will run in. Let julia manage paths |
361 | | - const setupCode = `import Pkg; Pkg.activate(mkpath(joinpath(Pkg.depots1(), "environments", "vscode-pluto-notebook", string(VERSION)))); Pkg.add("Pluto"); Pkg.instantiate(); Pkg.precompile();`; |
| 369 | + const setupCode = `import Pkg; |
| 370 | + s = string |
| 371 | + Pkg.activate(mkpath(joinpath(Pkg.depots1(), s(:environments), s(:vscode_pluto_notebook), string(VERSION)))); |
| 372 | + Pkg.Registry.add(); |
| 373 | + Pkg.add(s(:Pluto)); |
| 374 | + Pkg.instantiate(); |
| 375 | + Pkg.precompile();` |
| 376 | + .replaceAll("\n", ";") |
| 377 | + .trim(); |
362 | 378 | const setupExecution = new vscode.ShellExecution(command, [ |
363 | 379 | `+${juliaVersion}`, |
364 | 380 | ...baseArgs, |
365 | 381 | `-e`, |
366 | | - escapeJuliaCode(setupCode), |
| 382 | + setupCode, |
367 | 383 | ]); |
368 | 384 |
|
369 | 385 | const task1 = new vscode.Task( |
370 | 386 | setupTaskDefinition, |
371 | 387 | vscode.TaskScope.Workspace, |
372 | | - `Instantiate Pluto`, |
| 388 | + `Pluto Server (port ${this.actualPort})`, |
373 | 389 | "pluto-notebook", |
374 | 390 | setupExecution, |
375 | 391 | [] // No problem matchers |
376 | 392 | ); |
377 | 393 | task1.isBackground = false; |
| 394 | + task1.presentationOptions = { |
| 395 | + reveal: vscode.TaskRevealKind.Always, |
| 396 | + panel: vscode.TaskPanelKind.Shared, |
| 397 | + showReuseMessage: false, |
| 398 | + clear: false, |
| 399 | + focus: false, |
| 400 | + echo: true, |
| 401 | + }; |
378 | 402 |
|
379 | 403 | // Execute setup task and wait for it to complete |
380 | 404 | const setupExecution1 = await vscode.tasks.executeTask(task1); |
@@ -413,10 +437,10 @@ end; try read(\`${jhCommand} auth refresh\`, String) catch; end |
413 | 437 | [] // No problem matchers |
414 | 438 | ); |
415 | 439 |
|
416 | | - // Configure task presentation |
| 440 | + // Configure task presentation - use Shared panel to reuse the same terminal as setup task |
417 | 441 | task.presentationOptions = { |
418 | 442 | reveal: vscode.TaskRevealKind.Always, |
419 | | - panel: vscode.TaskPanelKind.Dedicated, |
| 443 | + panel: vscode.TaskPanelKind.Shared, |
420 | 444 | showReuseMessage: false, |
421 | 445 | clear: false, |
422 | 446 | focus: false, |
|
0 commit comments