Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .icons/zed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions registry/coder/modules/zed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
display_name: Zed
description: Add a one-click button to launch Zed
icon: ../../../../.icons/zed.svg
maintainer_github: coder
verified: true
tags: [ide, zed, editor]
---

# Zed

Add a button to open any workspace with a single click in Zed.

Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.

> [!IMPORTANT]
> Zed needs you to either have Coder CLI installed with `coder config-ssh` run or [Coder Desktop](https://coder.com/docs/user-guides/desktop)

```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
}
```

## Examples

### Open in a specific directory

```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
folder = "/home/coder/project"
}
```

### Custom display name and order

```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
display_name = "Zed Editor"
order = 1
}
```

### With custom agent name

```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
agent_name = coder_agent.example.name
}
```
81 changes: 81 additions & 0 deletions registry/coder/modules/zed/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { describe, expect, it } from "bun:test";
import {
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "~test";

describe("zed", async () => {
await runTerraformInit(import.meta.dir);

testRequiredVariables(import.meta.dir, {
agent_id: "foo",
});

it("default output", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
});
expect(state.outputs.zed_url.value).toBe(
"zed://ssh/default.coder",
);

const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "zed",
);

expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBeNull();
});

it("adds folder", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
folder: "/foo/bar",
});
expect(state.outputs.zed_url.value).toBe(
"zed://ssh/default.coder/foo/bar",
);
});

it("expect order to be set", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
order: "22",
});

const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "zed",
);

expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBe(22);
});

it("expect display_name to be set", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
display_name: "Custom Zed",
});

const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "zed",
);

expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.display_name).toBe("Custom Zed");
});

it("adds agent_name to hostname", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
agent_name: "myagent",
});
expect(state.outputs.zed_url.value).toBe(
"zed://ssh/myagent.default.default.coder",
);
});
});
77 changes: 77 additions & 0 deletions registry/coder/modules/zed/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
terraform {
required_version = ">= 1.0"

required_providers {
coder = {
source = "coder/coder"
version = ">= 2.5"
}
}
}

variable "agent_id" {
type = string
description = "The ID of a Coder agent"
}

variable "agent_name" {
type = string
description = "The name of the agent"
default = ""
}

variable "folder" {
type = string
description = "The folder to open in Zed"
default = ""
}

variable "order" {
type = number
description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)"
default = null
}

variable "group" {
type = string
description = "The name of a group that this app belongs to"
default = null
}

variable "slug" {
type = string
description = "The slug of the app"
default = "zed"
}

variable "display_name" {
type = string
description = "The display name of the app"
default = "Zed"
}

data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

locals {
workspace_name = lower(data.coder_workspace.me.name)
owner_name = lower(data.coder_workspace_owner.me.name)
agent_name = lower(var.agent_name)
hostname = var.agent_name != "" ? "${local.agent_name}.${local.workspace_name}.${local.owner_name}.coder" : "${local.workspace_name}.coder"
}

resource "coder_app" "zed" {
agent_id = var.agent_id
display_name = var.display_name
slug = var.slug
icon = "/icon/zed.svg"
external = true
order = var.order
group = var.group
url = "zed://ssh/${local.hostname}${var.folder}"
}

output "zed_url" {
value = coder_app.zed.url
description = "Zed URL"
}