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/