1

I'm trying out eglot with gopls and having trouble getting auto-imports working. My configuration looks like below; (which I gathered from github-issues of eglot 1)

(add-hook 'go-mode-hook #'eglot-ensure)

(defun own/eglot-organize-imports ()
  (call-interactively 'eglot-code-action-organize-imports))

(defun own/before-saving-go ()
  ;; you might also like:
  (add-hook 'before-save-hook #'eglot-format-buffer -10 t)
  (add-hook 'before-save-hook #'own/eglot-organize-imports nil t))

(add-hook 'go-mode-hook #'own/before-saving-go)

I got this config from the comments on relevant issue here: 1

Now when I open a new main.go and write the code below;

package main

func main() {
fmt.Println("hello")
}

it fixes the formatting on save.

package main

func main() {
    fmt.Println("hello")
}

so, I think my own/before-saving-go hook works fine; however, as you can see fmt package is not imported automatically.

Manually running M-x eglot-code-action-organize-imports in the buffer is also not adding the import statement. However, If I run M-x eglot-code-actions, it suggests me to import fmt package, and hitting return adds the package correctly. It's just I can't get this automatically run on save by eglot-code-action-organize-imports

On the code buffer, running M-x eglot-code-action-organize-imports actually receives the correct message from gopls, as seen below from eglot events buffer.

[client-request] (id:124) Wed Nov 30 23:03:36 2022:
(:jsonrpc "2.0" :id 124 :method "textDocument/codeAction" :params
          (:textDocument
           (:uri "file:///Users/muhammet.can/projects/tests/eglot/main.go")
           :range
           (:start
            (:line 5 :character 0)
            :end
            (:line 5 :character 0))
           :context
           (:diagnostics
            [(:range
              (:start
               (:line 3 :character 1)
               :end
               (:line 3 :character 4))
              :severity 1 :code "UndeclaredName" :codeDescription
              (:href "https://pkg.go.dev/golang.org/x/tools/internal/typesinternal#UndeclaredName")
              :source "compiler" :message "undeclared name: fmt")]
            :only
            ["source.organizeImports"])))
[server-reply] (id:124) Wed Nov 30 23:03:36 2022:
(:jsonrpc "2.0" :result
          [(:title "Organize Imports" :kind "source.organizeImports" :edit
                   (:documentChanges
                    [(:textDocument
                      (:version 74 :uri "file:///Users/muhammet.can/projects/tests/eglot/main.go")
                      :edits
                      [(:range
                        (:start
                         (:line 1 :character 0)
                         :end
                         (:line 1 :character 0))
                        :newText "\nimport \"fmt\"\n")])]))]
          :id 124)

If relevant; versions I do have;

$ emacs --version
GNU Emacs 28.1

$ gopls version
golang.org/x/tools/gopls v0.10.1

Any ideas?

Muhammet Can
  • 111
  • 3

1 Answers1

0

I was able to get automatic imports working with the code-snippet shared in this GitHub comment;

https://github.com/joaotavora/eglot/issues/574#issuecomment-749353427

;; eglot-organize-imports is hopefully a temporary stopgap until
;; https://github.com/joaotavora/eglot/issues/574 is addressed.
(defun eglot-organize-imports ()
  "Offer to execute the source.organizeImports code action."
  (interactive)
  (unless (eglot--server-capable :codeActionProvider)
    (eglot--error "Server can't execute code actions!"))
  (let* ((server (eglot--current-server-or-lose))
         (actions (jsonrpc-request
                   server
                   :textDocument/codeAction
                   (list :textDocument (eglot--TextDocumentIdentifier))))
         (action (cl-find-if
                  (jsonrpc-lambda (&key kind &allow-other-keys)
                    (string-equal kind "source.organizeImports" ))
                  actions)))
    (when action
      (eglot--dcase action
        (((Command) command arguments)
          (eglot-execute-command server (intern command) arguments))
        (((CodeAction) edit command)
          (when edit (eglot--apply-workspace-edit edit))
          (when command
            (eglot--dbind ((Command) command arguments) command
              (eglot-execute-command server (intern command) arguments))))))))

(defun eglot-organize-imports-on-save ()
  (defun eglot-organize-imports-nosignal ()
    "Run eglot-organize-imports, but demote errors to messages."
    ;; Demote errors to work around
    ;; https://github.com/joaotavora/eglot/issues/411#issuecomment-749305401
    ;; so that we do not prevent subsequent save hooks from running
    ;; if we encounter a spurious error.
    (with-demoted-errors "Error: %s" (eglot-organize-imports)))
  (add-hook 'before-save-hook #'eglot-organize-imports-on-save))

(add-hook 'go-mode-hook #'eglot-organize-imports-on-save)
Muhammet Can
  • 111
  • 3