|
1 ;;; haskell-flycheck.el --- Flychecker using the GHCi process |
|
2 |
|
3 ;; Copyright (c) 2014 Chris Done. All rights reserved. |
|
4 |
|
5 ;; This file is free software; you can redistribute it and/or modify |
|
6 ;; it under the terms of the GNU General Public License as published by |
|
7 ;; the Free Software Foundation; either version 3, or (at your option) |
|
8 ;; any later version. |
|
9 |
|
10 ;; This file is distributed in the hope that it will be useful, |
|
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 ;; GNU General Public License for more details. |
|
14 |
|
15 ;; You should have received a copy of the GNU General Public License |
|
16 ;; along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 |
|
18 ;;; Code: |
|
19 |
|
20 (require 'haskell-process) |
|
21 (require 'flycheck) |
|
22 |
|
23 (defun flycheck-haskell-process-start (checker callback) |
|
24 "Start a GHCi load with CHECKER. |
|
25 |
|
26 CALLBACK is the status callback passed by Flycheck." |
|
27 (let ((session (haskell-session))) |
|
28 (haskell-session-current-dir session) |
|
29 (let ((process (haskell-process))) |
|
30 (haskell-process-queue-command |
|
31 process |
|
32 (make-haskell-command |
|
33 :state |
|
34 (list :process process |
|
35 :session session |
|
36 :filename (buffer-file-name) |
|
37 :callback callback |
|
38 :buffer (current-buffer) |
|
39 :original (buffer-string)) |
|
40 :go |
|
41 (lambda (state) |
|
42 (with-current-buffer (plist-get state :buffer) |
|
43 (let* ((filename (plist-get state :filename))) |
|
44 (write-region (point-min) (point-max) filename) |
|
45 (clear-visited-file-modtime) |
|
46 (haskell-process-send-string |
|
47 (plist-get state :process) |
|
48 (format ":load \"%s\"" |
|
49 (replace-regexp-in-string |
|
50 "\"" |
|
51 "\\\\\"" |
|
52 filename)))))) |
|
53 :live (lambda (state _) |
|
54 (when (plist-get state :original) |
|
55 (with-temp-buffer |
|
56 (insert (plist-get state :original)) |
|
57 (write-region (point-min) (point-max) (plist-get state :filename)) |
|
58 (plist-put state :original nil)))) |
|
59 :complete |
|
60 (lambda (state response) |
|
61 (let ((session (plist-get state :session)) |
|
62 (process (plist-get state :process))) |
|
63 (haskell-process-set-response-cursor process 0) |
|
64 (let ((errors (list)) |
|
65 (next-error t)) |
|
66 (while next-error |
|
67 (setq next-error |
|
68 (haskell-process-errors-warnings |
|
69 session |
|
70 process |
|
71 response |
|
72 t)) |
|
73 (when (consp next-error) |
|
74 (add-to-list 'errors |
|
75 (flycheck-error-new-at |
|
76 (plist-get next-error :line) |
|
77 (plist-get next-error :col) |
|
78 (plist-get next-error :type) |
|
79 (plist-get next-error :msg) |
|
80 :checker 'haskell-process |
|
81 :buffer (plist-get state :buffer))))) |
|
82 (funcall (plist-get state :callback) |
|
83 'finished |
|
84 errors))))))))) |
|
85 |
|
86 |
|
87 (flycheck-define-generic-checker 'haskell-process |
|
88 "A syntax and type checker for Haskell using GHCi (via the |
|
89 haskell-process Emacs module)." |
|
90 :start 'flycheck-haskell-process-start |
|
91 :modes '(haskell-mode) |
|
92 :next-checkers '((warning . haskell-hlint))) |
|
93 |
|
94 ;; Register as an auto-selectable checker |
|
95 (setq flycheck-checkers (cons `haskell-process flycheck-checkers)) |
|
96 |
|
97 (provide 'haskell-flycheck) |