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