zed-local

  1#!/usr/bin/env node
  2
  3const { spawn, execFileSync } = require("child_process");
  4
  5const RESOLUTION_REGEX = /(\d+) x (\d+)/;
  6const DIGIT_FLAG_REGEX = /^--?(\d+)$/;
  7const ZED_2_MODE = "--zed2";
  8const RELEASE_MODE = "--release";
  9
 10const args = process.argv.slice(2);
 11
 12// Parse the number of Zed instances to spawn.
 13let instanceCount = 1;
 14const digitMatch = args[0]?.match(DIGIT_FLAG_REGEX);
 15if (digitMatch) {
 16  instanceCount = parseInt(digitMatch[1]);
 17  args.shift();
 18}
 19const isZed2 = args.some((arg) => arg === ZED_2_MODE);
 20const isReleaseMode = args.some((arg) => arg === RELEASE_MODE);
 21if (instanceCount > 4) {
 22  throw new Error("Cannot spawn more than 4 instances");
 23}
 24
 25// Parse the resolution of the main screen
 26const displayInfo = JSON.parse(
 27  execFileSync("system_profiler", ["SPDisplaysDataType", "-json"], {
 28    encoding: "utf8",
 29  }),
 30);
 31const mainDisplayResolution =
 32  displayInfo?.SPDisplaysDataType[0]?.spdisplays_ndrvs
 33    ?.find((entry) => entry.spdisplays_main === "spdisplays_yes")
 34    ?._spdisplays_resolution?.match(RESOLUTION_REGEX);
 35if (!mainDisplayResolution) {
 36  throw new Error("Could not parse screen resolution");
 37}
 38const screenWidth = parseInt(mainDisplayResolution[1]);
 39const screenHeight = parseInt(mainDisplayResolution[2]);
 40
 41// Determine the window size for each instance
 42let instanceWidth = screenWidth;
 43let instanceHeight = screenHeight;
 44if (instanceCount > 1) {
 45  instanceWidth = Math.floor(screenWidth / 2);
 46  if (instanceCount > 2) {
 47    instanceHeight = Math.floor(screenHeight / 2);
 48  }
 49}
 50
 51let users = ["nathansobo", "as-cii", "maxbrunsfeld", "iamnbutler"];
 52
 53const RUST_LOG = process.env.RUST_LOG || "info";
 54
 55// If a user is specified, make sure it's first in the list
 56const user = process.env.ZED_IMPERSONATE;
 57if (user) {
 58  users = [user].concat(users.filter((u) => u !== user));
 59}
 60
 61const positions = [
 62  "0,0",
 63  `${instanceWidth},0`,
 64  `0,${instanceHeight}`,
 65  `${instanceWidth},${instanceHeight}`,
 66];
 67
 68const buildArgs = (() => {
 69  const buildArgs = ["build"];
 70  if (isReleaseMode) {
 71    buildArgs.push("--release");
 72  }
 73
 74  if (isZed2) {
 75    buildArgs.push("-p", "zed2");
 76  }
 77
 78  return buildArgs;
 79})();
 80const zedBinary = (() => {
 81  const target = isReleaseMode ? "release" : "debug";
 82  const binary = isZed2 ? "Zed2" : "Zed";
 83
 84  return `target/${target}/${binary}`;
 85})();
 86
 87execFileSync("cargo", buildArgs, { stdio: "inherit" });
 88setTimeout(() => {
 89  for (let i = 0; i < instanceCount; i++) {
 90    spawn(zedBinary, i == 0 ? args : [], {
 91      stdio: "inherit",
 92      env: {
 93        ZED_IMPERSONATE: users[i],
 94        ZED_WINDOW_POSITION: positions[i],
 95        ZED_STATELESS: "1",
 96        ZED_ALWAYS_ACTIVE: "1",
 97        ZED_SERVER_URL: "http://localhost:8080",
 98        ZED_ADMIN_API_TOKEN: "secret",
 99        ZED_WINDOW_SIZE: `${instanceWidth},${instanceHeight}`,
100        PATH: process.env.PATH,
101        RUST_LOG,
102      },
103    });
104  }
105}, 0.1);