diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@
 ini = liftIO $ putStrLn "Welcome!"
 
 repl :: IO ()
-repl = evalRepl ">>> " cmd options (Word completer) ini
+repl = evalRepl (pure ">>> ") cmd options (Word completer) ini
 ```
 
 Trying it out:
@@ -62,9 +62,9 @@
 "spam"
 
 >>> :say Hello Haskell
- _______________ 
+ _______________
 < Hello Haskell >
- --------------- 
+ ---------------
         \   ^__^
          \  (oo)\_______
             (__)\       )\/\
@@ -113,12 +113,12 @@
 -- Tab completion inside of StateT
 repl :: IO ()
 repl = flip evalStateT Set.empty
-     $ evalRepl ">>> " cmd opts (Word comp) init
+     $ evalRepl (pure ">>> ") cmd opts (Word comp) init
 ```
 
 
 Prefix Completion
-----------------
+-----------------
 
 Just as GHCi will provide different tab completion for kind-level vs type-level symbols based on which prefix
 the user has entered, we can also set up a provide this as a first-level construct using a ``Prefix`` tab
@@ -164,7 +164,7 @@
 init = return ()
 
 repl :: IO ()
-repl = evalRepl ">> " cmd opts (Prefix (wordCompleter byWord) defaultMatcher) init
+repl = evalRepl (pure ">>> ") cmd opts (Prefix (wordCompleter byWord) defaultMatcher) init
 ```
 
 Trying it out:
diff --git a/repline.cabal b/repline.cabal
--- a/repline.cabal
+++ b/repline.cabal
@@ -1,5 +1,5 @@
 name:                repline
-version:             0.1.7.0
+version:             0.2.0.0
 synopsis:            Haskeline wrapper for GHCi-like REPL interfaces.
 license:             MIT
 license-file:        LICENSE
@@ -26,7 +26,7 @@
   exposed-modules:     System.Console.Repline
   build-depends:
     base       >= 4.6 && <5.0,
-    containers >= 0.5 && <0.6,
+    containers >= 0.5 && <0.7,
     mtl        >= 2.2 && <2.3,
     process    >= 1.2 && <2.0,
     haskeline  >= 0.7 && <0.8
diff --git a/src/System/Console/Repline.hs b/src/System/Console/Repline.hs
--- a/src/System/Console/Repline.hs
+++ b/src/System/Console/Repline.hs
@@ -72,7 +72,7 @@
 Putting it all together we have a little shell.
 
 > main :: IO ()
-> main = evalRepl ">>> " cmd options (Word completer) ini
+> main = evalRepl (pure ">>> ") cmd options (Word completer) ini
 
 Putting this in a file we can test out our cow-trek shell.
 
@@ -123,6 +123,7 @@
   evalRepl,
   abort,
   tryAction,
+  dontCrash,
 
   trimComplete,
 ) where
@@ -134,6 +135,7 @@
 import Data.List (isPrefixOf)
 import Control.Applicative
 import Control.Monad.State.Strict
+import Control.Monad.Reader
 
 -------------------------------------------------------------------------------
 -- Haskeline Transformer
@@ -161,6 +163,10 @@
   get = lift get
   put = lift . put
 
+instance MonadReader r m => MonadReader r (HaskelineT m) where
+  ask                    = lift ask
+  local f (HaskelineT m) = HaskelineT $ H.mapInputT (local f) m
+
 instance (MonadHaskeline m) => MonadHaskeline (StateT s m) where
   getInputLine = lift . getInputLine
   getInputChar = lift . getInputChar
@@ -183,35 +189,45 @@
 tryAction (HaskelineT f) = HaskelineT (H.withInterrupt loop)
     where loop = handle (\H.Interrupt -> loop) f
 
+-- | Catch all toplevel failures.
+dontCrash :: (MonadIO m, H.MonadException m) => m () -> m ()
+dontCrash m = H.catch m ( \ e@SomeException{} -> liftIO ( putStrLn ( show e ) ) )
+
 -- | Abort the current REPL loop, and continue.
 abort :: MonadIO m => HaskelineT m a
 abort = throwIO H.Interrupt
 
 -- | Completion loop.
-replLoop :: MonadException m
-         => String
+replLoop :: (Functor m, MonadException m)
+         => HaskelineT m String
          -> Command (HaskelineT m)
          -> Options (HaskelineT m)
+         -> Maybe Char
          -> HaskelineT m ()
-replLoop banner cmdM opts = loop
+replLoop banner cmdM opts optsPrefix = loop
   where
     loop = do
-      minput <- H.handleInterrupt (return (Just "")) $ getInputLine banner
+      prefix <- banner
+      minput <- H.handleInterrupt (return (Just "")) $ getInputLine prefix
       case minput of
         Nothing -> outputStrLn "Goodbye."
-
         Just "" -> loop
-        Just ":" -> loop
-
-        Just (':' : cmds) -> do
-          let (cmd:args) = words cmds
-          optMatcher cmd opts args
-          loop
-
+        Just (prefix: cmds)
+          | null cmds -> handleInput [prefix] >> loop
+          | Just prefix == optsPrefix ->
+            case words cmds of
+              [] -> loop
+              (cmd:args) -> do
+                let optAction = optMatcher cmd opts args
+                result <- H.handleInterrupt (return Nothing) $ Just <$> optAction
+                maybe exit (const loop) result
         Just input -> do
-          H.handleInterrupt (return ()) $ cmdM input
+          handleInput input
           loop
 
+    handleInput input = H.handleInterrupt exit $ cmdM input
+    exit = return ()
+
 -- | Match the options.
 optMatcher :: MonadHaskeline m => String -> Options m -> [String] -> m ()
 optMatcher s [] _ = outputStrLn $ "No such command :" ++ s
@@ -220,16 +236,17 @@
   | otherwise = optMatcher s xs args
 
 -- | Evaluate the REPL logic into a MonadException context.
-evalRepl :: MonadException m             -- Terminal monad ( often IO ).
-         => String                       -- ^ Banner
-         -> Command (HaskelineT m)       -- ^ Command function
-         -> Options (HaskelineT m)       -- ^ Options list and commands
-         -> CompleterStyle m             -- ^ Tab completion function
-         -> HaskelineT m a               -- ^ Initializer
+evalRepl :: (Functor m, MonadException m)  -- Terminal monad ( often IO ).
+         => HaskelineT m String            -- ^ Banner
+         -> Command (HaskelineT m)         -- ^ Command function
+         -> Options (HaskelineT m)         -- ^ Options list and commands
+         -> Maybe Char                     -- ^ Optional command prefix ( passing Nothing ignores the Options argument )
+         -> CompleterStyle m               -- ^ Tab completion function
+         -> HaskelineT m a                 -- ^ Initializer
          -> m ()
-evalRepl banner cmd opts comp initz = runHaskelineT _readline (initz >> monad)
+evalRepl banner cmd opts optsPrefix comp initz = runHaskelineT _readline (initz >> monad)
   where
-    monad = replLoop banner cmd opts
+    monad = replLoop banner cmd opts optsPrefix
     _readline = H.Settings
       { H.complete       = mkCompleter comp
       , H.historyFile    = Just ".history"
@@ -275,7 +292,7 @@
 completionNoSpace str = Completion str str False
 
 wordCompleter :: Monad m => WordCompleter m -> CompletionFunc m
-wordCompleter f (start, n) = (completeWord (Just '\\') " \t()[]" (_simpleComplete f)) (start, n)
+wordCompleter f (start, n) = completeWord (Just '\\') " \t()[]" (_simpleComplete f) (start, n)
 
 listCompleter :: Monad m => [String] -> CompletionFunc m
 listCompleter names (start, n) = completeWord (Just '\\') " \t()[]" (_simpleComplete (complete_aux names)) (start, n)
@@ -301,5 +318,5 @@
 runMatcher :: Monad m => [(String, CompletionFunc m)]
                       -> CompletionFunc m
                       -> CompletionFunc m
-runMatcher opts def (start, n) = do
-  (completeMatcher def (n ++ reverse start) opts) (start, n)
+runMatcher opts def (start, n) =
+  completeMatcher def (n ++ reverse start) opts (start, n)
