Last active
June 13, 2023 16:08
-
-
Save robfig/5975784 to your computer and use it in GitHub Desktop.
Emacs integration with goimports - https://github.com/bradfitz/goimports. Every time you save your Go code, 1. Add missing imports (standard library only), 2. Remove unnecessary imports, 3. Go fmt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; OSX - Update the PATH to match that from the shell | |
(defun set-exec-path-from-shell-PATH () | |
(let ((path-from-shell | |
(replace-regexp-in-string "[[:space:]\n]*$" "" | |
(shell-command-to-string "$SHELL -l -c 'echo $PATH'")))) | |
(setenv "PATH" path-from-shell) | |
(setq exec-path (split-string path-from-shell path-separator)))) | |
(when (equal system-type 'darwin) (set-exec-path-from-shell-PATH)) | |
;; Go mode | |
(require 'go-mode-load) ;; go/misc/emacs/go-mode.el and go-mode-load.el should be in your emacs path | |
(require 'go-imports) ;; the other file in this gist | |
;; Is goimports available? | |
(setq go-save-hook #'gofmt-before-save) ;; gofmt by default | |
(dolist (path exec-path) | |
(when (file-exists-p (concat path "/goimports")) | |
(setq go-save-hook #'goimports-before-save))) | |
;; Format / fix imports before every save. | |
(add-hook 'go-mode-hook | |
'(lambda() | |
(add-hook 'before-save-hook go-save-hook))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Mostly copied from go-mode.el | |
;;;###autoload | |
(defun goimports-before-save () | |
"Add this to .emacs to run gofmt on the current buffer when saving: | |
(add-hook 'before-save-hook 'gofmt-before-save). | |
Note that this will cause go-mode to get loaded the first time | |
you save any file, kind of defeating the point of autoloading." | |
(interactive) | |
(when (eq major-mode 'go-mode) (goimports))) | |
(defun goimports () | |
"Formats the current buffer according to the goimports tool." | |
(interactive) | |
(let ((tmpfile (make-temp-file "gofmt" nil ".go")) | |
(patchbuf (get-buffer-create "*Gofmt patch*")) | |
(errbuf (get-buffer-create "*Gofmt Errors*")) | |
(coding-system-for-read 'utf-8) | |
(coding-system-for-write 'utf-8)) | |
(with-current-buffer errbuf | |
(setq buffer-read-only nil) | |
(erase-buffer)) | |
(with-current-buffer patchbuf | |
(erase-buffer)) | |
(write-region nil nil tmpfile) | |
;; We're using errbuf for the mixed stdout and stderr output. This | |
;; is not an issue because gofmt -w does not produce any stdout | |
;; output in case of success. | |
(if (zerop (call-process "goimports" nil errbuf nil "-w" tmpfile)) | |
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile)) | |
(progn | |
(kill-buffer errbuf) | |
(message "Buffer is already gofmted")) | |
(go--apply-rcs-patch patchbuf) | |
(kill-buffer errbuf) | |
(message "Applied gofmt")) | |
(message "Could not apply gofmt. Check errors for details") | |
(gofmt--process-errors (buffer-file-name) tmpfile errbuf)) | |
(kill-buffer patchbuf) | |
(delete-file tmpfile))) | |
(provide 'go-imports) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment