1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
6 , P.align, P.cat, P.empty, P.fill, P.fillSep, P.hang
7 , P.hcat, P.hsep, P.indent, P.sep, P.vcat
8 , P.red, P.cyan, P.magenta, P.green, P.blue, P.black, P.yellow
9 , P.dullred, P.dullcyan, P.dullyellow
11 , fromString, fromText, fromName, fromInt
12 , toAnsi, toString, toLine
15 , stack, reflow, commaSep
16 , toSimpleNote, toSimpleHint, toFancyHint
17 , link, fancyLink, reflowLink, makeLink, makeNakedLink
19 , ordinal, intToOrdinal
25import Prelude hiding (cycle)
26import qualified Data.List as List
27import Data.Monoid ((<>))
28import qualified Data.Text as Text
29import qualified Data.Text.Lazy as TL
30import qualified Data.Text.Lazy.Builder as TB
31import qualified Elm.Name as N
32import qualified System.Console.ANSI.Types as Ansi
33import System.IO (Handle)
34import qualified Text.PrettyPrint.ANSI.Leijen as P
36import qualified Data.Index as Index
37import qualified Elm.Compiler.Version as Compiler
38import qualified Elm.Package as Pkg
39import qualified Json.Encode as E
46fromString :: String -> P.Doc
51fromText :: Text.Text -> P.Doc
53 P.text (Text.unpack txt)
56fromName :: N.Name -> P.Doc
58 P.text (N.toString name)
61fromInt :: Int -> P.Doc
70toAnsi :: Handle -> P.Doc -> IO ()
72 P.displayIO handle (P.renderPretty 1 80 doc)
75toString :: P.Doc -> String
77 P.displayS (P.renderPretty 1 80 (P.plain doc)) ""
80toLine :: P.Doc -> String
82 P.displayS (P.renderPretty 1 (div maxBound 2) (P.plain doc)) ""
89stack :: [P.Doc] -> P.Doc
91 P.vcat (List.intersperse "" docs)
94reflow :: String -> P.Doc
96 P.fillSep (map P.text (words paragraph))
99commaSep :: P.Doc -> (P.Doc -> P.Doc) -> [P.Doc] -> [P.Doc]
100commaSep conjunction addStyle names =
106 [ addStyle name1, conjunction, addStyle name2 ]
109 map (\name -> addStyle name <> ",") (init names)
112 , addStyle (last names)
120toSimpleNote :: String -> P.Doc
121toSimpleNote message =
122 P.fillSep ((P.underline "Note" <> ":") : map P.text (words message))
125toSimpleHint :: String -> P.Doc
126toSimpleHint message =
127 toFancyHint (map P.text (words message))
130toFancyHint :: [P.Doc] -> P.Doc
132 P.fillSep (P.underline "Hint" <> ":" : chunks)
139link :: P.Doc -> String -> String -> String -> P.Doc
140link word before fileName after =
142 (P.underline word <> ":")
143 : map P.text (words before)
144 ++ P.text (makeLink fileName)
145 : map P.text (words after)
148fancyLink :: P.Doc -> [P.Doc] -> String -> [P.Doc] -> P.Doc
149fancyLink word before fileName after =
151 (P.underline word <> ":") : before ++ P.text (makeLink fileName) : after
154makeLink :: String -> String
156 "<https://elm-lang.org/" <> Pkg.versionToString Compiler.version <> "/" <> fileName <> ">"
159makeNakedLink :: String -> String
160makeNakedLink fileName =
161 "https://elm-lang.org/" <> Pkg.versionToString Compiler.version <> "/" <> fileName
164reflowLink :: String -> String -> String -> P.Doc
165reflowLink before fileName after =
167 map P.text (words before)
168 ++ P.text (makeLink fileName)
169 : map P.text (words after)
178 show n <> if n == 1 then " argument" else " arguments"
181moreArgs :: Int -> String
183 show n <> " more" <> if n == 1 then " argument" else " arguments"
186ordinal :: Index.ZeroBased -> String
188 intToOrdinal (Index.toHuman index)
191intToOrdinal :: Int -> String
201 | remainder100 `elem` [11..13] = "th"
202 | remainder10 == 1 = "st"
203 | remainder10 == 2 = "nd"
204 | remainder10 == 3 = "rd"
207 show number <> ending
211cycle :: Int -> [N.Name] -> P.Doc
215 nameLine name = "│ " <> P.dullyellow (fromName name)
217 bottomLine = "└─────┘"
219 P.indent indent $ P.vcat $
220 topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ]
227encode :: P.Doc -> E.Value
229 E.array (toJsonHelp noStyle [] (P.renderPretty 1 80 doc))
236 , _color :: Maybe Color
242 Style False False Nothing
264toJsonHelp :: Style -> [TB.Builder] -> P.SimpleDoc -> [E.Value]
265toJsonHelp style revChunks simpleDoc =
269 "according to the main implementation, @SFail@ can not\
270 \ appear uncaught in a rendered @SimpleDoc@"
273 [ encodeChunks style revChunks ]
276 toJsonHelp style (TB.singleton char : revChunks) rest
278 P.SText _ string rest ->
279 toJsonHelp style (TB.fromString string : revChunks) rest
281 P.SLine indent rest ->
282 toJsonHelp style (spaces indent : "\n" : revChunks) rest
285 encodeChunks style revChunks : toJsonHelp (sgrToStyle sgrs style) [] rest
288spaces :: Int -> TB.Builder
290 TB.fromText (Text.replicate n " ")
293sgrToStyle :: [Ansi.SGR] -> Style -> Style
294sgrToStyle sgrs style@(Style bold underline color) =
302 Ansi.Reset -> noStyle
303 Ansi.SetConsoleIntensity i -> Style (isBold i) underline color
304 Ansi.SetItalicized _ -> style
305 Ansi.SetUnderlining u -> Style bold (isUnderline u) color
306 Ansi.SetBlinkSpeed _ -> style
307 Ansi.SetVisible _ -> style
308 Ansi.SetSwapForegroundBackground _ -> style
309 Ansi.SetColor l i c -> Style bold underline (toColor l i c)
310 Ansi.SetRGBColor _ _ -> style
313isBold :: Ansi.ConsoleIntensity -> Bool
316 Ansi.BoldIntensity -> True
317 Ansi.FaintIntensity -> False
318 Ansi.NormalIntensity -> False
321isUnderline :: Ansi.Underlining -> Bool
322isUnderline underlining =
324 Ansi.SingleUnderline -> True
325 Ansi.DoubleUnderline -> False
326 Ansi.NoUnderline -> False
329toColor :: Ansi.ConsoleLayer -> Ansi.ColorIntensity -> Ansi.Color -> Maybe Color
330toColor layer intensity color =
344 Ansi.Red -> pick Red RED
345 Ansi.Magenta -> pick Magenta MAGENTA
346 Ansi.Yellow -> pick Yellow YELLOW
347 Ansi.Green -> pick Green GREEN
348 Ansi.Cyan -> pick Cyan CYAN
349 Ansi.Blue -> pick Blue BLUE
350 Ansi.White -> pick White WHITE
351 Ansi.Black -> pick Black BLACK
354encodeChunks :: Style -> [TB.Builder] -> E.Value
355encodeChunks (Style bold underline color) revChunks =
363 TL.toStrict $ TB.toLazyText $
364 List.foldl' (\builder chunk -> chunk <> builder) c cs
367 Nothing | not bold && not underline ->
372 [ ("bold", E.bool bold)
373 , ("underline", E.bool underline)
374 , ("color", maybe E.null encodeColor color)
375 , ("string", E.text text)
379encodeColor :: Color -> E.Value
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list