fused-effects-readline (empty) → 0.0.0.0
raw patch · 7 files changed
+206/−0 lines, 7 filesdep +basedep +directorydep +filepathsetup-changed
Dependencies added: base, directory, filepath, fused-effects, fused-effects-readline, haskeline, prettyprinter, prettyprinter-ansi-terminal, terminal-size, transformers
Files
- CHANGELOG.md +3/−0
- LICENSE +29/−0
- Setup.hs +2/−0
- fused-effects-readline.cabal +65/−0
- src/Control/Carrier/Readline/Haskeline.hs +69/−0
- src/Control/Effect/Readline.hs +32/−0
- test/Test.hs +6/−0
+ CHANGELOG.md view
@@ -0,0 +1,3 @@+# v0.0.0.0++Initial release.
+ LICENSE view
@@ -0,0 +1,29 @@+BSD 3-Clause License++Copyright (c) 2019, Rob Rix+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 holder 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 HOLDER 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
+ fused-effects-readline.cabal view
@@ -0,0 +1,65 @@+cabal-version: 2.2++name: fused-effects-readline+version: 0.0.0.0+synopsis: A readline-like effect and carrier for fused-effects+description: A readline-like effect and carrier for fused-effects, using haskeline under the hood+homepage: https://github.com/fused-effects/fused-effects-readline+bug-reports: https://github.com/fused-effects/fused-effects-readline/issues+license: BSD-3-Clause+license-file: LICENSE+author: Rob Rix+maintainer: rob.rix@me.com+copyright: 2019 Rob Rix+category: Development+extra-source-files:+ CHANGELOG.md++common common+ default-language: Haskell2010+ ghc-options:+ -Weverything+ -Wno-all-missed-specialisations+ -Wno-implicit-prelude+ -Wno-missed-specialisations+ -Wno-missing-import-lists+ -Wno-missing-local-signatures+ -Wno-monomorphism-restriction+ -Wno-name-shadowing+ -Wno-safe+ -Wno-unsafe+ if (impl(ghc >= 8.6))+ ghc-options: -Wno-star-is-type+ if (impl(ghc >= 8.8))+ ghc-options: -Wno-missing-deriving-strategies++library+ import: common+ hs-source-dirs: src+ exposed-modules:+ Control.Carrier.Readline.Haskeline+ Control.Effect.Readline+ build-depends:+ base >= 4.12 && < 5+ , directory ^>= 1.3.3.2+ , filepath ^>= 1.4.2.1+ , fused-effects ^>= 1+ , haskeline ^>= 0.7+ , prettyprinter ^>= 1.5+ , prettyprinter-ansi-terminal ^>= 1.1+ , terminal-size ^>= 0.3+ , transformers >= 0.4 && < 0.6++test-suite test+ import: common+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Test.hs+ build-depends:+ base+ , fused-effects-readline+++source-repository head+ type: git+ location: https://github.com/fused-effects/fused-effects-readline
+ src/Control/Carrier/Readline/Haskeline.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, LambdaCase, MultiParamTypeClasses, ScopedTypeVariables, TypeApplications #-}+module Control.Carrier.Readline.Haskeline+( -- * Readline carrier+ runReadline+, runReadlineWithHistory+, ReadlineC(ReadlineC)+ -- * Readline effect+, module Control.Effect.Readline+) where++import Control.Algebra+import Control.Carrier.Lift+import Control.Carrier.Reader+import Control.Effect.Readline+import Control.Monad.Fix (MonadFix)+import Control.Monad.IO.Class (MonadIO(..))+import Control.Monad.Trans.Class (MonadTrans(..))+import Data.Coerce (coerce)+import Data.Text.Prettyprint.Doc+import Data.Text.Prettyprint.Doc.Render.Terminal+import System.Console.Haskeline+import System.Console.Terminal.Size as Size+import System.Directory+import System.Environment+import System.FilePath+import System.IO (stdout)++runReadline :: MonadException m => Prefs -> Settings m -> ReadlineC m a -> m a+runReadline prefs settings (ReadlineC m) = runInputTWithPrefs prefs (coerce settings) (runM (runReader (Line 0) m))++runReadlineWithHistory :: MonadException m => ReadlineC m a -> m a+runReadlineWithHistory block = do+ homeDir <- liftIO getHomeDirectory+ prefs <- liftIO $ readPrefs (homeDir </> ".haskeline")+ prog <- liftIO getExecutablePath+ let settingsDir = homeDir </> ".local" </> dropExtension (takeFileName prog)+ settings = Settings+ { complete = noCompletion+ , historyFile = Just (settingsDir </> "repl_history")+ , autoAddHistory = True+ }+ liftIO $ createDirectoryIfMissing True settingsDir++ runReadline prefs settings block++newtype ReadlineC m a = ReadlineC { runReadlineC :: ReaderC Line (LiftC (InputT m)) a }+ deriving (Applicative, Functor, Monad, MonadFix, MonadIO)++instance MonadTrans ReadlineC where+ lift = ReadlineC . lift . lift . lift++instance MonadException m => Algebra Readline (ReadlineC m) where+ alg = \case+ Prompt prompt k -> ReadlineC $ do+ str <- sendM (getInputLine @m (cyan <> prompt <> plain))+ Line line <- ask+ local increment (runReadlineC (k line str))+ where cyan = "\ESC[1;36m\STX"+ plain = "\ESC[0m\STX"+ Print doc k -> do+ s <- maybe 80 Size.width <$> liftIO size+ liftIO (renderIO stdout (layoutSmart defaultLayoutOptions { layoutPageWidth = AvailablePerLine s 0.8 } (doc <> line)))+ k+++newtype Line = Line Int++increment :: Line -> Line+increment (Line n) = Line (n + 1)
+ src/Control/Effect/Readline.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE DeriveFunctor, DeriveGeneric #-}+module Control.Effect.Readline+( -- * Readline effect+ Readline(..)+, prompt+, print+ -- * Re-exports+, Algebra+, Has+, run+) where++import Control.Algebra+import Data.Text.Prettyprint.Doc (Doc)+import Data.Text.Prettyprint.Doc.Render.Terminal (AnsiStyle)+import GHC.Generics (Generic1)+import Prelude hiding (print)++prompt :: Has Readline sig m => String -> m (Int, Maybe String)+prompt p = send (Prompt p (curry pure))++print :: Has Readline sig m => Doc AnsiStyle -> m ()+print s = send (Print s (pure ()))+++data Readline m k+ = Prompt String (Int -> Maybe String -> m k)+ | Print (Doc AnsiStyle) (m k)+ deriving (Functor, Generic1)++instance HFunctor Readline+instance Effect Readline
+ test/Test.hs view
@@ -0,0 +1,6 @@+module Main+( main+) where++main :: IO ()+main = pure ()