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