diff options
Diffstat (limited to 'misc/emacs/go-mode.el')
-rw-r--r-- | misc/emacs/go-mode.el | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el index 2624e87cb..692cabfe5 100644 --- a/misc/emacs/go-mode.el +++ b/misc/emacs/go-mode.el @@ -498,21 +498,45 @@ Useful for development work." (require 'go-mode) (go-mode)) -(provide 'go-mode) - +;;;###autoload (defun gofmt () - "Pipe the current buffer through the external tool `gofmt`." - - (interactive) - ;; for some reason save-excursion isn't working - ;; probably because shell-command-on-region deletes the contents of the - ;; region before filling in the new values - ;; so we will save the point/mark by hand - ;; similarly we can't use push-mark/pop-mark - (let ((old-mark (mark t)) (old-point (point))) - (save-restriction - (let (deactivate-mark) - (widen) - (shell-command-on-region (point-min) (point-max) "gofmt" t t shell-command-default-error-buffer))) - (goto-char (min old-point (point-max))) - (if old-mark (set-mark (min old-mark (point-max)))))) + "Pipe the current buffer through the external tool `gofmt`. +Replace the current buffer on success; display errors on failure." + + (interactive) + (let ((srcbuf (current-buffer))) + (with-temp-buffer + (let ((outbuf (current-buffer)) + (errbuf (get-buffer-create "*Gofmt Errors*"))) + (with-current-buffer errbuf (erase-buffer)) + (with-current-buffer srcbuf + (save-restriction + (let (deactivate-mark) + (widen) + (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" + outbuf nil errbuf)) + ;; gofmt succeeded: replace the current buffer with outbuf, + ;; restore the mark and point, and discard errbuf. + (let ((old-mark (mark t)) (old-point (point))) + (erase-buffer) + (insert-buffer-substring outbuf) + (goto-char (min old-point (point-max))) + (if old-mark (set-mark (min old-mark (point-max)))) + (kill-buffer errbuf)) + + ;; gofmt failed: display the errors + (display-buffer errbuf))))) + + ;; Collapse any window opened on outbuf if shell-command-on-region + ;; displayed it. + (delete-windows-on outbuf))))) + +;;;###autoload +(defun gofmt-before-save () + "Add this to .emacs to run gofmt on the current buffer when saving: + (add-hook 'before-save-hook #'gofmt-before-save)" + + (interactive) + (when (eq major-mode 'go-mode) (gofmt))) + +(provide 'go-mode) |