elisp/haskell-flycheck.el
changeset 71 b5976ed7311a
equal deleted inserted replaced
70:88c4f68cb191 71:b5976ed7311a
       
     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)