docFromRange :: ColorScheme -> Range -> Doc
docFromRange colors range
  = case map (limitLineLen 55) (limitLines 3 (lines (sourceFromRange range))) of
      []  -> empty
      src -> color (colorSource colors) (align (vcat (map text src)))
  where
    limitLineLen n line
      = if (length line <= n)
         then line
         else let n2    = div n 2
                  (x,y) = splitAt n2 line
                  pre   = reverse (dropWhile (not . isSpace) (reverse x))
                  post  = dropWhile (not . isSpace) (reverse (take (n2-5) (reverse y)))
              in pre ++ " ... " ++ post

    limitLines n ls
      = if (length ls <= n)
         then removeIndent ls
        else if (n <= 2)
         then failure "Message.docFromRange.limitLines: illegal n"
         else let n2   = div n 2
                  pre  = take n2 ls
                  post = reverse (take n2 (reverse ls))
                  prepost = removeIndent (pre ++ post)
              in take n2 prepost ++ ["..."] ++ drop n2 prepost
      where
        removeIndent ls
          = let i = minimum (map (length . takeWhile isSpace) ls)
            in map (drop i) ls
docFromRange :: ColorScheme -> Range -> Doc
docFromRange colors range
  = case map (limitLineLen 55) (limitLines 3 (lines (sourceFromRange range))) of
      []  -> empty
      src -> color (colorSource colors) (align (vcat (map text src)))
  where
    limitLineLen n line
      = if (length line <= n)
         then line
         else let n2    = div n 2
                  (x,y) = splitAt n2 line
                  pre   = reverse (dropWhile (not . isSpace) (reverse x))
                  post  = dropWhile (not . isSpace) (reverse (take (n2-5) (reverse y)))
              in pre ++ " ... " ++ post

    limitLines n ls
      = if (length ls <= n)
         then removeIndent ls
        else if (n <= 2)
         then failure "Message.docFromRange.limitLines: illegal n"
         else let n2   = div n 2
                  pre  = take n2 ls
                  post = reverse (take n2 (reverse ls))
                  prepost = removeIndent (pre ++ post)
              in take n2 prepost ++ ["..."] ++ drop n2 prepost
      where
        removeIndent ls
          = let i = minimum (map (length . takeWhile isSpace) ls)
            in map (drop i) ls
docFromRange colors range
  = case map (limitLineLen 55) (limitLines 3 (lines (sourceFromRange range))) of
      []  -> empty
      src -> color (colorSource colors) (align (vcat (map text src)))
  where
    limitLineLen n line
      = if (length line <= n)
         then line
         else let n2    = div n 2
                  (x,y) = splitAt n2 line
                  pre   = reverse (dropWhile (not . isSpace) (reverse x))
                  post  = dropWhile (not . isSpace) (reverse (take (n2-5) (reverse y)))
              in pre ++ " ... " ++ post

    limitLines n ls
      = if (length ls <= n)
         then removeIndent ls
        else if (n <= 2)
         then failure "Message.docFromRange.limitLines: illegal n"
         else let n2   = div n 2
                  pre  = take n2 ls
                  post = reverse (take n2 (reverse ls))
                  prepost = removeIndent (pre ++ post)
              in take n2 prepost ++ ["..."] ++ drop n2 prepost
      where
        removeIndent ls
          = let i = minimum (map (length . takeWhile isSpace) ls)
            in map (drop i) ls