on master help sign in
Make the --help messages much nicer
commit77b9f0964ebf76a0044399db955c0faa8228f1d1 authorEvan Czaplicki <evancz@users.noreply.github.com> dateTue 27 Mar 2018, 12:33 (9 years ago) parent4cd20e2
4 files changed+131−39
ui/terminal/src/Main.hs+110−16 ui/terminal/src/Terminal/Args.hs+6−7 ui/terminal/src/Terminal/Args/Error.hs+9−7 ui/terminal/src/Terminal/Args/Internal.hs+6−9
ui/terminal/src/Main.hs+110−16
@@ -6,6 +6,7 @@ module Main
66
77
88import GHC.IO.Encoding (setLocaleEncoding, utf8)
9+import qualified Data.List as List
910import qualified Text.PrettyPrint.ANSI.Leijen as P
1011import Text.PrettyPrint.ANSI.Leijen ((<>))
1112import Text.Read (readMaybe)
@@ -81,13 +82,19 @@ repl =
8182 \ expressions and it will tell you what they evaluate to."
8283
8384 details =
84− Details $ error "TODO"
85+ "The `repl` command opens up an interactive programming session:"
86+
87+ example =
88+ reflow
89+ "Start working through <https://guide.elm-lang.org> to learn how to use this!\
90+ \ It has a whole chapter that uses the REPL for everything, so that is probably\
91+ \ the quickest way to get started."
8592
8693 replFlags =
8794 flags Repl.Flags
8895 |-- flag "interpreter" interpreter "Path to a alternate JS interpreter, like node or nodejs."
8996 in
90− Interface "repl" (Common summary) details noArgs replFlags Repl.run
97+ Interface "repl" (Common summary) details example noArgs replFlags Repl.run
9198
9299
93100interpreter :: Parser String
@@ -113,13 +120,20 @@ reactor =
113120 \ click on an Elm file, it compiles it and shows the result."
114121
115122 details =
116− Details $ error "TODO"
123+ "The `reactor` command starts a local server on your computer:"
124+
125+ example =
126+ reflow
127+ "After running that command, you would have a server at <http://localhost:8000>\
128+ \ that helps with development. It shows your files like a file viewer. If you\
129+ \ click on an Elm file, it will compile it for you! And you can just press\
130+ \ the refresh button in the browser to recompile things."
117131
118132 reactorFlags =
119133 flags Develop.Flags
120134 |-- flag "port" port_ "The port of the server (default: 8000)"
121135 in
122− Interface "reactor" (Common summary) details noArgs reactorFlags Develop.run
136+ Interface "reactor" (Common summary) details example noArgs reactorFlags Develop.run
123137
124138
125139port_ :: Parser Int
@@ -145,7 +159,17 @@ make =
145159 \ will probably want this level of control during development."
146160
147161 details =
148− Details $ error "TODO"
162+ "The `make` command compiles Elm code into JS or HTML:"
163+
164+ example =
165+ stack
166+ [ reflow
167+ "For example:"
168+ , P.indent 4 $ P.green "elm make src/Main.elm"
169+ , reflow
170+ "This tries to compile an Elm file named src/Main.elm, putting the resulting\
171+ \ JavaScript code in an elm.js file."
172+ ]
149173
150174 makeFlags =
151175 flags Make.Flags
@@ -153,7 +177,7 @@ make =
153177 |-- onOff "debug" "Generate programs in debug mode."
154178 |-- flag "output" Output.output "Specify the name of the resulting JS file (use --output=/dev/null for no output)"
155179 in
156− Interface "make" (Common summary) details (zeroOrMore elmFile) makeFlags Make.run
180+ Interface "make" (Common summary) details example (zeroOrMore elmFile) makeFlags Make.run
157181
158182
159183
@@ -168,9 +192,25 @@ install =
168192 \ independent, so you can use different versions in different projects."
169193
170194 details =
171− Details $ error "TODO"
195+ "The `install` command fetches packages from <https://package.elm-lang.org> for\
196+ \ use in your project:"
197+
198+ example =
199+ stack
200+ [ reflow
201+ "For example, if you want to get packages for HTTP and JSON, you would say:"
202+ , P.indent 4 $ P.green $ P.vcat $
203+ [ "elm install elm-lang/http"
204+ , "elm install elm-lang/json"
205+ ]
206+ , reflow
207+ "Those commands would allow you to say `import Http` or `import Json.Decode` in\
208+ \ your project. And every project is independent, so it is no problem if one\
209+ \ project uses version 1.0.0 and another uses 2.0.0. No need to worry about\
210+ \ that sort of thing!"
211+ ]
172212 in
173− Interface "install" (Common summary) details (required package) noFlags Install.run
213+ Interface "install" (Common summary) details example (required package) noFlags Install.run
174214
175215
176216
@@ -181,9 +221,33 @@ publish :: Interface
181221publish =
182222 let
183223 details =
184− Details $ error "TODO"
224+ "The `publish` command publishes your package on <https://package.elm-lang.org>\
225+ \ so that anyone in the Elm community can use it."
226+
227+ example =
228+ stack
229+ [ reflow
230+ "Think hard if you are ready to publish NEW packages though!"
231+ , reflow
232+ "Part of what makes Elm great is the packages ecosystem. The fact that\
233+ \ there is usually one option (usually very well done) makes it way\
234+ \ easier to pick packages and become productive. So having a million\
235+ \ packages would be a failure in Elm. We do not need twenty of\
236+ \ everything, all coded in a single weekend."
237+ , reflow
238+ "So as community members gain wisdom through experience, we want\
239+ \ them to share that through thoughtful API design and excellent\
240+ \ documentation. It is more about sharing ideas and insights than\
241+ \ just sharing code! The first step may be asking for advice from\
242+ \ people you respect, or in community forums. The second step may\
243+ \ be using it at work to see if it is as nice as you think. Maybe\
244+ \ it ends up as an experiment on GitHub only. Point is, try to be\
245+ \ respectful of the community and package ecosystem!"
246+ , reflow
247+ "Check out <TODO> for guidance on how to create great packages!"
248+ ]
185249 in
186− Interface "publish" Uncommon details noArgs noFlags Publish.run
250+ Interface "publish" Uncommon details example noArgs noFlags Publish.run
187251
188252
189253
@@ -194,9 +258,16 @@ bump :: Interface
194258bump =
195259 let
196260 details =
197− Details $ error "TODO"
261+ "The `bump` command figures out the next version number based on API changes:"
262+
263+ example =
264+ reflow
265+ "Say you just published version 1.0.0, but then decided to remove a function.\
266+ \ I will compare the published API to what you have locally, figure out that\
267+ \ it is a MAJOR change, and bump your version number to 2.0.0. I do this with\
268+ \ all packages, so there cannot be MAJOR changes hiding in PATCH releases in Elm!"
198269 in
199− Interface "bump" Uncommon details noArgs noFlags Bump.run
270+ Interface "bump" Uncommon details example noArgs noFlags Bump.run
200271
201272
202273
@@ -207,9 +278,18 @@ diff :: Interface
207278diff =
208279 let
209280 details =
210− Details $
211− "The `diff` command detects API changes. Every Elm package has a known public\
212− \ API, so I can tell you exactly what changed from version to version."
281+ "The `diff` command detects API changes:"
282+
283+ example =
284+ stack
285+ [ reflow
286+ "For example, to see what changed in the HTML package between\
287+ \ versions 1.0.0 and 2.0.0, you can say:"
288+ , P.indent 4 $ P.green $ "elm diff elm-lang/html 1.0.0 2.0.0"
289+ , reflow
290+ "Sometimes a MAJOR change is not actually very big, so\
291+ \ this can help you plan your upgrade timelines."
292+ ]
213293
214294 diffArgs =
215295 oneOf
@@ -219,4 +299,18 @@ diff =
219299 , require3 Diff.GlobalInquiry package version version
220300 ]
221301 in
222− Interface "diff" Uncommon details diffArgs noFlags Diff.run
302+ Interface "diff" Uncommon details example diffArgs noFlags Diff.run
303+
304+
305+
306+-- HELPERS
307+
308+
309+stack :: [P.Doc] -> P.Doc
310+stack docs =
311+ P.vcat $ List.intersperse "" docs
312+
313+
314+reflow :: String -> P.Doc
315+reflow string =
316+ P.fillSep $ map P.text $ words string
ui/terminal/src/Terminal/Args.hs+6−7
@@ -2,7 +2,6 @@ module Terminal.Args
22 ( simple
33 , Interface(..)
44 , Summary(..)
5− , Details(..)
65 , complex
76 , Flags, noFlags, flags, (|--)
87 , Flag, flag, onOff
@@ -34,8 +33,8 @@ import qualified Terminal.Args.Error as Error
3433-- GET
3534
3635
37−simple :: String -> Args args -> Flags flags -> (args -> flags -> IO ()) -> IO ()
38−simple details args_ flags_ callback =
36+simple :: String -> P.Doc -> Args args -> Flags flags -> (args -> flags -> IO ()) -> IO ()
37+simple details example args_ flags_ callback =
3938 do argStrings <- Env.getArgs
4039 case argStrings of
4140 "<autocomplete>" : number : chunks ->
@@ -44,7 +43,7 @@ simple details args_ flags_ callback =
4443
4544 chunks ->
4645 if elem "--help" chunks then
47− Error.exitWithHelp Nothing details args_ flags_
46+ Error.exitWithHelp Nothing details example args_ flags_
4847
4948 else
5049 case snd $ Chomp.chomp Nothing chunks args_ flags_ of
@@ -71,9 +70,9 @@ complex intro outro interfaces =
7170 Nothing ->
7271 Error.exitWithUnknown command (map toName interfaces)
7372
74− Just (Interface _ _ (Details details) args_ flags_ callback) ->
73+ Just (Interface _ _ details example args_ flags_ callback) ->
7574 if elem "--help" chunks then
76− Error.exitWithHelp (Just command) details args_ flags_
75+ Error.exitWithHelp (Just command) details example args_ flags_
7776
7877 else
7978 case snd $ Chomp.chomp Nothing chunks args_ flags_ of
@@ -109,7 +108,7 @@ complexSuggest index strings interfaces =
109108 Nothing ->
110109 return (map toName interfaces)
111110
112− Just (Interface _ _ _ args_ flags_ _) ->
111+ Just (Interface _ _ _ _ args_ flags_ _) ->
113112 fst $ Chomp.chomp (Just (index-1)) chunks args_ flags_
114113
115114
ui/terminal/src/Terminal/Args/Error.hs+9−7
@@ -20,7 +20,7 @@ import GHC.IO.Handle (hIsTerminalDevice)
2020import qualified System.Environment as Env
2121import qualified System.Exit as Exit
2222import qualified System.FilePath as FP
23−import System.IO (stderr)
23+import System.IO (hPutStrLn, stderr)
2424import qualified Text.PrettyPrint.ANSI.Leijen as P
2525
2626import Elm.Utils (nearbyNames, distance)
@@ -76,6 +76,7 @@ exitWith code docs =
7676 let adjust = if isTerminal then id else P.plain
7777 P.displayIO stderr $ P.renderPretty 1 80 $
7878 adjust $ P.vcat $ concatMap (\d -> [d,""]) docs
79+ hPutStrLn stderr ""
7980 Exit.exitWith code
8081
8182
@@ -98,12 +99,13 @@ reflow string =
9899-- HELP
99100
100101
101−exitWithHelp :: Maybe String -> String -> Args args -> Flags flags -> IO a
102−exitWithHelp maybeCommand details (Args args) flags =
102+exitWithHelp :: Maybe String -> String -> P.Doc -> Args args -> Flags flags -> IO a
103+exitWithHelp maybeCommand details example (Args args) flags =
103104 do command <- toCommand maybeCommand
104105 exitSuccess $
105106 [ reflow details
106− , P.indent 4 $ P.dullcyan $ P.vcat $ map (argsToDoc command) args
107+ , P.indent 4 $ P.cyan $ P.vcat $ map (argsToDoc command) args
108+ , example
107109 ]
108110 ++
109111 case flagsToDocs flags [] of
@@ -111,7 +113,7 @@ exitWithHelp maybeCommand details (Args args) flags =
111113 []
112114
113115 docs@(_:_) ->
114− [ "It also accepts the following flags to customize its behavior:"
116+ [ "You can customize this command with the following flags:"
115117 , P.indent 4 $ stack docs
116118 ]
117119
@@ -200,7 +202,7 @@ exitWithOverview intro outro interfaces =
200202
201203
202204toSummary :: String -> Interface -> Maybe P.Doc
203−toSummary exeName (Interface name summary _ (Args (args:_)) _ _) =
205+toSummary exeName (Interface name summary _ _ (Args (args:_)) _ _) =
204206 case summary of
205207 Uncommon ->
206208 Nothing
@@ -208,7 +210,7 @@ toSummary exeName (Interface name summary _ (Args (args:_)) _ _) =
208210 Common summaryString ->
209211 Just $
210212 P.vcat
211− [ P.dullcyan $ argsToDoc (exeName ++ " " ++ name) args
213+ [ P.cyan $ argsToDoc (exeName ++ " " ++ name) args
212214 , P.indent 4 $ reflow summaryString
213215 ]
214216
ui/terminal/src/Terminal/Args/Internal.hs+6−9
@@ -3,7 +3,6 @@ module Terminal.Args.Internal
33 ( Interface(..)
44 , toName
55 , Summary(..)
6− , Details(..)
76 , Flags(..)
87 , Flag(..)
98 , Parser(..)
@@ -14,6 +13,9 @@ module Terminal.Args.Internal
1413 where
1514
1615
16+import Text.PrettyPrint.ANSI.Leijen (Doc)
17+
18+
1719
1820-- INTERFACE
1921
@@ -22,7 +24,8 @@ data Interface where
2224 Interface
2325 :: String
2426 -> Summary
25− -> Details
27+ -> String
28+ -> Doc
2629 -> Args args
2730 -> Flags flags
2831 -> (args -> flags -> IO ())
@@ -30,7 +33,7 @@ data Interface where
3033
3134
3235toName :: Interface -> String
33−toName (Interface name _ _ _ _ _) =
36+toName (Interface name _ _ _ _ _ _) =
3437 name
3538
3639
@@ -43,12 +46,6 @@ for a more complete explanation.
4346data Summary = Common String | Uncommon
4447
4548
46−{-| When you run `elm command --help` this is the first thing people will read.
47−Say what the command does.
48−-}
49−newtype Details = Details String
50−
51−
5249
5350-- FLAGS
5451