| # Gopls: Using Vim or Neovim |
| |
| * [vim-go](#vimgo) |
| * [LanguageClient-neovim](#lcneovim) |
| * [Ale](#ale) |
| * [vim-lsp](#vimlsp) |
| * [vim-lsc](#vimlsc) |
| * [coc.nvim](#cocnvim) |
| * [govim](#govim) |
| * [Neovim v0.5.0+](#neovim) |
| * [Installation](#neovim-install) |
| * [Custom Configuration](#neovim-config) |
| * [Imports](#neovim-imports) |
| * [Omnifunc](#neovim-omnifunc) |
| * [Additional Links](#neovim-links) |
| |
| ## <a href="#vimgo" id="vimgo">vim-go</a> |
| |
| Use [vim-go] ver 1.20+, with the following configuration: |
| |
| ```vim |
| let g:go_def_mode='gopls' |
| let g:go_info_mode='gopls' |
| ``` |
| |
| ## <a href="#lcneovim" id="lcneovim">LanguageClient-neovim</a> |
| |
| Use [LanguageClient-neovim], with the following configuration: |
| |
| ```vim |
| " Launch gopls when Go files are in use |
| let g:LanguageClient_serverCommands = { |
| \ 'go': ['gopls'] |
| \ } |
| " Run gofmt on save |
| autocmd BufWritePre *.go :call LanguageClient#textDocument_formatting_sync() |
| ``` |
| |
| ## <a href="#ale" id="ale">Ale</a> |
| |
| Use [ale]: |
| |
| ```vim |
| let g:ale_linters = { |
| \ 'go': ['gopls'], |
| \} |
| ``` |
| |
| see [this issue][ale-issue-2179] |
| |
| ## <a href="#vimlsp" id="vimlsp">vim-lsp</a> |
| |
| Use [prabirshrestha/vim-lsp], with the following configuration: |
| |
| ```vim |
| augroup LspGo |
| au! |
| autocmd User lsp_setup call lsp#register_server({ |
| \ 'name': 'go-lang', |
| \ 'cmd': {server_info->['gopls']}, |
| \ 'whitelist': ['go'], |
| \ }) |
| autocmd FileType go setlocal omnifunc=lsp#complete |
| "autocmd FileType go nmap <buffer> gd <plug>(lsp-definition) |
| "autocmd FileType go nmap <buffer> ,n <plug>(lsp-next-error) |
| "autocmd FileType go nmap <buffer> ,p <plug>(lsp-previous-error) |
| augroup END |
| ``` |
| |
| ## <a href="#vimlsc" id="vimlsc">vim-lsc</a> |
| |
| Use [natebosch/vim-lsc], with the following configuration: |
| |
| ```vim |
| let g:lsc_server_commands = { |
| \ "go": { |
| \ "command": "gopls serve", |
| \ "log_level": -1, |
| \ "suppress_stderr": v:true, |
| \ }, |
| \} |
| ``` |
| |
| The `log_level` and `suppress_stderr` parts are needed to prevent breakage from logging. See |
| issues [#180](https://github.com/natebosch/vim-lsc/issues/180) and |
| [#213](https://github.com/natebosch/vim-lsc/issues/213). |
| |
| ## <a href="#cocnvim" id="cocnvim">coc.nvim</a> |
| |
| Use [coc.nvim], with the following `coc-settings.json` configuration: |
| |
| ```json |
| "languageserver": { |
| "go": { |
| "command": "gopls", |
| "rootPatterns": ["go.work", "go.mod", ".vim/", ".git/", ".hg/"], |
| "filetypes": ["go"], |
| "initializationOptions": { |
| "usePlaceholders": true |
| } |
| } |
| } |
| ``` |
| |
| If you use `go.work` files, you may want to set the |
| `workspace.workspaceFolderCheckCwd` option. This will force coc.nvim to search |
| parent directories for `go.work` files, even if the current open directory has |
| a `go.mod` file. See the |
| [coc.nvim documentation](https://github.com/neoclide/coc.nvim/wiki/Using-workspaceFolders) |
| for more details. |
| |
| Other [settings](settings.md) can be added in `initializationOptions` too. |
| |
| 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`: |
| |
| ```vim |
| autocmd BufWritePre *.go :call CocAction('runCommand', 'editor.action.organizeImport') |
| ``` |
| |
| ## <a href="#govim" id="govim">govim</a> |
| |
| In vim classic only, use the experimental [`govim`], simply follow the [install steps][govim-install]. |
| |
| ## <a href="#neovim" id="neovim">Neovim v0.5.0+</a> |
| |
| To use the new native LSP client in Neovim, make sure you |
| [install][nvim-install] Neovim v.0.5.0+, |
| the `nvim-lspconfig` configuration helper plugin, and check the |
| [`gopls` configuration section][nvim-lspconfig] there. |
| |
| ### <a href="#neovim-install" id="neovim-install">Installation</a> |
| |
| You can use Neovim's native plugin system. On a Unix system, you can do that by |
| cloning the `nvim-lspconfig` repository into the correct directory: |
| |
| ```sh |
| dir="${HOME}/.local/share/nvim/site/pack/nvim-lspconfig/opt/nvim-lspconfig/" |
| mkdir -p "$dir" |
| cd "$dir" |
| git clone 'https://github.com/neovim/nvim-lspconfig.git' . |
| ``` |
| |
| ### <a href="#neovim-config" id="neovim-config">Configuration</a> |
| |
| nvim-lspconfig aims to provide reasonable defaults, so your setup can be very |
| brief. |
| |
| ```lua |
| local lspconfig = require("lspconfig") |
| lspconfig.gopls.setup({}) |
| ``` |
| |
| However, you can also configure `gopls` for your preferences. Here's an |
| example that enables `unusedparams`, `staticcheck`, and `gofumpt`. |
| |
| ```lua |
| local lspconfig = require("lspconfig") |
| lspconfig.gopls.setup({ |
| settings = { |
| gopls = { |
| analyses = { |
| unusedparams = true, |
| }, |
| staticcheck = true, |
| gofumpt = true, |
| }, |
| }, |
| }) |
| ``` |
| |
| ### <a href="#neovim-imports" id="neovim-imports">Imports and Formatting</a> |
| |
| Use the following configuration to have your imports organized on save using |
| the logic of `goimports` and your code formatted. |
| |
| ```lua |
| autocmd("BufWritePre", { |
| pattern = "*.go", |
| callback = function() |
| local params = vim.lsp.util.make_range_params() |
| params.context = {only = {"source.organizeImports"}} |
| -- buf_request_sync defaults to a 1000ms timeout. Depending on your |
| -- machine and codebase, you may want longer. Add an additional |
| -- argument after params if you find that you have to write the file |
| -- twice for changes to be saved. |
| -- E.g., vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 3000) |
| local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params) |
| for cid, res in pairs(result or {}) do |
| for _, r in pairs(res.result or {}) do |
| if r.edit then |
| local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or "utf-16" |
| vim.lsp.util.apply_workspace_edit(r.edit, enc) |
| end |
| end |
| end |
| vim.lsp.buf.format({async = false}) |
| end |
| }) |
| ``` |
| |
| ### <a href="#neovim-omnifunc" id="neovim-omnifunc">Omnifunc</a> |
| |
| In Neovim v0.8.1 and later if you don't set the option `omnifunc`, it will auto |
| set to `v:lua.vim.lsp.omnifunc`. If you are using an earlier version, you can |
| configure it manually: |
| |
| ```lua |
| local on_attach = function(client, bufnr) |
| -- Enable completion triggered by <c-x><c-o> |
| vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') |
| end |
| require('lspconfig').gopls.setup({ |
| on_attach = on_attach |
| }) |
| ``` |
| |
| ### <a href="#neovim-links" id="neovim-links">Additional Links</a> |
| |
| * [Neovim's official LSP documentation][nvim-docs]. |
| |
| [vim-go]: https://github.com/fatih/vim-go |
| [LanguageClient-neovim]: https://github.com/autozimu/LanguageClient-neovim |
| [ale]: https://github.com/w0rp/ale |
| [ale-issue-2179]: https://github.com/w0rp/ale/issues/2179 |
| [prabirshrestha/vim-lsp]: https://github.com/prabirshrestha/vim-lsp/ |
| [natebosch/vim-lsc]: https://github.com/natebosch/vim-lsc/ |
| [natebosch/vim-lsc#180]: https://github.com/natebosch/vim-lsc/issues/180 |
| [coc.nvim]: https://github.com/neoclide/coc.nvim/ |
| [`govim`]: https://github.com/myitcv/govim |
| [govim-install]: https://github.com/myitcv/govim/blob/master/README.md#govim---go-development-plugin-for-vim8 |
| [nvim-docs]: https://neovim.io/doc/user/lsp.html |
| [nvim-install]: https://github.com/neovim/neovim/wiki/Installing-Neovim |
| [nvim-lspconfig]: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#gopls |
| [nvim-lspconfig-imports]: https://github.com/neovim/nvim-lspconfig/issues/115 |