{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK hide #-}

-- This is an Internal module, hidden from Haddock
module Core.Text.Parsing
    ( calculatePositionEnd
    )
where

import Core.Text.Rope
import Data.Foldable (foldl')
import qualified Data.Text.Short as S (ShortText, foldl')

{- |
Calculate the line number and column number of a Rope (interpreting it as if
is a block of text in a file). By the convention observed by all leading
brands of text editor, lines and columns are @1@ origin, so an empty Rope is
position @(1,1)@.
-}

-- Of course, if Rope itself cached position information in the FingerTree
-- monoid this would be trivial.
calculatePositionEnd :: Rope -> (Int, Int)
calculatePositionEnd :: Rope -> (Int, Int)
calculatePositionEnd Rope
text =
    let x :: FingerTree Width ShortText
x = Rope -> FingerTree Width ShortText
unRope Rope
text
        (Int
l, Int
c) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Int, Int) -> ShortText -> (Int, Int)
calculateChunk (Int
1, Int
1) FingerTree Width ShortText
x
    in  (Int
l, Int
c)

calculateChunk :: (Int, Int) -> S.ShortText -> (Int, Int)
calculateChunk :: (Int, Int) -> ShortText -> (Int, Int)
calculateChunk (Int, Int)
loc ShortText
piece =
    forall a. (a -> Char -> a) -> a -> ShortText -> a
S.foldl' (Int, Int) -> Char -> (Int, Int)
f (Int, Int)
loc ShortText
piece
  where
    f :: (Int, Int) -> Char -> (Int, Int)
    f :: (Int, Int) -> Char -> (Int, Int)
f !(!Int
l, !Int
c) Char
ch =
        if Char
ch forall a. Eq a => a -> a -> Bool
== Char
'\n'
            then (Int
l forall a. Num a => a -> a -> a
+ Int
1, Int
1)
            else (Int
l, Int
c forall a. Num a => a -> a -> a
+ Int
1)