fuzzyworld-tools / commit
VS Code in the browser: open a file with &file=<path>[:<line>]
README.md | 2 +- vscode-web/fw-fs/extension.js | 3 ++- vscode-web/index.html | 19 +++++++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fb41bb8..ca15ad8 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,7 @@ Without runner screenshots, the images in a public repo's `screenshots/` folder ## VS Code in the browser `apps.fuzzyworld.net/vscode/?repo=<name>` (and `&branch=<branch>` for an unmerged branch) opens a public repo in -VS Code, linked from each summary page. It is the open-source VS Code web build (the `vscode-web` npm package, +VS Code (add `&file=<path>` to open a file, `&file=<path>:<line>` to jump to a line), linked from each summary page. It is the open-source VS Code web build (the `vscode-web` npm package, 1.91.1, MIT) plus `vscode-web/fw-fs/`, an extension that reads `files.json` and `objects/<sha>` from code.fuzzyworld.net. Everything is static files; nothing can be changed (clone to edit). Quick open (Ctrl/Cmd+P) and search across files work; search reads text files up to 256 KB. Not yet: Markdown preview and other webviews diff --git a/vscode-web/fw-fs/extension.js b/vscode-web/fw-fs/extension.js index 9b853ac..0442d2f 100644 --- a/vscode-web/fw-fs/extension.js +++ b/vscode-web/fw-fs/extension.js @@ -173,7 +173,8 @@ exports.activate = function (context) { // domain per view, which this static site doesn't have yet; so it isn't opened by default.) async function openReadme() { const folder = vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders[0]; - if (!folder || folder.uri.scheme !== "fuzzyworld" || vscode.window.visibleTextEditors.length) return; + // index.html adds a query to the folder when the address has &file=: that file is opened instead. + if (!folder || folder.uri.scheme !== "fuzzyworld" || folder.uri.query || vscode.window.visibleTextEditors.length) return; try { const m = await manifest(folder.uri); const readme = [...m.dirs.get("").keys()].find((n) => /^readme(\.md|\.markdown|\.txt)?$/i.test(n)); diff --git a/vscode-web/index.html b/vscode-web/index.html index 53dbd31..808c7e4 100644 --- a/vscode-web/index.html +++ b/vscode-web/index.html @@ -1,5 +1,5 @@ <!doctype html> -<!-- VS Code in the browser for code.fuzzyworld.net: apps.fuzzyworld.net/vscode/?repo=<name>[&branch=<branch>]. +<!-- VS Code in the browser for code.fuzzyworld.net: apps.fuzzyworld.net/vscode/?repo=<name>[&branch=<branch>][&file=<path>[:<line>]]. Installed by vscode-web/install.sh, beside dist/ (the vscode-web build) and fw-fs/ (our read-only file system). --> <html lang="en"> <head> @@ -16,13 +16,18 @@ </head> <body aria-label=""> <script> - // Which repository: ?repo=<name>, optionally &branch=<branch> (the default branch otherwise). + // Which repository: ?repo=<name>, optionally &branch=<branch> (the default branch otherwise), + // and &file=<path>[:<line>] to open a file (and jump to a line) at startup. (function () { var q = new URLSearchParams(location.search); var repo = q.get("repo") || "", branch = q.get("branch") || ""; var okName = /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(repo); + var file = q.get("file") || "", line = 0; + var lm = /:(\d+)$/.exec(file); + if (lm) { line = +lm[1]; file = file.slice(0, lm.index); } + var okFile = !file || !(/^\/|\/$|\\|[\x00-\x1f]/.test(file) || file.split("/").some(function (s) { return s === "" || s === "." || s === ".."; })); var okBranch = !branch || (!/[\s~^:?*\[\\@]|\.\.|\/\/|^\/|\/$/.test(branch)); - if (!okName || !okBranch) { + if (!okName || !okBranch || !okFile) { document.body.innerHTML = '<div class="fw-missing"><h1>Which repository?</h1><p>Open a repository from its page on ' + '<a href="https://code.fuzzyworld.net/">code.fuzzyworld.net</a> ("Open in VS Code in the browser"), or add ' + '<code>?repo=<name></code> to this address.</p></div>'; @@ -42,7 +47,13 @@ // Webviews (e.g. Markdown preview) load from this site, not from Microsoft's CDN. webviewContentExternalBaseUrlTemplate: new URL("dist/out/vs/workbench/contrib/webview/browser/pre/", app).href, }, - folderUri: { scheme: "fuzzyworld", path: "/" + repo + (branch ? "@" + branch : "") }, + // The query marks a visit with &file=: fw-fs then leaves the README closed. File systems read only the path. + folderUri: { scheme: "fuzzyworld", path: "/" + repo + (branch ? "@" + branch : ""), query: file ? "file" : "" }, + // force: open the file on every visit, not only the first one to this workspace. + defaultLayout: file ? { force: true, editors: [{ + uri: { scheme: "fuzzyworld", path: "/" + repo + (branch ? "@" + branch : "") + "/" + file, query: "file" }, + options: line ? { selection: { startLineNumber: line, startColumn: 1 } } : undefined, + }] } : undefined, additionalBuiltinExtensions: [{ scheme: app.protocol.slice(0, -1), authority: app.host, path: app.pathname + "fw-fs" }], }; })();