diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,7 @@
 Changelog for ghcid (* = breaking change)
 
+0.8.7, released 2020-06-06
+    #319, allow eval multiline commands
 0.8.6, released 2020-04-13
     #314, report GHC panics as error messages
 0.8.5, released 2020-03-19
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -53,7 +53,14 @@
 Using the `ghci` session that `ghcid` manages you can also evaluate expressions:
 
 * You can pass any `ghci` expression with the `--test` flag, e.g. `--test=:main`, which will be run whenever the code is warning free (or pass `--warnings` for when the code is merely error free).
-* If you pass the `--allow-eval` flag then comments in the source files such as `-- $> expr` will run `expr` after loading - see [this blog post](https://jkeuhlen.com/2019/10/19/Compile-Your-Comments-In-Ghcid.html) for more details.
+* If you pass the `--allow-eval` flag then comments in the source files such as `-- $> expr` will run `expr` after loading - see [this blog post](https://jkeuhlen.com/2019/10/19/Compile-Your-Comments-In-Ghcid.html) for more details. Multiline comments are also supported with the following syntax:
+
+      {- $>
+      expr1
+      expr2
+      ...
+      exprN
+      <$ -}
 
 ### FAQ
 
diff --git a/ghcid.cabal b/ghcid.cabal
--- a/ghcid.cabal
+++ b/ghcid.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.18
 build-type:         Simple
 name:               ghcid
-version:            0.8.6
+version:            0.8.7
 license:            BSD3
 license-file:       LICENSE
 category:           Development
diff --git a/src/Language/Haskell/Ghcid.hs b/src/Language/Haskell/Ghcid.hs
--- a/src/Language/Haskell/Ghcid.hs
+++ b/src/Language/Haskell/Ghcid.hs
@@ -184,6 +184,7 @@
                     writeInp "import qualified System.IO as INTERNAL_GHCID"
                     writeInp ":unset +t +s" -- see https://github.com/ndmitchell/ghcid/issues/162
                     writeInp $ ":set prompt " ++ ghcid_prefix
+                    writeInp $ ":set prompt-cont " ++ ghcid_prefix
 
                     -- failure isn't harmful, so do them one-by-one
                     forM_ (ghciFlagsRequired ++ ghciFlagsRequiredVersioned) $ \flag ->
diff --git a/src/Session.hs b/src/Session.hs
--- a/src/Session.hs
+++ b/src/Session.hs
@@ -149,7 +149,7 @@
     fmap join $ forM cmds $ \(file, cmds') ->
         forM cmds' $ \(num, cmd) -> do
             ref <- newIORef []
-            execStream ghci (unwords $ lines cmd) $ \_ resp -> modifyIORef ref (resp :)
+            execStream ghci cmd $ \_ resp -> modifyIORef ref (resp :)
             resp <- unlines . reverse <$> readIORef ref
             pure $ Eval $ EvalResult file (num, 1) cmd resp
 
@@ -164,7 +164,10 @@
 splitCommands ((num, line) : ls)
     | isCommand line =
           let (cmds, xs) = span (isCommand . snd) ls
-           in (num, unlines $ fmap (drop $ length commandPrefix) $ line : fmap snd cmds) : splitCommands xs
+           in (num, unwords $ fmap (drop $ length commandPrefix) $ line : fmap snd cmds) : splitCommands xs
+    | isMultilineCommandPrefix line =
+          let (cmds, xs) = break (isMultilineCommandSuffix . snd) ls
+           in (num, unlines (wrapGhciMultiline (fmap snd cmds))) : splitCommands (drop1 xs)
     | otherwise = splitCommands ls
 
 isCommand :: String -> Bool
@@ -173,8 +176,20 @@
 commandPrefix :: String
 commandPrefix = "-- $> "
 
+isMultilineCommandPrefix :: String -> Bool
+isMultilineCommandPrefix = (==) multilineCommandPrefix
 
+multilineCommandPrefix :: String
+multilineCommandPrefix = "{- $>"
 
+isMultilineCommandSuffix :: String -> Bool
+isMultilineCommandSuffix = (==) multilineCommandSuffix
+
+multilineCommandSuffix :: String
+multilineCommandSuffix = "<$ -}"
+
+wrapGhciMultiline :: [String] -> [String]
+wrapGhciMultiline xs = [":{"] ++ xs ++ [":}"]
 
 -- | Reload, returning the same information as 'sessionStart'. In particular, any
 --   information that GHCi doesn't repeat (warnings from loaded modules) will be
