1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Render.Code
13import qualified Data.List as List
14import qualified Data.Text as Text
15import Text.PrettyPrint.ANSI.Leijen (Doc, (<>), hardline, dullred, empty, text)
17import qualified Reporting.Region as R
25 Source [(Int, Text.Text)]
28toSource :: Text.Text -> Source
31 Text.lines source ++ [Text.empty]
38(|>) :: a -> (a -> b) -> b
43(<==>) :: Doc -> Doc -> Doc
48render :: Source -> R.Region -> Maybe R.Region -> Doc
49render (Source sourceLines) region@(R.Region start end) maybeSubRegion =
51 (R.Position startLine _) = start
52 (R.Position endLine _) = end
56 |> drop (startLine - 1)
57 |> take (1 + endLine - startLine)
60 length (show (fst (last relevantLines)))
63 maybe region id maybeSubRegion
65 case makeUnderline width endLine smallerRegion of
67 drawLines True width smallerRegion relevantLines empty
70 drawLines False width smallerRegion relevantLines underline
73makeUnderline :: Int -> Int -> R.Region -> Maybe Doc
74makeUnderline width realEndLine (R.Region (R.Position start c1) (R.Position end c2)) =
75 if start /= end || end < realEndLine then
80 spaces = replicate (c1 + width + 1) ' '
81 zigzag = replicate (max 1 (c2 - c1)) '^'
83 Just (text spaces <> dullred (text zigzag))
86drawLines :: Bool -> Int -> R.Region -> [(Int, Text.Text)] -> Doc -> Doc
87drawLines addZigZag width (R.Region start end) sourceLines finalLine =
89 (R.Position startLine _) = start
90 (R.Position endLine _) = end
92 foldr (<==>) finalLine $
93 map (drawLine addZigZag width startLine endLine) sourceLines
96drawLine :: Bool -> Int -> Int -> Int -> (Int, Text.Text) -> Doc
97drawLine addZigZag width startLine endLine (n, line) =
98 addLineNumber addZigZag width startLine endLine n (text (Text.unpack line))
101addLineNumber :: Bool -> Int -> Int -> Int -> Int -> Doc -> Doc
102addLineNumber addZigZag width start end n line =
105 if n < 0 then " " else show n
108 replicate (width - length number) ' ' ++ number ++ "|"
111 if addZigZag && start <= n && n <= end then
116 text lineNumber <> spacer <> line
128renderPair :: Source -> R.Region -> R.Region -> CodePair
129renderPair source@(Source sourceLines) region1 region2 =
131 (R.Region (R.Position startRow1 startCol1) (R.Position endRow1 endCol1)) = region1
132 (R.Region (R.Position startRow2 startCol2) (R.Position endRow2 endCol2)) = region2
134 if startRow1 == endRow1 && endRow1 == startRow2 && startRow2 == endRow2 then
136 lineNumber = show startRow1
137 spaces1 = replicate (startCol1 + length lineNumber + 1) ' '
138 zigzag1 = replicate (endCol1 - startCol1) '^'
139 spaces2 = replicate (startCol2 - endCol1) ' '
140 zigzag2 = replicate (endCol2 - startCol2) '^'
142 (Just line) = List.lookup startRow1 sourceLines
145 text lineNumber <> "| " <> text (Text.unpack line)
147 <> text spaces1 <> dullred (text zigzag1)
148 <> text spaces2 <> dullred (text zigzag2)
152 (render source region1 Nothing)
153 (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