golang.org/x/tools/gopls@v0.15.3/doc/emacs.md (about) 1 # Emacs 2 3 ## Installing `gopls` 4 5 To use `gopls` with Emacs, you must first 6 [install the `gopls` binary](../README.md#installation) and ensure that the directory 7 containing the resulting binary (either `$(go env GOBIN)` or `$(go env 8 GOPATH)/bin`) is in your `PATH`. 9 10 ## Choosing an Emacs LSP client 11 12 To use `gopls` with Emacs, you will need to choose and install an Emacs LSP 13 client package. Two popular client packages are [LSP Mode] and [Eglot]. 14 15 LSP Mode takes a batteries-included approach, with many integrations enabled 16 “out of the box” and several additional behaviors provided by `lsp-mode` itself. 17 18 Eglot takes a minimally-intrusive approach, focusing on smooth integration with 19 other established packages. It provides a few of its own `eglot-` commands but 20 no additional keybindings by default. 21 22 Once you have selected which client you want to use, install it per the packages 23 instructions: see [Eglot 1-2-3](https://github.com/joaotavora/eglot#1-2-3) or 24 [LSP Mode Installation](https://emacs-lsp.github.io/lsp-mode/page/installation/). 25 26 ## Common configuration 27 28 Both Eglot and LSP Mode can integrate with popular packages in the Emacs 29 ecosystem: 30 31 * The built-in [`xref`] package provides cross-references. 32 * The built-in [Flymake] package provides an on-the-fly diagnostic overlay. 33 * [Company] mode displays code completion candidates (with a richer UI than 34 the built-in [`completion-at-point`]). 35 36 Eglot provides documentation using the built-in [ElDoc] minor mode, while LSP 37 Mode by default provides documentation using its own [`lsp-ui`] mode. 38 39 Eglot by default locates the project root using the [`project`] package. In LSP 40 Mode, this behavior can be configured using the `lsp-auto-guess-root` setting. 41 42 ## Configuring LSP Mode 43 44 ### Loading LSP Mode in `.emacs` 45 46 ```elisp 47 (require 'lsp-mode) 48 (add-hook 'go-mode-hook #'lsp-deferred) 49 50 ;; Set up before-save hooks to format buffer and add/delete imports. 51 ;; Make sure you don't have other gofmt/goimports hooks enabled. 52 (defun lsp-go-install-save-hooks () 53 (add-hook 'before-save-hook #'lsp-format-buffer t t) 54 (add-hook 'before-save-hook #'lsp-organize-imports t t)) 55 (add-hook 'go-mode-hook #'lsp-go-install-save-hooks) 56 ``` 57 58 ### Configuring `gopls` via LSP Mode 59 60 See [settings] for information about available gopls settings. 61 62 Stable gopls settings have corresponding configuration variables in `lsp-mode`. 63 For example, `(setq lsp-gopls-use-placeholders nil)` will disable placeholders 64 in completion snippets. See [`lsp-go`] for a list of available variables. 65 66 Experimental settings can be configured via `lsp-register-custom-settings`: 67 68 ```lisp 69 (lsp-register-custom-settings 70 '(("gopls.completeUnimported" t t) 71 ("gopls.staticcheck" t t))) 72 ``` 73 74 Note that after changing settings you must restart gopls using e.g. `M-x 75 lsp-restart-workspace`. 76 77 ## Configuring Eglot 78 79 ### Configuring `project` for Go modules in `.emacs` 80 81 Eglot uses the built-in `project` package to identify the LSP workspace for a 82 newly-opened buffer. The `project` package does not natively know about `GOPATH` 83 or Go modules. Fortunately, you can give it a custom hook to tell it to look for 84 the nearest parent `go.mod` file (that is, the root of the Go module) as the 85 project root. 86 87 ```elisp 88 (require 'project) 89 90 (defun project-find-go-module (dir) 91 (when-let ((root (locate-dominating-file dir "go.mod"))) 92 (cons 'go-module root))) 93 94 (cl-defmethod project-root ((project (head go-module))) 95 (cdr project)) 96 97 (add-hook 'project-find-functions #'project-find-go-module) 98 ``` 99 100 ### Loading Eglot in `.emacs` 101 102 ```elisp 103 ;; Optional: load other packages before eglot to enable eglot integrations. 104 (require 'company) 105 (require 'yasnippet) 106 107 (require 'go-mode) 108 (require 'eglot) 109 (add-hook 'go-mode-hook 'eglot-ensure) 110 111 ;; Optional: install eglot-format-buffer as a save hook. 112 ;; The depth of -10 places this before eglot's willSave notification, 113 ;; so that that notification reports the actual contents that will be saved. 114 (defun eglot-format-buffer-on-save () 115 (add-hook 'before-save-hook #'eglot-format-buffer -10 t)) 116 (add-hook 'go-mode-hook #'eglot-format-buffer-on-save) 117 ``` 118 119 ### Configuring `gopls` via Eglot 120 121 See [settings] for information about available gopls settings. 122 123 LSP server settings are controlled by the `eglot-workspace-configuration` 124 variable, which can be set either globally in `.emacs` or in a `.dir-locals.el` file in the project root. 125 126 `.emacs`: 127 ```elisp 128 (setq-default eglot-workspace-configuration 129 '((:gopls . 130 ((staticcheck . t) 131 (matcher . "CaseSensitive"))))) 132 ``` 133 134 `.dir-locals.el`: 135 ```elisp 136 ((nil (eglot-workspace-configuration . ((gopls . ((staticcheck . t) 137 (matcher . "CaseSensitive"))))))) 138 ``` 139 140 ### Organizing imports with Eglot 141 142 `gopls` provides the import-organizing functionality of `goimports` as an LSP 143 code action, which you can invoke as needed by running `M-x eglot-code-actions` 144 (or a key of your choice bound to the `eglot-code-actions` function) and 145 selecting `Organize Imports` at the prompt. 146 147 To automatically organize imports before saving, add a hook: 148 149 ```elisp 150 (add-hook 'before-save-hook 151 (lambda () 152 (call-interactively 'eglot-code-action-organize-imports)) 153 nil t) 154 ``` 155 156 ## Troubleshooting 157 158 Common errors: 159 160 * When prompted by Emacs for your project folder, if you are using modules you 161 must select the module's root folder (i.e. the directory with the "go.mod"). 162 If you are using GOPATH, select your $GOPATH as your folder. 163 * Emacs must have your environment set properly (PATH, GOPATH, etc). You can 164 run `M-x getenv <RET> PATH <RET>` to see if your PATH is set in Emacs. If 165 not, you can try starting Emacs from your terminal, using [this 166 package][exec-path-from-shell], or moving your shell config from `.bashrc` 167 into `.profile` and logging out and back in. 168 * Make sure only one LSP client mode is installed. (For example, if using 169 `lsp-mode`, ensure that you are not _also_ enabling `eglot`.) 170 * Look for errors in the `*lsp-log*` buffer or run `M-x eglot-events-buffer`. 171 * Ask for help in the `#emacs` channel on the [Gophers slack]. 172 173 [LSP Mode]: https://emacs-lsp.github.io/lsp-mode/ 174 [Eglot]: https://github.com/joaotavora/eglot/blob/master/README.md 175 [`xref`]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Xref.html 176 [Flymake]: https://www.gnu.org/software/emacs/manual/html_node/flymake/Using-Flymake.html#Using-Flymake 177 [Company]: https://company-mode.github.io/ 178 [`completion-at-point`]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion-in-Buffers.html 179 [ElDoc]: https://elpa.gnu.org/packages/eldoc.html 180 [`lsp-ui`]: https://emacs-lsp.github.io/lsp-ui/ 181 [`lsp-go`]: https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-go.el 182 [`use-package`]: https://github.com/jwiegley/use-package 183 [`exec-path-from-shell`]: https://github.com/purcell/exec-path-from-shell 184 [settings]: settings.md 185 [Gophers slack]: https://invite.slack.golangbridge.org/