proteome-0.9.9.9: lib/Proteome/Grep/Parse.hs
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 cwd =
GrepOutputLine <$> path <*> (subtract 1 <$> number) <*> optional number <*> (toText <$> many anyChar)
where
path = do
s <- manyTill (noneOf ":") (char ':')
maybe (fail "not a path") pure (parseAbsFile s <|> ((cwd </>) <$> parseRelFile s))
number =
(fromInteger <$> natural) <* char ':'
formatGrepLine :: Path Abs Dir -> GrepOutputLine -> Text
formatGrepLine cwd (GrepOutputLine path line col text) =
[exon|#{relativePath} #{lineNumber} #{show line}:#{show (fromMaybe 1 col)} #{Text.strip text}|]
where
relativePath =
maybe (pathText path) pathText (stripProperPrefix cwd path)
parseGrepOutput ::
Members [Log, Embed IO] r =>
Path Abs Dir ->
Text ->
Sem r (Maybe (MenuItem GrepOutputLine))
parseGrepOutput cwd =
item . parseOnly (grepParser cwd)
where
item (Right a) = do
ident <- identText <$> generateIdent
pure (Just (convert ident a))
item (Left err) =
Nothing <$ Log.debug [exon|parsing grep output failed: #{toText err}|]
convert _ file =
MenuItem file text [exon| * #{text}|]
where
text =
formatGrepLine cwd file