1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Render.Code
13import qualified Data.ByteString as B
14import qualified Data.ByteString.UTF8 as UTF8_BS
15import qualified Data.List as List
16import Data.Word (Word16)
18import qualified Reporting.Annotation as A
19import qualified Reporting.Doc as D
20import Reporting.Doc (Doc)
28 Source [(Word16, String)]
31toSource :: B.ByteString -> Source
34 lines (UTF8_BS.toString source) ++ [""]
41(|>) :: a -> (a -> b) -> b
46render :: Source -> A.Region -> Maybe A.Region -> Doc
47render (Source sourceLines) region@(A.Region (A.Position startLine _) (A.Position endLine _)) maybeSubRegion =
51 |> drop (fromIntegral (startLine - 1))
52 |> take (fromIntegral (1 + endLine - startLine))
55 length (show (fst (last relevantLines)))
58 maybe region id maybeSubRegion
60 case makeUnderline width endLine smallerRegion of
62 drawLines True width smallerRegion relevantLines D.empty
65 drawLines False width smallerRegion relevantLines underline
68makeUnderline :: Int -> Word16 -> A.Region -> Maybe Doc
69makeUnderline width realEndLine (A.Region (A.Position start c1) (A.Position end c2)) =
70 if start /= end || end < realEndLine then
75 spaces = replicate (fromIntegral c1 + width + 1) ' '
76 zigzag = replicate (max 1 (fromIntegral (c2 - c1))) '^'
78 Just (D.fromChars spaces <> D.dullred (D.fromChars zigzag))
81drawLines :: Bool -> Int -> A.Region -> [(Word16, String)] -> Doc -> Doc
82drawLines addZigZag width (A.Region (A.Position startLine _) (A.Position endLine _)) sourceLines finalLine =
84 map (drawLine addZigZag width startLine endLine) sourceLines
88drawLine :: Bool -> Int -> Word16 -> Word16 -> (Word16, String) -> Doc
89drawLine addZigZag width startLine endLine (n, line) =
90 addLineNumber addZigZag width startLine endLine n (D.fromChars line)
93addLineNumber :: Bool -> Int -> Word16 -> Word16 -> Word16 -> Doc -> Doc
94addLineNumber addZigZag width start end n line =
100 replicate (width - length number) ' ' ++ number ++ "|"
103 if addZigZag && start <= n && n <= end then
108 D.fromChars lineNumber <> spacer <> line
120renderPair :: Source -> A.Region -> A.Region -> CodePair
121renderPair source@(Source sourceLines) region1 region2 =
123 (A.Region (A.Position startRow1 startCol1) (A.Position endRow1 endCol1)) = region1
124 (A.Region (A.Position startRow2 startCol2) (A.Position endRow2 endCol2)) = region2
126 if startRow1 == endRow1 && endRow1 == startRow2 && startRow2 == endRow2 then
128 lineNumber = show startRow1
129 spaces1 = replicate (fromIntegral startCol1 + length lineNumber + 1) ' '
130 zigzag1 = replicate (fromIntegral (endCol1 - startCol1)) '^'
131 spaces2 = replicate (fromIntegral (startCol2 - endCol1)) ' '
132 zigzag2 = replicate (fromIntegral (endCol2 - startCol2)) '^'
134 (Just line) = List.lookup startRow1 sourceLines
138 [ D.fromChars lineNumber <> "| " <> D.fromChars line
139 , D.fromChars spaces1 <> D.dullred (D.fromChars zigzag1) <>
140 D.fromChars spaces2 <> D.dullred (D.fromChars zigzag2)
145 (render source region1 Nothing)
146 (render source region2 Nothing)
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