diff --git a/app/Command/REPL.hs b/app/Command/REPL.hs index 07ee153b32..df9a66e12d 100644 --- a/app/Command/REPL.hs +++ b/app/Command/REPL.hs @@ -96,15 +96,15 @@ psciOptions = PSCiOptions <$> many inputFile <*> backend -- | Parses the input and returns either a command, or an error as a 'String'. -getCommand :: forall m. MonadException m => InputT m (Either String (Maybe Command)) -getCommand = handleInterrupt (return (Right Nothing)) $ do +getCommand :: forall m. MonadException m => InputT m (Either String [Command]) +getCommand = handleInterrupt (return (Right [])) $ do line <- withInterrupt $ getInputLine "> " case line of - Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty - Just "" -> return (Right Nothing) - Just s -> return . fmap Just $ parseCommand s + Nothing -> return (Right [QuitPSCi]) -- Ctrl-D when input is empty + Just "" -> return (Right []) + Just s -> return (parseCommand s) -pasteMode :: forall m. MonadException m => InputT m (Either String Command) +pasteMode :: forall m. MonadException m => InputT m (Either String [Command]) pasteMode = parseCommand <$> go [] where @@ -343,16 +343,20 @@ command = loop <$> options c <- getCommand case c of Left err -> outputStrLn err >> go state - Right Nothing -> go state - Right (Just PasteLines) -> do + Right xs -> goExec xs + where + goExec :: [Command] -> InputT (StateT PSCiState (ReaderT PSCiConfig IO)) () + goExec xs = case xs of + [] -> go state + (PasteLines : rest) -> do c' <- pasteMode case c' of - Left err -> outputStrLn err >> go state - Right c'' -> handleCommandWithInterrupts state c'' - Right (Just QuitPSCi) -> do + Left err -> outputStrLn err >> goExec rest + Right c'' -> handleCommandWithInterrupts state c'' >> goExec rest + (QuitPSCi : _) -> do outputStrLn quitMessage liftIO $ shutdown state - Right (Just c') -> handleCommandWithInterrupts state c' + (c' : rest) -> handleCommandWithInterrupts state [c'] >> goExec rest loadUserConfig :: state -> StateT PSCiState (ReaderT PSCiConfig IO) () loadUserConfig state = do @@ -366,12 +370,11 @@ command = loop <$> options handleCommandWithInterrupts :: state - -> Command + -> [Command] -> InputT (StateT PSCiState (ReaderT PSCiConfig IO)) () - handleCommandWithInterrupts state cmd = do + handleCommandWithInterrupts state cmds = do handleInterrupt (outputStrLn "Interrupted.") - (withInterrupt (lift (handleCommand' state cmd))) - go state + (withInterrupt (lift (for_ cmds (handleCommand' state)))) putStrLn prologueMessage backendState <- setup diff --git a/src/Language/PureScript/Interactive/Parser.hs b/src/Language/PureScript/Interactive/Parser.hs index 9d6df35f69..cc12d55e42 100644 --- a/src/Language/PureScript/Interactive/Parser.hs +++ b/src/Language/PureScript/Interactive/Parser.hs @@ -33,11 +33,11 @@ parseDotFile filePath s = first show $ do -- | -- Parses PSCI metacommands or expressions input from the user. -- -parseCommand :: String -> Either String Command +parseCommand :: String -> Either String [Command] parseCommand cmdString = case cmdString of - (':' : cmd) -> parseDirective cmd - _ -> parseRest psciCommand cmdString + (':' : cmd) -> pure <$> parseDirective cmd + _ -> parseRest (many1 psciCommand) cmdString parseRest :: P.TokenParser a -> String -> Either String a parseRest p s = first show $ do diff --git a/tests/TestPsci/TestEnv.hs b/tests/TestPsci/TestEnv.hs index 84cb90fba5..646d93bcd6 100644 --- a/tests/TestPsci/TestEnv.hs +++ b/tests/TestPsci/TestEnv.hs @@ -9,6 +9,7 @@ import Control.Exception.Lifted (bracket_) import Control.Monad (void, when) import Control.Monad.IO.Class (liftIO) import Control.Monad.Trans.RWS.Strict (evalRWST, asks, local, RWST) +import Data.Foldable (traverse_) import Data.List (isSuffixOf) import qualified Data.Text as T import qualified Language.PureScript as P @@ -70,10 +71,10 @@ runAndEval :: String -> TestPSCi () -> (String -> TestPSCi ()) -> TestPSCi () runAndEval comm jsOutputEval textOutputEval = case parseCommand comm of Left errStr -> liftIO $ putStrLn errStr >> exitFailure - Right command -> + Right commands -> -- The JS result is ignored, as it's already written in a JS source file. -- For the detail, please refer to Interactive.hs - handleCommand (\_ -> jsOutputEval) (return ()) textOutputEval command + traverse_ (handleCommand (\_ -> jsOutputEval) (return ()) textOutputEval) commands -- | Run a PSCi command, evaluate compiled JS, and ignore evaluation output and printed output run :: String -> TestPSCi () diff --git a/tests/purs/psci/Multiline.purs b/tests/purs/psci/Multiline.purs index 86f0dcf420..c12f543732 100644 --- a/tests/purs/psci/Multiline.purs +++ b/tests/purs/psci/Multiline.purs @@ -1,5 +1,7 @@ +-- @paste import Prelude import Data.Array +-- @paste -- @paste fac :: Int -> Int