Skip to content

Commit 11ebb4a

Browse files
Add Zed IDE module
Adds a new official module for Zed IDE integration with Coder workspaces. The module provides a one-click button to open workspaces in Zed IDE using the zed:// protocol. Features: - Configurable folder path - Customizable display name and order - Support for app grouping - External app integration Co-authored-by: matifali <[email protected]>
1 parent e95d90d commit 11ebb4a

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
display_name: Zed IDE
3+
description: Add a one-click button to launch Zed IDE
4+
icon: ../../../../.icons/zed.svg
5+
maintainer_github: coder
6+
verified: true
7+
tags: [ide, zed, editor]
8+
---
9+
10+
# Zed IDE
11+
12+
Add a button to open any workspace with a single click in Zed IDE.
13+
14+
Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
15+
16+
```tf
17+
module "zed" {
18+
count = data.coder_workspace.me.start_count
19+
source = "registry.coder.com/coder/zed/coder"
20+
version = "1.0.0"
21+
agent_id = coder_agent.example.id
22+
}
23+
```
24+
25+
## Examples
26+
27+
### Open in a specific directory
28+
29+
```tf
30+
module "zed" {
31+
count = data.coder_workspace.me.start_count
32+
source = "registry.coder.com/coder/zed/coder"
33+
version = "1.0.0"
34+
agent_id = coder_agent.example.id
35+
folder = "/home/coder/project"
36+
}
37+
```
38+
39+
### Custom display name and order
40+
41+
```tf
42+
module "zed" {
43+
count = data.coder_workspace.me.start_count
44+
source = "registry.coder.com/coder/zed/coder"
45+
version = "1.0.0"
46+
agent_id = coder_agent.example.id
47+
display_name = "Zed Editor"
48+
order = 1
49+
}
50+
```
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { describe, expect, it } from "bun:test";
2+
import {
3+
runTerraformApply,
4+
runTerraformInit,
5+
testRequiredVariables,
6+
} from "~test";
7+
8+
describe("zed", async () => {
9+
await runTerraformInit(import.meta.dir);
10+
11+
testRequiredVariables(import.meta.dir, {
12+
agent_id: "foo",
13+
});
14+
15+
it("default output", async () => {
16+
const state = await runTerraformApply(import.meta.dir, {
17+
agent_id: "foo",
18+
});
19+
expect(state.outputs.zed_url.value).toBe(
20+
"zed://ssh/default.default.coder/",
21+
);
22+
23+
const coder_app = state.resources.find(
24+
(res) => res.type === "coder_app" && res.name === "zed",
25+
);
26+
27+
expect(coder_app).not.toBeNull();
28+
expect(coder_app?.instances.length).toBe(1);
29+
expect(coder_app?.instances[0].attributes.order).toBeNull();
30+
});
31+
32+
it("adds folder", async () => {
33+
const state = await runTerraformApply(import.meta.dir, {
34+
agent_id: "foo",
35+
folder: "/foo/bar",
36+
});
37+
expect(state.outputs.zed_url.value).toBe(
38+
"zed://ssh/default.default.coder/foo/bar",
39+
);
40+
});
41+
42+
it("expect order to be set", async () => {
43+
const state = await runTerraformApply(import.meta.dir, {
44+
agent_id: "foo",
45+
order: "22",
46+
});
47+
48+
const coder_app = state.resources.find(
49+
(res) => res.type === "coder_app" && res.name === "zed",
50+
);
51+
52+
expect(coder_app).not.toBeNull();
53+
expect(coder_app?.instances.length).toBe(1);
54+
expect(coder_app?.instances[0].attributes.order).toBe(22);
55+
});
56+
57+
it("expect display_name to be set", async () => {
58+
const state = await runTerraformApply(import.meta.dir, {
59+
agent_id: "foo",
60+
display_name: "Custom Zed",
61+
});
62+
63+
const coder_app = state.resources.find(
64+
(res) => res.type === "coder_app" && res.name === "zed",
65+
);
66+
67+
expect(coder_app).not.toBeNull();
68+
expect(coder_app?.instances.length).toBe(1);
69+
expect(coder_app?.instances[0].attributes.display_name).toBe("Custom Zed");
70+
});
71+
});

registry/coder/modules/zed/main.tf

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
coder = {
6+
source = "coder/coder"
7+
version = ">= 2.5"
8+
}
9+
}
10+
}
11+
12+
variable "agent_id" {
13+
type = string
14+
description = "The ID of a Coder agent."
15+
}
16+
17+
variable "folder" {
18+
type = string
19+
description = "The folder to open in Zed IDE."
20+
default = ""
21+
}
22+
23+
variable "order" {
24+
type = number
25+
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)."
26+
default = null
27+
}
28+
29+
variable "group" {
30+
type = string
31+
description = "The name of a group that this app belongs to."
32+
default = null
33+
}
34+
35+
variable "slug" {
36+
type = string
37+
description = "The slug of the app."
38+
default = "zed"
39+
}
40+
41+
variable "display_name" {
42+
type = string
43+
description = "The display name of the app."
44+
default = "Zed IDE"
45+
}
46+
47+
data "coder_workspace" "me" {}
48+
data "coder_workspace_owner" "me" {}
49+
50+
locals {
51+
workspace_name = lower(data.coder_workspace.me.name)
52+
owner_name = lower(data.coder_workspace_owner.me.name)
53+
hostname = "${local.workspace_name}.${local.owner_name}.coder"
54+
}
55+
56+
resource "coder_app" "zed" {
57+
agent_id = var.agent_id
58+
display_name = var.display_name
59+
slug = var.slug
60+
icon = "/icon/zed.svg"
61+
external = true
62+
order = var.order
63+
group = var.group
64+
url = "zed://ssh/${local.hostname}/${var.folder}"
65+
}
66+
67+
output "zed_url" {
68+
value = coder_app.zed.url
69+
description = "Zed IDE URL."
70+
}

0 commit comments

Comments
 (0)