module Proteome.Grep.Parse where import Chiasma.Data.Ident (generateIdent, identText) import Data.Attoparsec.Text (parseOnly) import qualified Data.Text as Text (strip) import Exon (exon) import qualified Log import Path (Abs, Dir, Path, parseAbsFile, parseRelFile, stripProperPrefix, (</>)) import Ribosome (pathText) import Ribosome.Menu.Data.MenuItem (MenuItem (MenuItem)) import Text.Parser.Char (anyChar, char, noneOf) import Text.Parser.Combinators (manyTill) import Text.Parser.Token (TokenParsing, natural) import Proteome.Data.GrepOutputLine (GrepOutputLine (GrepOutputLine)) import Proteome.Grep.Syntax (lineNumber) grepParser :: MonadFail m => TokenParsing m => Path Abs Dir -> m GrepOutputLine grepParser :: forall (m :: * -> *). (MonadFail m, TokenParsing m) => Path Abs Dir -> m GrepOutputLine grepParser Path Abs Dir cwd = Path Abs File -> Int -> Maybe Int -> Text -> GrepOutputLine GrepOutputLine (Path Abs File -> Int -> Maybe Int -> Text -> GrepOutputLine) -> m (Path Abs File) -> m (Int -> Maybe Int -> Text -> GrepOutputLine) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m (Path Abs File) path m (Int -> Maybe Int -> Text -> GrepOutputLine) -> m Int -> m (Maybe Int -> Text -> GrepOutputLine) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> (Int -> Int -> Int forall a. Num a => a -> a -> a subtract Int 1 (Int -> Int) -> m Int -> m Int forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m Int number) m (Maybe Int -> Text -> GrepOutputLine) -> m (Maybe Int) -> m (Text -> GrepOutputLine) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> m Int -> m (Maybe Int) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional m Int number m (Text -> GrepOutputLine) -> m Text -> m GrepOutputLine forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> ([Char] -> Text forall a. ToText a => a -> Text toText ([Char] -> Text) -> m [Char] -> m Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m Char -> m [Char] forall (f :: * -> *) a. Alternative f => f a -> f [a] many m Char forall (m :: * -> *). CharParsing m => m Char anyChar) where path :: m (Path Abs File) path = do [Char] s <- m Char -> m Char -> m [Char] forall (m :: * -> *) a end. Alternative m => m a -> m end -> m [a] manyTill ([Char] -> m Char forall (m :: * -> *). CharParsing m => [Char] -> m Char noneOf [Char] ":") (Char -> m Char forall (m :: * -> *). CharParsing m => Char -> m Char char Char ':') m (Path Abs File) -> (Path Abs File -> m (Path Abs File)) -> Maybe (Path Abs File) -> m (Path Abs File) forall b a. b -> (a -> b) -> Maybe a -> b maybe ([Char] -> m (Path Abs File) forall (m :: * -> *) a. MonadFail m => [Char] -> m a fail [Char] "not a path") Path Abs File -> m (Path Abs File) forall (f :: * -> *) a. Applicative f => a -> f a pure ([Char] -> Maybe (Path Abs File) forall (m :: * -> *). MonadThrow m => [Char] -> m (Path Abs File) parseAbsFile [Char] s Maybe (Path Abs File) -> Maybe (Path Abs File) -> Maybe (Path Abs File) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> ((Path Abs Dir cwd Path Abs Dir -> Path Rel File -> Path Abs File forall b t. Path b Dir -> Path Rel t -> Path b t </>) (Path Rel File -> Path Abs File) -> Maybe (Path Rel File) -> Maybe (Path Abs File) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Char] -> Maybe (Path Rel File) forall (m :: * -> *). MonadThrow m => [Char] -> m (Path Rel File) parseRelFile [Char] s)) number :: m Int number = (Integer -> Int forall a. Num a => Integer -> a fromInteger (Integer -> Int) -> m Integer -> m Int forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m Integer forall (m :: * -> *). TokenParsing m => m Integer natural) m Int -> m Char -> m Int forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a <* Char -> m Char forall (m :: * -> *). CharParsing m => Char -> m Char char Char ':' formatGrepLine :: Path Abs Dir -> GrepOutputLine -> Text formatGrepLine :: Path Abs Dir -> GrepOutputLine -> Text formatGrepLine Path Abs Dir cwd (GrepOutputLine Path Abs File path Int line Maybe Int col Text text) = [exon|#{relativePath} #{lineNumber} #{show line}:#{show (fromMaybe 1 col)} #{Text.strip text}|] where relativePath :: Text relativePath = Text -> (Path Rel File -> Text) -> Maybe (Path Rel File) -> Text forall b a. b -> (a -> b) -> Maybe a -> b maybe (Path Abs File -> Text forall b t. Path b t -> Text pathText Path Abs File path) Path Rel File -> Text forall b t. Path b t -> Text pathText (Path Abs Dir -> Path Abs File -> Maybe (Path Rel File) forall (m :: * -> *) b t. MonadThrow m => Path b Dir -> Path b t -> m (Path Rel t) stripProperPrefix Path Abs Dir cwd Path Abs File path) parseGrepOutput :: Members [Log, Embed IO] r => Path Abs Dir -> Text -> Sem r (Maybe (MenuItem GrepOutputLine)) parseGrepOutput :: forall (r :: EffectRow). Members '[Log, Embed IO] r => Path Abs Dir -> Text -> Sem r (Maybe (MenuItem GrepOutputLine)) parseGrepOutput Path Abs Dir cwd = Either [Char] GrepOutputLine -> Sem r (Maybe (MenuItem GrepOutputLine)) item (Either [Char] GrepOutputLine -> Sem r (Maybe (MenuItem GrepOutputLine))) -> (Text -> Either [Char] GrepOutputLine) -> Text -> Sem r (Maybe (MenuItem GrepOutputLine)) forall b c a. (b -> c) -> (a -> b) -> a -> c . Parser GrepOutputLine -> Text -> Either [Char] GrepOutputLine forall a. Parser a -> Text -> Either [Char] a parseOnly (Path Abs Dir -> Parser GrepOutputLine forall (m :: * -> *). (MonadFail m, TokenParsing m) => Path Abs Dir -> m GrepOutputLine grepParser Path Abs Dir cwd) where item :: Either [Char] GrepOutputLine -> Sem r (Maybe (MenuItem GrepOutputLine)) item (Right GrepOutputLine a) = do Text ident <- Ident -> Text identText (Ident -> Text) -> Sem r Ident -> Sem r Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Sem r Ident forall (m :: * -> *). MonadIO m => m Ident generateIdent pure (MenuItem GrepOutputLine -> Maybe (MenuItem GrepOutputLine) forall a. a -> Maybe a Just (Text -> GrepOutputLine -> MenuItem GrepOutputLine convert Text ident GrepOutputLine a)) item (Left [Char] err) = Maybe (MenuItem GrepOutputLine) forall a. Maybe a Nothing Maybe (MenuItem GrepOutputLine) -> Sem r () -> Sem r (Maybe (MenuItem GrepOutputLine)) forall (f :: * -> *) a b. Functor f => a -> f b -> f a <$ Text -> Sem r () forall (r :: EffectRow). (HasCallStack, Member Log r) => Text -> Sem r () Log.debug [exon|parsing grep output failed: #{toText err}|] convert :: Text -> GrepOutputLine -> MenuItem GrepOutputLine convert Text _ GrepOutputLine file = GrepOutputLine -> Text -> Text -> MenuItem GrepOutputLine forall a. a -> Text -> Text -> MenuItem a MenuItem GrepOutputLine file Text text [exon| * #{text}|] where text :: Text text = Path Abs Dir -> GrepOutputLine -> Text formatGrepLine Path Abs Dir cwd GrepOutputLine file