[mirror] Make your go dev experience better
github.com/olexsmir/gopher.nvim
neovim
golang
1# gopher.nvim
2
3[](https://stand-with-ukraine.pp.ua)
4
5Minimalistic plugin for Go development in Neovim written in Lua.
6
7It's **NOT** an LSP tool, the goal of this plugin is to add go tooling support in Neovim.
8
9> All development of new and maybe undocumented, and unstable features is happening on [develop](https://github.com/olexsmir/gopher.nvim/tree/develop) branch.
10
11## Table of content
12* [How to install](#install-using-lazynvim)
13* [Features](#features)
14* [Configuration](#configuration)
15* [Troubleshooting](#troubleshooting)
16* [Contributing](#contributing)
17
18## Install (using [lazy.nvim](https://github.com/folke/lazy.nvim))
19
20Requirements:
21
22- **Neovim 0.10** or later
23- Treesitter parser for `go`(`:TSInstall go` if you use [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter))
24- [Go](https://github.com/golang/go) installed
25
26> [!IMPORTANT]
27> If you prefer using other forges, this repository is also mirrored at:
28> - [tangled.org](https://tangled.org): [`https://tangled.org/olexsmir.xyz/gopher.nvim`](https://tangled.org/olexsmir.xyz/gopher.nvim)
29> - [codeberg.org](https://codeberg.org): [`https://codeberg.org/olexsmir/gopher.nvim`](https://codeberg.org/olexsmir/gopher.nvim)
30
31```lua
32-- NOTE: this plugin is already lazy-loaded and adds only about 1ms
33-- of load time to your config
34{
35 "olexsmir/gopher.nvim",
36 ft = "go",
37 -- branch = "develop"
38 -- (optional) updates the plugin's dependencies on each update
39 build = function()
40 vim.cmd.GoInstallDeps()
41 end,
42 ---@module "gopher"
43 ---@type gopher.Config
44 opts = {},
45}
46```
47
48## Features
49
50<details>
51 <summary>
52 <b>Install plugin's go deps</b>
53 </summary>
54
55 ```vim
56 :GoInstallDeps
57 ```
58
59 This will install the following tools:
60
61 - [gomodifytags](https://github.com/fatih/gomodifytags)
62 - [impl](https://github.com/josharian/impl)
63 - [gotests](https://github.com/cweill/gotests)
64 - [iferr](https://github.com/koron/iferr)
65 - [json2go](https://github.com/olexsmir/json2go)
66</details>
67
68<details>
69 <summary>
70 <b>Add and remove tags for structs via <a href="https://github.com/fatih/gomodifytags">gomodifytags</a></b>
71 </summary>
72
73 
74
75 By default `json` tag will be added/removed, if not set:
76
77 ```vim
78 " add json tag
79 :GoTagAdd json
80
81 " add json tag with omitempty option
82 :GoTagAdd json=omitempty
83
84 " remove yaml tag
85 :GoTagRm yaml
86 ```
87
88 ```lua
89 -- or you can use lua api
90 require("gopher").tags.add "xml"
91 require("gopher").tags.rm "proto"
92 ```
93</details>
94
95<details>
96 <summary>
97 <b>Generating tests via <a href="https://github.com/cweill/gotests">gotests</a></b>
98 </summary>
99
100 ```vim
101 " Generate one test for a specific function/method(one under cursor)
102 :GoTestAdd
103
104 " Generate all tests for all functions/methods in the current file
105 :GoTestsAll
106
107 " Generate tests for only exported functions/methods in the current file
108 :GoTestsExp
109 ```
110
111 ```lua
112 -- or you can use lua api
113 require("gopher").test.add()
114 require("gopher").test.exported()
115 require("gopher").test.all()
116 ```
117
118 For named tests see `:h gopher.nvim-gotests-named`
119</details>
120
121<details>
122 <summary>
123 <b>Run commands like <code>go mod/get/etc</code> inside of nvim</b>
124 </summary>
125
126 ```vim
127 :GoGet github.com/gorilla/mux
128
129 " Link can have an `http` or `https` prefix.
130 :GoGet https://github.com/lib/pq
131
132 " You can provide more than one package url
133 :GoGet github.com/jackc/pgx/v5 github.com/google/uuid/
134
135 " go mod commands
136 :GoMod tidy
137 :GoMod init new-shiny-project
138
139 " go work commands
140 :GoWork sync
141
142 " run go generate in cwd
143 :GoGenerate
144
145 " run go generate for the current file
146 :GoGenerate %
147 ```
148</details>
149
150<details>
151 <summary>
152 <b>Interface implementation via <a href="https://github.com/josharian/impl">impl<a></b>
153 </summary>
154
155 
156
157 Syntax of the command:
158 ```vim
159 :GoImpl [receiver] [interface]
160
161 " also you can put a cursor on the struct and run
162 :GoImpl [interface]
163 ```
164
165 Usage examples:
166 ```vim
167 :GoImpl r Read io.Reader
168 :GoImpl Write io.Writer
169
170 " or you can simply put a cursor on the struct and run
171 :GoImpl io.Reader
172 ```
173</details>
174
175<details>
176 <summary>
177 <b>Generate boilerplate for doc comments</b>
178 </summary>
179
180 
181
182 First set a cursor on **public** package/function/interface/struct and execute:
183
184 ```vim
185 :GoCmt
186 ```
187</details>
188
189<details>
190 <summary>
191 <b>Convert json to Go types</b>
192 </summary>
193
194 
195
196 `:GoJson` opens a temporary buffer where you can paste or write JSON.
197 Saving the buffer (`:w` or `:wq`) automatically closes it and inserts the generated Go struct into the original buffer at the cursor position.
198
199 Alternatively, you can pass JSON directly as an argument:
200 ```vim
201 :GoJson {"name": "Alice", "age": 30}
202 ```
203
204 Additionally, `gopher.json2go` provides lua api, see `:h gopher.nvim-json2go` for details.
205</details>
206
207
208<details>
209 <summary>
210 <b>Generate <code>if err != nil {</code> via <a href="https://github.com/koron/iferr">iferr</a></b>
211 </summary>
212
213 
214
215 Set the cursor on the line with `err` and execute
216
217 ```vim
218 :GoIfErr
219 ```
220</details>
221
222## Configuration
223
224> [!IMPORTANT]
225>
226> If you need more info look `:h gopher.nvim`
227
228**Take a look at default options (might be a bit outdated, look `:h gopher.nvim-config`)**
229
230```lua
231require("gopher").setup {
232 -- log level, you might consider using DEBUG or TRACE for debugging the plugin
233 log_level = vim.log.levels.INFO,
234
235 -- timeout for running internal commands
236 timeout = 2000,
237
238 -- timeout for running installer commands(e.g :GoDepsInstall, :GoDepsInstallSync)
239 installer_timeout = 999999,
240
241 -- user specified paths to binaries
242 commands = {
243 go = "go",
244 gomodifytags = "gomodifytags",
245 gotests = "gotests",
246 impl = "impl",
247 iferr = "iferr",
248 },
249 gotests = {
250 -- a default template that gotess will use.
251 -- gotets doesn't have template named `default`, we use it to represent absence of the provided template.
252 template = "default",
253
254 -- path to a directory containing custom test code templates
255 template_dir = nil,
256
257 -- use named tests(map with test name as key) in table tests(slice of structs by default)
258 named = false,
259 },
260 gotag = {
261 transform = "snakecase",
262
263 -- default tags to add to struct fields
264 default_tag = "json",
265
266 -- default tag option added struct fields, set to nil to disable
267 -- e.g: `option = "json=omitempty,xml=omitempty`
268 option = nil,
269 },
270 iferr = {
271 -- choose a custom error message, nil to use default
272 -- e.g: `message = 'fmt.Errorf("failed to %w", err)'`
273 message = nil,
274 },
275 json2go = {
276 -- command used to open interactive input.
277 -- e.g: `split`, `botright split`, `tabnew`
278 interactive_cmd = "vsplit",
279
280 -- name of autogenerated struct
281 -- e.g: "MySuperCoolName"
282 type_name = nil,
283 },
284}
285```
286
287## Troubleshooting
288The most common issue with the plugin is missing dependencies.
289Run `:checkhealth gopher` to verify that the plugin is installed correctly.
290If any binaries are missing, install them using `:GoInstallDeps`.
291
292If the issue persists, feel free to [open a new issue](https://github.com/olexsmir/gopher.nvim/issues/new).
293
294## Contributing
295
296PRs are always welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md)