diff --git a/uhexdump.cabal b/uhexdump.cabal
--- a/uhexdump.cabal
+++ b/uhexdump.cabal
@@ -1,23 +1,23 @@
 name:                uhexdump
-version:             0.2.3
+version:             0.3
 synopsis:            hex dumper for UTF-8 text
 description:         hex dumper for UTF-8 text
 category:            Text
 license:             BSD3
 license-file:        LICENSE
 author:              Eric Kow
-maintainer:          <E.Y.Kow@brighton.ac.uk>
+maintainer:          <eric.kow@gmail.com>
 build-type:          Simple
 cabal-version:       >= 1.6
 
 source-repository head
   type:     darcs
-  location: http://patch-tag.com/r/kowey/uhexdump
+  location: http://darcsden.com/kowey/uhexdump
 
 executable           uhexdump
-  build-Depends:       base         < 4.1,
-                       bytestring  == 0.9.*,
-                       utf8-string == 0.3.*
+  build-Depends:       base         < 5
+                     , bytestring  == 0.9.*
+                     , split       == 0.1.*
   main-is:             uhexdump.hs
   ghc-options:         -Wall
   other-modules:       UTF8
diff --git a/uhexdump.hs b/uhexdump.hs
--- a/uhexdump.hs
+++ b/uhexdump.hs
@@ -12,14 +12,13 @@
 import Data.Bits
 import qualified Data.ByteString as B
 import Data.Char (isPrint)
-import Data.List (intersperse, inits)
+import Data.List (intersperse, intercalate, inits)
+import Data.List.Split (split, keepDelimsR, whenElt)
 import Data.Word (Word8)
 import System.Environment (getArgs)
-import System.IO (stdin, hClose, IOMode(ReadMode))
+import System.IO (stdin, hClose, IOMode(ReadMode), openBinaryFile)
 import qualified Numeric as N
-import Prelude hiding (putStrLn, putStr)
 
-import System.IO.UTF8
 import UTF8 (decodeOne, Error(..))
 
 main :: IO ()
@@ -30,25 +29,32 @@
            _  -> mapM (\f -> openBinaryFile f ReadMode) args
     forM_ hs $ \h ->
      do bs <- B.unpack `fmap` B.hGetContents h
-        putStr $ unlines $
-          map (dump h_size) $ clump c_size $ decode bs
+        putStr . unlines
+               $ map (dump h_size)
+               $ concatMap (clump h_size)
+               $ split (keepDelimsR (whenElt isNewline))
+               $ decode bs
         hClose h
  where
-  h_size = 55
-  c_size = 16
+  clump sz = clumpBy (length . showHex . decoratedBytes) sz 1
+  h_size = 40 -- keep in mind that each byte takes 2 chars a
+              -- space; and that each code point takes at
+              -- most 4 bytes.  So we need (3 * 4 * n) just
+              -- to display the hex part of the window
 
+isNewline :: HexChar -> Bool
+isNewline (HexChar c _) = c == '\n'
+isNewline _ = False
+
 dump :: Int -> [HexChar] -> String
-dump hex_sz hs =
-  hex_part ++ padding ++ char_part
+dump hex_sz cs =
+   hexPart ++ padding ++ charPart
  where
-  hex_part  = (foldr (.) id $
-                intersperse (showChar ' ') $
-                map showHex hs) ""
-  char_part  = concat $ map show hs
-  padding    = replicate (hex_sz - length hex_part) ' '
+   hexPart  = intercalate " " (map showHex dbs)
+   dbs      = map decoratedBytes cs
+   charPart = concatMap show cs
+   padding  = replicate (hex_sz - length hexPart) ' '
 
-clump :: Show a => Int -> [a] -> [[a]]
-clump n = clumpBy (length.show) n 1
 
 -- | break a list of items into sublists of length < the clump
 --   size, taking into consideration that each item in the clump
@@ -67,30 +73,47 @@
    case break toobig (drop 1 $ inits cs) of
         ([],_)    -> next 1           -- first too big
         (_,[])    -> iter (cs:acc) [] -- none too big
-        (_,(x:_)) -> next (length x)
+        (_,(x:_)) -> next (length x - 1)
    where next n = iter (take n cs : acc) (drop n cs)
   toobig x = (sum . intersperse sep . map f) x > l
 
+-- ----------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------
+
+data ByteSequence = ByteSequence [Word8] Char -- bytes and sep
+
+decoratedBytes :: HexChar -> ByteSequence
+decoratedBytes c = ByteSequence bytes seps
+  where
+   bytes = getBytes c
+   seps  = case c of
+     HexChar  _ _ -> '-'
+     HexError _ _ -> '#'
+
 -- -------------------------------------------------------------------
 --
 -- -------------------------------------------------------------------
 
 class ShowHex a where
- showHex :: a -> String -> String
+ showHex :: a -> String
 
 instance ShowHex Int where
- showHex = N.showHex
+ showHex x = N.showHex x ""
 
 instance ShowHex Word8 where
- showHex w = showHex big . showHex small
+ showHex w = showHex big ++ showHex small
   where
     small, big :: Int
     small = fromIntegral $ w .&. 0x0f
     big   = fromIntegral $ shiftR w 4
 
 instance ShowHex HexChar where
- showHex h = foldr (.) id $ map showHex $ getBytes h
+ showHex h = concatMap showHex (getBytes h)
 
+instance ShowHex ByteSequence where
+ showHex (ByteSequence bs s) = intercalate [s] (map showHex bs)
+
 -- -------------------------------------------------------------------
 --
 -- -------------------------------------------------------------------
@@ -105,7 +128,7 @@
  show (HexChar '\t' _) = noshow
  show (HexChar c _) | isPrint c  = [c]
  show (HexChar _ _) = noshow
- show h@(HexError _ _) = showString "{{" $ (showHex h) "}}"
+ show (HexError _ _) = noshow
 
 noshow :: String
 noshow = "."
