diff --git a/misc/emacs/go-mode-load.el b/misc/emacs/go-mode-load.el index c73156317c..0ace46dfa9 100644 --- a/misc/emacs/go-mode-load.el +++ b/misc/emacs/go-mode-load.el @@ -18,10 +18,11 @@ ;; (let ((generated-autoload-file buffer-file-name)) (update-file-autoloads "go-mode.el")) -;;;### (autoloads (go-mode) "go-mode" "go-mode.el" (19168 32439)) +;;;### (autoloads (gofmt-before-save gofmt go-mode) "go-mode" "go-mode.el" +;;;;;; (19847 61431)) ;;; Generated autoloads from go-mode.el -(autoload (quote go-mode) "go-mode" "\ +(autoload 'go-mode "go-mode" "\ Major mode for editing Go source text. This provides basic syntax highlighting for keywords, built-ins, @@ -30,7 +31,19 @@ functions, and some types. It also provides indentation that is \(fn)" t nil) -(add-to-list (quote auto-mode-alist) (cons "\\.go$" (function go-mode))) +(add-to-list 'auto-mode-alist (cons "\\.go$" #'go-mode)) + +(autoload 'gofmt "go-mode" "\ +Pipe the current buffer through the external tool `gofmt`. +Replace the current buffer on success; display errors on failure. + +\(fn)" t nil) + +(autoload 'gofmt-before-save "go-mode" "\ +Add this to .emacs to run gofmt on the current buffer when saving: + (add-hook 'before-save-hook #'gofmt-before-save) + +\(fn)" t nil) ;;;*** diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el index 2624e87cbd..692cabfe58 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)