packages feed

core-text-0.3.0.0: lib/Core/Text/Parsing.hs

{-# 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 text =
  let x = unRope text
      (l, c) = foldl' calculateChunk (1, 1) x
   in (l, c)

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