1
1
mirror of https://github.com/github/semantic.git synced 2025-01-03 04:51:57 +03:00

Catch all forms of newlines in sourceLineRangesWithin

This commit is contained in:
Timothy Clem 2017-11-14 14:49:46 -08:00
parent 6b1ac4f0fa
commit 4ed36b699a

View File

@ -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