diff --git a/addons/vscode/src/extension.ts b/addons/vscode/src/extension.ts index a8f71a42..045f80cf 100644 --- a/addons/vscode/src/extension.ts +++ b/addons/vscode/src/extension.ts @@ -152,7 +152,14 @@ function syncEditorChanges(addonΠserver: WebSocket) { })); } -function runServer(command: string, args: string[], outputChannel: vscode.OutputChannel): Promise<[string, string, ChildProcessWithoutNullStreams]> { +interface LaunchCliResult { + serverProcess: ChildProcessWithoutNullStreams, + controlPlanePort: string, + dataPlanePort: string, + staticFilePort?: string, +} + +function runServer(command: string, args: string[], outputChannel: vscode.OutputChannel, openInBrowser: boolean): Promise { const serverProcess = spawn(command, args, { env: { ...process.env, @@ -181,19 +188,30 @@ function runServer(command: string, args: string[], outputChannel: vscode.Output return new Promise((resolve, reject) => { let dataPlanePort: string | undefined = undefined; let controlPlanePort: string | undefined = undefined; + let staticFilePort: string | undefined = undefined; serverProcess.stderr.on('data', (data: Buffer) => { if (data.toString().includes("listening on")) { console.log(data.toString()); let ctrlPort = data.toString().match(/Control plane server listening on: 127\.0\.0\.1:(\d+)/)?.[1]; let dataPort = data.toString().match(/Data plane server listening on: 127\.0\.0\.1:(\d+)/)?.[1]; + let staticPort = data.toString().match(/Static file server listening on: 127\.0\.0\.1:(\d+)/)?.[1]; if (ctrlPort !== undefined) { controlPlanePort = ctrlPort; } if (dataPort !== undefined) { dataPlanePort = dataPort; } + if (staticPort !== undefined) { + staticFilePort = staticPort; + } if (dataPlanePort !== undefined && controlPlanePort !== undefined) { - resolve([dataPlanePort, controlPlanePort, serverProcess]); + if (openInBrowser) { + if (staticFilePort !== undefined) { + resolve({ dataPlanePort, controlPlanePort, staticFilePort, serverProcess }); + } + } else { + resolve({ dataPlanePort, controlPlanePort, serverProcess }); + } } } }); @@ -353,9 +371,9 @@ const launchPreview = async (task: LaunchInBrowserTask | LaunchInWebViewTask) => console.log(`Watching ${filePath} for changes`); const projectRoot = getProjectRoot(filePath); const rootArgs = ["--root", projectRoot]; - const staticFileArgs = openInBrowser ? ["--open-in-browser", "--open-in-browser-host", "127.0.0.1:0"] : []; + const staticFileArgs = openInBrowser ? ["--server-static-file", "--static-file-host", "127.0.0.1:0"] : []; const partialRenderingArgs = vscode.workspace.getConfiguration().get('typst-preview.partialRendering') ? ["--partial-rendering"] : []; - const [dataPlanePort, controlPlanePort, serverProcess] = await runServer(serverPath, [ + const { dataPlanePort, controlPlanePort, staticFilePort, serverProcess } = await runServer(serverPath, [ "--data-plane-host", "127.0.0.1:0", "--control-plane-host", "127.0.0.1:0", ...rootArgs, @@ -363,8 +381,11 @@ const launchPreview = async (task: LaunchInBrowserTask | LaunchInWebViewTask) => ...partialRenderingArgs, ...codeGetCliFontArgs(), filePath, - ], outputChannel); + ], outputChannel, openInBrowser); console.log(`Launched server, data plane port:${dataPlanePort}, control plane port:${controlPlanePort}`); + if (openInBrowser) { + vscode.env.openExternal(vscode.Uri.parse(`http://127.0.0.1:${staticFilePort}`)); + } // window.typstWebsocket.send("current"); return { serverProcess, dataPlanePort, controlPlanePort diff --git a/src/args.rs b/src/args.rs index 528a4bba..2dfa4f58 100644 --- a/src/args.rs +++ b/src/args.rs @@ -31,15 +31,19 @@ pub struct CliArguments { /// Host to open the preview in the browser. #[clap( - long = "open-in-browser-host", + long = "static-file-host", value_name = "HOST", default_value = "127.0.0.1:23627" )] - pub open_in_browser_host: String, + pub static_file_host: String, /// Open the preview in the browser after compilation. #[clap(long = "open-in-browser")] pub open_in_browser: bool, + + /// Serve html for preview in the browser. + #[clap(long = "server-static-file")] + pub server_static_file: bool, /// Only render visible part of the document. This can improve performance but still being experimental. #[clap(long = "partial-rendering")] diff --git a/src/main.rs b/src/main.rs index d8da4be1..fb34df0f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -481,8 +481,8 @@ async fn main() { } } }); - let static_file_addr = arguments.open_in_browser_host; - if arguments.open_in_browser { + let static_file_addr = arguments.static_file_host; + if arguments.server_static_file || arguments.open_in_browser { let data_plane_port = data_plane_port_rx.await.unwrap(); let make_service = make_service_fn(|_| { let data_plane_port = data_plane_port; @@ -510,9 +510,11 @@ async fn main() { } }); let server = hyper::Server::bind(&static_file_addr.parse().unwrap()).serve(make_service); - if let Err(e) = open::that_detached(format!("http://{}", server.local_addr())) { - error!("failed to open browser: {}", e); - }; + if arguments.open_in_browser { + if let Err(e) = open::that_detached(format!("http://{}", server.local_addr())) { + error!("failed to open browser: {}", e); + }; + } info!("Static file server listening on: {}", server.local_addr()); if let Err(e) = server.await { error!("Static file server error: {}", e);