diff --git a/shelltest.hs b/shelltest.hs
--- a/shelltest.hs
+++ b/shelltest.hs
@@ -1,5 +1,5 @@
 #!/usr/bin/env runhaskell
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable, TemplateHaskell #-}
 {- |
 
 shelltest - a tool for testing command-line programs.
@@ -41,13 +41,14 @@
 import qualified System.FilePath.FindCompat as Find (extension)
 import Control.Applicative ((<$>))
 import Data.Algorithm.Diff
+import Distribution.PackageDescription.TH (packageVariable, package, pkgVersion)
 
 strace :: Show a => a -> a
 strace a = trace (show a) a
 
-version, progname, progversion :: String
-version = "1.1" -- keep synced with shelltestrunner.cabal and README
+progname, version, progversion :: String
 progname = "shelltest"
+version = $(packageVariable (pkgVersion . package))
 progversion = progname ++ " " ++ version
 proghelpsuffix :: [String]
 proghelpsuffix = [
@@ -77,6 +78,7 @@
      all_        :: Bool
     ,color       :: Bool
     ,diff        :: Bool
+    ,precise     :: Bool
     ,exclude     :: [String]
     ,execdir     :: Bool
     ,extension   :: String
@@ -88,16 +90,17 @@
     } deriving (Show, Data, Typeable)
 
 argdefs = Args {
-     all_        = def     &= name "a" &= help "Show all output on failures, even if large"
+     all_        = def     &= help "Show all failure output, even if large"
     ,color       = def     &= help "Show colored output if your terminal supports it"
-    ,diff        = def     &= name "d" &= help "Show expected vs. actual in diff format (implies -a)"
+    ,diff        = def     &= name "d" &= help "Show failures in diff format"
+    ,precise     = def     &= help "Show failure output precisely (good for whitespace)"
     ,exclude     = def     &= name "x" &= typ "STR" &= help "Exclude test files whose path contains STR"
     ,execdir     = def     &= help "Run tests from within the test file's directory"
     ,extension   = ".test" &= typ "EXT" &= help "Filename suffix of test files (default: .test)"
     ,with        = def     &= typ "EXECUTABLE" &= help "Replace the first word of (unindented) test commands"
     ,debug       = def     &= help "Show debug info, for troubleshooting"
     ,debug_parse = def     &= help "Show test file parsing info and stop"
-    ,help_format = def     &= help "Display test format help"
+    ,help_format = def     &= explicit &= name "help-format" &= help "Display test format help"
     ,testpaths   = def     &= args &= typ "TESTFILES|TESTDIRS"
     }
     &= program progname
@@ -348,38 +351,46 @@
 matches s (Lines _ p)         = s == p
 
 showExpectedActual :: Args -> String -> Matcher -> String -> String
-showExpectedActual Args{diff=True} _ (Lines ln e) a =
-    printf "--- Expected\n+++ Got\n" ++ showDiff (1,ln) (getDiff (lines a) (lines e))
-showExpectedActual args field e a =
-    printf "Expected %s: %s\nGot %s:      %s" field (show' e) field (show $ trim' a)
+showExpectedActual args@Args{diff=True} _ (Lines ln e) a =
+    printf "--- Expected\n+++ Got\n" ++ showDiff args(1,ln) (getDiff (lines a) (lines e))
+showExpectedActual Args{all_=all_,precise=precise} field e a =
+    printf "Expected %s: %s\nGot %s:      %s" field (show' $ showm e) field (show' $ trim' a)
     where
-      trim' = if all_ args then id else trim
-      show' = if all_ args then showMatcherAll else showMatcherTrimmed
+      show' = if precise then show else ("\n"++)
+      showm = if all_ then showMatcher else showMatcherTrimmed
+      trim' = if all_ then id else trim
 
-showDiff :: (Int,Int) -> [(DI, String)] -> String
-showDiff _ []             = ""
-showDiff (l,r) ((F, ln) : ds) =
-  printf "+%4d " l ++ ln ++ "\n" ++ showDiff (l+1,r) ds
-showDiff (l,r) ((S, ln) : ds) =
-  printf "-%4d " r ++ ln ++ "\n" ++ showDiff (l,r+1) ds
-showDiff (l,r) ((B, _ ) : ds) =
-  showDiff (l+1,r+1) ds
+showDiff :: Args -> (Int,Int) -> [(DI, String)] -> String
+showDiff _ _ []                   = ""
+showDiff args@Args{all_=all_,precise=precise} (l,r) ((F, ln) : ds) =
+    printf "+%4d " l ++ ln' ++ "\n" ++ showDiff args (l+1,r) ds
+    where
+      ln' = trim' $ show' ln
+      trim' = if all_ then id else trim
+      show' = if precise then show else id
+showDiff args@Args{all_=all_,precise=precise} (l,r) ((S, ln) : ds) =
+    printf "-%4d " r ++ ln' ++ "\n" ++ showDiff args (l,r+1) ds
+    where
+      ln' = trim' $ show' ln
+      trim' = if all_ then id else trim
+      show' = if precise then show else id
+showDiff args (l,r) ((B, _ ) : ds) = showDiff args (l+1,r+1) ds
 
 instance Show Matcher where show = showMatcherTrimmed
 
 showMatcherTrimmed :: Matcher -> String
 showMatcherTrimmed (PositiveRegex r)   = "/"++(trim r)++"/"
 showMatcherTrimmed (NegativeRegex r)   = "!/"++(trim r)++"/"
-showMatcherTrimmed (Numeric s)         = show $ trim s
-showMatcherTrimmed (NegativeNumeric s) = "!"++ show (trim s)
-showMatcherTrimmed (Lines _ s)         = show $ trim s
+showMatcherTrimmed (Numeric s)         = trim s
+showMatcherTrimmed (NegativeNumeric s) = "!"++ trim s
+showMatcherTrimmed (Lines _ s)         = trim s
 
-showMatcherAll :: Matcher -> String
-showMatcherAll (PositiveRegex r)   = "/"++r++"/"
-showMatcherAll (NegativeRegex r)   = "!/"++r++"/"
-showMatcherAll (Numeric s)         = show s
-showMatcherAll (NegativeNumeric s) = "!"++ show s
-showMatcherAll (Lines _ s)         = show s
+showMatcher :: Matcher -> String
+showMatcher (PositiveRegex r)   = "/"++r++"/"
+showMatcher (NegativeRegex r)   = "!/"++r++"/"
+showMatcher (Numeric s)         = s
+showMatcher (NegativeNumeric s) = "!"++ s
+showMatcher (Lines _ s)         = s
 
 instance Show ShellTest where
     show ShellTest{testname=n,command=c,stdin=i,stdoutExpected=o,stderrExpected=e,exitCodeExpected=x} =
diff --git a/shelltestrunner.cabal b/shelltestrunner.cabal
--- a/shelltestrunner.cabal
+++ b/shelltestrunner.cabal
@@ -1,11 +1,11 @@
 name:           shelltestrunner
--- keep synced with shelltest.hs and README:
-version:        1.1
+-- sync with README.md, ANNOUNCE:
+version:        1.2
 category:       Testing
 synopsis:       A tool for testing command-line programs.
 description:
- shelltestrunner is a handy cross-platform tool for testing command-line
- programs or arbitrary shell commands.  It reads simple declarative tests
+ shelltestrunner is a cross-platform tool for testing command-line
+ programs (or arbitrary shell commands.)  It reads simple declarative tests
  specifying a command, some input, and the expected output, error output
  and exit status.  Tests can be run selectively, in parallel, with a
  timeout, in color, and/or with differences highlighted.
@@ -13,10 +13,10 @@
 license-file:   LICENSE
 author:         Simon Michael <simon@joyful.com>
 maintainer:     Simon Michael <simon@joyful.com>
-homepage:       http://joyful.com/repos/shelltestrunner
+homepage:       http://joyful.com/shelltestrunner
 bug-reports:    mailto:simon@joyful.com
-stability:      beta
-tested-with:    GHC==6.12.3, GHC==7.0.2, GHC==7.2.1
+stability:      stable
+tested-with:    GHC==6.12.3, GHC==7.0.2, GHC==7.2.1, GHC==7.4.1
 cabal-version:  >= 1.6
 build-type:     Simple
 
@@ -28,15 +28,16 @@
   ghc-options:    -threaded -W -fwarn-tabs
   build-depends:
                  base                 >= 4     && < 5
+                ,cabal-file-th
                 ,FileManipCompat      >= 0.18  && < 0.19
                 ,HUnit                            < 1.3
-                ,cmdargs              >= 0.7   && < 0.8
+                ,cmdargs              >= 0.7   && < 0.10
                 ,directory            >= 1.0
                 ,filepath             >= 1.0
                 ,parsec                           < 3.2
                 ,regex-tdfa           >= 1.1   && < 1.2
                 ,process                          < 1.2
-                ,test-framework       >= 0.3.2 && < 0.5
+                ,test-framework       >= 0.3.2 && < 0.6
                 ,test-framework-hunit >= 0.2   && < 0.3
                 ,utf8-string          >= 0.3.5 && < 0.4
                 ,Diff                 >= 0.1   && < 0.2
