Skip to content

Commit bae8f14

Browse files
committed
Merge pull request #1333 from gracjan/pr-stylish-buffer
Improve stylish buffer invocation
2 parents 8e29e23 + 900f864 commit bae8f14

File tree

4 files changed

+113
-49
lines changed

4 files changed

+113
-49
lines changed

haskell-commands.el

+39-42
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
(require 'highlight-uses-mode)
3838
(require 'haskell-cabal)
3939

40+
(defcustom haskell-mode-stylish-haskell-path "stylish-haskell"
41+
"Path to `stylish-haskell' executable."
42+
:group 'haskell
43+
:type 'string)
44+
4045
;;;###autoload
4146
(defun haskell-process-restart ()
4247
"Restart the inferior Haskell process."
@@ -783,7 +788,7 @@ inferior GHCi process."
783788
(interactive)
784789
(let ((column (current-column))
785790
(line (line-number-at-pos)))
786-
(haskell-mode-buffer-apply-command "stylish-haskell")
791+
(haskell-mode-buffer-apply-command haskell-mode-stylish-haskell-path)
787792
(goto-char (point-min))
788793
(forward-line (1- line))
789794
(goto-char (+ column (point)))))
@@ -793,47 +798,39 @@ inferior GHCi process."
793798
Use buffer as input and replace the whole buffer with the
794799
output. If CMD fails the buffer remains unchanged."
795800
(set-buffer-modified-p t)
796-
(let* ((chomp (lambda (str)
797-
(while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'" str)
798-
(setq str (replace-match "" t t str)))
799-
str))
800-
(_errout (lambda (fmt &rest args)
801-
(let* ((warning-fill-prefix " "))
802-
(display-warning cmd (apply 'format fmt args) :warning))))
803-
(filename (buffer-file-name (current-buffer)))
804-
(cmd-prefix (replace-regexp-in-string " .*" "" cmd))
805-
(tmp-file (make-temp-file cmd-prefix))
806-
(err-file (make-temp-file cmd-prefix))
807-
(default-directory (if (and (boundp 'haskell-session)
808-
haskell-session)
809-
(haskell-session-cabal-dir haskell-session)
810-
default-directory))
811-
(_errcode (with-temp-file tmp-file
812-
(call-process cmd filename
813-
(list (current-buffer) err-file) nil)))
814-
(stderr-output
815-
(with-temp-buffer
816-
(insert-file-contents err-file)
817-
(funcall chomp (buffer-substring-no-properties (point-min) (point-max)))))
818-
(stdout-output
819-
(with-temp-buffer
820-
(insert-file-contents tmp-file)
821-
(buffer-substring-no-properties (point-min) (point-max)))))
822-
(if (string= "" stderr-output)
823-
(if (string= "" stdout-output)
824-
(message "Error: %s produced no output, leaving buffer alone" cmd)
825-
(save-restriction
826-
(widen)
827-
;; command successful, insert file with replacement to preserve
828-
;; markers.
829-
(insert-file-contents tmp-file nil nil nil t)))
830-
(progn
831-
;; non-null stderr, command must have failed
832-
(message "Error: %s ended with errors, leaving buffer alone" cmd)
833-
;; use (warning-minimum-level :debug) to see this
834-
(display-warning cmd stderr-output :debug)))
835-
(delete-file tmp-file)
836-
(delete-file err-file)))
801+
(let* ((tmp-buf (generate-new-buffer "stylish-output"))
802+
(err-file (make-temp-file "stylish-error")))
803+
(unwind-protect
804+
(let* ((_errcode
805+
(call-process-region (point-min) (point-max) cmd nil
806+
(list (buffer-name tmp-buf) err-file)
807+
nil))
808+
(stderr-output
809+
(with-temp-buffer
810+
(insert-file-contents err-file)
811+
(buffer-substring-no-properties (point-min) (point-max))))
812+
(stdout-output
813+
(with-temp-buffer
814+
(insert-buffer-substring tmp-buf)
815+
(buffer-substring-no-properties (point-min) (point-max)))))
816+
(if (string= "" stderr-output)
817+
(if (string= "" stdout-output)
818+
(message "Error: %s produced no output, leaving buffer alone" cmd)
819+
(save-restriction
820+
(widen)
821+
;; command successful, insert file with replacement to preserve
822+
;; markers.
823+
(erase-buffer)
824+
(insert-buffer-substring tmp-buf)))
825+
(progn
826+
;; non-null stderr, command must have failed
827+
(message "Error: %s ended with errors, leaving buffer alone" cmd)
828+
;; use (warning-minimum-level :debug) to see this
829+
(display-warning cmd stderr-output :debug))))
830+
(ignore-errors
831+
(delete-file err-file))
832+
(ignore-errors
833+
(kill-buffer tmp-buf)))))
837834

838835
;;;###autoload
839836
(defun haskell-mode-find-uses ()

haskell-mode.el

+2-1
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,8 @@ To be added to `flymake-init-create-temp-buffer-copy'."
10421042

10431043
(defun haskell-mode-before-save-handler ()
10441044
"Function that will be called before buffer's saving."
1045-
)
1045+
(when haskell-stylish-on-save
1046+
(ignore-errors (haskell-mode-stylish-buffer))))
10461047

10471048
;; From Bryan O'Sullivan's blog:
10481049
;; http://www.serpentine.com/blog/2007/10/09/using-emacs-to-insert-scc-annotations-in-haskell-code/

haskell.el

+2-6
Original file line numberDiff line numberDiff line change
@@ -361,12 +361,8 @@ Give optional NEXT-P parameter to override value of
361361
;;;###autoload
362362
(defun haskell-mode-after-save-handler ()
363363
"Function that will be called after buffer's saving."
364-
(when haskell-tags-on-save (ignore-errors (haskell-mode-generate-tags)))
365-
(when haskell-stylish-on-save
366-
(ignore-errors (haskell-mode-stylish-buffer))
367-
(let ((before-save-hook '())
368-
(after-save-hook '()))
369-
(basic-save-buffer))))
364+
(when haskell-tags-on-save
365+
(ignore-errors (haskell-mode-generate-tags))))
370366

371367
;;;###autoload
372368
(defun haskell-mode-tag-find (&optional _next-p)

tests/haskell-mode-tests.el

+70
Original file line numberDiff line numberDiff line change
@@ -556,4 +556,74 @@ moves over sexps."
556556
(should (equal "-e\n-x\n./T1.hs\n./src/T2.hs\n"
557557
(buffer-substring (point-min) (point-max))))))))
558558

559+
(defun haskell-stylish-haskell-add-first-line ()
560+
(message-stdout "-- HEADER")
561+
(let (line)
562+
(while (setq line (read-stdin))
563+
(message-stdout line))))
564+
565+
(defun haskell-stylish-haskell-no-change ()
566+
(let (line)
567+
(while (setq line (read-stdin))
568+
(message-stdout line))))
569+
570+
(defun haskell-stylish-haskell-bad-exit-code ()
571+
(when noninteractive
572+
(kill-emacs 34)))
573+
574+
(defun haskell-stylish-haskell-error-message ()
575+
(message-stderr "Something wrong"))
576+
577+
(ert-deftest haskell-stylish-on-save-add-first-line ()
578+
(with-temp-dir-structure
579+
(("T.hs" . "main :: IO ()"))
580+
(with-script-path
581+
haskell-mode-stylish-haskell-path
582+
haskell-stylish-haskell-add-first-line
583+
(let ((haskell-stylish-on-save t))
584+
(with-current-buffer (find-file-noselect "T.hs")
585+
(insert "main = return ()\n")
586+
(save-buffer)
587+
(goto-char (point-min))
588+
(should (looking-at-p "-- HEADER")))))))
589+
590+
(ert-deftest haskell-stylish-on-save-no-change ()
591+
(with-temp-dir-structure
592+
(("T.hs" . "main :: IO ()"))
593+
(with-script-path
594+
haskell-mode-stylish-haskell-path
595+
haskell-stylish-haskell-no-change
596+
(let ((haskell-stylish-on-save t))
597+
(with-current-buffer (find-file-noselect "T.hs")
598+
(insert "main = return ()\n")
599+
(save-buffer)
600+
(goto-char (point-min))
601+
(should (looking-at-p "main = return")))))))
602+
603+
(ert-deftest haskell-stylish-on-save-bad-exit-code ()
604+
(with-temp-dir-structure
605+
(("T.hs" . "main :: IO ()"))
606+
(with-script-path
607+
haskell-mode-stylish-haskell-path
608+
haskell-stylish-haskell-bad-exit-code
609+
(let ((haskell-stylish-on-save t))
610+
(with-current-buffer (find-file-noselect "T.hs")
611+
(insert "main = return ()\n")
612+
(save-buffer)
613+
(goto-char (point-min))
614+
(should (looking-at-p "main = return ()")))))))
615+
616+
(ert-deftest haskell-stylish-on-save-error-message ()
617+
(with-temp-dir-structure
618+
(("T.hs" . "main :: IO ()"))
619+
(with-script-path
620+
haskell-mode-stylish-haskell-path
621+
haskell-stylish-haskell-error-message
622+
(let ((haskell-stylish-on-save t))
623+
(with-current-buffer (find-file-noselect "T.hs")
624+
(insert "main = return ()\n")
625+
(save-buffer)
626+
(goto-char (point-min))
627+
(should (looking-at-p "main = return ()")))))))
628+
559629
(provide 'haskell-mode-tests)

0 commit comments

Comments
 (0)