Add Rome binary search to VSCode extension
MODIFY
package.json
package.json
"@types/react-dom": "^16.8.5",
"typescript": "^3.7.0"
},
+ "romeLSPBin": "./scripts/vendor-rome",
"scripts": {
- "rome": "./scripts/vendor-rome",
"dev-rome": "./scripts/dev-rome",
"test": "./scripts/dev-rome test",
"lint": "./scripts/dev-rome lint",

MODIFY
packages/@romejs-editor/vscode/src/extension.ts
packages/@romejs-editor/vscode/src/extension.ts
@@ -11,18 +11,130 @@ import {
ServerOptions,
TransportKind,
} from 'vscode-languageclient';
+import * as vscode from 'vscode';
+import path = require('path');
+import fs = require('fs');
+import os = require('os');
let client: LanguageClient;
-export function activate() {
+function crawl(root: string): Iterable<string> {
+ return {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ const value = root;
+ root = path.dirname(value);
+
+ return {
+ value,
+ done: root === '.' || root === '/',
+ };
+ },
+ };
+ },
+ };
+}
+
+async function tryChain(
+ root: string,
+ suffix: string,
+): Promise<undefined | string> {
+ for (const dir of crawl(root)) {
+ const possible = path.join(dir, suffix);
+
+ try {
+ await fs.promises.access(possible);
+ return possible;
+ } catch (err) {}
+ }
+}
+
+async function tryManifest(root: string): Promise<undefined | string> {
+ for (const dir of crawl(root)) {
+ const manifestLoc = path.join(dir, 'package.json');
+
+ try {
+ const content = await fs.promises.readFile(manifestLoc, 'utf8');
+ const json = JSON.parse(content);
+ if (json.romeLSPBin) {
+ return String(path.resolve(dir, json.romeLSPBin));
+ }
+ } catch (err) {
+ if (err instanceof SyntaxError || err.code === 'ENOENT') {
+ continue;
+ } else {
+ throw err;
+ }
+ }
+ }
+}
+
+async function getRomeLocation(): Promise<undefined | string> {
+ // Find relative to workspace folders
+ for (const {uri} of vscode.workspace.workspaceFolders) {
+ if (uri.scheme === 'file') {
+ const manifest = await tryManifest(uri.path);
+ if (manifest !== undefined) {
+ return manifest;
+ }
+
+ const nodeModules = await tryChain(
+ uri.path,
+ `node_modules/rome/index.js`,
+ );
+ if (nodeModules !== undefined) {
+ return nodeModules;
+ }
+ }
+ }
+
+ // Find development build
+ try {
+ const possible = path.join(os.tmpdir(), 'rome-dev', 'index.js');
+ await fs.promises.access(possible);
+ return possible;
+ } catch (err) {}
+}
+
+export async function activate() {
+ const outputChannel = vscode.window.createOutputChannel('Rome');
+
+ function log(message: string) {
+ outputChannel.appendLine(message);
+ }
+
+ let romePath: undefined | string = await getRomeLocation();
+
+ // If no romePath was found then watch workspace folders until we find one
+ if (romePath === undefined) {
+ log(
+ 'No Rome path found. Waiting for workspace folder changes before trying again',
+ );
+
+ await new Promise(resolve => {
+ const event = vscode.workspace.onDidChangeWorkspaceFolders(() => {
+ getRomeLocation().then(filename => {
+ if (filename !== undefined) {
+ romePath = filename;
+ event.dispose();
+ resolve();
+ }
+ });
+ });
+ });
+ }
+
+ log(`Discovered Rome path ${romePath}`);
+
let serverOptions: ServerOptions = {
- module: '/tmp/rome-dev/index.js',
+ module: romePath,
args: ['lsp'],
transport: TransportKind.stdio,
- runtime: 'node',
};
let clientOptions: LanguageClientOptions = {
+ outputChannel,
documentSelector: [
{scheme: 'file', language: 'javascript'},
{scheme: 'file', language: 'javascriptreact'},

Add Rome binary search to VSCode extension