LEFT | RIGHT |
1 ;;; go-mode.el --- Major mode for the Go programming language | 1 ;;; go-mode.el --- Major mode for the Go programming language |
2 | 2 |
3 ;;; Commentary: | 3 ;;; Commentary: |
4 | 4 |
5 ;; For installation instructions, see go-mode-load.el | 5 ;; For installation instructions, see go-mode-load.el |
6 | 6 |
7 ;;; To do: | 7 ;;; To do: |
8 | 8 |
9 ;; * Indentation is *almost* identical to gofmt | 9 ;; * Indentation is *almost* identical to gofmt |
10 ;; ** We think struct literal keys are labels and outdent them | 10 ;; ** We think struct literal keys are labels and outdent them |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 491 |
492 (defun go-mode-reload () | 492 (defun go-mode-reload () |
493 "Reload go-mode.el and put the current buffer into Go mode. | 493 "Reload go-mode.el and put the current buffer into Go mode. |
494 Useful for development work." | 494 Useful for development work." |
495 | 495 |
496 (interactive) | 496 (interactive) |
497 (unload-feature 'go-mode) | 497 (unload-feature 'go-mode) |
498 (require 'go-mode) | 498 (require 'go-mode) |
499 (go-mode)) | 499 (go-mode)) |
500 | 500 |
501 (provide 'go-mode) | 501 ;;;###autoload |
502 | |
503 (defun gofmt-buffer (outbuf replace errbuf) | |
504 ;; for some reason save-excursion isn't working | |
505 ;; probably because shell-command-on-region deletes the contents of the | |
506 ;; region before filling in the new values | |
507 ;; so we will save the point/mark by hand | |
508 ;; similarly we can't use push-mark/pop-mark | |
509 (let ((old-mark (mark t)) (old-point (point))) | |
510 (save-restriction | |
511 (let (deactivate-mark) | |
512 (widen) | |
513 (setq exit-status (shell-command-on-region (point-min) (point-max) "gofm
t" | |
514 » » » » » » outbuf replace errbuf)))) | |
515 (goto-char (min old-point (point-max))) | |
516 (if old-mark (set-mark (min old-mark (point-max))))) | |
517 exit-status) | |
518 | |
519 (defun gofmt () | 502 (defun gofmt () |
520 "Pipe the current buffer through the external tool `gofmt`." | 503 "Pipe the current buffer through the external tool `gofmt`. |
521 ·· | 504 Replace the current buffer on success; display errors on failure." |
522 (interactive) | 505 |
523 (gofmt-buffer t t shell-command-default-error-buffer)) | 506 (interactive) |
524 | 507 (let ((srcbuf (current-buffer))) |
525 (defun get-empty-buffer (name) | 508 (with-temp-buffer |
526 "Finds or creates the buffer named name, erases it, and returns it." | 509 (let ((outbuf (current-buffer)) |
527 | 510 (errbuf (get-buffer-create "*Gofmt Errors*"))) |
528 (let ((buf (get-buffer-create name))) | 511 (with-current-buffer errbuf (erase-buffer)) |
529 (save-current-buffer | 512 (with-current-buffer srcbuf |
530 (set-buffer buf) | 513 (save-restriction |
531 (erase-buffer)) | 514 (let (deactivate-mark) |
532 buf)) | 515 (widen) |
| 516 (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" |
| 517 outbuf nil errbuf)) |
| 518 ;; gofmt succeeded: replace the current buffer with outbuf, |
| 519 ;; restore the mark and point, and discard errbuf. |
| 520 (let ((old-mark (mark t)) (old-point (point))) |
| 521 (erase-buffer) |
| 522 (insert-buffer-substring outbuf) |
| 523 (goto-char (min old-point (point-max))) |
| 524 (if old-mark (set-mark (min old-mark (point-max)))) |
| 525 (kill-buffer errbuf)) |
| 526 |
| 527 ;; gofmt failed: display the errors |
| 528 (display-buffer errbuf))))) |
| 529 |
| 530 ;; Collapse any window opened on outbuf if shell-command-on-region |
| 531 ;; displayed it. |
| 532 (delete-windows-on outbuf))))) |
533 | 533 |
534 ;;;###autoload | 534 ;;;###autoload |
535 (defun gofmt-before-save () | 535 (defun gofmt-before-save () |
536 "Add this to .emacs to run gofmt on the current buffer when saving: | 536 "Add this to .emacs to run gofmt on the current buffer when saving: |
537 (add-hook 'before-save-hook 'gofmt-before-save)" | 537 (add-hook 'before-save-hook #'gofmt-before-save)" |
538 | 538 |
539 (interactive) | 539 (interactive) |
540 (when (eq major-mode 'go-mode) | 540 (when (eq major-mode 'go-mode) (gofmt))) |
541 (let ((outbuf (get-empty-buffer "Gofmt Output")) | 541 |
542 » (errbuf (get-empty-buffer "Gofmt Errors"))) | 542 (provide 'go-mode) |
543 (if (= 0 (gofmt-buffer outbuf nil errbuf)) | |
544 | |
545 » ;; gofmt succeeded: copy outbuf into the current buffer, | |
546 » ;; preserving the current mark and point | |
547 » (let ((old-mark (mark t)) (old-point (point))) | |
548 » (erase-buffer) | |
549 » (insert-buffer-substring outbuf) | |
550 » (goto-char (min old-point (point-max))) | |
551 » (if old-mark (set-mark (min old-mark (point-max)))) | |
552 » (kill-buffer errbuf)) | |
553 | |
554 » ;; gofmt failed: display the errors | |
555 » (display-buffer errbuf)) | |
556 | |
557 ;; Kill outbuf, collapsing its window first if | |
558 ;; shell-command-on-region displayed it. | |
559 (delete-windows-on outbuf) | |
560 (kill-buffer outbuf)))) | |
LEFT | RIGHT |