packages feed

ghc-mod (empty) → 0.1.0

raw patch · 9 files changed

+685/−0 lines, 9 filesdep +basedep +haskell-src-extsdep +parsecsetup-changed

Dependencies added: base, haskell-src-exts, parsec, process

Files

+ GHCMod.hs view
@@ -0,0 +1,234 @@+module Main where++import Control.Exception hiding (try)+import Data.Char+import Data.List+import Language.Haskell.Exts.Extension+import Language.Haskell.Exts.Parser hiding (parse)+import Language.Haskell.Exts.Syntax+import Prelude hiding (catch)+import System.Console.GetOpt+import System.Environment+import System.IO+import System.Process+import Text.ParserCombinators.Parsec++----------------------------------------------------------------++usage :: String+usage =    "ghc-mod version 0.1.0\n"+        ++ "Usage:\n"+        ++ "\t ghc-mod list\n"+        ++ "\t ghc-mod browse <module>\n"+        ++ "\t ghc-mod help\n"++----------------------------------------------------------------++data Options   = Options { optToLisp :: Bool+                         } deriving Show++defaultOptions :: Options+defaultOptions = Options { optToLisp = False+                         }++argspec :: [OptDescr (Options -> Options)]+argspec = [ Option ['l'] ["tolisp"]+            (NoArg (\opts -> opts { optToLisp = True }))+            "print as a list of Lisp"+          ]++parseArgs :: [OptDescr (Options -> Options)] -> [String] -> (Options, [String])+parseArgs spec argv+    = case getOpt Permute spec argv of+        (o,n,[]  ) -> (foldl (flip id) defaultOptions o, n)+        (_,_,errs) -> error (concat errs ++ usageInfo usage argspec)++----------------------------------------------------------------++main :: IO ()+main = flip catch handler $ do+    args <- getArgs+    let (opt,cmdArg) = parseArgs argspec args+        transform = if optToLisp opt then toLisp else toPlain+    ll <- case cmdArg !! 0 of+            cmd | cmd == "browse" -> browseModule $ cmdArg !! 1+                | cmd == "list"   -> listModules+            _                     -> error usage+    putStr $ transform $ nub $ sort $ ll+  where+    handler :: ErrorCall -> IO ()+    handler _ = putStr usage++----------------------------------------------------------------++browseModule :: String -> IO [String]+browseModule mname = do+    xs <- getSyntax mname+    let ys = preprocess xs+    return $ parseSyntax ys++getSyntax :: String -> IO String+getSyntax mname  = do+    (inp,out,_,_) <- runInteractiveProcess "ghci" [] Nothing Nothing+    mapM_ setFD [inp,out]+    hPutStrLn inp ":set prompt \"\""+    hPutStrLn inp "1"+    hPutStrLn inp $ ":browse " ++ mname+    hPutStrLn inp ":set prompt \"Prelude>\""+    hPutStrLn inp ":quit"+    cs <- hGetContents out+    return $ unlines $ dropTailer $ dropHeader $ lines $ cs+  where+    isNotPrefixOf x y = not (x `isPrefixOf` y)+    dropHeader xs = tail $ dropWhile (isNotPrefixOf "Prelude>") xs+    dropTailer = takeWhile (isNotPrefixOf "Prelude>")+    setFD h = do+        hSetBinaryMode h False+        hSetBuffering h LineBuffering++parseSyntax :: String -> [String]+parseSyntax xs = do+    let mode = defaultParseMode { extensions = NewQualifiedOperators : ExplicitForall : glasgowExts }+        res = parseModuleWithMode mode xs+    case res of+      ParseOk x       -> identifiers x+--      e               -> error $ show e+      _               -> []++----------------------------------------------------------------++listModules :: IO [String]+listModules = do+  cs <- getDump+  return $ exposedModules cs++getDump :: IO String+getDump = do+  (_,hout,_,_) <- runInteractiveProcess "ghc-pkg" ["dump"] Nothing Nothing+  hGetContents hout++exposedModules :: String -> [String]+exposedModules cs = let ls = unfoldLines cs+                        ns = values "name: " ls+                        ms = values "exposed-modules: " ls+                        zs = zip ns ms+                        xs = filter (\(nm,_) -> nm `notElem` ["ghc", "ghc-prim", "rts", "integer"]) zs+                        ss = map snd xs+                    in filter (\x -> not ("GHC" `isPrefixOf` x)) $ concatMap words ss++values :: String -> [String] -> [String]+values tag ls = let len = length tag+                    fs = filter (tag `isPrefixOf`) ls+                in map (drop len) fs++----------------------------------------------------------------++unfoldLines :: String -> [String]+unfoldLines xs = self xs+    where+      splitNL = break (== '\n')+      self "" = []+      self s  = let (l, s') = splitNL s+                in case s' of+                     []          -> [l]+                     (_:' ':s'') -> cont s'' l+                     (_:s'')     -> l : self s''+      cont s a = let (l, s') = splitNL $ dropWhile (== ' ') s+                     a' = a ++ " " ++ l+                 in case s' of+                      []          -> [a']+                      (_:' ':s'') -> cont s'' a'+                      (_:s'')     -> a' : self s''++toLisp :: [String] -> String+toLisp ms = "(" ++ unwords quoted ++ ")\n"+    where+      quote x = "\"" ++ x ++ "\""+      quoted = map quote ms++toPlain :: [String] -> String+toPlain = unlines++----------------------------------------------------------------++preprocess :: String -> String+preprocess cs = case parse remove "remove" cs of+                  Right a -> a+                  Left  e -> error $ show e++modName :: Parser String+modName = do c <- oneOf ['A'..'Z']+             cs <- many1 $ oneOf $ ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9'] ++ "_'#"+             return $ c:cs++anyName :: Parser String+anyName = many1 $ oneOf $ ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9'] ++ "_'#"++manyBefore :: Show tok => GenParser tok st a -> GenParser tok st [tok] -> GenParser tok st [a]+manyBefore p anchor = manyTill p (eof <|> try anc)+    where+      anc = do pos <- getPosition+               s <- anchor+               ss <- getInput+               setInput $ s ++ ss+               setPosition pos+               return ()++keyword :: Parser String+keyword = do ms <- modName+             char '.'+             return $ ms ++ ['.']++ghcName :: Parser String+ghcName = do keyword+             try sep <|> end+  where+   sep = do+       ws <- sepBy1 anyName (char '.')+       return $ last ws+   end = do+       endBy1 anyName (char '.')+       return ""++nonGhcName :: Parser String+nonGhcName = do c <- anyChar  -- making this func non-empty+                cs <- manyBefore anyChar keyword+                return $ c:cs++remove :: Parser String+remove = do l1 <- try ghcName <|> return ""+            l2 <- nonGhcName+            ll <- many (do x <- ghcName+                           y <- nonGhcName+                           return $ x ++ y)+            return $ concat $ l1 : l2 : ll++----------------------------------------------------------------++identifiers :: Module -> [String]+identifiers (Module _ _ _ _ _ _ x) = filter hid $ concatMap decl x+  where+    hid = all (\c -> isAlphaNum c || elem c "_'")++decl :: Decl -> [String]+decl (TypeSig _ [x] _) = [name x]+decl (DataDecl _ _ _ x _ y _) = name x : (map qualConDecl y)+decl (ClassDecl _ _ x _ _ y) = name x : (map classDecl y)+decl (TypeDecl _ x _ _) = [name x]+decl x = [show x]++qualConDecl :: QualConDecl -> String+qualConDecl (QualConDecl _ _ _ x) = conDecl x++conDecl :: ConDecl -> String+conDecl (ConDecl (Ident x) _) = x+conDecl (InfixConDecl _ (Ident x) _) = x+conDecl x = show x++classDecl :: ClassDecl -> String+classDecl (ClsDecl x) = concat $ decl x -- xxx+classDecl x = show x++name :: Name -> String+name (Symbol x) = x+name (Ident x) = x
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2009, IIJ Innovation Institute Inc.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++  * Redistributions of source code must retain the above copyright+    notice, this list of conditions and the following disclaimer.+  * Redistributions in binary form must reproduce the above copyright+    notice, this list of conditions and the following disclaimer in+    the documentation and/or other materials provided with the+    distribution.+  * Neither the name of the copyright holders nor the names of its+    contributors may be used to endorse or promote products derived+    from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ elisp/Makefile view
@@ -0,0 +1,17 @@+SRCS = ghc.el ghc-func.el ghc-doc.el ghc-comp.el+EMACS = emacs+++TEMPFILE  = temp.el++all: $(TEMPFILE) ghc.el+	$(EMACS) -batch -q -no-site-file -l ./$(TEMPFILE) -f ghc-compile++$(TEMPFILE):+	@echo '(setq load-path (cons "." load-path))' >> $(TEMPFILE)+	@echo '(defun ghc-compile () (mapcar (lambda (x) (byte-compile-file x)) (list ' >> $(TEMPFILE)+	@echo $(SRCS)| sed -e 's/\(ghc[^ ]*\.el\)/"\1"/g' >> $(TEMPFILE)+	@echo ')))' >> $(TEMPFILE)++clean:+	rm -f *.elc $(TEMPFILE)
+ elisp/ghc-comp.el view
@@ -0,0 +1,218 @@+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; ghc-comp.el+;;;++;; Author:  Kazu Yamamoto <Kazu@Mew.org>+;; Created: Sep 25, 2009++;;; Code:++(require 'ghc-func)++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Customize Variables+;;;++(defvar ghc-module-command "ghc-mod")++(defvar ghc-idle-timer-interval 30)++;; must be sorted+(defvar ghc-reserved-keyword-for-bol '("class" "data" "default" "import" "infix" "infixl" "infixr" "instance" "main" "module" "newtype" "type"))++;; must be sorted+(defvar ghc-reserved-keyword '("case" "deriving" "do" "else" "if" "in" "let" "module" "of" "then" "where"))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Local Variables+;;;++(defvar ghc-window-configuration nil)++(mapc 'make-variable-buffer-local+      '(ghc-window-configuration))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Initializer+;;;++(defvar ghc-module-names nil)   ;; completion for "import"+(defvar ghc-merged-keyword nil) ;; completion for type/func/...++(defvar ghc-keyword-prefix "ghc-keyword-")+(defvar ghc-keyword-Prelude nil)+(defvar ghc-loaded-module nil)++(defun ghc-comp-init ()+  (setq ghc-module-names (ghc-load-keyword "list"))+  (setq ghc-keyword-Prelude (ghc-load-keyword "browse" "Prelude"))+  (setq ghc-loaded-module '("Prelude"))+  (ghc-merge-keywords)+  (run-with-idle-timer ghc-idle-timer-interval 'repeat 'ghc-idle-timer))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Executing command+;;;++(defun ghc-load-keyword (&rest args)+  (if (not (ghc-which ghc-module-command))+      (message "%s not found" ghc-module-command)+    (ghc-read-lisp+     (lambda ()+       (let ((msg (mapconcat 'identity (cons ghc-module-command args) " ")))+	 (message "Executing \"%s\"..." msg)+	 (apply 'call-process-shell-command+		ghc-module-command nil t nil (cons "-l" args))+	 (message "Executing \"%s\"...done" msg))))))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Completion+;;;++(defvar ghc-completion-buffer-name "*Completions*")++(defun ghc-complete ()+  (interactive)+  (if (ghc-should-scroll)+      (ghc-scroll-completion-buffer)+    (ghc-try-complete)))++(defun ghc-should-scroll ()+  (let ((window (ghc-completion-window)))+    (and (eq last-command this-command)+	 window (window-live-p window) (window-buffer window)+	 (buffer-name (window-buffer window)))))++(defun ghc-scroll-completion-buffer ()+  (let ((window (ghc-completion-window)))+    (with-current-buffer (window-buffer window)+      (if (pos-visible-in-window-p (point-max) window)+	  (set-window-start window (point-min))+	(save-selected-window+	  (select-window window)+	  (scroll-up))))))++(defun ghc-completion-window ()+  (get-buffer-window ghc-completion-buffer-name 0))++(defun ghc-try-complete ()+  (let* ((end (point))+	 (symbols (ghc-select-completion-symbol))+	 (beg (ghc-completion-start-point))+	 (pattern (buffer-substring-no-properties beg end))+	 (completion (try-completion pattern symbols)))+    (cond+     ((eq completion t) ;; completed+      ) ;; do nothing+     ((null completion) ;; no completions+      (ding))+     ((not (string= pattern completion)) ;; ???+      (delete-region beg end)+      (insert completion)+      (ghc-reset-window-configuration))+     (t ;; multiple completions+      (let* ((list0 (all-completions pattern symbols))+	     (list (sort list0 'string<)))+	(if (= (length list) 1)+	    (ghc-reset-window-configuration)+	  (ghc-save-window-configuration)+	  (with-output-to-temp-buffer ghc-completion-buffer-name+	    (display-completion-list list pattern))))))))++(defun ghc-save-window-configuration ()+  (unless (get-buffer-window ghc-completion-buffer-name)+    (setq ghc-window-configuration (current-window-configuration))))++(defun ghc-reset-window-configuration ()+  (when ghc-window-configuration+    (set-window-configuration ghc-window-configuration)+    (setq ghc-window-configuration nil)))++(defun ghc-select-completion-symbol ()+  (cond+   ((or (minibufferp)+	(save-excursion+	  (beginning-of-line)+	  (looking-at "import ")))+    ghc-module-names)+   ((or (bolp)+	(let ((end (point)))+	  (save-excursion+	    (beginning-of-line)+	    (not (search-forward " " end t)))))+    ghc-reserved-keyword-for-bol)+   (t ghc-merged-keyword)))++(defun ghc-completion-start-point ()+  (save-excursion+    (let ((beg (save-excursion (beginning-of-line) (point))))+      (if (re-search-backward "[ (,`]" beg t)+	  (1+ (point))+	beg))))+++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Loading keywords+;;;++(add-hook 'find-file-hook 'ghc-load-module-buffer)++(defun ghc-load-module-buffer ()+  (interactive)+  (when (eq major-mode 'haskell-mode)+    (mapc 'ghc-load-module (ghc-gather-import-modules-buffer))))++(defun ghc-load-module (mod)+  (when (and (member mod ghc-module-names)+	     (not (member mod ghc-loaded-module)))+    (let ((keywords (ghc-load-keyword "browse" mod)))+      (when (or (consp keywords) (null keywords))+	(set (intern (concat ghc-keyword-prefix mod)) keywords)+	(setq ghc-loaded-module (cons mod ghc-loaded-module))))))++(defun ghc-merge-keywords ()+  (let* ((modkeys (mapcar 'ghc-module-keyword ghc-loaded-module))+	 (keywords (cons ghc-reserved-keyword modkeys))+	 (uniq-sorted (sort (ghc-uniq-lol keywords) 'string<)))+    (setq ghc-merged-keyword uniq-sorted)))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Background Idle Timer+;;;++(defun ghc-idle-timer ()+  (dolist (mod (ghc-gather-import-modules))+    (ghc-load-module mod))+  (ghc-merge-keywords))++(defun ghc-gather-import-modules ()+  (let ((bufs (mapcar 'buffer-name (buffer-list)))+	ret)+    (save-excursion+      (dolist (buf bufs)+	(when (string-match "\\.hs$" buf)+	  (set-buffer buf)+	  (setq ret (cons (ghc-gather-import-modules-buffer) ret)))))+    (ghc-uniq-lol ret)))++(defun ghc-gather-import-modules-buffer ()+  (let (ret)+    (save-excursion+      (goto-char (point-min))+      (while (re-search-forward "^import *\\([^\n ]+\\)" nil t)+	(setq ret (cons (match-string-no-properties 1) ret))+	(forward-line)))+    ret))++(defun ghc-module-keyword (mod)+  (symbol-value (intern (concat ghc-keyword-prefix mod))))++(provide 'ghc-comp)
+ elisp/ghc-doc.el view
@@ -0,0 +1,59 @@+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; ghc.el+;;;++;; Author:  Kazu Yamamoto <Kazu@Mew.org>+;; Created: Sep 25, 2009++(require 'ghc-func)+(require 'ghc-comp)++;;; Code:++(defun ghc-browse-document (&optional haskell-org)+  (interactive "P")+  (let* ((mod0 (ghc-extract-module))+	 (mod (ghc-read-module-name mod0))+	 (pkg (ghc-resolve-package-name mod)))+    (ghc-display-document pkg mod haskell-org)))++(defun ghc-resolve-package-name (mod)+  (with-temp-buffer+    (call-process "ghc-pkg" nil t nil "find-module" "--simple-output" mod)+    (goto-char (point-min))+    (when (looking-at "^\\([^-]+\\)-")+      (match-string-no-properties 1))))++(defun ghc-resolve-document-path (pkg)+  (with-temp-buffer+    (call-process "ghc-pkg" nil t nil "field" pkg "haddock-html")+    (goto-char (point-min))+    (when (looking-at "^haddock-html: \\([^ \n]+\\)$")+      (match-string-no-properties 1))))++(defvar ghc-doc-local-format "file://%s/%s.html")+(defvar ghc-doc-hackage-format+  "http://hackage.haskell.org/packages/archive/%s/latest/doc/html/%s.html")++(defun ghc-display-document (pkg mod haskell-org)+  (when (and pkg mod)+    (let* ((mod- (ghc-replace-character mod ?. ?-))+	   (url (if haskell-org+		    (format ghc-doc-hackage-format pkg mod-)+		  (format ghc-doc-local-format+			  (ghc-resolve-document-path pkg) mod-))))+      (browse-url url))))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;++(defvar ghc-input-map nil)++(unless ghc-input-map+  (setq ghc-input-map+	(if (boundp 'minibuffer-local-map)+	    (copy-keymap minibuffer-local-map)+	  (make-sparse-keymap)))+  (define-key ghc-input-map "\t" 'ghc-complete))++(provide 'ghc-doc)
+ elisp/ghc-func.el view
@@ -0,0 +1,52 @@+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; ghc-func.el+;;;++;; Author:  Kazu Yamamoto <Kazu@Mew.org>+;; Created: Sep 25, 2009++;;; Code:++(defun ghc-replace-character (string from to)+  "Replace characters equal to FROM to TO in STRING."+  (let ((ret (copy-sequence string)))+    (dotimes (cnt (length ret) ret)+      (if (char-equal (aref ret cnt) from)+	  (aset ret cnt to)))))++(defun ghc-which (cmd)+  (catch 'loop+    (dolist (dir exec-path)+      (let ((path (expand-file-name cmd dir)))+      (if (file-exists-p path)+          (throw 'loop path))))))++(defun ghc-uniq-lol (lol)+  (let ((hash (make-hash-table :test 'equal))+	ret)+    (dolist (lst lol)+      (dolist (key lst)+	(puthash key key hash)))+    (maphash (lambda (key val) (setq ret (cons key ret))) hash)+    ret))++(defun ghc-read-lisp (func)+  (with-temp-buffer+    (funcall func)+    (goto-char (point-min))+    (condition-case nil+	(read (current-buffer))+      (error ()))))++(defun ghc-extract-module ()+  (interactive)+  (save-excursion+    (beginning-of-line)+    (if (looking-at "^\\(import\\|module\\) +\\(qualified +\\)?\\([^ (\n]+\\)")+	(match-string-no-properties 3))))++(defun ghc-read-module-name (def)+  (read-from-minibuffer "Module name: " def ghc-input-map))++(provide 'ghc-func)
+ elisp/ghc.el view
@@ -0,0 +1,45 @@+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; ghc.el+;;;++;; Author:  Kazu Yamamoto <Kazu@Mew.org>+;; Created: Sep 25, 2009+;; Revised:++;; Put the following code to your "~/.emacs".+;;+;; (autoload 'ghc-init "ghc" nil t)+;; (add-hook 'haskell-mode-hook (lambda () (ghc-init)))++;;; Code:++(defvar ghc-version "0.1")++;; (require 'haskell-mode)+(require 'ghc-comp)+(require 'ghc-doc)++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Customize Variables+;;;++(defvar ghc-completion-key "\e\t")+(defvar ghc-document-key   "\e\C-d")+(defvar ghc-import-key     "\e\C-m")++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;+;;; Initializer+;;;++(defvar ghc-initialized nil)++(defun ghc-init ()+  (unless ghc-initialized+    (define-key haskell-mode-map ghc-completion-key 'ghc-complete)+    (define-key haskell-mode-map ghc-document-key   'ghc-browse-document)+    (define-key haskell-mode-map ghc-import-key     'ghc-load-module-buffer)+    (ghc-comp-init)+    (setq ghc-initialized t)))
+ ghc-mod.cabal view
@@ -0,0 +1,29 @@+Name:                   ghc-mod+Version:                0.1.0+Author:                 Kazu Yamamoto <kazu@iij.ad.jp>+Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>+License:                BSD3+License-File:           LICENSE+Homepage:               http://www.mew.org/~kazu/proj/ghc-mod/+Synopsis:               Happy Haskell programming on Emacs+Description:            This packages includes Elisp files+			and a Haskell command, "ghc-mod".+			"ghc*.el" enable completion of+			Haskell symbols on Emacs.+			"ghc-mod" is a backend of "ghc*.el".+			It lists up all installed modules+                        or extracts names of functions, classes,+                        and data declarations.+Category:               Development+Cabal-Version:          >= 1.6+Build-Type:             Simple+Data-Dir:               elisp+Data-Files:             Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el+Executable ghc-mod+  Main-Is:              GHCMod.hs+  GHC-Options:          -Wall+  Build-Depends:        base >= 4.0 && < 10,+                        parsec, process, haskell-src-exts+Source-Repository head+  Type:                 git+  Location:             git://github.com/kazu-yamamoto/ghc-mod.git