diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@
   *  When given file arguments, eddie feeds them to your function.
   *  Eddie can easily add modules to the namespace you use.
   *  Eddie has options for processing things a line or file at a time.
-  *  Eddie will use binary file IO methods when asked to.
+  *  Eddie uses either Text or ByteStrings by default, not lists of characters.
 
 # More information
 
@@ -40,12 +40,12 @@
 
 # Testing
 
-Test use the haskell shelltestrunner package (can be installed with
-cabal). Run `shelltest tests` in the source directory to run
-the tests with the currently installed eddie. Use
-`shelltest tests -w eddie.hs` to run them using the current
-source. Use `shelltest tests -w dist/build/eddie/eddie` to
-run them with the compiled binary.
+Testing is done with the haskell shelltestrunner package (which can be
+installed with cabal). Run `shelltest tests` in the source directory
+to run the tests with the currently installed eddie. Use `shelltest
+tests -w eddie.hs` to run them using the current source. Use
+`shelltest tests -w dist/build/eddie/eddie` to run them with the
+compiled binary.
 
 # Documentation
 
diff --git a/eddie.1 b/eddie.1
--- a/eddie.1
+++ b/eddie.1
@@ -1,49 +1,58 @@
 .TH "eddie" "1" "" "" ""
 .SH NAME
 .PP
-eddie \- run haskell filters from the command line
+eddie \- run Haskell filters from the command line
 .SH SYNOPSYS
 .PP
-\f[B]eddie\f[] [ \f[I]options\f[] ] [ \f[I]expr\f[] ] \f[I]file\f[] ...
+\f[B]eddie\f[] [ \f[I]options\f[] ] [ \f[I]EXPRESSION\f[] ]
+\f[I]FILE\f[] ...
 .SH DESCRIPTION
 .PP
-\f[B]eddie\f[] evalutes the provided \f[I]expression\f[] on either the
-contents of \f[I]the file\f[] arguments concatenated together, or
-standard input if no *file arguments are present.
+\f[B]eddie\f[] evalutes the provided \f[I]EXPRESSION\f[] on either the
+contents of the \f[I]FILE\f[] arguments concatenated together, or
+standard input if no \f[I]FILE\f[] arguments are present.
 .PP
-The \f[B]\-\-line\f[], \f[B]\-\-file\f[] and \f[B]\-\-list\f[] options
-can be used to cause \f[I]expression\f[] to be used to process each
-line, each file, or a list of files or lines respectively.
+The \f[C]\-\-lines\f[], \f[C]\-\-files\f[] and \f[C]\-\-names\f[]
+options can be used to cause \f[I]expression\f[] to be used to process
+each line, each file, or tuple of \f[C](name,\ content)\f[] for each
+file, respectively.
+The \f[C]\-\-lists\f[] option can be used with \f[C]\-\-lines\f[],
+\f[C]\-\-files\f[] and \f[C]\-\-names\f[] to cause the \f[I]files\f[] to
+be processed as a list instead of one element at a time.
 .PP
-The prelude, \f[C]Data.List\f[] and \f[C]Data.Char\f[] modules are
-available for building expressions.
-Other modules may be added with the \f[B]\-\-Modules\f[] and
-\f[B]\-\-modules\f[] options.
+The \f[C]ClassyPrelude\f[] module is used instead of the default
+\f[C]Prelude\f[] when building expressions.
+The default type for input and output is \f[C]Text\f[], but input or
+both can be changed to \f[C]ByteString\f[] with the \f[C]\-\-binary\f[]
+and \f[C]\-\-text\f[] options.
+.PP
+Other modules may be added with the \f[C]\-\-Module\f[] and
+\f[C]\-\-module\f[] options.
 .SH OPTIONS
 .TP
-.B \f[B]\-\-expr\f[]
-The \f[B]\-\-expr\f[] \f[I]expr\f[] (short form \f[B]\-e\f[]
-\f[I]expr\f[] ) option concatenates it\[aq]s value to the haskell
+.B \f[B]\-\-expression\f[]
+The \f[B]\-\-expression\f[] \f[I]EXPRESSION\f[] (short form \f[B]\-e\f[]
+\f[I]EXPRESSION\f[] ) option concatenates it\[aq]s value to the Haskell
 expression being evaluated with a newline separator.
 Multiple occurrences can be used to build up a multi\-line expression.
 .RS
 .PP
-If no \f[B]\-e\f[] \f[I]expr\f[] option is present, the first non\-flag
-argument will be used for the haskell expression.
+If no \f[B]\-e\f[] \f[I]EXPRESSION\f[] option is present, the first
+non\-flag argument will be used for the Haskell expression.
 .RE
 .TP
-.B \f[B]\-\-line\f[]
-The \f[B]\-\-line\f[] (short form \f[B]\-l\f[]) option causes
-\f[B]eddie\f[] to process input line at a time.
-The \f[I]expr\f[] will be run on each line and the results concatenated
-together (using unlines).
+.B \f[B]\-\-lines\f[]
+The \f[B]\-\-lines\f[] (short form \f[B]\-l\f[]) option causes
+\f[B]eddie\f[] to process the input one line at a time.
+The \f[I]EXPRESSION\f[] will be run on each line and the results
+concatenated together (using unlines).
 .RS
 .PP
 The command
 .IP
 .nf
 \f[C]
-eddie\ \-l\ *expr\ file*\ ...
+eddie\ \-l\ EXPRESSION\ file\ ...
 \f[]
 .fi
 .PP
@@ -51,31 +60,44 @@
 .IP
 .nf
 \f[C]
-eddie\ "unlines\ .\ map\ *expr*\ \ .\ lines"\ *file*\ ...
+eddie\ "unlines\ .\ map\ EXPRESSION\ \ .\ lines"\ file\ ...
 \f[]
 .fi
+.PP
+Note that the \f[B]\-\-lines\f[], \f[B]\-\-files\f[] and
+\f[B]\-\-names\f[] options cannot be used together.
 .RE
 .TP
-.B \f[B]\-\-file\f[]
-The \f[B]\-\-file\f[] (short form \f[B]\-f\f[]) causes each file to be
+.B \f[B]\-\-files\f[]
+The \f[B]\-\-files\f[] (short form \f[B]\-f\f[]) causes each file to be
 processed individually.
 .RS
 .PP
-Note that the \f[B]\-l\f[] and \f[B]\-f\f[] options cannot be used
-together.
+Note that the \f[B]\-\-lines\f[], \f[B]\-\-files\f[] and
+\f[B]\-\-names\f[] options cannot be used together.
 .RE
 .TP
+.B \f[B]\-\-names\f[]
+The \f[B]\-\-names\f[] (short form \f[B]\-n\f[]) causes each file to be
+processed individually, as a tuple of \f[C](name,\ content)\f[].
+.RS
+.PP
+Note that the \f[B]\-\-lines\f[], \f[B]\-\-files\f[] and
+\f[B]\-\-names\f[] options cannot be used together.
+.RE
+.TP
 .B \f[B]\-\-list\f[]
 The \f[B]\-\-list\f[] (short form \f[B]\-L\f[]) option causes
 \f[B]eddie\f[] to pass the expression a list of lines or files.
-This requires one of the \f[B]\-l\f[] or \f[B]\-f\f[] options be used.
+This requires one of the \f[B]\-\-list\f[], \f[B]\-\-files\f[] or
+\f[B]\-\-names\f[] options be used.
 .RS
 .PP
 The command
 .IP
 .nf
 \f[C]
-eddie\ \-lL\ *expr\ file*\ ...
+eddie\ \-l\ \-L\ EXPRESSION\ file\ ...
 \f[]
 .fi
 .PP
@@ -83,43 +105,97 @@
 .IP
 .nf
 \f[C]
-eddie\ "unlines\ .\ *expr*\ .\ lines"\ filei\ ...
+eddie\ "EXPRESSION\ .\ lines"\ file\ ...
 \f[]
 .fi
 .RE
 .TP
 .B \f[B]\-\-binary\f[]
-The \f[B]\-\-binary\f[] (short form \f[B]\-b\f[]) option switches the
-output mode to binary.
-It also disables the maybe newline processing.
-Normally \f[B]eddie\f[] will output a final newline if the last
-character of the input is not a newline to place the prompt properly.
-If the \f[B]\-b\f[] option is used, the final newline will not be
-output.
+The \f[B]\-\-binary\f[] (short form \f[B]\-b\f[]) option changes the
+data from \f[C]Text\f[] to \f[C]ByteString\f[].
+This disable all processing of the input and output.
 .RS
 .RE
 .TP
-.B \f[B]\-\-modules\f[]
-The \f[B]\-\-modules\f[] \f[I]name\f[] (short form \f[B]\-m\f[]
-\f[I]name\f[]) option is used to import module \f[I]name\f[] into
-haskell before evaluating the expression.
+.B \f[B]\-\-lazy\f[]
+The \f[B]\-\-lazy\f[] (no short form) option switches the data types to
+their \f[I]lazy\f[] versions.
 .RS
+.PP
+Note that using this is \f[B]NOT\f[] recommended unless you know what
+you are doing.
+It seems to break type checking, cause hangs, or incorrect results when
+used.
+Even if everything works as expected, using it improperly can
+drastically increase memory usage and run time.
 .RE
 .TP
-.B \f[B]\-\-Modules\f[]
-The \f[B]\-\-Modules\f[] \f[I]name\f[],\f[I]as\f[] (short form
-\f[B]\-M\f[] \f[I]name\f[],\f[I]as\f[]) option imports the \f[I]name\f[]
-module using a qualified import with an as clause, with \f[I]as\f[]
+.B \f[B]\-\-text\f[]
+The \f[B]\-\-text\f[] (short form \f[B]\-t\f[]) option switches the
+output type back to \f[C]Text\f[] if the \f[B]\-\-binary\f[] or
+\f[B]\-\-lazy\f[] option was used.
+.RS
+.PP
+Using \f[B]\-\-text\f[] without \f[B]\-\-binary\f[] or \f[B]\-\-lazy\f[]
+is an error.
+.RE
+.TP
+.B \f[B]\-\-input\-encoding\f[]
+The \f[B]\-\-input\-encoding\f[] \f[I]ENCODING\f[] (no short form)
+option sets the encoding of the input file(s) to \f[I]ENCODING\f[].
+.RS
+.PP
+It is an error to use \f[B]\-\-input\-encoding\f[] with
+\f[B]\-\-binary\f[].
+.RE
+.TP
+.B \f[B]\-\-output\-encoding\f[]
+The \f[B]\-\-output\-encoding\f[] \f[I]ENCODING\f[] (no short form)
+option sets the encoding of the output file to \f[I]ENCODING\f[].
+.RS
+.PP
+It is an error to use \f[B]\-\-output\-encoding\f[] with
+\f[B]\-\-binary\f[] unless \f[B]\-\-text\f[] is also specified.
+.RE
+.TP
+.B \f[B]\-\-encoding\f[]
+The \f[B]\-\-encoding\f[] \f[I]ENCODING\f[] (no short form) option sets
+the encoding of all text files to \f[I]ENCODING\f[], whether for input
+or output.
+.RS
+.PP
+It is an error to use \f[B]\-\-encoding\f[] with \f[B]\-\-binary\f[]
+unless \f[B]\-\-text\f[] is also specified.
+.RE
+.TP
+.B \f[B]\-\-module\f[]
+The \f[B]\-\-module\f[] \f[I]NAME\f[] (short form \f[B]\-m\f[]
+\f[I]NAME\f[]) option is used to import module \f[I]NAME\f[] into
+Haskell before evaluating the expression.
+.RS
+.RE
+.TP
+.B \f[B]\-\-Module\f[]
+The \f[B]\-\-Module\f[] \f[I]NAME\f[],\f[I]AS\f[] (short form
+\f[B]\-M\f[] \f[I]NAME\f[],\f[I]AS\f[]) option imports the \f[I]NAME\f[]
+module using a qualified import with an as clause, with \f[I]AS\f[]
 being the value for the as clause.
 .RS
 .RE
+.TP
+.B \f[B]\-\-extension\f[]
+The \f[B]\-\-extension\f[] \f[I]EXTENSION\f[] (short form \f[B]\-X\f[]
+\f[I]EXTENSION\f[]) option is used to enable the named GHC extension
+when evaluating the expression.
+.RS
+.RE
 .SH DIAGNOSTICS
 .PP
 If the command runs with no problems, eddie will exit with a status of
 0.
 If there are problems with the options, such that the expression is
 never evaluated, then eddie will exit with a status of 1.
-If haskell returns an error \- probably a compilation problem \- then
+If Haskell returns an error \- probably a compilation problem \- then
 eddie will exit with the status of 2.
 .SH SEE ALSO
 .PP
diff --git a/eddie.cabal b/eddie.cabal
--- a/eddie.cabal
+++ b/eddie.cabal
@@ -1,5 +1,5 @@
 Name:                eddie
-Version:             0.5.1
+Version:             1.0.0
 Synopsis:	     Command line file filtering with haskell
 Description:	     A tool to let you use short haskell expressions to filter
 		     files at the command line.
@@ -7,7 +7,7 @@
 License:             BSD3
 License-file:	     LICENSE
 Author:              Mike Meyer
-Copyright:	     (c) 2011 Mike Meyer
+Copyright:	     (c) 2014 Mike Meyer
 Maintainer:          mwm@mired.org
 Build-type:          Simple
 Homepage:	     http://chiselapp.com/user/mwm/repository/eddie/
@@ -17,7 +17,9 @@
 
 Executable eddie
     Main-is:         eddie.hs
-    Build-Depends:   hint >= 0.3.3.2, base >= 4.2.0 && < 5, cmdargs >= 0.7
+    Build-Depends:   hint >= 0.3.3.2, base >= 4.2.0 && < 5,
+                     optparse-applicative >= 0.11, bifunctors >= 4.2,
+                     safe >= 0.3.8, classy-prelude >= 0.12
 
 Source-repository head
     Type: fs
@@ -26,4 +28,4 @@
 Source-repository this
     Type: fs
     Location: https://chiselapp.com/user/mwm/repository/eddie/
-    Tag: 0.5.1
+    Tag: 1.0.0
diff --git a/eddie.hs b/eddie.hs
--- a/eddie.hs
+++ b/eddie.hs
@@ -1,151 +1,281 @@
-#!/usr/bin/env runghc
-{-# LANGUAGE DeriveDataTypeable #-}
+#!/usr/bin/env runhaskell
 {-# LANGUAGE GADTs #-}
-{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ViewPatterns #-}
 
-import Language.Haskell.Interpreter
-  (setImportsQ, interpret, runInterpreter, as, MonadInterpreter,
-   InterpreterError (..), GhcError (..))
-import Data.IORef (newIORef, readIORef, writeIORef)
-import System.Environment (getArgs, getProgName)
-import System.IO
-       (openFile, openBinaryFile, hClose, stdin, IOMode (ReadMode), hIsEOF,
-        hGetChar, Handle, hSetBinaryMode, stdout, stderr, hPutStrLn)
-import System.IO.Unsafe (unsafeInterleaveIO)
-import System.Console.CmdArgs.Implicit
-  (cmdArgs, (&=), Data, Typeable, help, explicit, name, args, summary, program,
-   details)
-import System.Exit (exitWith, ExitCode (..))
-import Control.Exception (finally, evaluate)
-import Control.Monad     (when, liftM, join)
+import ClassyPrelude hiding ((<>))
 
-main = do
-  myName <- getProgName
-  opts <- cmdArgs (eddie &= program myName)
-  case parseOpts opts of
-    Left e -> do hPutStrLn stderr $ "usage: " ++ myName ++ " " ++ e
-                 exitWith (ExitFailure 1)
-    Right o -> runIt myName o
-      where runIt name opts = do
-              let opener = if binary opts then openBinaryFile else openFile
-              let outputFunc = putStrMaybeLn (binary opts)
-              when (binary opts) $ hSetBinaryMode stdout True
-              fun <- runInterpreter $ makeFun opts
-              case fun of
-                Left e -> do hPutStrLn stderr $ name ++ ": Error: " ++ interpreterErrorMsg e
-                             exitWith (ExitFailure 2)
-                Right f -> withFiles (files opts) opener (outputFunc . f)
+import Data.Bifunctor (second)
+import Data.Version (showVersion)
+import Language.Haskell.Interpreter (
+  as, interpret, languageExtensions, MonadInterpreter, runInterpreter, set,
+  setImportsQ, setUseLanguageExtensions,
+  GhcError(..), InterpreterError(..), OptionVal((:=)),
+  Extension(NoImplicitPrelude, OverloadedStrings, UnknownExtension))
+import Options.Applicative (
+  (<>), customExecParser, disambiguate, header, help, helper, hidden,
+  info, infoOption, long,  many, metavar, option, prefs, short,
+  str, strArgument, strOption, switch, value, Parser)
+import Paths_eddie (version)
+import Safe (tailMay)
+import System.Environment (getProgName)
+import System.Exit (exitWith, exitSuccess, ExitCode(..))
+import System.IO (hSetBinaryMode, hSetEncoding, mkTextEncoding, openFile,
+                 IOMode(ReadMode), TextEncoding)
+import Text.Read (read)
 
 
-interpreterErrorMsg :: InterpreterError -> String
-interpreterErrorMsg err = case err of
-  UnknownError msg      -> "Unknown error: " ++ msg
-  WontCompile ghcErrors -> "GHC errors:\n" ++ concatMap errMsg ghcErrors
-  NotAllowed msg        -> "Not allowed: " ++ msg
-  GhcException msg      -> "GHC exceptions: " ++ msg
+{- Data types -}
+data Eddie = Eddie -- Command line arguments and options.
+                   [String]                 -- exprs
+                   Bool			    -- lazy
+                   Bool                     -- binary
+                   Bool                     -- text
+                   Bool                     -- line
+                   Bool                     -- file
+                   Bool                     -- names
+                   Bool                     -- list
+                   (Maybe String)           -- encoding
+                   (Maybe String)           -- inputEncoding
+                   (Maybe String)           -- outputEncoding
+                   [String]                 -- modules
+                   [(String, Maybe String)] -- asModules
+                   [String]                 -- extensions
+                   [String]                 -- files
+                   deriving (Show)
 
+data Proxy a b = Proxy -- Proxy for input and output data types 
 
-putStrMaybeLn :: Bool -> String -> IO ()
-putStrMaybeLn binary val =
-  (if binary || last val == '\n' then putStr else putStrLn) val
+data Mode a b -- Processing mode for the expression
+     where Mode :: (IsSequence a, IsSequence b, Typeable b, Typeable c)
+                => (c -> b)               -- witness to interpret
+                -> (Handle -> IO a)       -- Read input
+                -> ([(Text, a)] -> d)     -- preprocess
+                -> ((c -> b) -> d -> b)   -- wrapper of interpreted function
+                -> (b -> IO ())           -- Write output
+                -> Mode a b
 
+data Args = Args -- Arguments for turning the expression into a function
+                 String                     -- Expression
+                 [String]                   -- Files
+                 [(String, Maybe String)]   -- Modules
+                 [Extension]                   -- Extensions
 
-makeFun :: MonadInterpreter m => Eddie -> m ([(FilePath, String)] -> String)
-makeFun opts = do
-  setImportsQ (asModules opts)
-  eval (head (expr opts)) mode
-    where mode | line opts && list opts = Mode (as :: [String] -> [String]) id
-                                               (lines . concat . map snd) unlines
-               | line opts = Mode (as :: String -> String) map
-                                  (lines . concat . map snd) unlines
-               | file opts && list opts = Mode (as :: [String] -> [String]) id
-                                               (map snd) concat
-               | file opts = Mode (as :: String -> String) map (map snd) concat
-               | otherwise = Mode (as :: String -> String) id (concat . map snd)
-                                  id
+data Options = Options -- Options controlling how data is passed to the function
+                 Bool                      -- lines
+                 Bool                      -- files
+                 Bool                      -- names
+                 Bool                      -- list
+                 (IO (Maybe TextEncoding)) -- input encoding
+                 (IO (Maybe TextEncoding)) -- output encoding
 
 
-data Mode where
-    Mode :: (Typeable a, Typeable b)
-         => (a -> b)                    -- witness to `interpret`
-         -> ((a -> b) -> c -> d)        -- application of interpreted function
-         -> ([(FilePath, String)] -> c) -- preprocess
-         -> (d -> String)               -- postprocess
-         -> Mode
+main :: IO ()
+main = eddie =<< options
 
-eval :: MonadInterpreter m => String
-                           -> Mode -> m ([(FilePath, String)] -> String)
-eval s (Mode f t bra ket) = liftM ((ket .) . (. bra) . t) $ interpret s f
 
--- an even lazier version of  withFile (courtesy of Heinrich Apfelmus)
--- Tweaked by mwm to accept a handle instead of a file so caller can
--- use favorite opening function or pass in stdin.
-withFile :: IO Handle -> (String -> IO a) -> IO a
-withFile ih f = do
-    fin <- newIORef (return ())
-    h <- ih
-    let close = join (readIORef fin)
-        open  = do
-          writeIORef fin (hClose h)
-          lazyRead h
-    finally (unsafeInterleaveIO open >>= f >>= evaluate) close
+-- eddie takes an Eddie and create a Mode then calls eddie' to do the work
+eddie :: Eddie -> IO ()
+-- Handle usage errors
+eddie opts@(Eddie exprs lazy binary text lines files names list
+                  encoding input output _ _ _ fileNames)
+  | text && not (binary || lazy) =
+      printError "Usage: --text requires --binary or --lazy"
+  | lines && files = printError "Usage: --lines is incompatible with --files"
+  | lines && names = printError "Usage: --lines is incompatible with --names"
+  | files && names = printError "Usage: --files is incompatible with --names"
+  | files && null fileNames =
+      printError "Usage: --files requires at least one file"
+  | names && null fileNames =
+      printError "Usage: --names requires at least one file"
+  | list && not (lines || files || names) =
+      printError "Usage: --list requires one of --lines, --files or --names"
+  | null fileNames && null exprs = printError "Usage: Must provide an expression"
+  | isJust encoding && (isJust input || isJust output) =
+      printError "Usage: --encoding is incompatible with --input-encoding and --output-encoding"
+  | binary && isJust input =
+      printError "Usage: --input-encoding is incompatible with --binary"
+  | binary && not text && isJust output =
+      printError "Usage: can only use --output-encoding for text output"
 
-    where lazyRead h = hIsEOF h >>= \b ->
-            if b
-            then do hClose h; return []
-            else do c  <- hGetChar h
-                    cs <- unsafeInterleaveIO $ lazyRead h
-                    return (c:cs)
+-- Shuffle convenience options into the right places
+eddie (Eddie [] lazy binary text lines files names list Nothing input output
+             modules asModules extensions (expr:fileNames)) =
+  eddie (Eddie [expr] lazy binary text lines files names list Nothing input output
+               modules asModules extensions fileNames)
+eddie (Eddie exprs lazy binary text lines files names list encoding@(Just _) input
+             output modules asModules extensions fileNames)
+  | not binary = eddie (Eddie exprs lazy binary text lines files names list Nothing
+                              encoding encoding modules asModules extensions
+                              fileNames)
+  | otherwise  = eddie (Eddie exprs lazy binary text lines files names list Nothing
+                              Nothing encoding modules asModules extensions
+                              fileNames)
 
+-- Sort out the types and pass things to eddie'
+eddie (Eddie exprs lazy binary text lines files names list _ input output
+             modules asModules extensions fileNames)
+  | binary && text && lazy = eddie' (makeBinaryMode
+                                     (Proxy :: Proxy LByteString Text) opts
+                                     hGetContents $ putMaybeLn outputEncoding)
+                           args
+  | binary && text = eddie' (makeBinaryMode
+                             (Proxy :: Proxy ByteString Text) opts
+                             hGetContents $ putMaybeLn outputEncoding)
+                            args
+  | binary && lazy = eddie' (makeBinaryMode (Proxy ::Proxy LByteString LByteString)
+                                            opts hGetContents putBinary)
+                            args
+  | binary = eddie' (makeBinaryMode (Proxy :: Proxy ByteString ByteString) opts
+                                     hGetContents putBinary)
+                    args
+  | lazy && text = eddie' (makeTextMode (Proxy :: Proxy LText Text) opts) args
+  | lazy = eddie' (makeTextMode (Proxy :: Proxy LText LText) opts) args
+  | otherwise = eddie' (makeTextMode (Proxy :: Proxy Text Text) opts) args
+  where args = Args (unlines exprs) fileNames (makeModules modules asModules)
+                    (map makeExtension extensions)
+        inputEncoding = mapM mkTextEncoding input
+        outputEncoding = mapM mkTextEncoding output
+        opts = Options lines files names list inputEncoding outputEncoding
 
-withFiles :: [FilePath] -> (FilePath -> IOMode -> IO Handle) ->
-             ([(FilePath, String)] -> IO a) -> IO a
-withFiles []     o f = withFile (return stdin) (\s -> f [("", s)])
-withFiles [x]    o f = withFile (o x ReadMode) (\s -> f [(x, s)])
-withFiles (x:xs) o f = withFile (o x ReadMode) $ \s ->
-    let f' t = f ((x, s):t) in withFiles xs o f'
+eddie' :: Mode a b -> Args -> IO ()
+eddie' mode@(Mode _ reader _ _ writer) args@(Args _ files _ _) = do
+  fun <- runInterpreter $ makeFun mode args
+  case fun of
+   Left e -> printErrorCode 2 $ interpreterErrorMsg e
+   Right f -> do
+     handles <- if null files then return [stdin]
+                              else mapM (flip openFile ReadMode) files
+     mapM reader handles >>= writer . f . zip (map fromString files ++ [""])
+     exitSuccess
 
 
--- argument processing
-data Eddie = Eddie { line :: Bool,
-                     file :: Bool,
-                     list :: Bool,
-                     withNames :: Bool,
-                     binary :: Bool,
-                     expr :: [String],
-                     files :: [String],
-                     modules :: [String],
-                     asModules :: [(String, Maybe String)]
-                   } deriving (Show, Data, Typeable)
+{- Tools for making the various elements used above -}
+makeTextMode :: forall a b. (IOData a, Textual a, Typeable a,
+                             IOData b, Textual b, Typeable b)
+             => Proxy a b -> Options -> Mode a b
+makeTextMode proxy opts@(Options line _ _ list input output)
+  | not line  = makeBinaryMode proxy opts reader writer
+  | list      = Mode (as :: [a] -> b) reader (lines . concatMap snd) id writer
+  | otherwise = Mode (as :: a -> b) reader (lines . concatMap snd)
+                     (\f -> unlines . map f) writer
+  where reader = hGetEncoded input
+        writer = putMaybeLn output
 
-parseOpts :: Eddie -> Either String Eddie
-parseOpts opts =
-  let es = expr opts
-      fs = files opts
-      e:fs' = case (es, fs) of
-        ([], []) -> [""]
-        ([], _) -> fs
-        (_, _) -> unlines es:fs
-      mods = zip (modules opts) (repeat Nothing) ++ asModules opts
-  in
-   if e == "" || (file opts && null fs') || (file opts && line opts)
-              || (list opts && not (file opts || line opts))
-   then Left $ unlines ["[options] (-e expr | expr) [files ...]",
-                                   "--help for options"]
-   else Right $ opts {expr = [e], asModules = mods, files = fs' }
+makeBinaryMode :: forall a b. (IOData a, Typeable a, IOData b, Typeable b)
+               => Proxy a b -> Options -> (Handle -> IO a) -> (b -> IO ())
+               -> Mode a b
+makeBinaryMode _ (Options _ files names list _ _) reader writer
+  | files && list = Mode (as :: [a] -> b) reader (map snd) id writer
+  | names && list = Mode (as :: [(Text, a)] -> b) reader id id writer
+  | files         = Mode (as :: a -> b) reader (map snd) concatMap writer
+  | names         = Mode (as :: (Text, a) -> b) reader id concatMap writer
+  | otherwise     = Mode (as :: a -> b) reader (concatMap snd) id writer
 
 
-eddie = Eddie {line = False &= help "Process one line at a time (conflicts with --file)",
-               file = False &= help "Process files individually (requires at least one file name)",
-               list = False &= help "Process the list of files/lines (requires --line or --file)" &= name "L",
-               withNames = False &= help "Prepends file name to output lines (conflicts with --list, requires --line or --file and at least one file name)"
-               &= explicit &= name "name" &= name "n",
-               binary = False &= help "Process binary data",
-               expr = [] &= help "Line of expression to evaluate" &= name "e",
-               modules = ["Prelude", "Data.List", "Data.Char"]
-                         &= help "Modules to import for expr",
-               asModules = [] &= help "Modules to import qualified" &= explicit
-                           &= name "M" &= name "Modules",
-               files = [] &= args}
-        &= summary "eddie 0.6" &= details ["Haskell for shell scripts."]
+makeModules :: [String] -> [(String, Maybe String)] -> [(String, Maybe String)]
+makeModules modules asModules = zip modules (repeat Nothing) ++ asModules
 
+makeExtension :: String -> Extension
+makeExtension extension =
+  fromMaybe (UnknownExtension extension) $ readMay extension
+
+
+makeFun :: MonadInterpreter m => Mode a b -> Args -> m ([(Text, a)] -> b)
+makeFun (Mode witness _ pre wrap _) (Args expr _ modules extensions) = do
+  set [languageExtensions := ([NoImplicitPrelude, OverloadedStrings] ++
+                              extensions)] 
+  setImportsQ (("ClassyPrelude", Nothing):modules)
+  liftM ((. pre) . wrap) $ interpret expr witness
+
+
+{- Argument handling -}
+options :: IO Eddie
+options = do
+  name <- getProgName
+  let versionString = showVersion version
+      fullName = name ++ " " ++ versionString
+  customExecParser (prefs disambiguate)
+    $ info (eddieOptions <**> helper <**>
+            infoOption fullName (short 'V' <> long "version" <>
+                                 help "Print version information") <**>
+            infoOption versionString (long "numeric-version" <>
+                                      help "Print just the version number"))
+           (header $ name ++ " - Haskell for shell scripts")
+
+eddieOptions :: Parser Eddie
+eddieOptions =
+  Eddie <$> many (strOption (short 'e' <> long "expression" <> metavar "EXPR" <>
+                             help "Line of expression to evaluate")) <*>
+            switch (long "lazy" <> help "Use lazy data types" <> hidden) <*>
+            switch (short 'b' <> long "binary" <> help "Process binary data") <*>
+            switch (short 't' <> long "text" <> help "Produce text output") <*>
+            switch (short 'l' <> long "lines" <>
+                    help "Process one line at a time (conflicts with --files and --names)") <*>
+            switch (short 'f' <> long "files" <>
+                    help "Process files individually (requires at least one file name)") <*>
+            switch (short 'n' <> long "names" <>
+                    help "Process files individually as (NAME, DATA) tuples (requires at least one file name)") <*>
+            switch (short 'L' <> long "list" <>
+                    help "Process the list of files/lines (requires --lines, --files or --names )") <*>
+            option (Just <$> str) (long "encoding" <> value Nothing <>
+                                   help "Encoding for text file.") <*>
+            option (Just <$> str) (long "input-encoding" <> value Nothing <>
+                                   help "Encoding for input text file.") <*>
+            option (Just <$> str) (long "output-encoding" <> value Nothing <>
+                                   help "Encoding for output text file.") <*>
+            many (strOption (short 'm' <> long "module" <> metavar "MODULE" <>
+                             help "Module to import for expr")) <*>
+            many (option (second tailMay . break (== ',') <$> str)
+                         (short 'M' <> long "Module" <> metavar "MODULE,AS" <>
+                          help "Module to import qualified")) <*>
+            many (strOption (short 'X' <> long "extension" <>
+                             metavar "EXTENSION" <>
+                             help "Extension to enable")) <*>
+            many (strArgument (metavar "[EXPR] FILES ..."))
+
+
+{- Utilities -}
+-- Probably sucks the performance right out of Text, but it makes the output
+-- pretty. Maybe make it optional?
+putBinary :: IOData a => a -> IO ()
+putBinary s = hSetBinaryMode stdout True >> hPut stdout s
+
+putMaybeLn :: forall a. (IOData a, Textual a)
+            => IO (Maybe TextEncoding) -> a -> IO ()
+putMaybeLn encoding out = do
+  hSetMaybeEncoding encoding stdout
+  putMaybeLn' True out
+  where putMaybeLn' newline (uncons -> Nothing) =
+          unless newline $ hPut stdout ("\n" :: a)
+        putMaybeLn' _ (uncons -> Just (c, cs)) = do
+              hPut stdout $ (singleton c :: a)
+              putMaybeLn' (c == '\n') cs
+
+hGetEncoded :: IOData a => IO (Maybe TextEncoding) -> Handle -> IO a
+hGetEncoded encoding handle = do
+  hSetMaybeEncoding encoding handle
+  hGetContents handle
+  
+hSetMaybeEncoding :: IO (Maybe TextEncoding) -> Handle -> IO ()
+hSetMaybeEncoding encoding handle =
+  encoding >>= maybe (return ()) (hSetEncoding handle)
+
+
+interpreterErrorMsg :: InterpreterError -> String
+interpreterErrorMsg err = case err of
+  UnknownError msg      -> "Unknown error: " ++ msg
+  WontCompile ghcErrors -> "GHC errors:\n" ++ concatMap errMsg ghcErrors
+  NotAllowed msg        -> "Not allowed: " ++ msg
+  GhcException msg      -> "GHC exceptions: " ++ msg
+
+printErrorCode :: Int -> String -> IO ()
+printErrorCode code string = do
+  name <- getProgName
+  hPutStrLn stderr $ name ++ ": " ++ string
+  exitWith (ExitFailure code)
+
+printError :: String -> IO ()
+printError = printErrorCode 1
diff --git a/eddie.html b/eddie.html
--- a/eddie.html
+++ b/eddie.html
@@ -12,49 +12,78 @@
 <h1 class="title">eddie(1)</h1>
 </div>
 <h1 id="name">NAME</h1>
-<p>eddie - run haskell filters from the command line</p>
+<p>eddie - run Haskell filters from the command line</p>
 <h1 id="synopsys">SYNOPSYS</h1>
-<p><strong>eddie</strong> [ <em>options</em> ] [ <em>expr</em> ] <em>file</em> ...</p>
+<p><strong>eddie</strong> [ <em>options</em> ] [ <em>EXPRESSION</em> ] <em>FILE</em> ...</p>
 <h1 id="description">DESCRIPTION</h1>
-<p><strong>eddie</strong> evalutes the provided <em>expression</em> on either the contents of <em>the file</em> arguments concatenated together, or standard input if no *file arguments are present.</p>
-<p>The <strong>--line</strong>, <strong>--file</strong> and <strong>--list</strong> options can be used to cause <em>expression</em> to be used to process each line, each file, or a list of files or lines respectively.</p>
-<p>The prelude, <code>Data.List</code> and <code>Data.Char</code> modules are available for building expressions. Other modules may be added with the <strong>--Modules</strong> and <strong>--modules</strong> options.</p>
+<p><strong>eddie</strong> evalutes the provided <em>EXPRESSION</em> on either the contents of the <em>FILE</em> arguments concatenated together, or standard input if no <em>FILE</em> arguments are present.</p>
+<p>The <code>--lines</code>, <code>--files</code> and <code>--names</code> options can be used to cause <em>expression</em> to be used to process each line, each file, or tuple of <code>(name, content)</code> for each file, respectively. The <code>--lists</code> option can be used with <code>--lines</code>, <code>--files</code> and <code>--names</code> to cause the <em>files</em> to be processed as a list instead of one element at a time.</p>
+<p>The <code>ClassyPrelude</code> module is used instead of the default <code>Prelude</code> when building expressions. The default type for input and output is <code>Text</code>, but input or both can be changed to <code>ByteString</code> with the <code>--binary</code> and <code>--text</code> options.</p>
+<p>Other modules may be added with the <code>--Module</code> and <code>--module</code> options.</p>
 <h1 id="options">OPTIONS</h1>
 <dl>
-<dt><strong>--expr</strong></dt>
-<dd><p>The <strong>--expr</strong> <em>expr</em> (short form <strong>-e</strong> <em>expr</em> ) option concatenates it's value to the haskell expression being evaluated with a newline separator. Multiple occurrences can be used to build up a multi-line expression.</p>
-<p>If no <strong>-e</strong> <em>expr</em> option is present, the first non-flag argument will be used for the haskell expression.</p>
+<dt><strong>--expression</strong></dt>
+<dd><p>The <strong>--expression</strong> <em>EXPRESSION</em> (short form <strong>-e</strong> <em>EXPRESSION</em> ) option concatenates it's value to the Haskell expression being evaluated with a newline separator. Multiple occurrences can be used to build up a multi-line expression.</p>
+<p>If no <strong>-e</strong> <em>EXPRESSION</em> option is present, the first non-flag argument will be used for the Haskell expression.</p>
 </dd>
-<dt><strong>--line</strong></dt>
-<dd><p>The <strong>--line</strong> (short form <strong>-l</strong>) option causes <strong>eddie</strong> to process input line at a time. The <em>expr</em> will be run on each line and the results concatenated together (using unlines).</p>
+<dt><strong>--lines</strong></dt>
+<dd><p>The <strong>--lines</strong> (short form <strong>-l</strong>) option causes <strong>eddie</strong> to process the input one line at a time. The <em>EXPRESSION</em> will be run on each line and the results concatenated together (using unlines).</p>
 <p>The command</p>
-<pre><code>eddie -l *expr file* ...</code></pre>
+<pre><code>eddie -l EXPRESSION file ...</code></pre>
 <p>is equivalent to the command</p>
-<pre><code>eddie &quot;unlines . map *expr*  . lines&quot; *file* ...</code></pre>
+<pre><code>eddie &quot;unlines . map EXPRESSION  . lines&quot; file ...</code></pre>
+<p>Note that the <strong>--lines</strong>, <strong>--files</strong> and <strong>--names</strong> options cannot be used together.</p>
 </dd>
-<dt><strong>--file</strong></dt>
-<dd><p>The <strong>--file</strong> (short form <strong>-f</strong>) causes each file to be processed individually.</p>
-<p>Note that the <strong>-l</strong> and <strong>-f</strong> options cannot be used together.</p>
+<dt><strong>--files</strong></dt>
+<dd><p>The <strong>--files</strong> (short form <strong>-f</strong>) causes each file to be processed individually.</p>
+<p>Note that the <strong>--lines</strong>, <strong>--files</strong> and <strong>--names</strong> options cannot be used together.</p>
 </dd>
+<dt><strong>--names</strong></dt>
+<dd><p>The <strong>--names</strong> (short form <strong>-n</strong>) causes each file to be processed individually, as a tuple of <code>(name, content)</code>.</p>
+<p>Note that the <strong>--lines</strong>, <strong>--files</strong> and <strong>--names</strong> options cannot be used together.</p>
+</dd>
 <dt><strong>--list</strong></dt>
-<dd><p>The <strong>--list</strong> (short form <strong>-L</strong>) option causes <strong>eddie</strong> to pass the expression a list of lines or files. This requires one of the <strong>-l</strong> or <strong>-f</strong> options be used.</p>
+<dd><p>The <strong>--list</strong> (short form <strong>-L</strong>) option causes <strong>eddie</strong> to pass the expression a list of lines or files. This requires one of the <strong>--list</strong>, <strong>--files</strong> or <strong>--names</strong> options be used.</p>
 <p>The command</p>
-<pre><code>eddie -lL *expr file* ...</code></pre>
+<pre><code>eddie -l -L EXPRESSION file ...</code></pre>
 <p>is equivalent to the command</p>
-<pre><code>eddie &quot;unlines . *expr* . lines&quot; filei ...</code></pre>
+<pre><code>eddie &quot;EXPRESSION . lines&quot; file ...</code></pre>
 </dd>
 <dt><strong>--binary</strong></dt>
-<dd>The <strong>--binary</strong> (short form <strong>-b</strong>) option switches the output mode to binary. It also disables the maybe newline processing. Normally <strong>eddie</strong> will output a final newline if the last character of the input is not a newline to place the prompt properly. If the <strong>-b</strong> option is used, the final newline will not be output.
+<dd>The <strong>--binary</strong> (short form <strong>-b</strong>) option changes the data from <code>Text</code> to <code>ByteString</code>. This disable all processing of the input and output.
 </dd>
-<dt><strong>--modules</strong></dt>
-<dd>The <strong>--modules</strong> <em>name</em> (short form <strong>-m</strong> <em>name</em>) option is used to import module <em>name</em> into haskell before evaluating the expression.
+<dt><strong>--lazy</strong></dt>
+<dd><p>The <strong>--lazy</strong> (no short form) option switches the data types to their <em>lazy</em> versions.</p>
+<p>Note that using this is <strong>NOT</strong> recommended unless you know what you are doing. It seems to break type checking, cause hangs, or incorrect results when used. Even if everything works as expected, using it improperly can drastically increase memory usage and run time.</p>
 </dd>
-<dt><strong>--Modules</strong></dt>
-<dd>The <strong>--Modules</strong> <em>name</em>,<em>as</em> (short form <strong>-M</strong> <em>name</em>,<em>as</em>) option imports the <em>name</em> module using a qualified import with an as clause, with <em>as</em> being the value for the as clause.
+<dt><strong>--text</strong></dt>
+<dd><p>The <strong>--text</strong> (short form <strong>-t</strong>) option switches the output type back to <code>Text</code> if the <strong>--binary</strong> or <strong>--lazy</strong> option was used.</p>
+<p>Using <strong>--text</strong> without <strong>--binary</strong> or <strong>--lazy</strong> is an error.</p>
 </dd>
+<dt><strong>--input-encoding</strong></dt>
+<dd><p>The <strong>--input-encoding</strong> <em>ENCODING</em> (no short form) option sets the encoding of the input file(s) to <em>ENCODING</em>.</p>
+<p>It is an error to use <strong>--input-encoding</strong> with <strong>--binary</strong>.</p>
+</dd>
+<dt><strong>--output-encoding</strong></dt>
+<dd><p>The <strong>--output-encoding</strong> <em>ENCODING</em> (no short form) option sets the encoding of the output file to <em>ENCODING</em>.</p>
+<p>It is an error to use <strong>--output-encoding</strong> with <strong>--binary</strong> unless <strong>--text</strong> is also specified.</p>
+</dd>
+<dt><strong>--encoding</strong></dt>
+<dd><p>The <strong>--encoding</strong> <em>ENCODING</em> (no short form) option sets the encoding of all text files to <em>ENCODING</em>, whether for input or output.</p>
+<p>It is an error to use <strong>--encoding</strong> with <strong>--binary</strong> unless <strong>--text</strong> is also specified.</p>
+</dd>
+<dt><strong>--module</strong></dt>
+<dd>The <strong>--module</strong> <em>NAME</em> (short form <strong>-m</strong> <em>NAME</em>) option is used to import module <em>NAME</em> into Haskell before evaluating the expression.
+</dd>
+<dt><strong>--Module</strong></dt>
+<dd>The <strong>--Module</strong> <em>NAME</em>,<em>AS</em> (short form <strong>-M</strong> <em>NAME</em>,<em>AS</em>) option imports the <em>NAME</em> module using a qualified import with an as clause, with <em>AS</em> being the value for the as clause.
+</dd>
+<dt><strong>--extension</strong></dt>
+<dd>The <strong>--extension</strong> <em>EXTENSION</em> (short form <strong>-X</strong> <em>EXTENSION</em>) option is used to enable the named GHC extension when evaluating the expression.
+</dd>
 </dl>
 <h1 id="diagnostics">DIAGNOSTICS</h1>
-<p>If the command runs with no problems, eddie will exit with a status of 0. If there are problems with the options, such that the expression is never evaluated, then eddie will exit with a status of 1. If haskell returns an error - probably a compilation problem - then eddie will exit with the status of 2.</p>
+<p>If the command runs with no problems, eddie will exit with a status of 0. If there are problems with the options, such that the expression is never evaluated, then eddie will exit with a status of 1. If Haskell returns an error - probably a compilation problem - then eddie will exit with the status of 2.</p>
 <h1 id="see-also">SEE ALSO</h1>
 <p>The wiki at <a href="https://chiselapp.com/user/mwm/repository/eddie/wcontent" class="uri">https://chiselapp.com/user/mwm/repository/eddie/wcontent</a> for examples.</p>
 <h1 id="bugs">BUGS</h1>
diff --git a/eddie.md b/eddie.md
--- a/eddie.md
+++ b/eddie.md
@@ -1,119 +1,168 @@
 % eddie(1)
 
-NAME
-====
+# NAME
 
-eddie \- run haskell filters from the command line
+eddie \- run Haskell filters from the command line
 
-SYNOPSYS
-========
+# SYNOPSYS
 
 
-**eddie** [ *options* ] [ *expr* ] *file* ...
+**eddie** [ *options* ] [ *EXPRESSION* ] *FILE* ...
 
-DESCRIPTION
-===========
+# DESCRIPTION
 
 
-**eddie** evalutes the provided *expression* on either the contents of
-*the file* arguments concatenated together, or standard input if no
-*file arguments are present.
+**eddie** evalutes the provided *EXPRESSION* on either the contents of
+the *FILE* arguments concatenated together, or standard input if no
+*FILE* arguments are present.
 
-The **--line**, **--file** and **--list** options can be used to cause
-*expression* to be used to process each line, each file, or a list of
-files or lines respectively.
+The `--lines`, `--files` and `--names` options can be used to cause
+*expression* to be used to process each line, each file, or tuple of
+`(name, content)` for each file, respectively. The `--lists` option
+can be used with `--lines`, `--files` and `--names` to cause the
+*files* to be processed as a list instead of one element at a time.
 
-The prelude, `Data.List` and `Data.Char` modules are available for building
-expressions. Other modules may be added with the **--Modules** and
-**--modules** options.
+The `ClassyPrelude` module is used instead of the default `Prelude`
+when building expressions. The default type for input and output is
+`Text`, but input or both can be changed to `ByteString` with the
+`--binary` and `--text` options.
 
-OPTIONS
-=======
+Other modules may be added with the `--Module` and `--module`
+options.
 
-**--expr**
-:   The **--expr** *expr* (short form **-e** *expr* ) option
-    concatenates it's value to the haskell expression being evaluated
+# OPTIONS
+
+**--expression**
+:   The **--expression** *EXPRESSION* (short form **-e** *EXPRESSION* ) option
+    concatenates it's value to the Haskell expression being evaluated
     with a newline separator.  Multiple occurrences can be used to
     build up a multi-line expression.
 
-    If no **-e** *expr* option is present, the first non-flag argument
-    will be used for the haskell expression.
+    If no **-e** *EXPRESSION* option is present, the first non-flag argument
+    will be used for the Haskell expression.
 
-**--line**
-:   The **--line** (short form **-l**) option causes **eddie** to
-    process input line at a time. The *expr* will be run on each line
-    and the results concatenated together (using unlines).
+**--lines**
+:   The **--lines** (short form **-l**) option causes **eddie** to
+    process the input one line at a time. The *EXPRESSION* will be run
+    on each line and the results concatenated together (using
+    unlines).
 
     The command
     ```
-    eddie -l *expr file* ...
+    eddie -l EXPRESSION file ...
     ```
     is equivalent to the command
 	```
-    eddie "unlines . map *expr*  . lines" *file* ...
+    eddie "unlines . map EXPRESSION  . lines" file ...
     ```
 
-**--file**
-:   The **--file** (short form **-f**) causes each file to be processed
+    Note that the **--lines**, **--files** and **--names** options
+    cannot be used together.
+
+**--files**
+:   The **--files** (short form **-f**) causes each file to be processed
     individually.
 
-    Note that the **-l** and **-f** options cannot be used together.
+    Note that the **--lines**, **--files** and **--names** options
+    cannot be used together.
 
+**--names**
+:   The **--names** (short form **-n**) causes each file to
+    be processed individually, as a tuple of `(name, content)`.
+
+    Note that the **--lines**, **--files** and **--names** options
+    cannot be used together.
+
 **--list**
 :   The **--list** (short form **-L**) option causes **eddie** to pass
     the expression a list of lines or files.  This requires one of the
-	**-l** or **-f** options be used.
+	**--list**, **--files** or **--names** options be used.
 
     The command
     
     ```
-    eddie -lL *expr file* ...
+    eddie -l -L EXPRESSION file ...
     ```
     is equivalent to the command
     
     ```
-    eddie "unlines . *expr* . lines" filei ...
+    eddie "EXPRESSION . lines" file ...
     ```
 
 **--binary**
-:   The **--binary** (short form **-b**) option switches the output mode
-    to binary.  It also disables the maybe newline processing.
-    Normally **eddie** will output a final newline if the last
-    character of the input is not a newline to place the prompt
-    properly.  If the **-b** option is used, the final newline will
-    not be output.
+:   The **--binary** (short form **-b**) option changes the data from
+    `Text` to `ByteString`. This disable all processing of the input
+    and output.
 
-**--modules**
-:   The **--modules** *name* (short form **-m** *name*) option is used
-    to import module *name* into haskell before evaluating the
+**--lazy**
+:   The **--lazy** (no short form) option switches the data types
+    to their *lazy* versions.
+    
+    Note that using this is **NOT** recommended unless you know what you
+    are doing. It seems to break type checking, cause hangs, or
+    incorrect results when used. Even if everything works as expected,
+    using it improperly can drastically increase memory usage and run
+    time.
+
+**--text**
+:   The **--text** (short form **-t**) option switches the output type
+    back to `Text` if the **--binary** or **--lazy** option was used.
+
+    Using **--text** without **--binary** or **--lazy** is an error.
+
+**--input-encoding**
+:   The **--input-encoding** *ENCODING* (no short form) option sets
+    the encoding of the input file(s) to *ENCODING*.
+    
+    It is an error to use **--input-encoding** with **--binary**.
+
+**--output-encoding**
+:   The **--output-encoding** *ENCODING* (no short form) option sets
+    the encoding of the output file to *ENCODING*.
+    
+    It is an error to use **--output-encoding** with **--binary**
+    unless **--text** is also specified.
+
+**--encoding**
+:   The **--encoding** *ENCODING* (no short form) option sets the
+    encoding of all text files to *ENCODING*, whether for input or
+    output.
+
+    It is an error to use **--encoding** with **--binary**
+    unless **--text** is also specified.
+
+**--module**
+:   The **--module** *NAME* (short form **-m** *NAME*) option is used
+    to import module *NAME* into Haskell before evaluating the
     expression.
 
-**--Modules**
-:   The **--Modules** *name*,*as* (short form **-M** *name*,*as*) option
-    imports the *name* module using a qualified import with an as
-    clause, with *as* being the value for the as clause.
+**--Module**
+:   The **--Module** *NAME*,*AS* (short form **-M** *NAME*,*AS*) option
+    imports the *NAME* module using a qualified import with an as
+    clause, with *AS* being the value for the as clause.
 
-DIAGNOSTICS
-===========
+**--extension**
+:   The **--extension** *EXTENSION* (short form **-X** *EXTENSION*)
+    option is used to enable the named GHC extension when evaluating
+    the expression.
 
+# DIAGNOSTICS
+
 If the command runs with no problems, eddie will exit with a status of 0.
 If there are problems with the options, such that the expression is never
 evaluated, then eddie will exit with a status of 1.
-If haskell returns an error - probably a compilation problem - then
+If Haskell returns an error - probably a compilation problem - then
 eddie will exit with the status of 2.
 
-SEE ALSO
-========
+# SEE ALSO
 
 The wiki at <https://chiselapp.com/user/mwm/repository/eddie/wcontent>
 for examples.
 
-BUGS
-====
+# BUGS
 
 See the issues list at <https://chiselapp.com/user/mwm/repository/eddie/rptview?rn=1>.
 
-AUTHOR
-======
+# AUTHOR
 
 Mike Meyer <mwm@mired.org>
diff --git a/tests/counters.test b/tests/counters.test
--- a/tests/counters.test
+++ b/tests/counters.test
@@ -1,11 +1,11 @@
-eddie show.length
+eddie tshow.length
 <<<
 asdf
 >>>
 5
 >>>= 0
 
-eddie show.length.lines
+eddie tshow.length.lines
 <<<
 1
 2
@@ -15,7 +15,7 @@
 4
 >>>= 0
 
-eddie show.length.words
+eddie tshow.length.words
 <<<
 now is the time for all good programmers to come to haskell
 >>>
diff --git a/tests/encoding.test b/tests/encoding.test
new file mode 100644
Binary files /dev/null and b/tests/encoding.test differ
diff --git a/tests/error.test b/tests/error.test
--- a/tests/error.test
+++ b/tests/error.test
@@ -2,6 +2,6 @@
 >>>2 /GHC errors:/
 >>>= 2
 
-eddie show.length ./-
+eddie tshow.length ./-
 >>>2 /does not exist/
 >>>= 1
diff --git a/tests/expr.test b/tests/expr.test
--- a/tests/expr.test
+++ b/tests/expr.test
@@ -1,4 +1,4 @@
-eddie -e show.length.words
+eddie -e tshow.length.words
 <<<
 now is the time for all good programmers to come to haskell
 >>>
diff --git a/tests/extension.test b/tests/extension.test
new file mode 100644
--- /dev/null
+++ b/tests/extension.test
@@ -0,0 +1,17 @@
+eddie tshow.(,1.0).length
+<<<
+>>>
+>>>= 2
+
+eddie --extension TupleSections  'tshow.(,1.0).length'
+<<<
+aaaa
+>>>
+(5,1.0)
+>>>= 0
+
+eddie --extension Tuplesections  'tshow.(,1.0).length'
+<<<
+aaaa
+>>>2 /Tuplesections/
+>>>= 2
diff --git a/tests/files.test b/tests/files.test
--- a/tests/files.test
+++ b/tests/files.test
@@ -1,9 +1,9 @@
-eddie -fL "(:[]).show.length" tests/test.data tests/test.data
+eddie -f -L "tshow.length" tests/test.data tests/test.data
 >>>
 2
 >>>= 0
 
-eddie -f "show.length" tests/test.data tests/test.data
+eddie -f "tshow.length" tests/test.data tests/test.data
 >>>
 6161
 >>>= 0
diff --git a/tests/imports.test b/tests/imports.test
--- a/tests/imports.test
+++ b/tests/imports.test
@@ -15,3 +15,8 @@
 >>>
 aaaa
 >>>= 0
+
+eddie -m noSuchModule id
+<<<
+>>>2 /noSuchModule/
+>>>= 2
diff --git a/tests/lines.test b/tests/lines.test
--- a/tests/lines.test
+++ b/tests/lines.test
@@ -11,7 +11,7 @@
 emit
 >>>= 0
 
-eddie -lL "take 4"
+eddie -l -L "unlines . take 4"
 <<<
 now
 is
diff --git a/tests/names.test b/tests/names.test
new file mode 100644
--- /dev/null
+++ b/tests/names.test
@@ -0,0 +1,9 @@
+eddie --names --list "tshow . length" tests/test.data tests/test.data
+>>>
+2
+>>>= 0
+
+eddie --binary --text --names "tshow . second length" tests/test-utf16.data
+>>>
+("tests/test-utf16.data",122)
+>>>= 0
diff --git a/tests/test-utf16.data b/tests/test-utf16.data
new file mode 100644
Binary files /dev/null and b/tests/test-utf16.data differ
diff --git a/tests/usage.test b/tests/usage.test
--- a/tests/usage.test
+++ b/tests/usage.test
@@ -1,11 +1,48 @@
+eddie --text id
+>>>2 /Usage: --text requires --binary or --lazy/
+>>>= 1
+
+eddie --lines --files id
+>>>2 /Usage: --lines is incompatible with --files/
+>>>= 1
+
+eddie --lines --names id
+>>>2 /Usage: --lines is incompatible with --names/
+>>>= 1
+
+eddie --names --files id
+>>>2 /Usage: --files is incompatible with --names/
+>>>= 1
+
+eddie --files id
+>>>2 /Usage: --files requires at least one file/
+>>>= 1
+
+eddie --names id
+>>>2 /Usage: --names requires at least one file/
+>>>= 1
+
+eddie --list id
+>>>2 /Usage: --list requires one of --lines, --files or --names/
+>>>= 1
+
 eddie
->>>2 /usage:/
+>>>2 /Usage: Must provide an expression/
 >>>= 1
 
-eddie -lf reverse
->>>2 /usage:/
+eddie --encoding utf8 --input-encoding utf8 id
+>>>2 /Usage: --encoding is incompatible with --input-encoding and --output-encoding/
 >>>= 1
 
-eddie -L reverse
->>>2 /usage:/
+eddie --encoding utf8 --output-encoding utf8 id
+>>>2 /Usage: --encoding is incompatible with --input-encoding and --output-encoding/
 >>>= 1
+
+eddie --binary --input-encoding utf8 id
+>>>2 /Usage: --input-encoding is incompatible with --binary/
+>>>= 1
+
+eddie --binary --output-encoding utf8 id
+>>>2 /Usage: can only use --output-encoding for text output/
+>>>= 1
+
