1---
2title: Go
3description: "Configure Go language support in Zed, including language servers, formatting, and debugging."
4---
5
6# Go
7
8Go support is available natively in Zed.
9
10- Tree-sitter: [tree-sitter/tree-sitter-go](https://github.com/tree-sitter/tree-sitter-go)
11- Language Server: [golang/tools/tree/master/gopls](https://github.com/golang/tools/tree/master/gopls)
12- Debug Adapter: [delve](https://github.com/go-delve/delve)
13
14## Setup
15
16We recommend installing gopls via go's package manager and not via Homebrew or your Linux distribution's package manager.
17
181. Make sure you have uninstalled any version of gopls you have installed via your package manager:
19
20```sh
21# MacOS homebrew
22brew remove gopls
23# Ubuntu
24sudo apt-get remove gopls
25sudo snap remove gopls
26# Arch
27sudo pacman -R gopls
28```
29
302. Install/Update `gopls` to the latest version using the go module tool:
31
32```sh
33go install golang.org/x/tools/gopls@latest
34```
35
363. Ensure that `gopls` is in your path:
37
38```sh
39which gopls
40gopls version
41```
42
43If `gopls` is not found you will likely need to add `export PATH="$PATH:$HOME/go/bin"` to your `.zshrc` / `.bash_profile`
44
45## Inlay Hints
46
47Zed sets the following initialization options for inlay hints:
48
49```json
50"hints": {
51 "assignVariableTypes": true,
52 "compositeLiteralFields": true,
53 "compositeLiteralTypes": true,
54 "constantValues": true,
55 "functionTypeParameters": true,
56 "parameterNames": true,
57 "rangeVariableTypes": true
58}
59```
60
61to make the language server send back inlay hints when Zed has them enabled in the settings.
62
63Use
64
65```json
66"lsp": {
67 "gopls": {
68 "initialization_options": {
69 "hints": {
70 // ....
71 }
72 }
73 }
74}
75```
76
77to override these settings.
78
79See [gopls inlayHints documentation](https://github.com/golang/tools/blob/master/gopls/doc/inlayHints.md) for more information.
80
81## Debugging
82
83Zed supports zero-configuration debugging of Go tests and entry points (`func main`) using Delve. Run {#action debugger::Start} ({#kb debugger::Start}) to see a contextual list of these preconfigured debug tasks.
84
85For more control, you can add debug configurations to `.zed/debug.json`. See below for examples.
86
87- [Delve configuration documentation](https://github.com/go-delve/delve/blob/master/Documentation/api/dap/README.md#launch-and-attach-configurations)
88
89### Debug Go Packages
90
91To debug a specific package, you can do so by setting the Delve mode to "debug". In this case "program" should be set to the package name.
92
93```json [debug]
94[
95 {
96 "label": "Go (Delve)",
97 "adapter": "Delve",
98 "program": "$ZED_FILE",
99 "request": "launch",
100 "mode": "debug"
101 },
102 {
103 "label": "Run server",
104 "adapter": "Delve",
105 "request": "launch",
106 "mode": "debug",
107 // For Delve, the program can be a package name
108 "program": "./cmd/server"
109 // "args": [],
110 // "buildFlags": [],
111 }
112]
113```
114
115### Debug Go Tests
116
117To debug the tests for a package, set the Delve mode to "test".
118The "program" is still the package name, and you can use the "buildFlags" to do things like set tags, and the "args" to set args on the test binary. (See `go help testflags` for more information on doing that).
119
120```json [debug]
121[
122 {
123 "label": "Run integration tests",
124 "adapter": "Delve",
125 "request": "launch",
126 "mode": "test",
127 "program": ".",
128 "buildFlags": ["-tags", "integration"]
129 // To filter down to just the test your cursor is in:
130 // "args": ["-test.run", "$ZED_SYMBOL"]
131 }
132]
133```
134
135### Build and debug separately
136
137If you need to build your application with a specific command, you can use the "exec" mode of Delve. In this case "program" should point to an executable,
138and the "build" command should build that.
139
140```json [debug]
141[
142 {
143 "label": "Debug Prebuilt Unit Tests",
144 "adapter": "Delve",
145 "request": "launch",
146 "mode": "exec",
147 "program": "${ZED_WORKTREE_ROOT}/__debug_unit",
148 "args": ["-test.v", "-test.run=${ZED_SYMBOL}"],
149 "build": {
150 "command": "go",
151 "args": [
152 "test",
153 "-c",
154 "-tags",
155 "unit",
156 "-gcflags\"all=-N -l\"",
157 "-o",
158 "__debug_unit",
159 "./pkg/..."
160 ]
161 }
162 }
163]
164```
165
166### Attaching to an existing instance of Delve
167
168You might find yourself needing to connect to an existing instance of Delve that's not necessarily running on your machine; in such case, you can use `tcp_arguments` to instrument Zed's connection to Delve.
169
170```json [debug]
171[
172 {
173 "adapter": "Delve",
174 "label": "Connect to a running Delve instance",
175 "program": "/Users/zed/Projects/language_repositories/golang/hello/hello",
176 "cwd": "/Users/zed/Projects/language_repositories/golang/hello",
177 "args": [],
178 "env": {},
179 "request": "launch",
180 "mode": "exec",
181 "stopOnEntry": false,
182 "tcp_connection": { "host": "127.0.0.1", "port": 53412 }
183 }
184]
185```
186
187In such case Zed won't spawn a new instance of Delve, as it opts to use an existing one. The consequence of this is that _there will be no terminal_ in Zed; you have to interact with the Delve instance directly, as it handles stdin/stdout of the debuggee.
188
189## Go Mod
190
191- Tree-sitter: [camdencheek/tree-sitter-go-mod](https://github.com/camdencheek/tree-sitter-go-mod)
192- Language Server: N/A
193
194## Go Sum
195
196- Tree-sitter: [amaanq/tree-sitter-go-sum](https://github.com/amaanq/tree-sitter-go-sum)
197- Language Server: N/A
198
199## Go Work
200
201- Tree-sitter:
202 [tree-sitter-go-work](https://github.com/d1y/tree-sitter-go-work)
203- Language Server: N/A