Skip to content

Commit

Permalink
Add --context flag (#81)
Browse files Browse the repository at this point in the history
This limits the context to the specified number of
characters/words/lines

Fixes #42
Fixes #80
  • Loading branch information
Gabriella439 authored Mar 2, 2024
1 parent 872cac9 commit 126fb40
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 23 deletions.
31 changes: 21 additions & 10 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@

module Main where

import Control.Applicative ((<|>))
import Control.Applicative ((<|>), optional)
import Data.Text (Text)
import Options.Applicative (Parser, ParserInfo)
import Numeric.Natural (Natural)

import qualified Control.Monad.Reader
import qualified Control.Monad.State
import qualified Data.Aeson
import qualified Data.ByteString.Lazy.Char8
import qualified Data.Set
import qualified Data.Text.IO as Text.IO
import qualified GHC.IO.Encoding
import qualified Options.Applicative
import qualified System.Posix.IO
import qualified System.Posix.Terminal
import qualified Data.Aeson
import qualified Data.ByteString.Lazy.Char8
import qualified Data.Text.IO as Text.IO

import Nix.Diff
import Nix.Diff.Types
Expand Down Expand Up @@ -71,6 +72,14 @@ parseLineOriented =
<> Options.Applicative.help ("Display textual differences on a per-" <> x <> " basis")
)

parseContext :: Parser Natural
parseContext =
Options.Applicative.option
Options.Applicative.auto
( Options.Applicative.long "context"
<> Options.Applicative.help "Limit context to N lines/words/characters (depending on mode)"
)

parseEnvironment :: Parser Bool
parseEnvironment =
Options.Applicative.switch
Expand Down Expand Up @@ -115,17 +124,19 @@ data Options = Options
, environment :: Bool
, renderRunner :: RenderRunner
, transformOptions :: TransformOptions
, context :: Maybe Natural
}

parseOptions :: Parser Options
parseOptions = do
left <- parseLeft
right <- parseRight
color <- parseColor
orientation <- parseLineOriented
environment <- parseEnvironment
renderRunner <- parseRenderRunner
left <- parseLeft
right <- parseRight
color <- parseColor
orientation <- parseLineOriented
environment <- parseEnvironment
renderRunner <- parseRenderRunner
transformOptions <- parseTransformOptions
context <- optional parseContext

return (Options { .. })
where
Expand Down
10 changes: 1 addition & 9 deletions src/Nix/Diff.hs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,7 @@ getGroupedDiff oldList newList = go $ Patience.diff oldList newList
let (fs, rest) = goNews xs
in Patience.New (x : fs) : go rest
Patience.Both x y : xs ->
let (fs, rest) = goBoth xs
(fxs, fys) = unzip fs
in Patience.Both (x : fxs) (y : fys) : go rest
Patience.Both [x] [y] : go xs
[] -> []

goOlds = \case
Expand All @@ -196,12 +194,6 @@ getGroupedDiff oldList newList = go $ Patience.diff oldList newList
in (x : fs, rest)
xs -> ([], xs)

goBoth = \case
Patience.Both x y : xs ->
let (fs, rest) = goBoth xs
in ((x, y) : fs, rest)
xs -> ([], xs)

-- | Diff two outputs
diffOutput
:: Text
Expand Down
24 changes: 22 additions & 2 deletions src/Nix/Diff/Render/HumanReadable.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ data RenderContext = RenderContext
{ orientation :: Orientation
, tty :: TTY
, indent :: Natural
, context :: Maybe Natural
}

newtype Render a = Render { unRender :: ReaderT RenderContext (Writer Text) a}
Expand Down Expand Up @@ -253,7 +254,7 @@ renderDiffHumanReadable = \case

renderText :: TextDiff -> Render Text
renderText (TextDiff chunks) = do
RenderContext{ indent, orientation, tty } <- ask
RenderContext{ indent, orientation, tty, context } <- ask

let n = fromIntegral indent

Expand All @@ -276,6 +277,25 @@ renderDiffHumanReadable = \case
renderChunk (Patience.Both l _) =
grey orientation tty l

return (format (Text.concat (fmap renderChunk chunks)))
let windowedChunks = case context of
Nothing -> chunks
Just m -> fmap middle (filter predicate (zippers chunks))
where
notBoth (Patience.Both _ _) = False
notBoth _ = True

nat = fromIntegral m

predicate (before, line, after) =
any notBoth (line : take nat before ++ take nat after)

middle (_, line, _) = line
return (format (Text.concat (fmap renderChunk windowedChunks)))

ifExist m l = maybe (pure ()) l m

zippers :: [a] -> [([a], a, [a])]
zippers = go []
where
go _ [] = []
go prefix (x : xs) = (prefix, x, xs) : go (x : prefix) xs
2 changes: 1 addition & 1 deletion test/Golden/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ goldenTests simpleTd complexTd = testGroup "Golden tests"
where
toJson drv = (<> "\n") . decodeUtf8 . BS.toStrict $ (Data.Aeson.encode drv)

humanReadable_words = toHumanReadable (renderContext Word)
humanReadable_words = toHumanReadable (renderContext Word Nothing)
toHumanReadable ctx drv = runRender' (renderDiffHumanReadable drv) ctx

simple_env_words = mkDTSimple (diffContextEnv Word)
Expand Down
2 changes: 1 addition & 1 deletion test/Golden/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ nixInstantiate :: FilePath -> ProcessConfig () () ()
nixInstantiate fp = shell ("nix-instantiate " <> fp)

nixPathInfo :: FilePath -> ProcessConfig () () ()
nixPathInfo fp = shell ("nix path-info --experimental-features 'nix-command flakes' --derivation " <> fp)
nixPathInfo fp = shell ("nix path-info --experimental-features 'nix-command flakes' --derivation " <> fp <> "#packages.x86_64-linux.default")

makeDiffTree :: TestableDerivations -> DiffContext -> IO DerivationDiff
makeDiffTree TestableDerivations{..} diffContext = do
Expand Down

0 comments on commit 126fb40

Please sign in to comment.