From 4ed36b699ada52841d3d69c6e28c3a24663abd36 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Tue, 14 Nov 2017 14:49:46 -0800 Subject: [PATCH] Catch all forms of newlines in sourceLineRangesWithin --- src/Data/Source.hs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Data/Source.hs b/src/Data/Source.hs index 310d26e7b..19ca4bf91 100644 --- a/src/Data/Source.hs +++ b/src/Data/Source.hs @@ -103,7 +103,29 @@ sourceLineRanges source = sourceLineRangesWithin (totalRange source) source -- | Compute the 'Range's of each line in a 'Range' of a 'Source'. sourceLineRangesWithin :: Range -> Source -> [Range] -sourceLineRangesWithin range = uncurry (zipWith Range) . ((start range:) &&& (<> [ end range ])) . fmap (+ succ (start range)) . B.elemIndices (toEnum (ord '\n')) . sourceBytes . slice range +sourceLineRangesWithin range = uncurry (zipWith Range) + . ((start range:) &&& (<> [ end range ])) + . fmap (+ succ (start range)) + . newlineIndices + . sourceBytes + . slice range + +-- | Return all indices of newlines ('\n', '\r', '\r\n') in the 'ByteString'. +newlineIndices :: B.ByteString -> [Int] +newlineIndices = loop 0 + where + loop i bytes = case B.uncons bytes of + Nothing -> [] + Just (b, bs) | isLF b -> i : loop (succ i) bs + | isCR b -> case B.uncons bs of + Nothing -> loop (succ i) bs + Just (b', bs') | isLF b' -> succ i : loop (succ (succ i)) bs' + | otherwise -> i : loop (succ i) bs + | otherwise -> loop (succ i) bs + isLF = (== toEnum (ord '\n')) + isCR = (== toEnum (ord '\r')) + +{-# INLINE newlineIndices #-} -- Conversion