Skip to content

Commit 5f79978

Browse files
committed
Does not compile completely but is starting to make sense.
1 parent 9b5afa9 commit 5f79978

4 files changed

Lines changed: 281 additions & 214 deletions

File tree

src/Options/Applicative/Help/Core.hs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,36 @@ import Data.Semigroup (Semigroup (..))
3535
#endif
3636
import Options.Applicative.Common
3737
import Options.Applicative.Help.Chunk
38+
import Options.Applicative.Help.HelpDoc (HelpDoc, HelpType (CmdName, Description, Metavar, OptionName, Title), annotateHelp, ansiDocToHelpDoc)
3839
import Options.Applicative.Help.Pretty
3940
import Options.Applicative.Types
4041
import Prelude hiding (any)
4142

43+
-- XXX(Martin): Seems like this returns a ton of helpers for generating Help, there is no proper top level function,
44+
-- instead they are called and combined together in Options.Applicative.Extra .
45+
4246
-- | Style for rendering an option.
4347
data OptDescStyle = OptDescStyle
44-
{ descSep :: Doc,
48+
{ descSep :: HelpDoc,
4549
descHidden :: Bool,
4650
descGlobal :: Bool
4751
}
4852

4953
safelast :: [a] -> Maybe a
5054
safelast = foldl' (const Just) Nothing
5155

56+
-- XXX(Martin): What does this really generate? Just the names for the option + metavar?
57+
-- Or does it also generate its usage information? I don't see where usage is getting generated.
58+
5259
-- | Generate description for a single option.
53-
optDesc :: ParserPrefs -> OptDescStyle -> ArgumentReachability -> Option a -> (Chunk Doc, Parenthetic)
60+
optDesc :: ParserPrefs -> OptDescStyle -> ArgumentReachability -> Option a -> (Chunk HelpDoc, Parenthetic)
5461
optDesc pprefs style _reachability opt =
5562
let names =
5663
sort . optionNames . optMain $ opt
5764
meta =
58-
stringChunk $ optMetaVar opt
65+
annotateHelp Metavar <$> stringChunk (optMetaVar opt)
5966
descs =
60-
map (pretty . showOption) names
67+
map (annotateHelp OptionName . pretty . showOption) names
6168
descriptions =
6269
listToChunk (intersperse (descSep style) descs)
6370
desc
@@ -88,8 +95,12 @@ optDesc pprefs style _reachability opt =
8895
maybe id fmap (optDescMod opt) rendered
8996
in (modified, wrapping)
9097

98+
-- TODO(Martin): I started going through this file and annotating chunks,
99+
-- but there is still more to annotate and I am not having an easy time figuring out what
100+
-- is what in the codebase, so it goes very slow.
101+
91102
-- | Generate descriptions for commands.
92-
cmdDesc :: ParserPrefs -> Parser a -> [(Maybe String, Chunk Doc)]
103+
cmdDesc :: ParserPrefs -> Parser a -> [(Maybe String, Chunk HelpDoc)]
93104
cmdDesc pprefs = mapParser desc
94105
where
95106
desc _ opt =
@@ -98,23 +109,25 @@ cmdDesc pprefs = mapParser desc
98109
(,) gn $
99110
tabulate
100111
(prefTabulateFill pprefs)
101-
[ (pretty nm, align (extractChunk (infoProgDesc cmd)))
102-
| (nm, cmd) <- reverse cmds
112+
[ ( annotateHelp CmdName $ pretty cmdName,
113+
align (annotateHelp Description $ ansiDocToHelpDoc $ extractChunk (infoProgDesc cmdInfo))
114+
)
115+
| (cmdName, cmdInfo) <- reverse cmds
103116
]
104117
_ -> mempty
105118

106119
-- | Generate a brief help text for a parser.
107-
briefDesc :: ParserPrefs -> Parser a -> Chunk Doc
120+
briefDesc :: ParserPrefs -> Parser a -> Chunk HelpDoc
108121
briefDesc = briefDesc' True
109122

110123
-- | Generate a brief help text for a parser, only including mandatory
111124
-- options and arguments.
112-
missingDesc :: ParserPrefs -> Parser a -> Chunk Doc
125+
missingDesc :: ParserPrefs -> Parser a -> Chunk HelpDoc
113126
missingDesc = briefDesc' False
114127

115128
-- | Generate a brief help text for a parser, allowing the specification
116129
-- of if optional arguments are show.
117-
briefDesc' :: Bool -> ParserPrefs -> Parser a -> Chunk Doc
130+
briefDesc' :: Bool -> ParserPrefs -> Parser a -> Chunk HelpDoc
118131
briefDesc' showOptional pprefs =
119132
wrapOver NoDefault MaybeRequired
120133
. foldTree pprefs style
@@ -134,7 +147,7 @@ briefDesc' showOptional pprefs =
134147
}
135148

136149
-- | Wrap a doc in parentheses or brackets if required.
137-
wrapOver :: AltNodeType -> Parenthetic -> (Chunk Doc, Parenthetic) -> Chunk Doc
150+
wrapOver :: AltNodeType -> Parenthetic -> (Chunk HelpDoc, Parenthetic) -> Chunk HelpDoc
138151
wrapOver altnode mustWrapBeyond (chunk, wrapping)
139152
| altnode == MarkDefault =
140153
fmap brackets chunk
@@ -145,7 +158,7 @@ wrapOver altnode mustWrapBeyond (chunk, wrapping)
145158

146159
-- Fold a tree of option docs into a single doc with fully marked
147160
-- optional areas and groups.
148-
foldTree :: ParserPrefs -> OptDescStyle -> OptTree (Chunk Doc, Parenthetic) -> (Chunk Doc, Parenthetic)
161+
foldTree :: ParserPrefs -> OptDescStyle -> OptTree (Chunk HelpDoc, Parenthetic) -> (Chunk HelpDoc, Parenthetic)
149162
foldTree _ _ (Leaf x) =
150163
x
151164
foldTree prefs s (MultNode xs) =
@@ -168,7 +181,7 @@ foldTree prefs s (AltNode b xs) =
168181
. map (foldTree prefs s)
169182
$ xs
170183
where
171-
alt_node :: [(Chunk Doc, Parenthetic)] -> (Chunk Doc, Parenthetic)
184+
alt_node :: [(Chunk HelpDoc, Parenthetic)] -> (Chunk HelpDoc, Parenthetic)
172185
alt_node [n] = n
173186
alt_node ns =
174187
(\y -> (y, AlwaysRequired))
@@ -185,16 +198,16 @@ foldTree prefs s (BindNode x) =
185198
in (withSuffix, NeverRequired)
186199

187200
-- | Generate a full help text for a parser
188-
fullDesc :: ParserPrefs -> Parser a -> Chunk Doc
201+
fullDesc :: ParserPrefs -> Parser a -> Chunk HelpDoc
189202
fullDesc = optionsDesc False
190203

191204
-- | Generate a help text for the parser, showing
192205
-- only what is relevant in the "Global options: section"
193-
globalDesc :: ParserPrefs -> Parser a -> Chunk Doc
206+
globalDesc :: ParserPrefs -> Parser a -> Chunk HelpDoc
194207
globalDesc = optionsDesc True
195208

196209
-- | Common generator for full descriptions and globals
197-
optionsDesc :: Bool -> ParserPrefs -> Parser a -> Chunk Doc
210+
optionsDesc :: Bool -> ParserPrefs -> Parser a -> Chunk HelpDoc
198211
optionsDesc global pprefs = tabulate (prefTabulateFill pprefs) . catMaybes . mapParser doc
199212
where
200213
doc info opt = do
@@ -213,28 +226,28 @@ optionsDesc global pprefs = tabulate (prefTabulateFill pprefs) . catMaybes . map
213226
descGlobal = global
214227
}
215228

216-
errorHelp :: Chunk Doc -> ParserHelp
229+
errorHelp :: Chunk HelpDoc -> ParserHelp
217230
errorHelp chunk = mempty {helpError = chunk}
218231

219-
headerHelp :: Chunk Doc -> ParserHelp
232+
headerHelp :: Chunk HelpDoc -> ParserHelp
220233
headerHelp chunk = mempty {helpHeader = chunk}
221234

222-
suggestionsHelp :: Chunk Doc -> ParserHelp
235+
suggestionsHelp :: Chunk HelpDoc -> ParserHelp
223236
suggestionsHelp chunk = mempty {helpSuggestions = chunk}
224237

225-
globalsHelp :: Chunk Doc -> ParserHelp
238+
globalsHelp :: Chunk HelpDoc -> ParserHelp
226239
globalsHelp chunk = mempty {helpGlobals = chunk}
227240

228-
usageHelp :: Chunk Doc -> ParserHelp
241+
usageHelp :: Chunk HelpDoc -> ParserHelp
229242
usageHelp chunk = mempty {helpUsage = chunk}
230243

231-
descriptionHelp :: Chunk Doc -> ParserHelp
244+
descriptionHelp :: Chunk HelpDoc -> ParserHelp
232245
descriptionHelp chunk = mempty {helpDescription = chunk}
233246

234-
bodyHelp :: Chunk Doc -> ParserHelp
247+
bodyHelp :: Chunk HelpDoc -> ParserHelp
235248
bodyHelp chunk = mempty {helpBody = chunk}
236249

237-
footerHelp :: Chunk Doc -> ParserHelp
250+
footerHelp :: Chunk HelpDoc -> ParserHelp
238251
footerHelp chunk = mempty {helpFooter = chunk}
239252

240253
-- TODO: fullDesc and cmdDesc already return chunked usage information, so we need to look into them.
@@ -255,17 +268,18 @@ parserHelp pprefs p =
255268

256269
cmdGroups = groupBy ((==) `on` fst) $ cmdDesc pprefs p
257270

258-
with_title :: String -> Chunk Doc -> Chunk Doc
259-
with_title title = fmap (annotate (color Green <> bold) . (pretty title .$.))
271+
with_title :: String -> Chunk HelpDoc -> Chunk HelpDoc
272+
with_title title = fmap (annotateHelp Title . (pretty title .$.))
260273

274+
-- | XXX(Martin): This generates just a part of parser help.
261275
parserGlobals :: ParserPrefs -> Parser a -> ParserHelp
262276
parserGlobals pprefs p =
263277
globalsHelp $
264278
(.$.) <$> stringChunk "Global options:"
265279
<*> globalDesc pprefs p
266280

267281
-- | Generate option summary.
268-
parserUsage :: ParserPrefs -> Parser a -> String -> Doc
282+
parserUsage :: ParserPrefs -> Parser a -> String -> HelpDoc
269283
parserUsage pprefs p progn =
270284
group $
271285
hsep
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
1+
{-# LANGUAGE TupleSections #-}
2+
13
module Options.Applicative.Help.HelpDoc
24
( HelpDoc,
35
HelpType (..),
6+
ansiDocToHelpDoc,
7+
helpDocToAnsiDoc,
8+
annotateHelp,
9+
annotateStyle,
410
)
511
where
612

7-
import Options.Applicative.Help.Pretty (AnsiDoc)
13+
import Options.Applicative.Help.Pretty (AnsiDoc, AnsiStyle, annotate, reAnnotate)
814
import qualified Prettyprinter as PP
915
import Prelude
1016

11-
type HelpDoc = PP.Doc HelpType
17+
type HelpDoc = PP.Doc HelpAnn
18+
19+
data HelpAnn = HelpAnnType HelpType | HelpAnnStyle AnsiStyle
20+
21+
data HelpType = CmdName | OptionName | Description | Title | Metavar
22+
23+
annotateHelp :: HelpType -> HelpDoc -> HelpDoc
24+
annotateHelp helpType = annotate $ HelpAnnType helpType
25+
26+
annotateStyle :: AnsiStyle -> HelpDoc -> HelpDoc
27+
annotateStyle ansiStyle = annotate $ HelpAnnStyle ansiStyle
1228

13-
-- TODO: Make these types more relevant, this was just my quick guess to put something in.
14-
data HelpType = Header | Usage | Description | Title | Undefined
29+
ansiDocToHelpDoc :: AnsiDoc -> HelpDoc
30+
ansiDocToHelpDoc = reAnnotate HelpAnnStyle
1531

1632
helpDocToAnsiDoc :: HelpDoc -> AnsiDoc
33+
-- TODO(Martin): I will want to probably use reAnnotate here -> for each HelpAnn, I will generate 0 to N AnsiStyle annotations. However maybe I should not do this for Docs, but for SimpleDocStream, as they recommended! So maybe we should not implement this function, but instead one that does SimpleDocStream HelpAnn -> SimpleDocStream AnsiStyle.
1734
helpDocToAnsiDoc = error "TODO"

src/Options/Applicative/Help/Types.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import Data.Semigroup
88
import Options.Applicative.Help.Chunk
99
import Options.Applicative.Help.HelpDoc (HelpDoc, helpDocToAnsiDoc)
1010
import Options.Applicative.Help.Pretty
11-
import qualified Prettyprinter as PP
1211
import Prelude
1312

1413
data ParserHelp = ParserHelp
@@ -51,6 +50,6 @@ helpText (ParserHelp e s h u d b g f) =
5150
-- | Convert a help text to 'String'.
5251
renderHelp :: Int -> ParserHelp -> String
5352
renderHelp cols =
54-
prettyString 1.0 cols
53+
ansiDocToPrettyString 1.0 cols
5554
. helpDocToAnsiDoc
5655
. helpText

0 commit comments

Comments
 (0)