File: Multiline.hs

package info (click to toggle)
haskell-repline 0.4.2.0-3
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 104 kB
  • sloc: haskell: 460; makefile: 5
file content (85 lines) | stat: -rw-r--r-- 1,941 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
module Main (main, repl) where

import Control.Monad.Trans
import Data.List (isPrefixOf)
import Data.Monoid
import System.Console.Repline
import System.Process (callCommand)

type Repl a = HaskelineT IO a

-- Evaluation : handle each line user inputs
cmd :: String -> Repl ()
cmd input = liftIO $ print input

-- Commands
help :: [String] -> Repl ()
help args = liftIO $ print $ "Help: " ++ show args

say :: String -> Repl ()
say args = do
  _ <- liftIO $ callCommand $ "cowsay" ++ " " ++ args
  return ()

load :: FilePath -> Repl ()
load args = do
  contents <- liftIO $ readFile args
  liftIO $ putStrLn contents

-- Options
opts :: [(String, String -> Repl ())]
opts =
  [ ("help", help . words), -- :help
    ("load", load), -- :load
    ("say", say) -- :say
  ]

-- Tab Completion: return a completion for partial words entered
completer :: Monad m => WordCompleter m
completer n = do
  let names = ["kirk", "spock", "mccoy"]
  return $ filter (isPrefixOf n) names

-- Completer
defaultMatcher :: (MonadIO m) => [([Char], CompletionFunc m)]
defaultMatcher =
  [ -- Commands
    (":load", fileCompleter),
    (":help", wordCompleter completer)
  ]

byWord :: Monad m => WordCompleter m
byWord n = do
  let names = fmap ((":" <>) . fst) opts
  return $ filter (isPrefixOf n) names

-- Initialiser function
ini :: Repl ()
ini = liftIO $ putStrLn "Welcome!"

-- Finaliser function
final :: Repl ExitDecision
final = do
  liftIO $ putStrLn "Goodbye!"
  return Exit

customBanner :: MultiLine -> Repl String
customBanner SingleLine = pure ">>> "
customBanner MultiLine = pure "| "

repl :: IO ()
repl =
  evalReplOpts $
    ReplOpts
      { banner = customBanner,
        command = cmd,
        options = opts,
        prefix = Just ':',
        multilineCommand = Just "paste",
        tabComplete = (Prefix (wordCompleter byWord) defaultMatcher),
        initialiser = ini,
        finaliser = final
      }

main :: IO ()
main = pure ()