ghciと通信して補完をする(かなり強引)
とりあえず目処は立った。
でも、他の人に進めようとする気にはなれないな。*1
(defmacro toggle! (name) `(progn (setq ,name (not ,name)) (message (format "%s:%s" ,(symbol-name name) ,name)))) (require 'inf-haskell) (defun haskell-send-string (str) (condition-case err (comint-send-string (get-process "haskell") (format "%s\n" str)) (error err))) (defvar haskell-preoutput-filter-functions nil) (defvar haskell-output-storage nil) (defvar haskell-connect-inistalled nil) (defun haskell-connect-cleanup () (setq haskell-output-storage nil)) (defmacro haskell-connect-with-repl (send-func) `(let ((haskell-reading-p t) (old-filter comint-preoutput-filter-functions) (comint-preoutput-filter-functions haskell-preoutput-filter-functions)) (unwind-protect (progn (haskell-connect-cleanup) ,send-func (while haskell-reading-p (sleep-for 0 100)) (funcall haskell-output-filter (apply 'concat (reverse haskell-output-storage)))) (setq comint-preoutput-filter-functions old-filter)))) (defun haskell-repl-running-p () (get-process "haskell")) (defmacro haskell-filter-function-maker (regexp) (let1 s (gensym) `(lambda (,s) (when (string-match-p ,regexp ,s) (setq haskell-reading-p nil)) (push ,s haskell-output-storage) ""))) (defvar haskell-connect-ask-y-or-n-messages '("Display +all +[0-9]+ +possibilities\\? (y or n)" "--More--")) (defvar haskell-connect-junk-messages `("<interactive>:[0-9]+:[0-9]+: parse error on input.*" ,@haskell-connect-ask-y-or-n-messages)) (defun haskell-connect-install () (interactive) (when (and (haskell-repl-running-p) (not haskell-connect-inistalled)) (haskell-send-string ":set prompt \"REPL> \"") (toggle! haskell-connect-inistalled) (add-hook 'haskell-preoutput-filter-functions (haskell-filter-function-maker "REPL> *$")) (add-hook 'haskell-preoutput-filter-functions (lambda (s) (when (some (lambda (regexp) (string-match-p regexp s)) haskell-connect-ask-y-or-n-messages) (haskell-send-string "y")) s)) (setq haskell-output-filter (lambda (s) (substring-no-properties s 0 -7))) ))
実行
(require 'inf-haskell) (haskell-mode) (run-haskell) (haskell-connect-install) (let1 result (haskell-connect-with-repl (haskell-send-string "\t\t")) (loop for regexp in haskell-connect-junk-messages do (setq result (replace-regexp-in-string regexp "" result)) finally return result)) ; => ;; !! Prelude.asTypeOf Prelude.scanl fst ;; $ Prelude.asin Prelude.scanl1 gcd ;; $! Prelude.asinh Prelude.scanr getChar ;; && Prelude.atan Prelude.scanr1 getContents ;; * Prelude.atan2 Prelude.seq getLine ;; ** Prelude.atanh Prelude.sequence head ;; + Prelude.break Prelude.sequence_ id ;; ++ Prelude.catch Prelude.show init ;; - Prelude.ceiling Prelude.showChar interact ;; . Prelude.compare Prelude.showList ioError ;; / Prelude.concat Prelude.showParen isDenormalized ;; /= Prelude.concatMap Prelude.showString isIEEE ;; < Prelude.const Prelude.shows isInfinite ;; <= Prelude.cos Prelude.showsPrec isNaN ;; =<< Prelude.cosh Prelude.significand isNegativeZero ;; == Prelude.curry Prelude.signum iterate ;; > Prelude.cycle Prelude.sin last ;; >= Prelude.decodeFloat Prelude.sinh lcm ;; >> Prelude.div Prelude.snd length ;; >>= Prelude.divMod Prelude.span lex ;; Bool Prelude.drop Prelude.splitAt lines ;; Bounded Prelude.dropWhile Prelude.sqrt log ;; Char Prelude.either Prelude.subtract logBase ;; Double Prelude.elem Prelude.succ lookup ;; EQ Prelude.encodeFloat Prelude.sum map ;; Either Prelude.enumFrom Prelude.tail mapM ;; Enum Prelude.enumFromThen Prelude.take mapM_ ;; Eq Prelude.enumFromThenTo Prelude.takeWhile max ;; False Prelude.enumFromTo Prelude.tan maxBound ;; FilePath Prelude.error Prelude.tanh maximum ;; Float Prelude.even Prelude.toEnum maybe ;; Floating Prelude.exp Prelude.toInteger min ;; Fractional Prelude.exponent Prelude.toRational minBound ;; Functor Prelude.fail Prelude.truncate minimum ;; GT Prelude.filter Prelude.uncurry mod ;; IO Prelude.flip Prelude.undefined negate ;; IOError Prelude.floatDigits Prelude.unlines not ;; Int Prelude.floatRadix Prelude.until notElem ;; Integer Prelude.floatRange Prelude.unwords null ;; Integral Prelude.floor Prelude.unzip odd ;; Just Prelude.fmap Prelude.unzip3 or ;; LT Prelude.foldl Prelude.userError otherwise ;; Left Prelude.foldl1 Prelude.words pi ;; Maybe Prelude.foldr Prelude.writeFile pred ;; Monad Prelude.foldr1 Prelude.zip print ;; Nothing Prelude.fromEnum Prelude.zip3 product ;; Num Prelude.fromInteger Prelude.zipWith properFraction ;; Ord Prelude.fromIntegral Prelude.zipWith3 putChar ;; Ordering Prelude.fromRational Prelude.|| putStr ;; Prelude.!! Prelude.fst Rational putStrLn ;; Prelude.$ Prelude.gcd Read quot ;; Prelude.$! Prelude.getChar ReadS quotRem ;; Prelude.&& Prelude.getContents Real read ;; Prelude.* Prelude.getLine RealFloat readFile ;; Prelude.** Prelude.head RealFrac readIO ;; Prelude.+ Prelude.id Right readList ;; Prelude.++ Prelude.init Show readLn ;; Prelude.- Prelude.interact ShowS readParen ;; Prelude.. Prelude.ioError String reads ;; Prelude./ Prelude.isDenormalized True readsPrec ;; Prelude./= Prelude.isIEEE ^ realToFrac ;; Prelude.< Prelude.isInfinite ^^ recip ;; Prelude.<= Prelude.isNaN abs rem ;; Prelude.=<< Prelude.isNegativeZero acos repeat ;; Prelude.== Prelude.iterate acosh replicate ;; Prelude.> Prelude.last all return ;; Prelude.>= Prelude.lcm and reverse ;; Prelude.>> Prelude.length any round ;; Prelude.>>= Prelude.lex appendFile scaleFloat ;; Prelude.Bool Prelude.lines asTypeOf scanl ;; Prelude.Bounded Prelude.log asin scanl1 ;; Prelude.Char Prelude.logBase asinh scanr ;; Prelude.Double Prelude.lookup atan scanr1 ;; Prelude.EQ Prelude.map atan2 seq ;; Prelude.Either Prelude.mapM atanh sequence ;; Prelude.Enum Prelude.mapM_ break sequence_ ;; Prelude.Eq Prelude.max catch show ;; Prelude.False Prelude.maxBound ceiling showChar ;; Prelude.FilePath Prelude.maximum compare showList ;; Prelude.Float Prelude.maybe concat showParen ;; Prelude.Floating Prelude.min concatMap showString ;; Prelude.Fractional Prelude.minBound const shows ;; Prelude.Functor Prelude.minimum cos showsPrec ;; Prelude.GT Prelude.mod cosh significand ;; Prelude.IO Prelude.negate curry signum ;; Prelude.IOError Prelude.not cycle sin ;; Prelude.Int Prelude.notElem decodeFloat sinh ;; Prelude.Integer Prelude.null div snd ;; Prelude.Integral Prelude.odd divMod span ;; Prelude.Just Prelude.or drop splitAt ;; Prelude.LT Prelude.otherwise dropWhile sqrt ;; Prelude.Left Prelude.pi either subtract ;; Prelude.Maybe Prelude.pred elem succ ;; Prelude.Monad Prelude.print encodeFloat sum ;; Prelude.Nothing Prelude.product enumFrom tail ;; Prelude.Num Prelude.properFraction enumFromThen take ;; Prelude.Ord Prelude.putChar enumFromThenTo takeWhile ;; Prelude.Ordering Prelude.putStr enumFromTo tan ;; Prelude.Rational Prelude.putStrLn error tanh ;; Prelude.Read Prelude.quot even toEnum ;; Prelude.ReadS Prelude.quotRem exp toInteger ;; Prelude.Real Prelude.read exponent toRational ;; Prelude.RealFloat Prelude.readFile fail truncate ;; Prelude.RealFrac Prelude.readIO filter uncurry ;; Prelude.Right Prelude.readList flip undefined ;; Prelude.Show Prelude.readLn floatDigits unlines ;; Prelude.ShowS Prelude.readParen floatRadix until ;; Prelude.String Prelude.reads floatRange unwords ;; Prelude.True Prelude.readsPrec floor unzip ;; Prelude.^ Prelude.realToFrac fmap unzip3 ;; Prelude.^^ Prelude.recip foldl userError ;; Prelude.abs Prelude.rem foldl1 words ;; Prelude.acos Prelude.repeat foldr writeFile ;; Prelude.acosh Prelude.replicate foldr1 zip ;; Prelude.all Prelude.return fromEnum zip3 ;; Prelude.and Prelude.reverse fromInteger zipWith ;; Prelude.any Prelude.round fromIntegral zipWith3 ;; Prelude.appendFile Prelude.scaleFloat fromRational ||
*1:汚すぎる