Skip to content

Commit eccd532

Browse files
authored
Merge pull request #474 from pcapriotti/topic/0.18.0
Move to Pretty Printer Proper
2 parents 2b3b129 + a67b20e commit eccd532

File tree

9 files changed

+79
-63
lines changed

9 files changed

+79
-63
lines changed

.github/workflows/haskell-ci.yml

-10
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,6 @@ jobs:
9898
compilerVersion: 7.4.2
9999
setup-method: hvr-ppa
100100
allow-failure: false
101-
- compiler: ghc-7.2.2
102-
compilerKind: ghc
103-
compilerVersion: 7.2.2
104-
setup-method: hvr-ppa
105-
allow-failure: false
106-
- compiler: ghc-7.0.4
107-
compilerKind: ghc
108-
compilerVersion: 7.0.4
109-
setup-method: hvr-ppa
110-
allow-failure: false
111101
fail-fast: false
112102
steps:
113103
- name: apt

CHANGELOG.md

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
1-
## Unreleased
1+
## Version 0.18.0.0 (22 May 2023)
2+
3+
- Move to 'prettyprinter` library for pretty printing.
4+
5+
This is a potentially breaking change when one uses the '*Doc' family of functions
6+
(like `headerDoc`) from `Options.Applicative`. However, as versions of
7+
'ansi-wl-pprint > 1.0' export a compatible `Doc` type, this can be mitigated by
8+
using a recent version.
9+
10+
One can also either import directly from `Options.Applicative.Help` or from the
11+
`Prettyprinter` module of 'prettyprinter'.
12+
13+
- Allow commands to be disambiguated in a similar manner to flags when the
14+
`disambiguate` modifier is used.
15+
16+
This is a potentially breaking change as the internal `CmdReader` constructor
17+
has been adapted so it is able to be inspected to a greater degree to support
18+
finding prefix matches.
19+
20+
## Version 0.17.1.0 (22 May 2023)
221

322
- Widen bounds for `ansi-wl-pprint`. This supports the use of `prettyprinter`
423
in a non-breaking way, as the `ansi-wl-pprint > 1.0` support the newer
@@ -10,15 +29,10 @@
1029

1130
- Add `simpleVersioner` utility for adding a '--version' option to a parser.
1231

13-
- Allow commands to be disambiguated in a similar manner to flags when the
14-
`disambiguate` modifier is used.
15-
16-
This is a potentially breaking change as the internal `CmdReader` constructor
17-
has been adapted so it is able to be inspected to a greater degree to support
18-
finding submatches.
19-
2032
- Improve documentation.
2133

34+
- Drop support for GHC 7.0 and 7.2.
35+
2236
## Version 0.17.0.0 (1 Feb 2022)
2337

2438
- Make tabulation width configurable in usage texts.

optparse-applicative.cabal

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: optparse-applicative
2-
version: 0.17.0.0
2+
version: 0.18.0.0
33
synopsis: Utilities and combinators for parsing command line options
44
description:
55
optparse-applicative is a haskell library for parsing options
@@ -100,10 +100,11 @@ library
100100
, Options.Applicative.Types
101101
, Options.Applicative.Internal
102102

103-
build-depends: base == 4.*
103+
build-depends: base >= 4.5 && < 5
104104
, transformers >= 0.2 && < 0.7
105105
, transformers-compat >= 0.3 && < 0.8
106-
, ansi-wl-pprint >= 0.6.8 && < 1.1
106+
, prettyprinter >= 1.7 && < 1.8
107+
, prettyprinter-ansi-terminal >= 1.1 && < 1.2
107108

108109
if flag(process)
109110
build-depends: process >= 1.0 && < 1.7

src/Options/Applicative/BashCompletion.hs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
21
-- | You don't need to import this module to enable bash completion.
32
--
43
-- See
@@ -150,7 +149,7 @@ bashCompletionQuery pinfo pprefs richness ws i _ = case runCompletion compl ppre
150149
-- If there was a line break, it would come across as a different completion
151150
-- possibility.
152151
render_line :: Int -> Doc -> String
153-
render_line len doc = case lines (displayS (renderPretty 1 len doc) "") of
152+
render_line len doc = case lines (prettyString 1 len doc) of
154153
[] -> ""
155154
[x] -> x
156155
x : _ -> x ++ "..."

src/Options/Applicative/Help/Chunk.hs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
21
module Options.Applicative.Help.Chunk
32
( Chunk(..)
43
, chunked
@@ -116,7 +115,7 @@ isEmpty = isNothing . unChunk
116115
-- > extractChunk . stringChunk = string
117116
stringChunk :: String -> Chunk Doc
118117
stringChunk "" = mempty
119-
stringChunk s = pure (string s)
118+
stringChunk s = pure (pretty s)
120119

121120
-- | Convert a paragraph into a 'Chunk'. The resulting chunk is composed by the
122121
-- words of the original paragraph separated by softlines, so it will be

src/Options/Applicative/Help/Core.hs

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{-# LANGUAGE CPP #-}
2-
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
32
module Options.Applicative.Help.Core (
43
cmdDesc,
54
briefDesc,
@@ -58,7 +57,7 @@ optDesc pprefs style _reachability opt =
5857
meta =
5958
stringChunk $ optMetaVar opt
6059
descs =
61-
map (string . showOption) names
60+
map (pretty . showOption) names
6261
descriptions =
6362
listToChunk (intersperse (descSep style) descs)
6463
desc
@@ -98,7 +97,7 @@ cmdDesc pprefs = mapParser desc
9897
CmdReader gn cmds ->
9998
(,) gn $
10099
tabulate (prefTabulateFill pprefs)
101-
[ (string nm, align (extractChunk (infoProgDesc cmd)))
100+
[ (pretty nm, align (extractChunk (infoProgDesc cmd)))
102101
| (nm, cmd) <- reverse cmds
103102
]
104103
_ -> mempty
@@ -127,7 +126,7 @@ briefDesc' showOptional pprefs =
127126
| otherwise =
128127
filterOptional
129128
style = OptDescStyle
130-
{ descSep = string "|",
129+
{ descSep = pretty '|',
131130
descHidden = False,
132131
descGlobal = False
133132
}
@@ -204,9 +203,9 @@ optionsDesc global pprefs = tabulate (prefTabulateFill pprefs) . catMaybes . map
204203
n = fst $ optDesc pprefs style info opt
205204
h = optHelp opt
206205
hdef = Chunk . fmap show_def . optShowDefault $ opt
207-
show_def s = parens (string "default:" <+> string s)
206+
show_def s = parens (pretty "default:" <+> pretty s)
208207
style = OptDescStyle
209-
{ descSep = string ",",
208+
{ descSep = pretty ',',
210209
descHidden = True,
211210
descGlobal = global
212211
}
@@ -251,7 +250,7 @@ parserHelp pprefs p =
251250
group_title _ = mempty
252251

253252
with_title :: String -> Chunk Doc -> Chunk Doc
254-
with_title title = fmap (string title .$.)
253+
with_title title = fmap (pretty title .$.)
255254

256255

257256
parserGlobals :: ParserPrefs -> Parser a -> ParserHelp
@@ -267,8 +266,8 @@ parserUsage :: ParserPrefs -> Parser a -> String -> Doc
267266
parserUsage pprefs p progn =
268267
group $
269268
hsep
270-
[ string "Usage:",
271-
string progn,
269+
[ pretty "Usage:",
270+
pretty progn,
272271
hangAtIfOver 9 35 (extractChunk (briefDesc pprefs p))
273272
]
274273

src/Options/Applicative/Help/Pretty.hs

+36-21
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,41 @@
11
{-# LANGUAGE CPP #-}
2-
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
32
module Options.Applicative.Help.Pretty
4-
( module Text.PrettyPrint.ANSI.Leijen
3+
( module Prettyprinter
4+
, module Prettyprinter.Render.Terminal
55
, Doc
6-
, indent
7-
, renderPretty
8-
, displayS
6+
, SimpleDoc
7+
98
, (.$.)
9+
, (</>)
10+
1011
, groupOrNestLine
1112
, altSep
1213
, hangAtIfOver
14+
15+
, prettyString
1316
) where
1417

1518
#if !MIN_VERSION_base(4,11,0)
16-
import Data.Semigroup ((<>))
19+
import Data.Semigroup ((<>), mempty)
1720
#endif
1821

19-
import Text.PrettyPrint.ANSI.Leijen hiding (Doc, (<$>), (<>), columns, indent, renderPretty, displayS)
20-
import qualified Text.PrettyPrint.ANSI.Leijen as PP
22+
import Prettyprinter hiding (Doc)
23+
import qualified Prettyprinter as PP
24+
import qualified Prettyprinter.Render.String as PP
25+
import Prettyprinter.Render.Terminal
2126

2227
import Prelude
2328

24-
type Doc = PP.Doc
29+
type Doc = PP.Doc Prettyprinter.Render.Terminal.AnsiStyle
30+
type SimpleDoc = SimpleDocStream AnsiStyle
2531

26-
indent :: Int -> PP.Doc -> PP.Doc
27-
indent = PP.indent
28-
29-
renderPretty :: Float -> Int -> PP.Doc -> SimpleDoc
30-
renderPretty = PP.renderPretty
31-
32-
displayS :: SimpleDoc -> ShowS
33-
displayS = PP.displayS
32+
linebreak :: Doc
33+
linebreak = flatAlt line mempty
3434

3535
(.$.) :: Doc -> Doc -> Doc
36-
(.$.) = (PP.<$>)
37-
36+
x .$. y = x <> line <> y
37+
(</>) :: Doc -> Doc -> Doc
38+
x </> y = x <> softline <> y
3839

3940
-- | Apply the function if we're not at the
4041
-- start of our nesting level.
@@ -58,7 +59,6 @@ ifElseAtRoot f g doc =
5859
then f doc
5960
else g doc
6061

61-
6262
-- | Render flattened text on this line, or start
6363
-- a new line before rendering any text.
6464
--
@@ -81,7 +81,7 @@ groupOrNestLine =
8181
-- next line.
8282
altSep :: Doc -> Doc -> Doc
8383
altSep x y =
84-
group (x <+> char '|' <> line) <//> y
84+
group (x <+> pretty '|' <> line) <> group linebreak <> y
8585

8686

8787
-- | Printer hacks to get nice indentation for long commands
@@ -102,3 +102,18 @@ hangAtIfOver i j d =
102102
align d
103103
else
104104
linebreak <> ifAtRoot (indent i) d
105+
106+
107+
renderPretty :: Double -> Int -> Doc -> SimpleDocStream AnsiStyle
108+
renderPretty ribbonFraction lineWidth
109+
= layoutSmart LayoutOptions
110+
{ layoutPageWidth = AvailablePerLine lineWidth ribbonFraction }
111+
112+
prettyString :: Double -> Int -> Doc -> String
113+
prettyString ribbonFraction lineWidth
114+
= streamToString
115+
. renderPretty ribbonFraction lineWidth
116+
117+
streamToString :: SimpleDocStream AnsiStyle -> String
118+
streamToString stream =
119+
PP.renderShowS stream ""

src/Options/Applicative/Help/Types.hs

+1-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,5 @@ helpText (ParserHelp e s h u d b g f) =
4242
-- | Convert a help text to 'String'.
4343
renderHelp :: Int -> ParserHelp -> String
4444
renderHelp cols
45-
= (`displayS` "")
46-
. renderPretty 1.0 cols
45+
= prettyString 1.0 cols
4746
. helpText

tests/test.hs

+6-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import qualified Options.Applicative.NonEmpty
2828

2929

3030
import qualified Options.Applicative.Help as H
31-
import Options.Applicative.Help.Pretty (Doc, SimpleDoc(..))
31+
import Options.Applicative.Help.Pretty (Doc)
3232
import qualified Options.Applicative.Help.Pretty as Doc
3333
import Options.Applicative.Help.Chunk
3434
import Options.Applicative.Help.Levenshtein
@@ -951,9 +951,9 @@ prop_long_command_line_flow = once $
951951
deriving instance Arbitrary a => Arbitrary (Chunk a)
952952

953953

954-
equalDocs :: Float -> Int -> Doc -> Doc -> Property
955-
equalDocs f w d1 d2 = Doc.displayS (Doc.renderPretty f w d1) ""
956-
=== Doc.displayS (Doc.renderPretty f w d2) ""
954+
equalDocs :: Double -> Int -> Doc -> Doc -> Property
955+
equalDocs f w d1 d2 = Doc.prettyString f w d1
956+
=== Doc.prettyString f w d2
957957

958958
prop_listToChunk_1 :: [String] -> Property
959959
prop_listToChunk_1 xs = isEmpty (listToChunk xs) === null xs
@@ -967,10 +967,10 @@ prop_extractChunk_1 x = extractChunk (pure x) === x
967967
prop_extractChunk_2 :: Chunk String -> Property
968968
prop_extractChunk_2 x = extractChunk (fmap pure x) === x
969969

970-
prop_stringChunk_1 :: Positive Float -> Positive Int -> String -> Property
970+
prop_stringChunk_1 :: Positive Double -> Positive Int -> String -> Property
971971
prop_stringChunk_1 (Positive f) (Positive w) s =
972972
equalDocs f w (extractChunk (stringChunk s))
973-
(Doc.string s)
973+
(Doc.pretty s)
974974

975975
prop_stringChunk_2 :: String -> Property
976976
prop_stringChunk_2 s = isEmpty (stringChunk s) === null s

0 commit comments

Comments
 (0)