Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 1 | # Vim / Neovim |
| 2 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 3 | * [vim-go](#vimgo) |
| 4 | * [LanguageClient-neovim](#lcneovim) |
| 5 | * [Ale](#ale) |
| 6 | * [vim-lsp](#vimlsp) |
| 7 | * [vim-lsc](#vimlsc) |
| 8 | * [coc.nvim](#cocnvim) |
| 9 | * [govim](#govim) |
| 10 | * [Neovim v0.5.0+](#neovim) |
| 11 | * [Installation](#neovim-install) |
| 12 | * [Custom Configuration](#neovim-config) |
| 13 | * [Imports](#neovim-imports) |
| 14 | * [Omnifunc](#neovim-omnifunc) |
| 15 | * [Additional Links](#neovim-links) |
| 16 | |
| 17 | ## <a href="#vimgo" id="vimgo">vim-go</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 18 | |
| 19 | Use [vim-go] ver 1.20+, with the following configuration: |
| 20 | |
Rebecca Stambler | d78b04b | 2020-12-28 13:26:14 -0500 | [diff] [blame] | 21 | ```vim |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 22 | let g:go_def_mode='gopls' |
| 23 | let g:go_info_mode='gopls' |
| 24 | ``` |
| 25 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 26 | ## <a href="#lcneovim" id="lcneovim">LanguageClient-neovim</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 27 | |
| 28 | Use [LanguageClient-neovim], with the following configuration: |
| 29 | |
Rebecca Stambler | d78b04b | 2020-12-28 13:26:14 -0500 | [diff] [blame] | 30 | ```vim |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 31 | " Launch gopls when Go files are in use |
| 32 | let g:LanguageClient_serverCommands = { |
| 33 | \ 'go': ['gopls'] |
| 34 | \ } |
| 35 | " Run gofmt on save |
| 36 | autocmd BufWritePre *.go :call LanguageClient#textDocument_formatting_sync() |
| 37 | ``` |
| 38 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 39 | ## <a href="#ale" id="ale">Ale</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 40 | |
| 41 | Use [ale]: |
| 42 | |
| 43 | ```vim |
| 44 | let g:ale_linters = { |
Rebecca Stambler | d78b04b | 2020-12-28 13:26:14 -0500 | [diff] [blame] | 45 | \ 'go': ['gopls'], |
| 46 | \} |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 47 | ``` |
| 48 | |
| 49 | see [this issue][ale-issue-2179] |
| 50 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 51 | ## <a href="#vimlsp" id="vimlsp">vim-lsp</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 52 | |
| 53 | Use [prabirshrestha/vim-lsp], with the following configuration: |
| 54 | |
| 55 | ```vim |
| 56 | augroup LspGo |
| 57 | au! |
| 58 | autocmd User lsp_setup call lsp#register_server({ |
| 59 | \ 'name': 'go-lang', |
| 60 | \ 'cmd': {server_info->['gopls']}, |
| 61 | \ 'whitelist': ['go'], |
| 62 | \ }) |
| 63 | autocmd FileType go setlocal omnifunc=lsp#complete |
| 64 | "autocmd FileType go nmap <buffer> gd <plug>(lsp-definition) |
| 65 | "autocmd FileType go nmap <buffer> ,n <plug>(lsp-next-error) |
| 66 | "autocmd FileType go nmap <buffer> ,p <plug>(lsp-previous-error) |
| 67 | augroup END |
| 68 | ``` |
| 69 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 70 | ## <a href="#vimlsc" id="vimlsc">vim-lsc</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 71 | |
| 72 | Use [natebosch/vim-lsc], with the following configuration: |
| 73 | |
| 74 | ```vim |
| 75 | let g:lsc_server_commands = { |
| 76 | \ "go": { |
| 77 | \ "command": "gopls serve", |
| 78 | \ "log_level": -1, |
Ainar Garipov | 1ccc110 | 2019-09-07 20:42:26 +0300 | [diff] [blame] | 79 | \ "suppress_stderr": v:true, |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 80 | \ }, |
| 81 | \} |
| 82 | ``` |
| 83 | |
Ainar Garipov | 1ccc110 | 2019-09-07 20:42:26 +0300 | [diff] [blame] | 84 | The `log_level` and `suppress_stderr` parts are needed to prevent breakage from logging. See |
Ainar Garipov | 846f856 | 2019-10-17 10:08:14 +0300 | [diff] [blame] | 85 | issues [#180](https://github.com/natebosch/vim-lsc/issues/180) and |
| 86 | [#213](https://github.com/natebosch/vim-lsc/issues/213). |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 87 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 88 | ## <a href="#cocnvim" id="cocnvim">coc.nvim</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 89 | |
| 90 | Use [coc.nvim], with the following `coc-settings.json` configuration: |
| 91 | |
| 92 | ```json |
| 93 | "languageserver": { |
| 94 | "golang": { |
| 95 | "command": "gopls", |
Robert Findley | cf66aec | 2022-02-01 14:20:33 -0500 | [diff] [blame] | 96 | "rootPatterns": ["go.work", "go.mod", ".vim/", ".git/", ".hg/"], |
Shengjing Zhu | 5fa5b17 | 2019-10-14 14:03:50 +0800 | [diff] [blame] | 97 | "filetypes": ["go"], |
| 98 | "initializationOptions": { |
| 99 | "usePlaceholders": true |
| 100 | } |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 101 | } |
| 102 | } |
| 103 | ``` |
| 104 | |
Robert Findley | cf66aec | 2022-02-01 14:20:33 -0500 | [diff] [blame] | 105 | If you use `go.work` files, you may want to set the |
| 106 | `workspace.workspaceFolderCheckCwd` option. This will force coc.nvim to search |
| 107 | parent directories for `go.work` files, even if the current open directory has |
| 108 | a `go.mod` file. See the |
| 109 | [coc.nvim documentation](https://github.com/neoclide/coc.nvim/wiki/Using-workspaceFolders) |
| 110 | for more details. |
| 111 | |
Shengjing Zhu | 5fa5b17 | 2019-10-14 14:03:50 +0800 | [diff] [blame] | 112 | Other [settings](settings.md) can be added in `initializationOptions` too. |
| 113 | |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 114 | The `editor.action.organizeImport` code action will auto-format code and add missing imports. To run this automatically on save, add the following line to your `init.vim`: |
| 115 | |
| 116 | ```vim |
| 117 | autocmd BufWritePre *.go :call CocAction('runCommand', 'editor.action.organizeImport') |
| 118 | ``` |
| 119 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 120 | ## <a href="#govim" id="govim">govim</a> |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 121 | |
| 122 | In vim classic only, use the experimental [`govim`], simply follow the [install steps][govim-install]. |
| 123 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 124 | ## <a href="#neovim" id="neovim">Neovim v0.5.0+</a> |
Ellison Leão | cd5a53e | 2020-04-07 18:57:22 +0000 | [diff] [blame] | 125 | |
GGCristo | de44776 | 2021-07-09 13:24:30 +0000 | [diff] [blame] | 126 | To use the new native LSP client in Neovim, make sure you |
| 127 | [install][nvim-install] Neovim v.0.5.0+, |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 128 | the `nvim-lspconfig` configuration helper plugin, and check the |
| 129 | [`gopls` configuration section][nvim-lspconfig] there. |
| 130 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 131 | ### <a href="#neovim-install" id="neovim-install">Installation</a> |
| 132 | |
| 133 | You can use Neovim's native plugin system. On a Unix system, you can do that by |
| 134 | cloning the `nvim-lspconfig` repository into the correct directory: |
| 135 | |
| 136 | ```sh |
| 137 | dir="${HOME}/.local/share/nvim/site/pack/nvim-lspconfig/opt/nvim-lspconfig/" |
| 138 | mkdir -p "$dir" |
| 139 | cd "$dir" |
| 140 | git clone 'https://github.com/neovim/nvim-lspconfig.git' . |
| 141 | ``` |
| 142 | |
| 143 | ### <a href="#neovim-config" id="neovim-config">Custom Configuration</a> |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 144 | |
| 145 | You can add custom configuration using Lua. Here is an example of enabling the |
| 146 | `unusedparams` check as well as `staticcheck`: |
| 147 | |
| 148 | ```vim |
| 149 | lua <<EOF |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 150 | lspconfig = require "lspconfig" |
Simon Drake | 625c871 | 2022-03-01 17:39:56 +0000 | [diff] [blame] | 151 | util = require "lspconfig/util" |
| 152 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 153 | lspconfig.gopls.setup { |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 154 | cmd = {"gopls", "serve"}, |
Simon Drake | 625c871 | 2022-03-01 17:39:56 +0000 | [diff] [blame] | 155 | filetypes = {"go", "gomod"}, |
| 156 | root_dir = util.root_pattern("go.work", "go.mod", ".git"), |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 157 | settings = { |
| 158 | gopls = { |
| 159 | analyses = { |
| 160 | unusedparams = true, |
| 161 | }, |
| 162 | staticcheck = true, |
| 163 | }, |
| 164 | }, |
| 165 | } |
| 166 | EOF |
| 167 | ``` |
| 168 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 169 | ### <a href="#neovim-imports" id="neovim-imports">Imports</a> |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 170 | |
| 171 | To get your imports ordered on save, like `goimports` does, you can define |
| 172 | a helper function in Lua: |
| 173 | |
| 174 | ```vim |
| 175 | lua <<EOF |
| 176 | -- … |
| 177 | |
Antoine Cotten | 4ff08b4 | 2022-08-06 15:08:18 +0200 | [diff] [blame] | 178 | function go_org_imports(wait_ms) |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 179 | local params = vim.lsp.util.make_range_params() |
Simon Drake | 72442fe | 2022-03-02 11:25:09 +0000 | [diff] [blame] | 180 | params.context = {only = {"source.organizeImports"}} |
| 181 | local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, wait_ms) |
Antoine Cotten | 4ff08b4 | 2022-08-06 15:08:18 +0200 | [diff] [blame] | 182 | for cid, res in pairs(result or {}) do |
Simon Drake | 72442fe | 2022-03-02 11:25:09 +0000 | [diff] [blame] | 183 | for _, r in pairs(res.result or {}) do |
| 184 | if r.edit then |
Antoine Cotten | 4ff08b4 | 2022-08-06 15:08:18 +0200 | [diff] [blame] | 185 | local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or "utf-16" |
| 186 | vim.lsp.util.apply_workspace_edit(r.edit, enc) |
Simon Drake | 72442fe | 2022-03-02 11:25:09 +0000 | [diff] [blame] | 187 | end |
stephen | f48e60b | 2021-02-23 06:23:38 +0000 | [diff] [blame] | 188 | end |
stephen | f48e60b | 2021-02-23 06:23:38 +0000 | [diff] [blame] | 189 | end |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 190 | end |
| 191 | EOF |
| 192 | |
Antoine Cotten | 4ff08b4 | 2022-08-06 15:08:18 +0200 | [diff] [blame] | 193 | autocmd BufWritePre *.go lua go_org_imports() |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 194 | ``` |
| 195 | |
| 196 | (Taken from the [discussion][nvim-lspconfig-imports] on Neovim issue tracker.) |
| 197 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 198 | ### <a href="#neovim-omnifunc" id="neovim-omnifunc">Omnifunc</a> |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 199 | |
| 200 | To make your <kbd>Ctrl</kbd>+<kbd>x</kbd>,<kbd>Ctrl</kbd>+<kbd>o</kbd> work, add |
| 201 | this to your `init.vim`: |
| 202 | |
| 203 | ```vim |
| 204 | autocmd FileType go setlocal omnifunc=v:lua.vim.lsp.omnifunc |
| 205 | ``` |
| 206 | |
Ainar Garipov | 0f6027f | 2020-12-17 00:48:15 +0300 | [diff] [blame] | 207 | ### <a href="#neovim-links" id="neovim-links">Additional Links</a> |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 208 | |
| 209 | * [Neovim's official LSP documentation][nvim-docs]. |
Ellison Leão | cd5a53e | 2020-04-07 18:57:22 +0000 | [diff] [blame] | 210 | |
Ian Cottrell | 062dbae | 2019-05-09 10:35:27 -0400 | [diff] [blame] | 211 | [vim-go]: https://github.com/fatih/vim-go |
| 212 | [LanguageClient-neovim]: https://github.com/autozimu/LanguageClient-neovim |
| 213 | [ale]: https://github.com/w0rp/ale |
| 214 | [ale-issue-2179]: https://github.com/w0rp/ale/issues/2179 |
| 215 | [prabirshrestha/vim-lsp]: https://github.com/prabirshrestha/vim-lsp/ |
| 216 | [natebosch/vim-lsc]: https://github.com/natebosch/vim-lsc/ |
| 217 | [natebosch/vim-lsc#180]: https://github.com/natebosch/vim-lsc/issues/180 |
| 218 | [coc.nvim]: https://github.com/neoclide/coc.nvim/ |
| 219 | [`govim`]: https://github.com/myitcv/govim |
Ainar Garipov | 1ccc110 | 2019-09-07 20:42:26 +0300 | [diff] [blame] | 220 | [govim-install]: https://github.com/myitcv/govim/blob/master/README.md#govim---go-development-plugin-for-vim8 |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 221 | [nvim-docs]: https://neovim.io/doc/user/lsp.html |
| 222 | [nvim-install]: https://github.com/neovim/neovim/wiki/Installing-Neovim |
Akhil | cadd57e | 2021-11-27 06:22:56 +0000 | [diff] [blame] | 223 | [nvim-lspconfig]: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#gopls |
Ainar Garipov | 34b80a0 | 2020-09-25 12:50:53 +0300 | [diff] [blame] | 224 | [nvim-lspconfig-imports]: https://github.com/neovim/nvim-lspconfig/issues/115 |