module Jikka.Common.Format.Location
  ( prettyLoc,
    prettyLocWithText,
  )
where

import Data.Text (Text)
import qualified Data.Text as T
import Jikka.Common.Format.Color
import Jikka.Common.Location

prettyLoc :: Loc -> String
prettyLoc :: Loc -> String
prettyLoc Loc
loc = String
"line " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Loc -> Int
line Loc
loc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" column " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Loc -> Int
column Loc
loc)

prettyLocWithText :: ColorFlag -> Text -> Loc -> [String]
prettyLocWithText :: ColorFlag -> Text -> Loc -> [String]
prettyLocWithText ColorFlag
color Text
text (Loc Int
y Int
x Int
width) = [String]
result
  where
    lines :: [Text]
    lines :: [Text]
lines = Text -> [Text]
T.lines Text
text
    paddingSize :: Int
    paddingSize :: Int
paddingSize = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
    padRight :: String -> String
    padRight :: String -> String
padRight String
s = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
paddingSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) Char
' '
    prettyLine :: (String -> String) -> Int -> [String]
    prettyLine :: (String -> String) -> Int -> [String]
prettyLine String -> String
f Int
y
      | Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
y Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
lines = [ColorFlag -> Color -> String -> String
withColor ColorFlag
color Color
Blue (String -> String
padRight (Int -> String
forall a. Show a => a -> String
show Int
y) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" |") String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
f (Text -> String
T.unpack ([Text]
lines [Text] -> Int -> Text
forall a. [a] -> Int -> a
!! (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)))]
      | Bool
otherwise = []
    result :: [String]
    result :: [String]
result
      | Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
y Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
lines =
        [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
          [ (String -> String) -> Int -> [String]
prettyLine String -> String
forall a. a -> a
id (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1),
            (String -> String) -> Int -> [String]
prettyLine (\String
line -> Int -> String -> String
forall a. Int -> [a] -> [a]
take (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) String
line String -> String -> String
forall a. [a] -> [a] -> [a]
++ ColorFlag -> Color -> String -> String
withColor ColorFlag
color Color
Red (Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
width (Int -> String -> String
forall a. Int -> [a] -> [a]
drop (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) String
line)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
forall a. Int -> [a] -> [a]
drop (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
width) String
line) Int
y,
            [Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
paddingSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Char
' ' String -> String -> String
forall a. [a] -> [a] -> [a]
++ ColorFlag -> Color -> String -> String
withColor ColorFlag
color Color
Red (Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
width) Char
'^')],
            (String -> String) -> Int -> [String]
prettyLine String -> String
forall a. a -> a
id (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
          ]
      | Bool
otherwise = [String
"<invalid loc>"]