1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Helpers
7 , toSimpleNote, toSimpleHint, toFancyHint
8 , link, reflowLink, makeLink
10 , commaSep, capitalize, ordinalize, drawCycle
11 , findPotentialTypos, findTypoPairs, vetTypos
12 , nearbyNames, distance
14 , Doc, (<+>), (<>), black, cat, dullyellow, fillSep, green, hang, hardline
15 , hcat, hsep, indent, magenta, parens, sep, text, underline, vcat
20import Data.Function (on)
21import qualified Data.Char as Char
22import qualified Data.List as List
23import qualified Data.Map as Map
24import Data.Monoid ((<>))
25import qualified Data.Set as Set
26import qualified Data.Text as Text
27import Data.Text (Text)
28import qualified Elm.Name as N
29import qualified Text.EditDistance as Dist
30import qualified Text.PrettyPrint.ANSI.Leijen as P
31import Text.PrettyPrint.ANSI.Leijen hiding ((<>))
33import qualified Elm.Compiler.Version as Compiler
34import qualified Elm.Package as Pkg
41textToDoc :: Text -> Doc
43 text (Text.unpack msg)
46nameToDoc :: N.Name -> Doc
48 text (N.toString name)
53 show n <> if n == 1 then " argument" else " arguments"
56moreArgs :: Int -> String
58 show n <> " more" <> if n == 1 then " argument" else " arguments"
65toSimpleNote :: String -> Doc
67 fillSep ((underline (text "Note") <> ":") : map text (words message))
70toSimpleHint :: String -> Doc
72 toFancyHint (map text (words message))
75toFancyHint :: [Doc] -> Doc
77 fillSep (underline (text "Hint") <> ":" : chunks)
80link :: Doc -> String -> String -> String -> Doc
81link word before fileName after =
83 (underline word <> ":")
84 : map text (words before)
85 ++ P.text (makeLink fileName)
86 : map text (words after)
89makeLink :: String -> String
91 "<https://elm-lang.org/hints/" <> Pkg.versionToString Compiler.version <> "/" <> fileName <> ">"
94reflowLink :: String -> String -> String -> Doc
95reflowLink before fileName after =
97 map text (words before)
98 ++ P.text (makeLink fileName)
99 : map text (words after)
106 error "function `stack` requires a non-empty list of docs"
109 List.foldl' (\a b -> a <> hardline <> hardline <> b) doc docs
112reflow :: String -> Doc
114 fillSep (map text (words paragraph))
117commaSep :: Doc -> (Doc -> Doc) -> [Doc] -> [Doc]
118commaSep conjunction addStyle names =
124 [ addStyle name1, conjunction, addStyle name2 ]
127 map (\name -> addStyle name <> ",") (init names)
130 , addStyle (last names)
134capitalize :: Text -> Text
136 case Text.uncons txt of
141 Text.cons (Char.toUpper c) rest
144ordinalize :: Int -> String
154 | remainder100 `elem` [11..13] = "th"
155 | remainder10 == 1 = "st"
156 | remainder10 == 2 = "nd"
157 | remainder10 == 3 = "rd"
160 show number <> ending
164drawCycle :: [N.Name] -> Doc
168 nameLine name = "│ " <> dullyellow (nameToDoc name)
170 bottomLine = "└─────┘"
172 vcat (topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ])
179findPotentialTypos :: [String] -> String -> [String]
180findPotentialTypos knownNames badName =
181 filter (\name -> distance badName name == 1) knownNames
184findTypoPairs :: [String] -> [String] -> [(String, String)]
185findTypoPairs leftOnly rightOnly =
188 map ((,) leftName) (findPotentialTypos rightOnly leftName)
190 concatMap veryNear leftOnly
193vetTypos :: [(String, String)] -> Maybe (Set.Set String, Set.Set String)
194vetTypos potentialTypos =
196 tallyNames (ln, rn) (lc, rc) =
197 ( Map.insertWith (+) ln 1 lc
198 , Map.insertWith (+) rn 1 rc
201 (leftCounts, rightCounts) =
202 foldr tallyNames (Map.empty, Map.empty) potentialTypos
204 acceptable :: Map.Map String Int -> Bool
206 not (Map.null counts)
208 Map.foldr (\n unique -> n < 2 && unique) True counts
210 if acceptable leftCounts && acceptable rightCounts then
211 Just (Map.keysSet leftCounts, Map.keysSet rightCounts)
221nearbyNames :: String -> [String] -> [String]
222nearbyNames name names =
225 if length name < 3 then 1 else 2
228 filter ( (<= editDistance) . abs . fst ) $
229 List.sortBy (compare `on` fst) $
230 map (\x -> (distance name x, x)) names
233distance :: String -> String -> Int
235 Dist.restrictedDamerauLevenshteinDistance Dist.defaultEditCosts x y
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