integrating hlint.

This commit is contained in:
Kazu Yamamoto 2010-05-06 15:29:55 +09:00
parent 85fdba4ffa
commit bb363c92e7
6 changed files with 62 additions and 9 deletions

View File

@ -5,6 +5,7 @@ import Check
import Control.Applicative import Control.Applicative
import Control.Exception hiding (try) import Control.Exception hiding (try)
import Lang import Lang
import Lint
import List import List
import Prelude hiding (catch) import Prelude hiding (catch)
import System.Console.GetOpt import System.Console.GetOpt
@ -21,18 +22,25 @@ usage = "ghc-mod version 0.4.0\n"
++ "\t ghc-mod lang\n" ++ "\t ghc-mod lang\n"
++ "\t ghc-mod browse <module> [<module> ...]\n" ++ "\t ghc-mod browse <module> [<module> ...]\n"
++ "\t ghc-mod check <HaskellFile>\n" ++ "\t ghc-mod check <HaskellFile>\n"
++ "\t ghc-mod lint <HaskellFile>\n"
++ "\t ghc-mod boot\n" ++ "\t ghc-mod boot\n"
++ "\t ghc-mod help\n" ++ "\t ghc-mod help\n"
---------------------------------------------------------------- ----------------------------------------------------------------
defaultOptions :: Options defaultOptions :: Options
defaultOptions = Options { convert = toPlain } defaultOptions = Options {
convert = toPlain
, hlint = "hlint"
}
argspec :: [OptDescr (Options -> Options)] argspec :: [OptDescr (Options -> Options)]
argspec = [ Option "l" ["tolisp"] argspec = [ Option "l" ["tolisp"]
(NoArg (\opts -> opts { convert = toLisp })) (NoArg (\opts -> opts { convert = toLisp }))
"print as a list of Lisp" "print as a list of Lisp"
, Option "f" ["hlint"]
(ReqArg (\str opts -> opts { hlint = str }) "hlint")
"path to hlint"
] ]
parseArgs :: [OptDescr (Options -> Options)] -> [String] -> (Options, [String]) parseArgs :: [OptDescr (Options -> Options)] -> [String] -> (Options, [String])
@ -50,12 +58,8 @@ main = flip catch handler $ do
res <- case head cmdArg of res <- case head cmdArg of
"browse" -> concat <$> mapM (browseModule opt) (tail cmdArg) "browse" -> concat <$> mapM (browseModule opt) (tail cmdArg)
"list" -> listModules opt "list" -> listModules opt
"check" -> do "check" -> withFile (checkSyntax opt) (cmdArg !! 1)
let file = cmdArg !! 1 "lint" -> withFile (lintSyntax opt) (cmdArg !! 1)
exist <- doesFileExist file
if exist
then checkSyntax opt file
else return ""
"lang" -> listLanguages opt "lang" -> listLanguages opt
"boot" -> do "boot" -> do
mods <- listModules opt mods <- listModules opt
@ -67,6 +71,11 @@ main = flip catch handler $ do
where where
handler :: ErrorCall -> IO () handler :: ErrorCall -> IO ()
handler _ = putStr usage handler _ = putStr usage
withFile cmd file = do
exist <- doesFileExist file
if exist
then cmd file
else return ""
---------------------------------------------------------------- ----------------------------------------------------------------
toLisp :: [String] -> String toLisp :: [String] -> String

20
Lint.hs Normal file
View File

@ -0,0 +1,20 @@
module Lint where
import Control.Applicative
import Data.List
import System.IO
import System.Process
import Types
lintSyntax :: Options -> String -> IO String
lintSyntax cmd file = pretty <$> lint cmd file
where
pretty = unlines . map (concat . intersperse "\0")
. filter (\x -> length x > 1)
. groupBy (\a b -> a /= "" && b /= "")
. lines
lint :: Options -> String -> IO String
lint cmd file = do
(_,hout,_,_) <- runInteractiveProcess (hlint cmd) [file] Nothing Nothing
hGetContents hout

View File

@ -6,6 +6,7 @@ import GHC.Paths (libdir)
data Options = Options { data Options = Options {
convert :: [String] -> String convert :: [String] -> String
, hlint :: String
} }
withGHC :: Ghc [String] -> IO [String] withGHC :: Ghc [String] -> IO [String]

View File

@ -30,7 +30,23 @@
(let ((after-save-hook nil)) (let ((after-save-hook nil))
(save-buffer)) (save-buffer))
(let ((file (file-name-nondirectory (buffer-file-name)))) (let ((file (file-name-nondirectory (buffer-file-name))))
(list ghc-module-command (list "check" file)))) (list ghc-module-command (ghc-flymake-command file))))
(defvar ghc-hlint (ghc-which "hlint"))
(defvar ghc-flymake-command nil) ;; nil: check, t: lint
(defun ghc-flymake-command (file)
(if ghc-flymake-command
(list "-f" ghc-hlint "lint" file)
(list "check" file)))
(defun ghc-flymake-toggle-command ()
(interactive)
(setq ghc-flymake-command (not ghc-flymake-command))
(if ghc-flymake-command
(message "Syntax check with hlint")
(message "Syntax check with GHC")))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -49,7 +65,7 @@
(defun ghc-flymake-insert-errors (title errs) (defun ghc-flymake-insert-errors (title errs)
(save-excursion (save-excursion
(insert title "\n") (insert title "\n")
(mapc (lambda (x) (insert x "\n")) errs))) (mapc (lambda (x) (insert (ghc-replace-character x ghc-null ghc-newline) "\n")) errs)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -79,4 +79,9 @@
(ghc-add ret (read m)))) (ghc-add ret (read m))))
(error ())))) (error ()))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defconst ghc-null 0)
(defconst ghc-newline 10)
(provide 'ghc-func) (provide 'ghc-func)

View File

@ -41,6 +41,7 @@
(defvar ghc-insert-key "\et") (defvar ghc-insert-key "\et")
(defvar ghc-sort-key "\es") (defvar ghc-sort-key "\es")
(defvar ghc-check-key "\C-x\C-s") (defvar ghc-check-key "\C-x\C-s")
(defvar ghc-toggle-key "\C-c\C-c")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
@ -61,6 +62,7 @@
(define-key haskell-mode-map ghc-insert-key 'ghc-insert-template) (define-key haskell-mode-map ghc-insert-key 'ghc-insert-template)
(define-key haskell-mode-map ghc-sort-key 'ghc-sort-lines) (define-key haskell-mode-map ghc-sort-key 'ghc-sort-lines)
(define-key haskell-mode-map ghc-check-key 'ghc-save-buffer) (define-key haskell-mode-map ghc-check-key 'ghc-save-buffer)
(define-key haskell-mode-map ghc-toggle-key 'ghc-flymake-toggle-command)
(ghc-comp-init) (ghc-comp-init)
(setq ghc-initialized t))) (setq ghc-initialized t)))