1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
8 , printError, printWarning
11import Control.Applicative ((<|>))
12import Control.Monad.Writer (Writer, execWriter, tell)
13import Data.Aeson ((.=))
14import qualified Data.Aeson.Types as Json
15import System.Console.ANSI
16import System.IO (hPutStr, stderr)
18import qualified Reporting.Region as R
23 , _highlight :: Maybe R.Region
29simple :: String -> String -> String -> Report
30simple title pre post =
31 Report title Nothing pre post
34toString :: String -> R.Region -> Report -> String -> String
35toString location region report source =
36 execWriter (render plain location region report source)
39printError :: String -> R.Region -> Report -> String -> IO ()
40printError location region report source =
41 render (ansi Error) location region report source
44printWarning :: String -> R.Region -> Report -> String -> IO ()
45printWarning location region report source =
46 render (ansi Warning) location region report source
57render renderer location region (Report title highlight pre post) source =
58 do messageBar renderer title location
59 normal renderer (pre ++ "\n\n")
60 grabRegion renderer highlight region source
61 normal renderer ("\n" ++ if null post then "\n" else post ++ "\n\n\n")
64toJson :: [Json.Pair] -> Report -> (Maybe R.Region, [Json.Pair])
65toJson extraFields (Report title subregion pre post) =
73 (subregion, fields ++ extraFields)
78data Renderer m = Renderer
79 { normal :: String -> m ()
80 , header :: String -> m ()
81 , accent :: String -> m ()
85plain :: Renderer (Writer String)
87 Renderer tell tell tell
90data Type = Error | Warning
93ansi :: Type -> Renderer IO
99 put' intensity color string =
100 do hSetSGR stderr [SetColor Foreground intensity color]
102 hSetSGR stderr [Reset]
112 (put' Dull accentColor)
119messageBar :: Renderer m -> String -> String -> m ()
120messageBar renderer tag location =
122 usedSpace = 4 + length tag + 1 + length location
126 ++ replicate (max 1 (80 - usedSpace)) '-'
127 ++ " " ++ location ++ "\n\n"
139grabRegion renderer maybeSubRegion region@(R.Region start end) source =
141 (R.Position startLine startColumn) = start
142 (R.Position endLine endColumn) = end
148 |> drop (startLine - 1)
149 |> take (endLine - startLine + 1)
151 case relevantLines of
156 singleLineRegion renderer startLine sourceLine $
157 case maybeSubRegion of
159 (0, startColumn, endColumn, length sourceLine)
161 Just (R.Region s e) ->
162 (startColumn, R.column s, R.column e, endColumn)
167 replicate (startColumn - 1) ' '
168 ++ drop (startColumn - 1) firstLine
171 take (endColumn) (last rest)
173 focusedRelevantLines =
174 filteredFirstLine : init rest ++ [filteredLastLine]
177 length (show endLine)
180 maybeSubRegion <|> Just region
184 (addLineNumber renderer subregion lineNumbersWidth)
185 [startLine .. endLine]
188 mapM_ (\line -> line >> normal renderer "\n") numberedLines
199addLineNumber renderer maybeSubRegion width n line =
202 if n < 0 then " " else show n
205 replicate (width - length number) ' ' ++ number ++ "|"
207 spacer (R.Region start end) =
208 if R.line start <= n && n <= R.line end
209 then accent renderer ">"
210 else normal renderer " "
212 do normal renderer lineNumber
213 maybe (normal renderer " ") spacer maybeSubRegion
222 -> (Int, Int, Int, Int)
224singleLineRegion renderer lineNum sourceLine (start, innerStart, innerEnd, end) =
227 length (show lineNum)
230 replicate (innerStart + width + 1) ' '
231 ++ replicate (max 1 (innerEnd - innerStart)) '^'
238 |> take (end - start + 1)
239 |> (++) (replicate (start - 1) ' ')
241 do addLineNumber renderer Nothing width lineNum trimmedSourceLine
242 accent renderer $ "\n" ++ underline
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