Allow multi-line deprecation messages.
Sometimes one line just isn't enough. There's two related issues, pretty source code and pretty warning messages.
It is a bit annoying when a DEPRECATED
pragma stretches on past 80-100 columns or whatever. Does the ordinary multi-line Haskell string syntax work in this situation? Even if it does it's not useful in practice due to the cpp-incompatibility, and because it's a pragma, we cannot use the normal ++
trick.
The other is presenting multi-line error messages to the user. Sometimes we want to present more info, like not just what the alternative is but for example when the alternative was added and when the deprecated thing will be removed.
In Cabal for example we've got ugly hack:
{-# DEPRECATED defaultUserHooks
"Use simpleUserHooks or autoconfUserHooks, unless you need Cabal-1.2\n compatibility in which case you must stick with defaultUserHooks" #-}
Yes it's really that wide :-)
Reformatted:
{-# DEPRECATED defaultUserHooks
"Use simpleUserHooks or autoconfUserHooks, unless you \
need Cabal-1.2\n compatibility in which \
case you must stick with defaultUserHooks" #-}
Note the silly "\n "
to make the multi-line message line up ok in current ghc versions.
To allow embedded '\n' more sensibly, it just needs a slight tweak in the rendering. Split the message into lines and then use hsep
or equivalent. That way we get correct indenting for free.
I'm not sure how long single-line messages get printed, but Cabal solves this problem for its error messages by re-wrapping text, though it also respects embedded newlines (to force line breaks or paragraph breaks).
-- | Wraps text to the default line width. Existing newlines are preserved.
wrapText :: String -> String
wrapText = unlines
. concatMap (map unwords
. wrapLine 79
. words)
. lines
-- | Wraps a list of words to a list of lines of words of a particular width.
wrapLine :: Int -> [String] -> [[String]]
wrapLine width = wrap 0 []
where wrap :: Int -> [String] -> [String] -> [[String]]
wrap 0 [] (w:ws)
| length w + 1 > width
= wrap (length w) [w] ws
wrap col line (w:ws)
| col + length w + 1 > width
= reverse line : wrap 0 [] (w:ws)
wrap col line (w:ws)
= let col' = col + length w + 1
in wrap col' (w:line) ws
wrap _ [] [] = []
wrap _ line [] = [reverse line]
There's also a more sophisticated version of this using the Doc
type in the gtk2hs code gen utils. It has a parameter for the line width and handles prefix text on the first line.
Trac metadata
Trac field | Value |
---|---|
Version | 6.10.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |