diff options
author | Alexander Foremny <aforemny@posteo.de> | 2023-12-03 13:29:00 +0100 |
---|---|---|
committer | Alexander Foremny <aforemny@posteo.de> | 2023-12-03 13:29:00 +0100 |
commit | 32c76fb1f411896a4727ba2a76cdfc9dcd3dc48a (patch) | |
tree | 9237f6dcd3c165d864861ab9533c0ed4a093d2a7 /app | |
parent | 22c71e24edc8655f15c8dba02244b8e6d059da5c (diff) |
feat: color patches
Diffstat (limited to 'app')
-rw-r--r-- | app/Exception.hs | 7 | ||||
-rw-r--r-- | app/History/CommitInfo.hs | 3 | ||||
-rw-r--r-- | app/History/IssueEvent.hs | 8 | ||||
-rw-r--r-- | app/Main.hs | 5 | ||||
-rw-r--r-- | app/Patch.hs | 37 |
5 files changed, 54 insertions, 6 deletions
diff --git a/app/Exception.hs b/app/Exception.hs index ddaef5a..49c9cb6 100644 --- a/app/Exception.hs +++ b/app/Exception.hs @@ -4,6 +4,7 @@ module Exception NoCommits (..), ProcessException (..), UnknownFileExtension (..), + InvalidDiff (..), ) where @@ -16,6 +17,7 @@ data AnyException | NoCommits' NoCommits | ProcessException' ProcessException | UnknownFileExtension' UnknownFileExtension + | InvalidDiff' InvalidDiff deriving (Show) instance Exception AnyException @@ -43,3 +45,8 @@ data UnknownFileExtension = UnknownFileExtension deriving (Show) instance Exception UnknownFileExtension + +data InvalidDiff = InvalidDiff String + deriving (Show) + +instance Exception InvalidDiff diff --git a/app/History/CommitInfo.hs b/app/History/CommitInfo.hs index dbb7e20..c5224b2 100644 --- a/app/History/CommitInfo.hs +++ b/app/History/CommitInfo.hs @@ -20,6 +20,7 @@ import History.PartialCommitInfo (PartialCommitInfo (..)) import Issue (Issue (..)) import Issue.Provenance qualified as I import Parallel (parSequence) +import Patch qualified as P import Process (sh) import System.FilePath ((</>)) import System.IO.Temp (withSystemTempDirectory) @@ -109,7 +110,7 @@ diffCommitInfos maybeOldInfo newInfo = let cwd = tmp T.writeFile (tmp </> "old") old T.writeFile (tmp </> "new") new - LT.toStrict . LT.decodeUtf8 <$> sh ("git diff --no-index -- old new || :" & setWorkingDir cwd) + P.parse . LT.toStrict . LT.decodeUtf8 <$> sh ("git diff --no-index -- old new || :" & setWorkingDir cwd) mergeListsBy :: (a -> a -> Bool) -> (a -> a -> b) -> (a -> b) -> (a -> b) -> [a] -> [a] -> [b] mergeListsBy eq onBoth onLeft onRight lefts rights = diff --git a/app/History/IssueEvent.hs b/app/History/IssueEvent.hs index 933b047..0900f13 100644 --- a/app/History/IssueEvent.hs +++ b/app/History/IssueEvent.hs @@ -1,24 +1,24 @@ module History.IssueEvent (IssueEvent (..)) where -import Data.Text qualified as T import History.CommitHash (CommitHash) import Issue (Issue) +import Patch (Patch) data IssueEvent = IssueCreated { hash :: CommitHash, issue :: Issue, - patch :: T.Text + patch :: Patch } | IssueChanged { hash :: CommitHash, oldIssue :: Issue, issue :: Issue, - patch :: T.Text + patch :: Patch } | IssueDeleted { hash :: CommitHash, issue :: Issue, - patch :: T.Text + patch :: Patch } deriving (Show) diff --git a/app/Main.hs b/app/Main.hs index 6f96aa5..8d785be 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -398,6 +398,7 @@ import Issue.Sort qualified as I import Issue.Tag qualified as I import Options.Applicative ((<**>)) import Options.Applicative qualified as O +import Patch qualified as P import Prettyprinter ((<+>)) import Prettyprinter qualified as P import Prettyprinter.Render.Terminal qualified as P @@ -670,7 +671,9 @@ main = do IssueDeleted {issue} -> shortHash <+> kwd "deleted" <+> title issue ) - <+> if patch then P.pretty e.patch else P.emptyDoc + <+> if patch + then P.hardline <> P.render e.patch + else P.emptyDoc ) es' ) diff --git a/app/Patch.hs b/app/Patch.hs new file mode 100644 index 0000000..f1c547a --- /dev/null +++ b/app/Patch.hs @@ -0,0 +1,37 @@ +module Patch + ( Patch, + parse, + render, + ) +where + +import Control.Exception (throw) +import Data.Text qualified as T +import Exception qualified as E +import Prettyprinter (pretty) +import Prettyprinter qualified as P +import Prettyprinter.Render.Terminal qualified as P +import Text.Diff.Parse qualified as D +import Text.Diff.Parse.Types qualified as D + +newtype Patch = Patch + { fileDeltas :: D.FileDeltas + } + deriving (Show) + +parse :: T.Text -> Patch +parse = either (throw . E.InvalidDiff) Patch . D.parseDiff + +render :: Patch -> P.Doc P.AnsiStyle +render (Patch {..}) = + P.vsep $ map prettyFileDelta fileDeltas + where + prettyFileDelta (D.FileDelta {..}) = prettyContent fileDeltaContent + prettyContent D.Binary = P.emptyDoc + prettyContent (D.Hunks hunks) = P.vsep (map prettyHunk hunks) + prettyHunk (D.Hunk {..}) = P.vsep $ map prettyLine hunkLines + prettyLine (D.Line {..}) = + case lineAnnotation of + D.Added -> P.annotate (P.color P.Green) $ P.pretty ("+" :: T.Text) <> pretty lineContent + D.Removed -> P.annotate (P.color P.Red) $ P.pretty ("-" :: T.Text) <> pretty lineContent + D.Context -> P.annotate (P.color P.White) $ P.pretty (" " :: T.Text) <> pretty lineContent |