1module Distribution.Pretty ( 2 Pretty (..), 3 prettyShow, 4 defaultStyle, 5 flatStyle, 6 -- * Utilities 7 showFilePath, 8 showToken, 9 showTokenStr, 10 showFreeText, 11 showFreeTextV3, 12 -- * Deprecated 13 Separator, 14 ) where 15 16import Distribution.CabalSpecVersion 17import Distribution.Compat.Prelude 18import Prelude () 19 20import qualified Text.PrettyPrint as PP 21 22class Pretty a where 23 pretty :: a -> PP.Doc 24 25 prettyVersioned :: CabalSpecVersion -> a -> PP.Doc 26 prettyVersioned _ = pretty 27 28-- | @since 3.4.0.0 29instance Pretty PP.Doc where 30 pretty = id 31 32instance Pretty Bool where 33 pretty = PP.text . show 34 35instance Pretty Int where 36 pretty = PP.text . show 37 38instance Pretty a => Pretty (Identity a) where 39 pretty = pretty . runIdentity 40 41prettyShow :: Pretty a => a -> String 42prettyShow = PP.renderStyle defaultStyle . pretty 43 44-- | The default rendering style used in Cabal for console 45-- output. It has a fixed page width and adds line breaks 46-- automatically. 47defaultStyle :: PP.Style 48defaultStyle = PP.Style { PP.mode = PP.PageMode 49 , PP.lineLength = 79 50 , PP.ribbonsPerLine = 1.0 51 } 52 53-- | A style for rendering all on one line. 54flatStyle :: PP.Style 55flatStyle = PP.Style { PP.mode = PP.LeftMode 56 , PP.lineLength = err "lineLength" 57 , PP.ribbonsPerLine = err "ribbonsPerLine" 58 } 59 where 60 err x = error ("flatStyle: tried to access " ++ x ++ " in LeftMode. " ++ 61 "This should never happen and indicates a bug in Cabal.") 62 63------------------------------------------------------------------------------- 64-- Utilities 65------------------------------------------------------------------------------- 66 67-- TODO: remove when ReadP parser is gone. 68type Separator = [PP.Doc] -> PP.Doc 69 70showFilePath :: FilePath -> PP.Doc 71showFilePath = showToken 72 73showToken :: String -> PP.Doc 74showToken = PP.text . showTokenStr 75 76showTokenStr :: String -> String 77showTokenStr str 78 -- if token looks like a comment (starts with --), print it in quotes 79 | "--" `isPrefixOf` str = show str 80 -- also if token ends with a colon (e.g. executable name), print it in quotes 81 | ":" `isSuffixOf` str = show str 82 | not (any dodgy str) && not (null str) = str 83 | otherwise = show str 84 where 85 dodgy c = isSpace c || c == ',' 86 87 88-- | Pretty-print free-format text, ensuring that it is vertically aligned, 89-- and with blank lines replaced by dots for correct re-parsing. 90showFreeText :: String -> PP.Doc 91showFreeText "" = mempty 92showFreeText s = PP.vcat [ PP.text (if null l then "." else l) | l <- lines_ s ] 93 94-- | Pretty-print free-format text. 95-- Since @cabal-version: 3.0@ we don't replace blank lines with dots. 96-- 97-- @since 3.0.0.0 98showFreeTextV3 :: String -> PP.Doc 99showFreeTextV3 "" = mempty 100showFreeTextV3 s = PP.vcat [ PP.text l | l <- lines_ s ] 101 102-- | 'lines_' breaks a string up into a list of strings at newline 103-- characters. The resulting strings do not contain newlines. 104lines_ :: String -> [String] 105lines_ [] = [""] 106lines_ s = 107 let (l, s') = break (== '\n') s 108 in l : case s' of 109 [] -> [] 110 (_:s'') -> lines_ s'' 111