-- Copyright (C) 2002-2003 David Roundy
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING.  If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-- Boston, MA 02110-1301, USA.

{-# LANGUAGE RecordWildCards #-}
module Darcs.UI.SelectChanges
    ( -- * Working with changes
      WhichChanges(..)
    , viewChanges
    , withSelectedPatchFromList
    , runSelection
    , runInvertibleSelection
    , selectionConfigPrim
    , selectionConfigGeneric
    , selectionConfig
    , SelectionConfig(allowSkipAll)
    -- * Interactive selection utils
    , PatchSelectionOptions(..)
    , InteractiveSelectionM
    , InteractiveSelectionState(..)
    , initialSelectionState
    -- ** Navigating the patchset
    , currentPatch
    , skipMundane
    , skipOne
    , backOne
    , backAll
    -- ** Decisions
    , decide
    , decideWholeFile
    -- ** Prompts and queries
    , isSingleFile
    , currentFile
    , promptUser
    , prompt
    , KeyPress(..)
    , keysFor
    , helpFor
    , askAboutDepends
    ) where

import Darcs.Prelude

import Control.Monad ( liftM, unless, when, (>=>) )
import Control.Monad.Identity ( Identity (..) )
import Control.Monad.Reader
    ( ReaderT
    , asks
    , runReaderT
    )
import Control.Monad.State
    ( StateT, execStateT, gets
    , modify, runStateT, state
    )
import Control.Monad.Trans ( liftIO )
import Data.List ( intercalate, union )
import Data.Maybe ( isJust )
import System.Exit ( exitSuccess )

import Darcs.Patch
    ( IsRepoType, RepoPatch, PrimOf
    , commuteFL, invert
    , listTouchedFiles
    )
import qualified Darcs.Patch ( thing, things )
import Darcs.Patch.Apply ( ApplyState )
import Darcs.Patch.Choices
    ( PatchChoices, Slot (..), LabelledPatch
    , forceFirst, forceLast, forceMatchingFirst
    , forceMatchingLast, getChoices
    , makeEverythingLater, makeEverythingSooner
    , forceMiddle, patchChoices
    , patchSlot
    , refineChoices, selectAllMiddles
    , separateFirstFromMiddleLast
    , substitute, label, unLabel
    , labelPatches
    )
import Darcs.Patch.Commute ( Commute )
import Darcs.Patch.Depends ( contextPatches )
import Darcs.Patch.Ident ( Ident(..), PatchId )
import Darcs.Patch.Info ( PatchInfo )
import Darcs.Patch.Inspect ( PatchInspect )
import Darcs.Patch.Invert ( Invert )
import Darcs.Patch.Invertible
import Darcs.Patch.Match
    ( Matchable
    , MatchableRP
    , haveNonrangeMatch
    , matchAPatch
    )
import Darcs.Patch.Named ( adddeps, anonymous )
import Darcs.Patch.PatchInfoAnd ( n2pia )
import Darcs.Patch.Permutations ( commuteWhatWeCanRL )
import Darcs.Patch.Show ( ShowPatch, ShowContextPatch )
import Darcs.Patch.Split ( Splitter(..) )
import Darcs.Patch.TouchesFiles ( selectNotTouching, deselectNotTouching )
import Darcs.Patch.Witnesses.Ordered
    ( (:>) (..), (:||:) (..), FL (..)
    , RL (..), filterFL, lengthFL, mapFL
    , mapFL_FL, spanFL, spanFL_M
    , (+>+), (+<<+)
    , reverseFL, reverseRL
    )
import Darcs.Patch.Witnesses.Sealed
    ( FlippedSeal (..), Sealed2 (..)
    , flipSeal, seal2, unseal2
    )
import Darcs.Patch.Witnesses.WZipper
    ( FZipper (..), focus, jokers, left, right
    , rightmost, toEnd, toStart
    )
import Darcs.Repository ( Repository, repoLocation, readTentativeRepo )
import Darcs.UI.External ( editText )
import Darcs.UI.Options.All
    ( Verbosity(..), WithSummary(..)
    , WithContext(..), SelectDeps(..), MatchFlag )
import Darcs.UI.PrintPatch
    ( printContent
    , printContentWithPager
    , printFriendly
    , printSummary
    , showFriendly
    )
import Darcs.Util.English ( Noun (..), englishNum, capitalize )
import Darcs.Util.Path ( AnchoredPath )
import Darcs.Util.Printer ( putDocLnWith, greenText, vcat )
import Darcs.Util.Printer.Color ( fancyPrinters )
import Darcs.Util.Prompt ( PromptConfig (..), askUser, promptChar )
import Darcs.Util.Tree ( Tree )


-- | When asking about patches, we either ask about them in
-- oldest-first or newest first (with respect to the current ordering
-- of the repository), and we either want an initial segment or a
-- final segment of the poset of patches.
--
-- 'First': ask for an initial
-- segment, first patches first (default for all pull-like commands)
--
-- 'FirstReversed': ask for an initial segment, last patches first
-- (used to ask about dependencies in record, and for pull-like
-- commands with the @--reverse@ flag).
--
-- 'LastReversed': ask for a final segment, last patches first. (default
-- for unpull-like commands, except for selecting *primitive* patches in
-- rollback)
--
-- 'Last': ask for a final segment, first patches first. (used for selecting
-- primitive patches in rollback, and for unpull-like commands with the
-- @--reverse@ flag
--
-- IOW: First = initial segment
--      Last = final segment
--      Reversed = start with the newest patch instead of oldest
-- As usual, terminology is not, ahem, very intuitive.
data WhichChanges = Last | LastReversed | First | FirstReversed deriving (WhichChanges -> WhichChanges -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WhichChanges -> WhichChanges -> Bool
$c/= :: WhichChanges -> WhichChanges -> Bool
== :: WhichChanges -> WhichChanges -> Bool
$c== :: WhichChanges -> WhichChanges -> Bool
Eq, Int -> WhichChanges -> ShowS
[WhichChanges] -> ShowS
WhichChanges -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WhichChanges] -> ShowS
$cshowList :: [WhichChanges] -> ShowS
show :: WhichChanges -> String
$cshow :: WhichChanges -> String
showsPrec :: Int -> WhichChanges -> ShowS
$cshowsPrec :: Int -> WhichChanges -> ShowS
Show)

-- | A 'WhichChanges' is 'backward' if the segment of patches we ask for
-- is at the opposite end of where we start to present them.
backward :: WhichChanges -> Bool
backward :: WhichChanges -> Bool
backward WhichChanges
w = WhichChanges
w forall a. Eq a => a -> a -> Bool
== WhichChanges
Last Bool -> Bool -> Bool
|| WhichChanges
w forall a. Eq a => a -> a -> Bool
== WhichChanges
FirstReversed

-- | A 'WhichChanges' is reversed if the order in which patches are presented
-- is latest (or newest) patch first.
reversed :: WhichChanges -> Bool
reversed :: WhichChanges -> Bool
reversed WhichChanges
w = WhichChanges
w forall a. Eq a => a -> a -> Bool
== WhichChanges
LastReversed Bool -> Bool -> Bool
|| WhichChanges
w forall a. Eq a => a -> a -> Bool
== WhichChanges
FirstReversed

-- | The type of the function we use to filter patches when @--match@ is
-- given.
data MatchCriterion p = MatchCriterion
   { forall (p :: * -> * -> *). MatchCriterion p -> Bool
mcHasNonrange :: Bool
   , forall (p :: * -> * -> *).
MatchCriterion p -> forall wA wB. p wA wB -> Bool
mcFunction :: forall wA wB. p wA wB -> Bool
   }

data PatchSelectionOptions = PatchSelectionOptions
  { PatchSelectionOptions -> Verbosity
verbosity :: Verbosity
  , PatchSelectionOptions -> [MatchFlag]
matchFlags :: [MatchFlag]
  , PatchSelectionOptions -> Bool
interactive :: Bool
  , PatchSelectionOptions -> SelectDeps
selectDeps :: SelectDeps
  , PatchSelectionOptions -> WithSummary
withSummary :: WithSummary
  , PatchSelectionOptions -> WithContext
withContext :: WithContext
  }

-- | All the static settings for selecting patches.
data SelectionConfig p =
  PSC { forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
opts :: PatchSelectionOptions
      , forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Splitter p)
splitter :: Maybe (Splitter p)
      , forall (p :: * -> * -> *).
SelectionConfig p -> Maybe [AnchoredPath]
files :: Maybe [AnchoredPath]
      , forall (p :: * -> * -> *). SelectionConfig p -> MatchCriterion p
matchCriterion :: MatchCriterion p
      , forall (p :: * -> * -> *). SelectionConfig p -> String
jobname :: String
      , forall (p :: * -> * -> *). SelectionConfig p -> Bool
allowSkipAll :: Bool
      , forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Tree IO)
pristine :: Maybe (Tree IO)
      , forall (p :: * -> * -> *). SelectionConfig p -> WhichChanges
whichChanges :: WhichChanges
      }

-- | A 'SelectionConfig' for selecting 'Prim' patches.
selectionConfigPrim :: WhichChanges
                    -> String
                    -> PatchSelectionOptions
                    -> Maybe (Splitter prim)
                    -> Maybe [AnchoredPath]
                    -> Maybe (Tree IO)
                    -> SelectionConfig prim
selectionConfigPrim :: forall (prim :: * -> * -> *).
WhichChanges
-> String
-> PatchSelectionOptions
-> Maybe (Splitter prim)
-> Maybe [AnchoredPath]
-> Maybe (Tree IO)
-> SelectionConfig prim
selectionConfigPrim WhichChanges
whch String
jn PatchSelectionOptions
o Maybe (Splitter prim)
spl Maybe [AnchoredPath]
fs Maybe (Tree IO)
p =
 PSC { opts :: PatchSelectionOptions
opts = PatchSelectionOptions
o
     , splitter :: Maybe (Splitter prim)
splitter = Maybe (Splitter prim)
spl
     , files :: Maybe [AnchoredPath]
files = Maybe [AnchoredPath]
fs
     , matchCriterion :: MatchCriterion prim
matchCriterion = forall (p :: * -> * -> *). MatchCriterion p
triv
     , jobname :: String
jobname = String
jn
     , allowSkipAll :: Bool
allowSkipAll = Bool
True
     , pristine :: Maybe (Tree IO)
pristine = Maybe (Tree IO)
p
     , whichChanges :: WhichChanges
whichChanges = WhichChanges
whch
     }

-- | A 'SelectionConfig' for selecting full ('Matchable') patches
selectionConfig :: Matchable p
                 => WhichChanges
                 -> String
                 -> PatchSelectionOptions
                 -> Maybe (Splitter p)
                 -> Maybe [AnchoredPath]
                 -> SelectionConfig p
selectionConfig :: forall (p :: * -> * -> *).
Matchable p =>
WhichChanges
-> String
-> PatchSelectionOptions
-> Maybe (Splitter p)
-> Maybe [AnchoredPath]
-> SelectionConfig p
selectionConfig WhichChanges
whch String
jn PatchSelectionOptions
o Maybe (Splitter p)
spl Maybe [AnchoredPath]
fs =
 PSC { opts :: PatchSelectionOptions
opts = PatchSelectionOptions
o
     , splitter :: Maybe (Splitter p)
splitter = Maybe (Splitter p)
spl
     , files :: Maybe [AnchoredPath]
files = Maybe [AnchoredPath]
fs
     , matchCriterion :: MatchCriterion p
matchCriterion = forall (p :: * -> * -> *) (q :: * -> * -> *).
Matchable p =>
(forall wX wY. q wX wY -> Sealed2 p)
-> [MatchFlag] -> MatchCriterion q
iswanted forall (a :: * -> * -> *) wX wY. a wX wY -> Sealed2 a
seal2 (PatchSelectionOptions -> [MatchFlag]
matchFlags PatchSelectionOptions
o)
     , jobname :: String
jobname = String
jn
     , allowSkipAll :: Bool
allowSkipAll = Bool
True
     , pristine :: Maybe (Tree IO)
pristine = forall a. Maybe a
Nothing
     , whichChanges :: WhichChanges
whichChanges = WhichChanges
whch
     }

-- | A generic 'SelectionConfig'.
selectionConfigGeneric :: Matchable p
                       => (forall wX wY . q wX wY -> Sealed2 p)
                       -> WhichChanges
                       -> String
                       -> PatchSelectionOptions
                       -> Maybe [AnchoredPath]
                       -> SelectionConfig q
selectionConfigGeneric :: forall (p :: * -> * -> *) (q :: * -> * -> *).
Matchable p =>
(forall wX wY. q wX wY -> Sealed2 p)
-> WhichChanges
-> String
-> PatchSelectionOptions
-> Maybe [AnchoredPath]
-> SelectionConfig q
selectionConfigGeneric forall wX wY. q wX wY -> Sealed2 p
extract WhichChanges
whch String
jn PatchSelectionOptions
o Maybe [AnchoredPath]
fs =
 PSC { opts :: PatchSelectionOptions
opts = PatchSelectionOptions
o
     , splitter :: Maybe (Splitter q)
splitter = forall a. Maybe a
Nothing
     , files :: Maybe [AnchoredPath]
files = Maybe [AnchoredPath]
fs
     , matchCriterion :: MatchCriterion q
matchCriterion = forall (p :: * -> * -> *) (q :: * -> * -> *).
Matchable p =>
(forall wX wY. q wX wY -> Sealed2 p)
-> [MatchFlag] -> MatchCriterion q
iswanted forall wX wY. q wX wY -> Sealed2 p
extract (PatchSelectionOptions -> [MatchFlag]
matchFlags PatchSelectionOptions
o)
     , jobname :: String
jobname = String
jn
     , allowSkipAll :: Bool
allowSkipAll = Bool
True
     , pristine :: Maybe (Tree IO)
pristine = forall a. Maybe a
Nothing
     , whichChanges :: WhichChanges
whichChanges = WhichChanges
whch
     }

-- | The dynamic parameters for interactive selection of patches.
data InteractiveSelectionState p wX wY =
 ISC { forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
total :: Int                           -- ^ total number of patches
     , forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
current :: Int                         -- ^ number of already-seen patches
     , forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps :: FZipper (LabelledPatch p) wX wY -- ^ the patches we offer
     , forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices :: PatchChoices p wX wY        -- ^ the user's choices
     }

type PatchSelectionM p a = ReaderT (SelectionConfig p) a

type InteractiveSelectionM p wX wY a =
    StateT (InteractiveSelectionState p wX wY)
           (PatchSelectionM p IO) a

-- Common match criteria

-- | For commands without @--match@, 'triv' matches all patches
triv :: MatchCriterion p
triv :: forall (p :: * -> * -> *). MatchCriterion p
triv = MatchCriterion { mcHasNonrange :: Bool
mcHasNonrange = Bool
False, mcFunction :: forall wA wB. p wA wB -> Bool
mcFunction = \ p wA wB
_ -> Bool
True }

-- | 'iswanted' selects patches according to the given match flags
iswanted :: Matchable p
         => (forall wX wY . q wX wY -> Sealed2 p)
         -> [MatchFlag]
         -> MatchCriterion q
iswanted :: forall (p :: * -> * -> *) (q :: * -> * -> *).
Matchable p =>
(forall wX wY. q wX wY -> Sealed2 p)
-> [MatchFlag] -> MatchCriterion q
iswanted forall wX wY. q wX wY -> Sealed2 p
extract [MatchFlag]
mflags = MatchCriterion
    { mcHasNonrange :: Bool
mcHasNonrange = [MatchFlag] -> Bool
haveNonrangeMatch [MatchFlag]
mflags
    , mcFunction :: forall wA wB. q wA wB -> Bool
mcFunction = forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 (forall (p :: * -> * -> *) wX wY.
Matchable p =>
[MatchFlag] -> p wX wY -> Bool
matchAPatch [MatchFlag]
mflags) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall wX wY. q wX wY -> Sealed2 p
extract
    }

-- | Run a 'PatchSelection' action in the given 'SelectionConfig',
-- without assuming that patches are invertible.
runSelection :: ( MatchableRP p, ShowPatch p, ShowContextPatch p
                , ApplyState p ~ Tree, ApplyState p ~ ApplyState (PrimOf p)
                )
             => FL p wX wY
             -> SelectionConfig p
             -> IO ((FL p :> FL p) wX wY)
runSelection :: forall (p :: * -> * -> *) wX wY.
(MatchableRP p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree, ApplyState p ~ ApplyState (PrimOf p)) =>
FL p wX wY -> SelectionConfig p -> IO ((:>) (FL p) (FL p) wX wY)
runSelection FL p wX wY
_ PSC { splitter :: forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Splitter p)
splitter = Just Splitter p
_ } =
  -- a Splitter makes sense for prim patches only and these are invertible anyway
  forall a. HasCallStack => String -> a
error String
"cannot use runSelection with Splitter"
runSelection FL p wX wY
ps PSC { matchCriterion :: forall (p :: * -> * -> *). SelectionConfig p -> MatchCriterion p
matchCriterion = MatchCriterion p
mc, Bool
String
Maybe [AnchoredPath]
Maybe (Tree IO)
Maybe (Splitter p)
PatchSelectionOptions
WhichChanges
whichChanges :: WhichChanges
pristine :: Maybe (Tree IO)
allowSkipAll :: Bool
jobname :: String
files :: Maybe [AnchoredPath]
splitter :: Maybe (Splitter p)
opts :: PatchSelectionOptions
whichChanges :: forall (p :: * -> * -> *). SelectionConfig p -> WhichChanges
pristine :: forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Tree IO)
jobname :: forall (p :: * -> * -> *). SelectionConfig p -> String
files :: forall (p :: * -> * -> *).
SelectionConfig p -> Maybe [AnchoredPath]
splitter :: forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Splitter p)
opts :: forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
allowSkipAll :: forall (p :: * -> * -> *). SelectionConfig p -> Bool
.. } = do
    forall {b :: * -> * -> *} {b :: * -> * -> *} {wX} {wY}.
(:>) (FL (Invertible b)) (FL (Invertible b)) wX wY
-> (:>) (FL b) (FL b) wX wY
unwrapOutput forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (p :: * -> * -> *) wX wY.
(Invert p, MatchableRP p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
FL p wX wY -> SelectionConfig p -> IO ((:>) (FL p) (FL p) wX wY)
runInvertibleSelection (forall {a :: * -> * -> *} {wX} {wZ}.
FL a wX wZ -> FL (Invertible a) wX wZ
wrapInput FL p wX wY
ps) SelectionConfig (Invertible p)
ictx
  where
    convertMC :: MatchCriterion p -> MatchCriterion (Invertible p)
    convertMC :: forall (p :: * -> * -> *).
MatchCriterion p -> MatchCriterion (Invertible p)
convertMC MatchCriterion { mcFunction :: forall (p :: * -> * -> *).
MatchCriterion p -> forall wA wB. p wA wB -> Bool
mcFunction = forall wA wB. p wA wB -> Bool
mcf, Bool
mcHasNonrange :: Bool
mcHasNonrange :: forall (p :: * -> * -> *). MatchCriterion p -> Bool
.. } =
      MatchCriterion { mcFunction :: forall wA wB. Invertible p wA wB -> Bool
mcFunction = forall (p :: * -> * -> *) r wX wY.
(forall wA wB. p wA wB -> r) -> Invertible p wX wY -> r
withInvertible forall wA wB. p wA wB -> Bool
mcf, Bool
mcHasNonrange :: Bool
mcHasNonrange :: Bool
.. }
    ictx :: SelectionConfig (Invertible p)
ictx = PSC { matchCriterion :: MatchCriterion (Invertible p)
matchCriterion = forall (p :: * -> * -> *).
MatchCriterion p -> MatchCriterion (Invertible p)
convertMC MatchCriterion p
mc, splitter :: Maybe (Splitter (Invertible p))
splitter = forall a. Maybe a
Nothing, Bool
String
Maybe [AnchoredPath]
Maybe (Tree IO)
PatchSelectionOptions
WhichChanges
whichChanges :: WhichChanges
pristine :: Maybe (Tree IO)
allowSkipAll :: Bool
jobname :: String
files :: Maybe [AnchoredPath]
opts :: PatchSelectionOptions
whichChanges :: WhichChanges
pristine :: Maybe (Tree IO)
jobname :: String
files :: Maybe [AnchoredPath]
opts :: PatchSelectionOptions
allowSkipAll :: Bool
.. }
    wrapInput :: FL a wX wZ -> FL (Invertible a) wX wZ
wrapInput = forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. p wX wY -> Invertible p wX wY
mkInvertible
    unwrapOutput :: (:>) (FL (Invertible b)) (FL (Invertible b)) wX wY
-> (:>) (FL b) (FL b) wX wY
unwrapOutput (FL (Invertible b) wX wZ
xs :> FL (Invertible b) wZ wY
ys) =
      forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. Invertible p wX wY -> p wX wY
fromPositiveInvertible FL (Invertible b) wX wZ
xs forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. Invertible p wX wY -> p wX wY
fromPositiveInvertible FL (Invertible b) wZ wY
ys

-- | Run a 'PatchSelection' action in the given 'SelectionConfig',
-- assuming patches are invertible.
runInvertibleSelection :: forall p wX wY .
                          ( Invert p, MatchableRP p, ShowPatch p
                          , ShowContextPatch p, ApplyState p ~ Tree
                          )
                       => FL p wX wY
                       -> SelectionConfig p
                       -> IO ((FL p :> FL p) wX wY)
runInvertibleSelection :: forall (p :: * -> * -> *) wX wY.
(Invert p, MatchableRP p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
FL p wX wY -> SelectionConfig p -> IO ((:>) (FL p) (FL p) wX wY)
runInvertibleSelection FL p wX wY
ps SelectionConfig p
psc = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall {wY} {wX}.
FL p wY wX
-> ReaderT (SelectionConfig p) IO ((:>) (FL p) (FL p) wY wX)
selection FL p wX wY
ps) SelectionConfig p
psc where
  selection :: FL p wY wX
-> ReaderT (SelectionConfig p) IO ((:>) (FL p) (FL p) wY wX)
selection
    | WhichChanges -> Bool
reversed WhichChanges
whch = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wY} {wX}.
FL p wY wX
-> ReaderT (SelectionConfig p) IO ((:>) (FL p) (FL p) wY wX)
doit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert
    | Bool
otherwise = forall {wY} {wX}.
FL p wY wX
-> ReaderT (SelectionConfig p) IO ((:>) (FL p) (FL p) wY wX)
doit
  -- efficiency note: we should first filterUnwanted to apply matchers,
  -- as this often requires to read only metadata; then filterNotTouching
  -- applies path restrictions which needs to read patch contents
  doit :: FL p wA wB
-> ReaderT (SelectionConfig p) IO ((:>) (FL p) (FL p) wA wB)
doit =
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall wA wB. (:>) (FL p) (FL p) wA wB -> (:>) (FL p) (FL p) wA wB
canonizeAfterSplitter forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall wA wB. PatchChoices p wA wB -> (:>) (FL p) (FL p) wA wB
selectedPatches) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    forall wA wB.
PatchChoices p wA wB -> PatchSelectionM p IO (PatchChoices p wA wB)
selectChanges forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
filterNotTouching forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
filterUnwanted forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY. FL p wX wY -> PatchChoices p wX wY
patchChoices

  -- configuration
  whch :: WhichChanges
whch = forall (p :: * -> * -> *). SelectionConfig p -> WhichChanges
whichChanges SelectionConfig p
psc
  fs :: Maybe [AnchoredPath]
fs = forall (p :: * -> * -> *).
SelectionConfig p -> Maybe [AnchoredPath]
files SelectionConfig p
psc
  os :: PatchSelectionOptions
os = forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
opts SelectionConfig p
psc
  crit :: MatchCriterion p
crit = forall (p :: * -> * -> *). SelectionConfig p -> MatchCriterion p
matchCriterion SelectionConfig p
psc
  mspl :: Maybe (Splitter p)
mspl = forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Splitter p)
splitter SelectionConfig p
psc

  -- after selecting with a splitter, the results may not be canonical
  canonizeAfterSplitter :: (FL p :> FL p) wA wB -> (FL p :> FL p) wA wB
  canonizeAfterSplitter :: forall wA wB. (:>) (FL p) (FL p) wA wB -> (:>) (FL p) (FL p) wA wB
canonizeAfterSplitter (FL p wA wZ
x :> FL p wZ wB
y) =
    let
      canonizeIfNeeded :: FL p wX wY -> FL p wX wY
canonizeIfNeeded =
        case Maybe (Splitter p)
mspl of
          Just Splitter p
s -> forall (p :: * -> * -> *).
Splitter p -> forall wX wY. FL p wX wY -> FL p wX wY
canonizeSplit Splitter p
s
          Maybe (Splitter p)
Nothing -> forall a. a -> a
id
    in forall {wX} {wY}. FL p wX wY -> FL p wX wY
canonizeIfNeeded FL p wA wZ
x forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall {wX} {wY}. FL p wX wY -> FL p wX wY
canonizeIfNeeded FL p wZ wB
y

  -- retrieve the results of patch selection
  selectedPatches :: PatchChoices p wA wB -> (FL p :> FL p) wA wB
  selectedPatches :: forall wA wB. PatchChoices p wA wB -> (:>) (FL p) (FL p) wA wB
selectedPatches PatchChoices p wA wB
pc
    | WhichChanges -> Bool
backward WhichChanges
whch =
        case forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices p wX wY
-> (:>)
     (FL (LabelledPatch p))
     (FL (LabelledPatch p) :> FL (LabelledPatch p))
     wX
     wY
getChoices PatchChoices p wA wB
pc of
          FL (LabelledPatch p) wA wZ
fc :> FL (LabelledPatch p) wZ wZ
mc :> FL (LabelledPatch p) wZ wB
lc -> forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel (FL (LabelledPatch p) wA wZ
fc forall (a :: * -> * -> *) wX wY wZ.
FL a wX wY -> FL a wY wZ -> FL a wX wZ
+>+ FL (LabelledPatch p) wZ wZ
mc) forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel FL (LabelledPatch p) wZ wB
lc
    | Bool
otherwise =
        case forall (p :: * -> * -> *) wX wZ.
PatchChoices p wX wZ
-> (:>) (FL (LabelledPatch p)) (FL (LabelledPatch p)) wX wZ
separateFirstFromMiddleLast PatchChoices p wA wB
pc of
          FL (LabelledPatch p) wA wZ
xs :> FL (LabelledPatch p) wZ wB
ys -> forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel FL (LabelledPatch p) wA wZ
xs forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel FL (LabelledPatch p) wZ wB
ys

  selectChanges :: PatchChoices p wA wB
                -> PatchSelectionM p IO (PatchChoices p wA wB)
  selectChanges :: forall wA wB.
PatchChoices p wA wB -> PatchSelectionM p IO (PatchChoices p wA wB)
selectChanges
    | PatchSelectionOptions -> Bool
interactive PatchSelectionOptions
os = forall (p :: * -> * -> *) (m :: * -> *) wX wY.
(Commute p, Monad m) =>
(forall wU wV.
 FL (LabelledPatch p) wU wV
 -> PatchChoices p wU wV -> m (PatchChoices p wU wV))
-> PatchChoices p wX wY -> m (PatchChoices p wX wY)
refineChoices forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, ShowPatch p, ShowContextPatch p,
 PatchInspect p, ApplyState p ~ Tree) =>
FL (LabelledPatch p) wX wY
-> PatchChoices p wX wY
-> PatchSelectionM p IO (PatchChoices p wX wY)
textSelect
    | Bool
otherwise      = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
promote

  promote :: PatchChoices p wX wY -> PatchChoices p wX wY
promote
    | WhichChanges -> Bool
backward WhichChanges
whch = forall (p :: * -> * -> *) wX wY.
PatchChoices p wX wY -> PatchChoices p wX wY
makeEverythingLater
    | Bool
otherwise     = forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices p wX wY -> PatchChoices p wX wY
makeEverythingSooner
  demote :: PatchChoices p wX wY -> PatchChoices p wX wY
demote
    | WhichChanges -> Bool
backward WhichChanges
whch = forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices p wX wY -> PatchChoices p wX wY
makeEverythingSooner
    | Bool
otherwise     = forall (p :: * -> * -> *) wX wY.
PatchChoices p wX wY -> PatchChoices p wX wY
makeEverythingLater

  filterNotTouching :: PatchChoices p wX wY -> PatchChoices p wX wY
filterNotTouching
    | WhichChanges -> Bool
backward WhichChanges
whch = forall (p :: * -> * -> *) wX wY.
(Apply p, Commute p, PatchInspect p, ApplyState p ~ Tree) =>
Maybe [AnchoredPath]
-> PatchChoices p wX wY -> PatchChoices p wX wY
selectNotTouching Maybe [AnchoredPath]
fs
    | Bool
otherwise     = forall (p :: * -> * -> *) wX wY.
(Apply p, Commute p, PatchInspect p, ApplyState p ~ Tree) =>
Maybe [AnchoredPath]
-> PatchChoices p wX wY -> PatchChoices p wX wY
deselectNotTouching Maybe [AnchoredPath]
fs

  -- when using @--match@, remove unmatched patches
  -- not depended upon by matched patches
  filterUnwanted :: PatchChoices p wA wB -> PatchChoices p wA wB
  filterUnwanted :: forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
filterUnwanted
    | forall (p :: * -> * -> *). MatchCriterion p -> Bool
mcHasNonrange MatchCriterion p
crit =
        case PatchSelectionOptions -> SelectDeps
selectDeps PatchSelectionOptions
os of
          SelectDeps
NoDeps -> forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
deselectUnwanted
          SelectDeps
_      -> forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
demote forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wX} {wY}. PatchChoices p wX wY -> PatchChoices p wX wY
selectWanted
    | Bool
otherwise = forall a. a -> a
id

  selectWanted :: PatchChoices p wA wB -> PatchChoices p wA wB
selectWanted
    | WhichChanges -> Bool
backward WhichChanges
whch = forall (p :: * -> * -> *) wA wB.
Commute p =>
(forall wX wY. LabelledPatch p wX wY -> Bool)
-> PatchChoices p wA wB -> PatchChoices p wA wB
forceMatchingLast forall {wA} {wB}. LabelledPatch p wA wB -> Bool
iswanted_
    | Bool
otherwise     = forall (p :: * -> * -> *) wA wB.
Commute p =>
(forall wX wY. LabelledPatch p wX wY -> Bool)
-> PatchChoices p wA wB -> PatchChoices p wA wB
forceMatchingFirst forall {wA} {wB}. LabelledPatch p wA wB -> Bool
iswanted_
  deselectUnwanted :: PatchChoices p wA wB -> PatchChoices p wA wB
deselectUnwanted
    | WhichChanges -> Bool
backward WhichChanges
whch = forall (p :: * -> * -> *) wA wB.
Commute p =>
(forall wX wY. LabelledPatch p wX wY -> Bool)
-> PatchChoices p wA wB -> PatchChoices p wA wB
forceMatchingFirst (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wA} {wB}. LabelledPatch p wA wB -> Bool
iswanted_)
    | Bool
otherwise     = forall (p :: * -> * -> *) wA wB.
Commute p =>
(forall wX wY. LabelledPatch p wX wY -> Bool)
-> PatchChoices p wA wB -> PatchChoices p wA wB
forceMatchingLast (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {wA} {wB}. LabelledPatch p wA wB -> Bool
iswanted_)
  iswanted_ :: LabelledPatch p wA wB -> Bool
iswanted_ = forall (p :: * -> * -> *).
MatchCriterion p -> forall wA wB. p wA wB -> Bool
mcFunction MatchCriterion p
crit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel

  {- end of runInvertibleSelection -}

-- | The equivalent of 'runSelection' for the @darcs log@ command
viewChanges :: (ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree)
            => PatchSelectionOptions -> [Sealed2 p] -> IO ()
viewChanges :: forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions -> [Sealed2 p] -> IO ()
viewChanges PatchSelectionOptions
ps_opts = forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
ps_opts forall a. Maybe a
Nothing Int
0 []

-- | The type of the answers to a "shall I [wiggle] that [foo]?" question
-- They are found in a [[KeyPress]] bunch, each list representing a set of
-- answers which belong together
data KeyPress = KeyPress { KeyPress -> Char
kp     :: Char
                           , KeyPress -> String
kpHelp :: String }

-- | Generates the help for a set of basic and advanced 'KeyPress' groups.
helpFor :: String -> [[KeyPress]] -> [[KeyPress]] -> String
helpFor :: String -> [[KeyPress]] -> [[KeyPress]] -> String
helpFor String
jn [[KeyPress]]
basicKeypresses [[KeyPress]]
advancedKeyPresses =
  [String] -> String
unlines forall a b. (a -> b) -> a -> b
$ [ String
"How to use "forall a. [a] -> [a] -> [a]
++String
jnforall a. [a] -> [a] -> [a]
++String
":" ]
            forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate [String
""] (forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map KeyPress -> String
help) [[KeyPress]]
keypresses)
            forall a. [a] -> [a] -> [a]
++ [ String
""
               , String
"?: show this help"
               , String
""
               , String
"<Space>: accept the current default (which is capitalized)"
               ]
  where help :: KeyPress -> String
help KeyPress
i = KeyPress -> Char
kp KeyPress
iforall a. a -> [a] -> [a]
:(String
": "forall a. [a] -> [a] -> [a]
++KeyPress -> String
kpHelp KeyPress
i)
        keypresses :: [[KeyPress]]
keypresses = [[KeyPress]]
basicKeypresses forall a. [a] -> [a] -> [a]
++ [[KeyPress]]
advancedKeyPresses

-- | The keys used by a list of 'keyPress' groups.
keysFor :: [[KeyPress]] -> [Char]
keysFor :: [[KeyPress]] -> String
keysFor = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall a b. (a -> b) -> [a] -> [b]
map KeyPress -> Char
kp)

-- | The function for selecting a patch to amend record. Read at your own risks.
withSelectedPatchFromList
    :: (Commute p, Matchable p, ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree)
    => String   -- name of calling command (always "amend" as of now)
    -> RL p wO wR
    -> PatchSelectionOptions
    -> (forall wA . (FL p :> p) wA wR -> IO ())
    -> IO ()
withSelectedPatchFromList :: forall (p :: * -> * -> *) wO wR.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> RL p wO wR
-> PatchSelectionOptions
-> (forall wA. (:>) (FL p) p wA wR -> IO ())
-> IO ()
withSelectedPatchFromList String
jn RL p wO wR
patches PatchSelectionOptions
o forall wA. (:>) (FL p) p wA wR -> IO ()
job = do
    Maybe (FlippedSeal (FL p :> p) wR)
sp <- forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
jn (forall (p :: * -> * -> *) wX wY.
Matchable p =>
[MatchFlag] -> p wX wY -> Bool
matchAPatch forall a b. (a -> b) -> a -> b
$ PatchSelectionOptions -> [MatchFlag]
matchFlags PatchSelectionOptions
o) RL p wO wR
patches forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
    case Maybe (FlippedSeal (FL p :> p) wR)
sp of
        Just (FlippedSeal (FL p wX wZ
skipped :> p wZ wR
selected')) -> forall wA. (:>) (FL p) p wA wR -> IO ()
job (FL p wX wZ
skipped forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> p wZ wR
selected')
        Maybe (FlippedSeal (FL p :> p) wR)
Nothing ->
            String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"Cancelling " forall a. [a] -> [a] -> [a]
++ String
jn forall a. [a] -> [a] -> [a]
++ String
" since no patch was selected."

data SkippedReason = SkippedAutomatically | SkippedManually

data WithSkipped p wX wY = WithSkipped
    { forall (p :: * -> * -> *) wX wY.
WithSkipped p wX wY -> SkippedReason
_skippedReason :: SkippedReason
    , forall (p :: * -> * -> *) wX wY. WithSkipped p wX wY -> p wX wY
skippedPatch :: p wX wY
    }

-- | This ensures that the selected patch commutes freely with the skipped
-- patches, including pending and also that the skipped sequences has an
-- ending context that matches the recorded state, z, of the repository.
wspfr :: forall p wX wY wU.
         (Commute p, Matchable p, ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree)
      => String
      -> (forall wA wB . p wA wB -> Bool)
      -> RL p wX wY
      -> FL (WithSkipped p) wY wU
      -> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr :: forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
_ forall wA wB. p wA wB -> Bool
_ RL p wX wY
NilRL FL (WithSkipped p) wY wU
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
wspfr String
jn forall wA wB. p wA wB -> Bool
matches remaining :: RL p wX wY
remaining@(RL p wX wY
pps:<:p wY wY
p) FL (WithSkipped p) wY wU
skipped
    | Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall wA wB. p wA wB -> Bool
matches p wY wY
p = forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
jn forall wA wB. p wA wB -> Bool
matches RL p wX wY
pps
                            (forall (p :: * -> * -> *) wX wY.
SkippedReason -> p wX wY -> WithSkipped p wX wY
WithSkipped SkippedReason
SkippedAutomatically p wY wY
p forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (WithSkipped p) wY wU
skipped)
    | Bool
otherwise =
    case forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p (FL p) wX wY -> Maybe ((:>) (FL p) p wX wY)
commuteFL (p wY wY
p forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY. WithSkipped p wX wY -> p wX wY
skippedPatch FL (WithSkipped p) wY wU
skipped) of
    Maybe ((:>) (FL p) p wY wU)
Nothing -> do String -> IO ()
putStrLn String
"\nSkipping depended-upon patch:"
                  forall {wX} {wY}. p wX wY -> IO ()
defaultPrintFriendly p wY wY
p
                  forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
jn forall wA wB. p wA wB -> Bool
matches RL p wX wY
pps (forall (p :: * -> * -> *) wX wY.
SkippedReason -> p wX wY -> WithSkipped p wX wY
WithSkipped SkippedReason
SkippedAutomatically p wY wY
p forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (WithSkipped p) wY wU
skipped)

    Just (FL p wY wZ
skipped' :> p wZ wU
p') -> do
        forall {wX} {wY}. p wX wY -> IO ()
defaultPrintFriendly p wY wY
p
        let repeatThis :: IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis = do
              Char
yorn <- PromptConfig -> IO Char
promptChar
                    PromptConfig { pPrompt :: String
pPrompt = String
prompt'
                                 , pBasicCharacters :: String
pBasicCharacters = [[KeyPress]] -> String
keysFor [[KeyPress]]
basicOptions
                                 , pAdvancedCharacters :: String
pAdvancedCharacters = [[KeyPress]] -> String
keysFor [[KeyPress]]
advancedOptions
                                 , pDefault :: Maybe Char
pDefault = forall a. a -> Maybe a
Just Char
'n'
                                 , pHelp :: String
pHelp = String
"?h" }
              case Char
yorn of
                Char
'y' -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wY. a wX wY -> FlippedSeal a wY
flipSeal forall a b. (a -> b) -> a -> b
$ FL p wY wZ
skipped' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> p wZ wU
p'
                Char
'n' -> IO (Maybe (FlippedSeal (FL p :> p) wU))
nextPatch
                Char
'j' -> IO (Maybe (FlippedSeal (FL p :> p) wU))
nextPatch
                Char
'k' -> forall wQ.
RL p wX wQ
-> FL (WithSkipped p) wQ wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
previousPatch RL p wX wY
remaining FL (WithSkipped p) wY wU
skipped
                Char
'v' -> forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContent p wY wY
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis
                Char
'p' -> forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContentWithPager p wY wY
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis
                Char
'x' -> do forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printSummary p wY wY
p
                          IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis
                Char
'r' -> forall {wX} {wY}. p wX wY -> IO ()
defaultPrintFriendly p wY wY
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis
                Char
'q' -> do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ (ShowS
capitalize String
jn) forall a. [a] -> [a] -> [a]
++ String
" cancelled."
                          forall a. IO a
exitSuccess
                Char
_   -> do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String -> [[KeyPress]] -> [[KeyPress]] -> String
helpFor String
jn [[KeyPress]]
basicOptions [[KeyPress]]
advancedOptions
                          IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis
        IO (Maybe (FlippedSeal (FL p :> p) wU))
repeatThis
  where prompt' :: String
prompt' = String
"Shall I " forall a. [a] -> [a] -> [a]
++ String
jn forall a. [a] -> [a] -> [a]
++ String
" this patch?"
        nextPatch :: IO (Maybe (FlippedSeal (FL p :> p) wU))
nextPatch = forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
jn forall wA wB. p wA wB -> Bool
matches RL p wX wY
pps (forall (p :: * -> * -> *) wX wY.
SkippedReason -> p wX wY -> WithSkipped p wX wY
WithSkipped SkippedReason
SkippedManually p wY wY
pforall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>:FL (WithSkipped p) wY wU
skipped)
        previousPatch :: RL p wX wQ
                      -> FL (WithSkipped p) wQ wU
                      -> IO (Maybe (FlippedSeal
                              (FL p :> p) wU))
        previousPatch :: forall wQ.
RL p wX wQ
-> FL (WithSkipped p) wQ wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
previousPatch RL p wX wQ
remaining' FL (WithSkipped p) wQ wU
NilFL = forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
jn forall wA wB. p wA wB -> Bool
matches RL p wX wQ
remaining' forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
        previousPatch RL p wX wQ
remaining' (WithSkipped SkippedReason
sk p wQ wY
prev :>: FL (WithSkipped p) wY wU
skipped'') =
            case SkippedReason
sk of
                SkippedReason
SkippedManually -> forall (p :: * -> * -> *) wX wY wU.
(Commute p, Matchable p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
String
-> (forall wA wB. p wA wB -> Bool)
-> RL p wX wY
-> FL (WithSkipped p) wY wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
wspfr String
jn forall wA wB. p wA wB -> Bool
matches (RL p wX wQ
remaining' forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: p wQ wY
prev) FL (WithSkipped p) wY wU
skipped''
                SkippedReason
SkippedAutomatically -> forall wQ.
RL p wX wQ
-> FL (WithSkipped p) wQ wU
-> IO (Maybe (FlippedSeal (FL p :> p) wU))
previousPatch (RL p wX wQ
remaining' forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: p wQ wY
prev) FL (WithSkipped p) wY wU
skipped''
        basicOptions :: [[KeyPress]]
basicOptions =
                    [[ Char -> String -> KeyPress
KeyPress Char
'y' (String
jn forall a. [a] -> [a] -> [a]
++ String
" this patch")
                     , Char -> String -> KeyPress
KeyPress Char
'n' (String
"don't " forall a. [a] -> [a] -> [a]
++ String
jn forall a. [a] -> [a] -> [a]
++ String
" it")
                     , Char -> String -> KeyPress
KeyPress Char
'j' String
"skip to next patch"
                     , Char -> String -> KeyPress
KeyPress Char
'k' String
"back up to previous patch"
                    ]]
        advancedOptions :: [[KeyPress]]
advancedOptions =
                    [[ Char -> String -> KeyPress
KeyPress Char
'v' String
"view this patch in full"
                     , Char -> String -> KeyPress
KeyPress Char
'p' String
"view this patch in full with pager"
                     , Char -> String -> KeyPress
KeyPress Char
'x' String
"view a summary of this patch"
                     , Char -> String -> KeyPress
KeyPress Char
'r' String
"view this patch"
                     , Char -> String -> KeyPress
KeyPress Char
'q' (String
"cancel " forall a. [a] -> [a] -> [a]
++ String
jn)
                    ]]
        defaultPrintFriendly :: p wX wY -> IO ()
defaultPrintFriendly =
          forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
Maybe (Tree IO)
-> Verbosity -> WithSummary -> WithContext -> p wX wY -> IO ()
printFriendly forall a. Maybe a
Nothing Verbosity
NormalVerbosity WithSummary
NoSummary WithContext
NoContext

-- | Runs a function on the underlying @PatchChoices@ object
liftChoices :: StateT (PatchChoices p wX wY) Identity a
            -> InteractiveSelectionM p wX wY a
liftChoices :: forall (p :: * -> * -> *) wX wY a.
StateT (PatchChoices p wX wY) Identity a
-> InteractiveSelectionM p wX wY a
liftChoices StateT (PatchChoices p wX wY) Identity a
act = do
  PatchChoices p wX wY
ch <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices
  let (a
result, PatchChoices p wX wY
_) = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT StateT (PatchChoices p wX wY) Identity a
act PatchChoices p wX wY
ch
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc {choices :: PatchChoices p wX wY
choices = PatchChoices p wX wY
ch} -- Should this be ch or the result of runState?
  forall (m :: * -> *) a. Monad m => a -> m a
return a
result

-- | @justDone n@ notes that @n@ patches have just been processed
justDone :: Int -> InteractiveSelectionM p wX wY ()
justDone :: forall (p :: * -> * -> *) wX wY.
Int -> InteractiveSelectionM p wX wY ()
justDone Int
n = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc{ current :: Int
current = forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
current InteractiveSelectionState p wX wY
isc forall a. Num a => a -> a -> a
+ Int
n}

initialSelectionState :: FL (LabelledPatch p) wX wY
                      -> PatchChoices p wX wY
                      -> InteractiveSelectionState p wX wY
initialSelectionState :: forall (p :: * -> * -> *) wX wY.
FL (LabelledPatch p) wX wY
-> PatchChoices p wX wY -> InteractiveSelectionState p wX wY
initialSelectionState FL (LabelledPatch p) wX wY
lps PatchChoices p wX wY
pcs =
  ISC { total :: Int
total = forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (LabelledPatch p) wX wY
lps
      , current :: Int
current = Int
0
      , lps :: FZipper (LabelledPatch p) wX wY
lps = forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> FL a wY wZ -> FZipper a wX wZ
FZipper forall (a :: * -> * -> *) wX. RL a wX wX
NilRL FL (LabelledPatch p) wX wY
lps
      , choices :: PatchChoices p wX wY
choices = PatchChoices p wX wY
pcs
      }

-- | The actual interactive selection process.
textSelect :: ( Commute p, Invert p, ShowPatch p, ShowContextPatch p
              , PatchInspect p, ApplyState p ~ Tree )
           => FL (LabelledPatch p) wX wY
           -> PatchChoices p wX wY
           -> PatchSelectionM p IO (PatchChoices p wX wY)
textSelect :: forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, ShowPatch p, ShowContextPatch p,
 PatchInspect p, ApplyState p ~ Tree) =>
FL (LabelledPatch p) wX wY
-> PatchChoices p wX wY
-> PatchSelectionM p IO (PatchChoices p wX wY)
textSelect FL (LabelledPatch p) wX wY
lps' PatchChoices p wX wY
pcs =
  forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT (forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p) =>
InteractiveSelectionM p wX wY ()
skipMundane forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {wX} {wY}.
StateT
  (InteractiveSelectionState p wX wY)
  (ReaderT (SelectionConfig p) IO)
  ()
textSelectIfAny)
      (forall (p :: * -> * -> *) wX wY.
FL (LabelledPatch p) wX wY
-> PatchChoices p wX wY -> InteractiveSelectionState p wX wY
initialSelectionState FL (LabelledPatch p) wX wY
lps' PatchChoices p wX wY
pcs)
  where
    textSelectIfAny :: StateT
  (InteractiveSelectionState p wX wY)
  (ReaderT (SelectionConfig p) IO)
  ()
textSelectIfAny = do
      FZipper (LabelledPatch p) wX wY
z <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps
      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (p :: * -> * -> *) wX wY. FZipper p wX wY -> Bool
rightmost FZipper (LabelledPatch p) wX wY
z) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, ShowPatch p, ShowContextPatch p,
 PatchInspect p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
textSelect'

textSelect' :: ( Commute p, Invert p, ShowPatch p, ShowContextPatch p
               , PatchInspect p, ApplyState p ~ Tree )
            => InteractiveSelectionM p wX wY ()
textSelect' :: forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, ShowPatch p, ShowContextPatch p,
 PatchInspect p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
textSelect' = do
  FZipper (LabelledPatch p) wX wY
z <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps
  Bool
done <- if Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. FZipper p wX wY -> Bool
rightmost FZipper (LabelledPatch p) wX wY
z
           then forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p, ShowContextPatch p, PatchInspect p,
 ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY Bool
textSelectOne
           else forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY Bool
lastQuestion
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
done forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, ShowPatch p, ShowContextPatch p,
 PatchInspect p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
textSelect'

optionsBasic :: String -> String -> [KeyPress]
optionsBasic :: String -> String -> [KeyPress]
optionsBasic String
jn String
aThing =
    [ Char -> String -> KeyPress
KeyPress Char
'y' (String
jnforall a. [a] -> [a] -> [a]
++String
" this "forall a. [a] -> [a] -> [a]
++String
aThing)
    , Char -> String -> KeyPress
KeyPress Char
'n' (String
"don't "forall a. [a] -> [a] -> [a]
++String
jnforall a. [a] -> [a] -> [a]
++String
" it")
    , Char -> String -> KeyPress
KeyPress Char
'w' String
"wait and decide later, defaulting to no" ]

optionsFile :: String -> [KeyPress]
optionsFile :: String -> [KeyPress]
optionsFile String
jn =
    [ Char -> String -> KeyPress
KeyPress Char
's' (String
"don't "forall a. [a] -> [a] -> [a]
++String
jnforall a. [a] -> [a] -> [a]
++String
" the rest of the changes to this file")
    , Char -> String -> KeyPress
KeyPress Char
'f' (String
jnforall a. [a] -> [a] -> [a]
++String
" the rest of the changes to this file") ]

optionsView :: String -> String -> [KeyPress]
optionsView :: String -> String -> [KeyPress]
optionsView String
aThing String
someThings =
    [ Char -> String -> KeyPress
KeyPress Char
'v' (String
"view this "forall a. [a] -> [a] -> [a]
++String
aThingforall a. [a] -> [a] -> [a]
++String
" in full")
    , Char -> String -> KeyPress
KeyPress Char
'p' (String
"view this "forall a. [a] -> [a] -> [a]
++String
aThingforall a. [a] -> [a] -> [a]
++String
" in full with pager")
    , Char -> String -> KeyPress
KeyPress Char
'r' (String
"view this "forall a. [a] -> [a] -> [a]
++String
aThing)
    , Char -> String -> KeyPress
KeyPress Char
'l' (String
"list all selected "forall a. [a] -> [a] -> [a]
++String
someThings) ]

optionsSummary :: String -> [KeyPress]
optionsSummary :: String -> [KeyPress]
optionsSummary String
aThing =
    [ Char -> String -> KeyPress
KeyPress Char
'x' (String
"view a summary of this "forall a. [a] -> [a] -> [a]
++String
aThing) ]

optionsQuit :: String -> Bool -> String -> [KeyPress]
optionsQuit :: String -> Bool -> String -> [KeyPress]
optionsQuit String
jn Bool
allowsa String
someThings =
    [ Char -> String -> KeyPress
KeyPress Char
'd' (String
jnforall a. [a] -> [a] -> [a]
++String
" selected "forall a. [a] -> [a] -> [a]
++String
someThingsforall a. [a] -> [a] -> [a]
++
                    String
", skipping all the remaining "forall a. [a] -> [a] -> [a]
++String
someThings)
            | Bool
allowsa ]
    forall a. [a] -> [a] -> [a]
++
    [ Char -> String -> KeyPress
KeyPress Char
'a' (String
jnforall a. [a] -> [a] -> [a]
++String
" all the remaining "forall a. [a] -> [a] -> [a]
++String
someThings)
    , Char -> String -> KeyPress
KeyPress Char
'q' (String
"cancel "forall a. [a] -> [a] -> [a]
++String
jn) ]

optionsNav :: String -> Bool -> [KeyPress]
optionsNav :: String -> Bool -> [KeyPress]
optionsNav String
aThing Bool
isLast=
    [ Char -> String -> KeyPress
KeyPress Char
'j' (String
"skip to next "forall a. [a] -> [a] -> [a]
++ String
aThing) | Bool -> Bool
not Bool
isLast ]
    forall a. [a] -> [a] -> [a]
++
    [ Char -> String -> KeyPress
KeyPress Char
'k' (String
"back up to previous "forall a. [a] -> [a] -> [a]
++ String
aThing)
    , Char -> String -> KeyPress
KeyPress Char
'g' (String
"start over from the first "forall a. [a] -> [a] -> [a]
++String
aThing)]

optionsSplit :: Maybe (Splitter a) -> String -> [KeyPress]
optionsSplit :: forall (a :: * -> * -> *).
Maybe (Splitter a) -> String -> [KeyPress]
optionsSplit Maybe (Splitter a)
split String
aThing
    | Just Splitter a
_ <- Maybe (Splitter a)
split
             = [ Char -> String -> KeyPress
KeyPress Char
'e' (String
"interactively edit this "forall a. [a] -> [a] -> [a]
++ String
aThing) ]
    | Bool
otherwise = []

optionsLast :: String -> String -> ([[KeyPress]], [[KeyPress]])
optionsLast :: String -> String -> ([[KeyPress]], [[KeyPress]])
optionsLast String
jn String
aThing =
  (String -> Bool -> [KeyPress]
optionsNav String
aThing Bool
Trueforall a. a -> [a] -> [a]
:
   [[ Char -> String -> KeyPress
KeyPress Char
'y' String
"confirm this operation"
    , Char -> String -> KeyPress
KeyPress Char
'q' (String
"cancel " forall a. [a] -> [a] -> [a]
++ String
jn) ]
    , [ Char -> String -> KeyPress
KeyPress Char
'l' String
"list all selected" ]
   ]
  ,[[Char -> String -> KeyPress
KeyPress Char
'a' String
"confirm this operation"
    , Char -> String -> KeyPress
KeyPress Char
'd' String
"confirm this operation"
    , Char -> String -> KeyPress
KeyPress Char
'n' (String
"cancel " forall a. [a] -> [a] -> [a]
++ String
jn) ]])

options :: (ShowPatch p)
        => Bool
        -> InteractiveSelectionM p wX wY ([[KeyPress]],[[KeyPress]])
options :: forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Bool -> InteractiveSelectionM p wX wY ([[KeyPress]], [[KeyPress]])
options Bool
single = do
  Maybe (Splitter p)
split <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Splitter p)
splitter
  String
jn <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> String
jobname
  Bool
allowsa <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> Bool
allowSkipAll
  String
aThing <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
thing
  String
someThings <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
things
  PatchSelectionOptions
o <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
opts
  forall (m :: * -> *) a. Monad m => a -> m a
return ([String -> String -> [KeyPress]
optionsBasic String
jn String
aThing]
         ,[forall (a :: * -> * -> *).
Maybe (Splitter a) -> String -> [KeyPress]
optionsSplit Maybe (Splitter p)
split String
aThing]
         forall a. [a] -> [a] -> [a]
++ [String -> [KeyPress]
optionsFile String
jn | Bool
single]
         forall a. [a] -> [a] -> [a]
++ [String -> String -> [KeyPress]
optionsView String
aThing String
someThings forall a. [a] -> [a] -> [a]
++
                if PatchSelectionOptions -> WithSummary
withSummary PatchSelectionOptions
o forall a. Eq a => a -> a -> Bool
== WithSummary
YesSummary
                    then []
                    else String -> [KeyPress]
optionsSummary String
aThing]
         forall a. [a] -> [a] -> [a]
++ [String -> Bool -> String -> [KeyPress]
optionsQuit String
jn Bool
allowsa String
someThings]
         forall a. [a] -> [a] -> [a]
++ [String -> Bool -> [KeyPress]
optionsNav String
aThing Bool
False]
         )

-- | Returns a 'Sealed2' version of the patch we are asking the user
-- about.
currentPatch :: InteractiveSelectionM p wX wY (Maybe (Sealed2 (LabelledPatch p)))
currentPatch :: forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM p wX wY (Maybe (Sealed2 (LabelledPatch p)))
currentPatch = forall (a :: * -> * -> *) wX wY.
FZipper a wX wY -> Maybe (Sealed2 a)
focus forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps

-- | Returns the patches we have yet to ask the user about.
todo :: InteractiveSelectionM p wX wY (FlippedSeal (FL (LabelledPatch p)) wY)
todo :: forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM
  p wX wY (FlippedSeal (FL (LabelledPatch p)) wY)
todo = forall (a :: * -> * -> *) wX wY.
FZipper a wX wY -> FlippedSeal (FL a) wY
jokers forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps

-- | Modify the underlying @PatchChoices@ by some function
modifyChoices :: (PatchChoices p wX wY -> PatchChoices p wX wY)
              -> InteractiveSelectionM p wX wY ()
modifyChoices :: forall (p :: * -> * -> *) wX wY.
(PatchChoices p wX wY -> PatchChoices p wX wY)
-> InteractiveSelectionM p wX wY ()
modifyChoices PatchChoices p wX wY -> PatchChoices p wX wY
f = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc{choices :: PatchChoices p wX wY
choices = PatchChoices p wX wY -> PatchChoices p wX wY
f forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices InteractiveSelectionState p wX wY
isc}

-- | returns @Just f@ if the 'currentPatch' only modifies @f@,
-- @Nothing@ otherwise.
currentFile :: (PatchInspect p)
            => InteractiveSelectionM p wX wY (Maybe AnchoredPath)
currentFile :: forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
InteractiveSelectionM p wX wY (Maybe AnchoredPath)
currentFile = do
  Maybe (Sealed2 (LabelledPatch p))
c <- forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM p wX wY (Maybe (Sealed2 (LabelledPatch p)))
currentPatch
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Maybe (Sealed2 (LabelledPatch p))
c of
             Maybe (Sealed2 (LabelledPatch p))
Nothing -> forall a. Maybe a
Nothing
             Just (Sealed2 LabelledPatch p wX wY
lp) ->
                 case forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles LabelledPatch p wX wY
lp of
                   [AnchoredPath
f] -> forall a. a -> Maybe a
Just AnchoredPath
f
                   [AnchoredPath]
_ -> forall a. Maybe a
Nothing

-- | @decide True@ selects the current patch, and @decide False@ deselects
-- it.
decide :: Commute p
       => Bool
       -> LabelledPatch p wT wU
       -> InteractiveSelectionM p wX wY ()
decide :: forall (p :: * -> * -> *) wT wU wX wY.
Commute p =>
Bool -> LabelledPatch p wT wU -> InteractiveSelectionM p wX wY ()
decide Bool
takeOrDrop LabelledPatch p wT wU
lp = do
    WhichChanges
whch <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> WhichChanges
whichChanges
    if WhichChanges -> Bool
backward WhichChanges
whch forall a. Eq a => a -> a -> Bool
== Bool
takeOrDrop -- we go backward xor we are dropping
    then forall (p :: * -> * -> *) wX wY.
(PatchChoices p wX wY -> PatchChoices p wX wY)
-> InteractiveSelectionM p wX wY ()
modifyChoices forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wA wB.
Commute p =>
Label -> PatchChoices p wA wB -> PatchChoices p wA wB
forceLast (forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> Label
label LabelledPatch p wT wU
lp)
    else forall (p :: * -> * -> *) wX wY.
(PatchChoices p wX wY -> PatchChoices p wX wY)
-> InteractiveSelectionM p wX wY ()
modifyChoices forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wA wB.
Commute p =>
Label -> PatchChoices p wA wB -> PatchChoices p wA wB
forceFirst (forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> Label
label LabelledPatch p wT wU
lp)

-- | like 'decide', but for all patches touching @file@
decideWholeFile :: (Commute p, PatchInspect p)
                => AnchoredPath -> Bool -> InteractiveSelectionM p wX wY ()
decideWholeFile :: forall (p :: * -> * -> *) wX wY.
(Commute p, PatchInspect p) =>
AnchoredPath -> Bool -> InteractiveSelectionM p wX wY ()
decideWholeFile AnchoredPath
path Bool
takeOrDrop =
    do
      FlippedSeal FL (LabelledPatch p) wX wY
lps_todo <- forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM
  p wX wY (FlippedSeal (FL (LabelledPatch p)) wY)
todo
      let patches_to_skip :: [Sealed2 (LabelledPatch p)]
patches_to_skip =
              forall (a :: * -> * -> *) wW wZ.
(forall wX wY. a wX wY -> Bool) -> FL a wW wZ -> [Sealed2 a]
filterFL (\LabelledPatch p wX wY
lp' -> forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles LabelledPatch p wX wY
lp' forall a. Eq a => a -> a -> Bool
== [AnchoredPath
path]) FL (LabelledPatch p) wX wY
lps_todo
      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wT wU wX wY.
Commute p =>
Bool -> LabelledPatch p wT wU -> InteractiveSelectionM p wX wY ()
decide Bool
takeOrDrop) [Sealed2 (LabelledPatch p)]
patches_to_skip

-- | Undecide the current patch.
postponeNext :: Commute p => InteractiveSelectionM p wX wY ()
postponeNext :: forall (p :: * -> * -> *) wX wY.
Commute p =>
InteractiveSelectionM p wX wY ()
postponeNext =
    do
      Just (Sealed2 LabelledPatch p wX wY
lp) <- forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM p wX wY (Maybe (Sealed2 (LabelledPatch p)))
currentPatch
      forall (p :: * -> * -> *) wX wY.
(PatchChoices p wX wY -> PatchChoices p wX wY)
-> InteractiveSelectionM p wX wY ()
modifyChoices forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wA wB.
Commute p =>
Label -> PatchChoices p wA wB -> PatchChoices p wA wB
forceMiddle (forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> Label
label LabelledPatch p wX wY
lp)

-- | Focus the next patch.
skipOne :: InteractiveSelectionM p wX wY ()
skipOne :: forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipOne = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall {p :: * -> * -> *} {wX} {wY}.
InteractiveSelectionState p wX wY
-> InteractiveSelectionState p wX wY
so
    where so :: InteractiveSelectionState p wX wY
-> InteractiveSelectionState p wX wY
so InteractiveSelectionState p wX wY
x = InteractiveSelectionState p wX wY
x{lps :: FZipper (LabelledPatch p) wX wY
lps = forall (p :: * -> * -> *) wX wY. FZipper p wX wY -> FZipper p wX wY
right (forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps InteractiveSelectionState p wX wY
x), current :: Int
current = forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
current InteractiveSelectionState p wX wY
x forall a. Num a => a -> a -> a
+Int
1}

-- | Focus the previous patch.
backOne :: InteractiveSelectionM p wX wY ()
backOne :: forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
backOne = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall {p :: * -> * -> *} {wX} {wY}.
InteractiveSelectionState p wX wY
-> InteractiveSelectionState p wX wY
so
    where so :: InteractiveSelectionState p wX wY
-> InteractiveSelectionState p wX wY
so InteractiveSelectionState p wX wY
isc = InteractiveSelectionState p wX wY
isc{lps :: FZipper (LabelledPatch p) wX wY
lps = forall (p :: * -> * -> *) wX wY. FZipper p wX wY -> FZipper p wX wY
left (forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps InteractiveSelectionState p wX wY
isc), current :: Int
current = forall a. Ord a => a -> a -> a
max (forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
current InteractiveSelectionState p wX wY
iscforall a. Num a => a -> a -> a
-Int
1) Int
0}

-- | Split the current patch (presumably a hunk), and add the replace it
-- with its parts.
splitCurrent :: Splitter p
             -> InteractiveSelectionM p wX wY ()
splitCurrent :: forall (p :: * -> * -> *) wX wY.
Splitter p -> InteractiveSelectionM p wX wY ()
splitCurrent Splitter p
s = do
    FZipper RL (LabelledPatch p) wX wY
lps_done (LabelledPatch p wY wY
lp:>:FL (LabelledPatch p) wY wY
lps_todo) <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps
    case forall (p :: * -> * -> *).
Splitter p
-> forall wX wY.
   p wX wY -> Maybe (ByteString, ByteString -> Maybe (FL p wX wY))
applySplitter Splitter p
s (forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel LabelledPatch p wY wY
lp) of
      Maybe (ByteString, ByteString -> Maybe (FL p wY wY))
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just (ByteString
text, ByteString -> Maybe (FL p wY wY)
parse) ->
          do
            ByteString
newText <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ String -> ByteString -> IO ByteString
editText String
"darcs-patch-edit" ByteString
text
            case ByteString -> Maybe (FL p wY wY)
parse ByteString
newText of
               Maybe (FL p wY wY)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
               Just FL p wY wY
ps -> do
                 FL (LabelledPatch p) wY wY
lps_new <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Maybe Label -> FL p wX wY -> FL (LabelledPatch p) wX wY
labelPatches (forall a. a -> Maybe a
Just (forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> Label
label LabelledPatch p wY wY
lp)) FL p wY wY
ps
                 forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc { total :: Int
total = forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
total InteractiveSelectionState p wX wY
isc forall a. Num a => a -> a -> a
+ forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (LabelledPatch p) wY wY
lps_new forall a. Num a => a -> a -> a
- Int
1
                                      , lps :: FZipper (LabelledPatch p) wX wY
lps = forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> FL a wY wZ -> FZipper a wX wZ
FZipper RL (LabelledPatch p) wX wY
lps_done
                                               (FL (LabelledPatch p) wY wY
lps_new forall (a :: * -> * -> *) wX wY wZ.
FL a wX wY -> FL a wY wZ -> FL a wX wZ
+>+ FL (LabelledPatch p) wY wY
lps_todo)
                                      , choices :: PatchChoices p wX wY
choices = forall (p :: * -> * -> *) wX wY.
Sealed2 (LabelledPatch p :||: FL (LabelledPatch p))
-> PatchChoices p wX wY -> PatchChoices p wX wY
substitute
                                                   (forall (a :: * -> * -> *) wX wY. a wX wY -> Sealed2 a
seal2 (LabelledPatch p wY wY
lp forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY.
a1 wX wY -> a2 wX wY -> (:||:) a1 a2 wX wY
:||: FL (LabelledPatch p) wY wY
lps_new))
                                                   (forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices InteractiveSelectionState p wX wY
isc)
                                      }

-- | Print the list of the selected patches. We currently choose to display
-- them in "commuted" form, that is, in the order in which they have been
-- selected and with deselected patches moved out of the way.
printSelected :: (Commute p, ShowPatch p) => InteractiveSelectionM p wX wY ()
printSelected :: forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p) =>
InteractiveSelectionM p wX wY ()
printSelected = do
  String
someThings <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
things
  PatchSelectionOptions
o <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
opts
  WhichChanges
w <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> WhichChanges
whichChanges
  let showFL :: FL (LabelledPatch p) wX wY -> Doc
showFL = [Doc] -> Doc
vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL (forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Verbosity -> WithSummary -> p wX wY -> Doc
showFriendly (PatchSelectionOptions -> Verbosity
verbosity PatchSelectionOptions
o) (PatchSelectionOptions -> WithSummary
withSummary PatchSelectionOptions
o) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel)
  (FL (LabelledPatch p) wX wZ
first_chs :> FL (LabelledPatch p) wZ wZ
_ :> FL (LabelledPatch p) wZ wY
last_chs) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices p wX wY
-> (:>)
     (FL (LabelledPatch p))
     (FL (LabelledPatch p) :> FL (LabelledPatch p))
     wX
     wY
getChoices forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Printers -> Doc -> IO ()
putDocLnWith Printers
fancyPrinters forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
vcat
    [ String -> Doc
greenText forall a b. (a -> b) -> a -> b
$ String
"---- selected "forall a. [a] -> [a] -> [a]
++String
someThingsforall a. [a] -> [a] -> [a]
++String
" ----"
    , if WhichChanges -> Bool
backward WhichChanges
w then forall {wX} {wY}. FL (LabelledPatch p) wX wY -> Doc
showFL FL (LabelledPatch p) wZ wY
last_chs else forall {wX} {wY}. FL (LabelledPatch p) wX wY -> Doc
showFL FL (LabelledPatch p) wX wZ
first_chs
    , String -> Doc
greenText forall a b. (a -> b) -> a -> b
$ String
"---- end of selected "forall a. [a] -> [a] -> [a]
++String
someThingsforall a. [a] -> [a] -> [a]
++String
" ----"
    ]

-- | Skips all remaining patches.
skipAll ::  InteractiveSelectionM p wX wY ()
skipAll :: forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipAll = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc {lps :: FZipper (LabelledPatch p) wX wY
lps = forall (p :: * -> * -> *) wX wY. FZipper p wX wY -> FZipper p wX wY
toEnd forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps InteractiveSelectionState p wX wY
isc}

backAll ::  InteractiveSelectionM p wX wY ()
backAll :: forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
backAll = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc {lps :: FZipper (LabelledPatch p) wX wY
lps = forall (p :: * -> * -> *) wX wY. FZipper p wX wY -> FZipper p wX wY
toStart forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps InteractiveSelectionState p wX wY
isc
                               ,current :: Int
current = Int
0}

isSingleFile :: PatchInspect p => p wX wY -> Bool
isSingleFile :: forall (p :: * -> * -> *) wX wY. PatchInspect p => p wX wY -> Bool
isSingleFile p wX wY
p = forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles p wX wY
p) forall a. Eq a => a -> a -> Bool
== Int
1

askConfirmation ::  InteractiveSelectionM p wX wY ()
askConfirmation :: forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
askConfirmation = do
    String
jn <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> String
jobname
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
jn forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"unpull", String
"unrecord", String
"obliterate"]) forall a b. (a -> b) -> a -> b
$ do
               String
yorn <- String -> IO String
askUser forall a b. (a -> b) -> a -> b
$ String
"Really " forall a. [a] -> [a] -> [a]
++ String
jn forall a. [a] -> [a] -> [a]
++ String
" all undecided patches? "
               case String
yorn of
                 (Char
'y':String
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                 String
_ -> forall a. IO a
exitSuccess

-- | The singular form of the noun for items of type @p@.
thing :: (ShowPatch p) => InteractiveSelectionM p wX wY String
thing :: forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
thing = (forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> String
Darcs.Patch.thing forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wA wB. PatchChoices p wA wB -> p wA wB
helper) forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices
        where
          helper :: PatchChoices p wA wB -> p wA wB
          helper :: forall (p :: * -> * -> *) wA wB. PatchChoices p wA wB -> p wA wB
helper = forall a. HasCallStack => a
undefined

-- | The plural form of the noun for items of type @p@.
things :: (ShowPatch p) => InteractiveSelectionM p wX wY String
things :: forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
things = (forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> String
Darcs.Patch.things forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wA wB. PatchChoices p wA wB -> p wA wB
helper) forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> PatchChoices p wX wY
choices
        where
          helper :: PatchChoices p wA wB -> p wA wB
          helper :: forall (p :: * -> * -> *) wA wB. PatchChoices p wA wB -> p wA wB
helper = forall a. HasCallStack => a
undefined

-- | The question to ask about one patch.
prompt :: (ShowPatch p) => InteractiveSelectionM p wX wY String
prompt :: forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
prompt = do
  String
jn <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> String
jobname
  String
aThing <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
thing
  Int
n <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
current
  Int
n_max <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY -> Int
total
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
"Shall I "forall a. [a] -> [a] -> [a]
++String
jnforall a. [a] -> [a] -> [a]
++String
" this "forall a. [a] -> [a] -> [a]
++String
aThingforall a. [a] -> [a] -> [a]
++String
"? "
             forall a. [a] -> [a] -> [a]
++ String
"(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
nforall a. Num a => a -> a -> a
+Int
1) forall a. [a] -> [a] -> [a]
++ String
"/" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
n_max forall a. [a] -> [a] -> [a]
++ String
") "

-- | Asks the user about one patch, returns their answer.
promptUser :: (ShowPatch p)
           => Bool -> Char -> InteractiveSelectionM p wX wY Char
promptUser :: forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Bool -> Char -> InteractiveSelectionM p wX wY Char
promptUser Bool
single Char
def = do
  String
thePrompt <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
prompt
  ([[KeyPress]]
basicOptions,[[KeyPress]]
advancedOptions) <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Bool -> InteractiveSelectionM p wX wY ([[KeyPress]], [[KeyPress]])
options Bool
single
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ PromptConfig -> IO Char
promptChar PromptConfig { pPrompt :: String
pPrompt = String
thePrompt
                                   , pBasicCharacters :: String
pBasicCharacters = [[KeyPress]] -> String
keysFor [[KeyPress]]
basicOptions
                                   , pAdvancedCharacters :: String
pAdvancedCharacters = [[KeyPress]] -> String
keysFor [[KeyPress]]
advancedOptions
                                   , pDefault :: Maybe Char
pDefault = forall a. a -> Maybe a
Just Char
def
                                   , pHelp :: String
pHelp = String
"?h"
                                   }

-- | Ask the user what to do with the next patch.
textSelectOne :: ( Commute p, ShowPatch p, ShowContextPatch p, PatchInspect p
                 , ApplyState p ~ Tree )
              => InteractiveSelectionM p wX wY Bool
textSelectOne :: forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p, ShowContextPatch p, PatchInspect p,
 ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY Bool
textSelectOne = do
 Maybe (Sealed2 (LabelledPatch p))
c <- forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM p wX wY (Maybe (Sealed2 (LabelledPatch p)))
currentPatch
 case Maybe (Sealed2 (LabelledPatch p))
c of
   Maybe (Sealed2 (LabelledPatch p))
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
   Just (Sealed2 LabelledPatch p wX wY
lp) ->
       do
         String
jn <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> String
jobname
         Maybe (Splitter p)
spl <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Splitter p)
splitter
         WhichChanges
whichch <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> WhichChanges
whichChanges
         let singleFile :: Bool
singleFile = forall (p :: * -> * -> *) wX wY. PatchInspect p => p wX wY -> Bool
isSingleFile (forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel LabelledPatch p wX wY
lp)
             p :: p wX wY
p = forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel LabelledPatch p wX wY
lp
         ([[KeyPress]]
basicOptions,[[KeyPress]]
advancedOptions) <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Bool -> InteractiveSelectionM p wX wY ([[KeyPress]], [[KeyPress]])
options Bool
singleFile
         Slot
theSlot <- forall (p :: * -> * -> *) wX wY a.
StateT (PatchChoices p wX wY) Identity a
-> InteractiveSelectionM p wX wY a
liftChoices forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wA wB wX wY.
Commute p =>
LabelledPatch p wA wB
-> PatchChoices p wX wY -> (Slot, PatchChoices p wX wY)
patchSlot LabelledPatch p wX wY
lp
         let the_default :: Char
the_default = Bool -> Slot -> Char
getDefault (WhichChanges -> Bool
backward WhichChanges
whichch) Slot
theSlot
         Char
yorn <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Bool -> Char -> InteractiveSelectionM p wX wY Char
promptUser Bool
singleFile Char
the_default
         let nextPatch :: StateT
  (InteractiveSelectionState p wX wY) (PatchSelectionM p IO) ()
nextPatch = forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p) =>
InteractiveSelectionM p wX wY ()
skipMundane forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent
         case Char
yorn of
               Char
'y' -> forall (p :: * -> * -> *) wT wU wX wY.
Commute p =>
Bool -> LabelledPatch p wT wU -> InteractiveSelectionM p wX wY ()
decide Bool
True LabelledPatch p wX wY
lp forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipOne forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {wX} {wY}.
StateT
  (InteractiveSelectionState p wX wY) (PatchSelectionM p IO) ()
nextPatch
                      forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'n' -> forall (p :: * -> * -> *) wT wU wX wY.
Commute p =>
Bool -> LabelledPatch p wT wU -> InteractiveSelectionM p wX wY ()
decide Bool
False LabelledPatch p wX wY
lp forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipOne forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {wX} {wY}.
StateT
  (InteractiveSelectionState p wX wY) (PatchSelectionM p IO) ()
nextPatch
                      forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'w' -> forall (p :: * -> * -> *) wX wY.
Commute p =>
InteractiveSelectionM p wX wY ()
postponeNext forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipOne forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {wX} {wY}.
StateT
  (InteractiveSelectionState p wX wY) (PatchSelectionM p IO) ()
nextPatch
                      forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'e' | (Just Splitter p
s) <- Maybe (Splitter p)
spl -> forall (p :: * -> * -> *) wX wY.
Splitter p -> InteractiveSelectionM p wX wY ()
splitCurrent Splitter p
s forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent
                                        forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
's' -> forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
InteractiveSelectionM p wX wY (Maybe AnchoredPath)
currentFile forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                       (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                       (\AnchoredPath
f -> forall (p :: * -> * -> *) wX wY.
(Commute p, PatchInspect p) =>
AnchoredPath -> Bool -> InteractiveSelectionM p wX wY ()
decideWholeFile AnchoredPath
f Bool
False) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {wX} {wY}.
StateT
  (InteractiveSelectionState p wX wY) (PatchSelectionM p IO) ()
nextPatch
                       forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'f' -> forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
InteractiveSelectionM p wX wY (Maybe AnchoredPath)
currentFile forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                       (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                       (\AnchoredPath
f -> forall (p :: * -> * -> *) wX wY.
(Commute p, PatchInspect p) =>
AnchoredPath -> Bool -> InteractiveSelectionM p wX wY ()
decideWholeFile AnchoredPath
f Bool
True) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {wX} {wY}.
StateT
  (InteractiveSelectionState p wX wY) (PatchSelectionM p IO) ()
nextPatch
                       forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'v' -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContent p wX wY
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'p' -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContentWithPager p wX wY
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'r' -> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'l' -> forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p) =>
InteractiveSelectionM p wX wY ()
printSelected forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'x' -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printSummary p wX wY
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'd' -> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipAll forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
               Char
'g' -> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
backAll forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'a' ->
                   do
                     forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
askConfirmation
                     forall (p :: * -> * -> *) wX wY.
(PatchChoices p wX wY -> PatchChoices p wX wY)
-> InteractiveSelectionM p wX wY ()
modifyChoices forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Commute p =>
Bool -> PatchChoices p wX wY -> PatchChoices p wX wY
selectAllMiddles (WhichChanges -> Bool
backward WhichChanges
whichch)
                     forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipAll
                     forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
               Char
'q' -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$
                      do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ ShowS
capitalize String
jn forall a. [a] -> [a] -> [a]
++ String
" cancelled."
                         forall a. IO a
exitSuccess
               Char
'j' -> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
skipOne forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'k' -> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
backOne forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
_   -> do
                 forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String -> [[KeyPress]] -> [[KeyPress]] -> String
helpFor String
jn [[KeyPress]]
basicOptions [[KeyPress]]
advancedOptions
                 forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

lastQuestion :: (Commute p, ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree)
             => InteractiveSelectionM p wX wY Bool
lastQuestion :: forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY Bool
lastQuestion = do
  String
jn <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> String
jobname
  String
theThings <-forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
things
  String
aThing <- forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
InteractiveSelectionM p wX wY String
thing
  let ([[KeyPress]]
basicOptions, [[KeyPress]]
advancedOptions) = String -> String -> ([[KeyPress]], [[KeyPress]])
optionsLast String
jn String
aThing
  Char
yorn <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. PromptConfig -> IO Char
promptChar forall a b. (a -> b) -> a -> b
$
            PromptConfig { pPrompt :: String
pPrompt = String
"Do you want to "forall a. [a] -> [a] -> [a]
++ShowS
capitalize String
jnforall a. [a] -> [a] -> [a]
++
                                      String
" these "forall a. [a] -> [a] -> [a]
++String
theThingsforall a. [a] -> [a] -> [a]
++String
"?"
                         , pBasicCharacters :: String
pBasicCharacters = String
"yglqk"
                         , pAdvancedCharacters :: String
pAdvancedCharacters = String
"dan"
                         , pDefault :: Maybe Char
pDefault = forall a. a -> Maybe a
Just Char
'y'
                         , pHelp :: String
pHelp = String
"?h"}
  case Char
yorn of Char
c | Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"yda" -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
                 | Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"qn" -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$
                                    do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
jn forall a. [a] -> [a] -> [a]
++String
" cancelled."
                                       forall a. IO a
exitSuccess
               Char
'g' -> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
backAll forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'l' -> forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p) =>
InteractiveSelectionM p wX wY ()
printSelected forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
'k' -> forall (p :: * -> * -> *) wX wY. InteractiveSelectionM p wX wY ()
backOne forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               Char
_ -> do
                 forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String -> [[KeyPress]] -> [[KeyPress]] -> String
helpFor String
"this confirmation prompt"
                    [[KeyPress]]
basicOptions [[KeyPress]]
advancedOptions
                 forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

-- | Shows the current patch as it should be seen by the user.
printCurrent :: (ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree)
             => InteractiveSelectionM p wX wY ()
printCurrent :: forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
InteractiveSelectionM p wX wY ()
printCurrent = do
  PatchSelectionOptions
o <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
opts
  Maybe (Tree IO)
pr <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> Maybe (Tree IO)
pristine
  Maybe (Sealed2 (LabelledPatch p))
c <- forall (p :: * -> * -> *) wX wY.
InteractiveSelectionM p wX wY (Maybe (Sealed2 (LabelledPatch p)))
currentPatch
  case Maybe (Sealed2 (LabelledPatch p))
c of
    Maybe (Sealed2 (LabelledPatch p))
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
    Just (Sealed2 LabelledPatch p wX wY
lp) ->
      forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
Maybe (Tree IO)
-> Verbosity -> WithSummary -> WithContext -> p wX wY -> IO ()
printFriendly Maybe (Tree IO)
pr (PatchSelectionOptions -> Verbosity
verbosity PatchSelectionOptions
o) (PatchSelectionOptions -> WithSummary
withSummary PatchSelectionOptions
o) (PatchSelectionOptions -> WithContext
withContext PatchSelectionOptions
o) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel LabelledPatch p wX wY
lp

-- | The interactive part of @darcs changes@
textView :: (ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree)
         => PatchSelectionOptions -> Maybe Int -> Int
         -> [Sealed2 p] -> [Sealed2 p]
         -> IO ()
textView :: forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
_ Maybe Int
_ Int
_ [Sealed2 p]
_ [] = forall (m :: * -> *) a. Monad m => a -> m a
return ()
textView PatchSelectionOptions
o Maybe Int
n_max Int
n
            [Sealed2 p]
ps_done ps_todo :: [Sealed2 p]
ps_todo@(Sealed2 p
p:[Sealed2 p]
ps_todo') = do
      Sealed2 p -> IO ()
defaultPrintFriendly Sealed2 p
p
      IO ()
repeatThis -- prompt the user
    where
        defaultPrintFriendly :: Sealed2 p -> IO ()
defaultPrintFriendly =
          forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 (forall (p :: * -> * -> *) wX wY.
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
Maybe (Tree IO)
-> Verbosity -> WithSummary -> WithContext -> p wX wY -> IO ()
printFriendly forall a. Maybe a
Nothing (PatchSelectionOptions -> Verbosity
verbosity PatchSelectionOptions
o) (PatchSelectionOptions -> WithSummary
withSummary PatchSelectionOptions
o) (PatchSelectionOptions -> WithContext
withContext PatchSelectionOptions
o))
        prev_patch :: IO ()
        prev_patch :: IO ()
prev_patch = case [Sealed2 p]
ps_done of
                       [] -> IO ()
repeatThis
                       (Sealed2 p
p':[Sealed2 p]
ps_done') ->
                         forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
o
                            Maybe Int
n_max (Int
nforall a. Num a => a -> a -> a
-Int
1) [Sealed2 p]
ps_done' (Sealed2 p
p'forall a. a -> [a] -> [a]
:[Sealed2 p]
ps_todo)
        next_patch :: IO ()
        next_patch :: IO ()
next_patch = case [Sealed2 p]
ps_todo' of
                         [] -> -- May as well work out the length now we have all
                                  -- the patches in memory
                               forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
o Maybe Int
n_max
                                   Int
n [Sealed2 p]
ps_done []
                         [Sealed2 p]
_ -> forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
o Maybe Int
n_max
                                  (Int
nforall a. Num a => a -> a -> a
+Int
1) (Sealed2 p
pforall a. a -> [a] -> [a]
:[Sealed2 p]
ps_done) [Sealed2 p]
ps_todo'
        first_patch :: IO ()
first_patch = forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
o Maybe Int
n_max Int
0 [] ([Sealed2 p]
ps_doneforall a. [a] -> [a] -> [a]
++[Sealed2 p]
ps_todo)
        options_yn :: [KeyPress]
options_yn =
          [ Char -> String -> KeyPress
KeyPress Char
'y' String
"view this patch and go to the next"
          , Char -> String -> KeyPress
KeyPress Char
'n' String
"skip to the next patch" ]
        optionsView' :: [KeyPress]
optionsView' =
          [ Char -> String -> KeyPress
KeyPress Char
'v' String
"view this patch in full"
          , Char -> String -> KeyPress
KeyPress Char
'p' String
"view this patch in full with pager"
          , Char -> String -> KeyPress
KeyPress Char
'r' String
"view this patch" ]
        optionsSummary' :: [KeyPress]
optionsSummary' =
          [ Char -> String -> KeyPress
KeyPress Char
'x' String
"view a summary of this patch" ]
        optionsNav' :: [KeyPress]
optionsNav' =
          [ Char -> String -> KeyPress
KeyPress Char
'q' String
"quit view changes"
          , Char -> String -> KeyPress
KeyPress Char
'k' String
"back up to previous patch"
          , Char -> String -> KeyPress
KeyPress Char
'j' String
"skip to next patch"
          , Char -> String -> KeyPress
KeyPress Char
'g' String
"start over from the first patch"
          , Char -> String -> KeyPress
KeyPress Char
'c' String
"count total patch number" ]
        basicOptions :: [[KeyPress]]
basicOptions = [ [KeyPress]
options_yn ]
        advancedOptions :: [[KeyPress]]
advancedOptions =
                     ([KeyPress]
optionsView' forall a. [a] -> [a] -> [a]
++
                        if PatchSelectionOptions -> WithSummary
withSummary PatchSelectionOptions
o forall a. Eq a => a -> a -> Bool
== WithSummary
YesSummary then [] else [KeyPress]
optionsSummary')
                  forall a. a -> [a] -> [a]
: [ [KeyPress]
optionsNav' ]
        prompt' :: String
prompt' = String
"Shall I view this patch? "
               forall a. [a] -> [a] -> [a]
++ String
"(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
nforall a. Num a => a -> a -> a
+Int
1) forall a. [a] -> [a] -> [a]
++ String
"/" forall a. [a] -> [a] -> [a]
++ forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"?" forall a. Show a => a -> String
show Maybe Int
n_max forall a. [a] -> [a] -> [a]
++ String
")"
        repeatThis :: IO ()
        repeatThis :: IO ()
repeatThis = do
          Char
yorn <- PromptConfig -> IO Char
promptChar (String -> String -> String -> Maybe Char -> String -> PromptConfig
PromptConfig String
prompt' ([[KeyPress]] -> String
keysFor [[KeyPress]]
basicOptions) ([[KeyPress]] -> String
keysFor [[KeyPress]]
advancedOptions) (forall a. a -> Maybe a
Just Char
'n') String
"?h")
          case Char
yorn of
            Char
'y' -> forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContent Sealed2 p
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
next_patch
            Char
'n' -> IO ()
next_patch
            Char
'v' -> forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContent Sealed2 p
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
repeatThis
            Char
'p' -> forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printContentWithPager Sealed2 p
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
repeatThis
            Char
'r' -> do Sealed2 p -> IO ()
defaultPrintFriendly Sealed2 p
p
                      IO ()
repeatThis
            Char
'x' -> do forall (a :: * -> * -> *) b.
(forall wX wY. a wX wY -> b) -> Sealed2 a -> b
unseal2 forall (p :: * -> * -> *) wX wY. ShowPatch p => p wX wY -> IO ()
printSummary Sealed2 p
p
                      IO ()
repeatThis
            Char
'q' -> forall a. IO a
exitSuccess
            Char
'k' -> IO ()
prev_patch
            Char
'j' -> IO ()
next_patch
            Char
'g' -> IO ()
first_patch
            Char
'c' -> forall (p :: * -> * -> *).
(ShowPatch p, ShowContextPatch p, ApplyState p ~ Tree) =>
PatchSelectionOptions
-> Maybe Int -> Int -> [Sealed2 p] -> [Sealed2 p] -> IO ()
textView PatchSelectionOptions
o
                       Maybe Int
count_n_max Int
n [Sealed2 p]
ps_done [Sealed2 p]
ps_todo
            Char
_   -> do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String -> [[KeyPress]] -> [[KeyPress]] -> String
helpFor String
"view changes" [[KeyPress]]
basicOptions [[KeyPress]]
advancedOptions
                      IO ()
repeatThis
        count_n_max :: Maybe Int
count_n_max | forall a. Maybe a -> Bool
isJust Maybe Int
n_max = Maybe Int
n_max
                    | Bool
otherwise    = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sealed2 p]
ps_done forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sealed2 p]
ps_todo

-- | Skips patches we should not ask the user about
skipMundane :: (Commute p, ShowPatch p)
            => InteractiveSelectionM p wX wY ()
skipMundane :: forall (p :: * -> * -> *) wX wY.
(Commute p, ShowPatch p) =>
InteractiveSelectionM p wX wY ()
skipMundane = do
  (FZipper RL (LabelledPatch p) wX wY
lps_done FL (LabelledPatch p) wY wY
lps_todo) <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall (p :: * -> * -> *) wX wY.
InteractiveSelectionState p wX wY
-> FZipper (LabelledPatch p) wX wY
lps
  PatchSelectionOptions
o <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *).
SelectionConfig p -> PatchSelectionOptions
opts
  MatchCriterion p
crit <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> MatchCriterion p
matchCriterion
  String
jn <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (p :: * -> * -> *). SelectionConfig p -> String
jobname
  (FL (LabelledPatch p) wY wZ
skipped :> FL (LabelledPatch p) wZ wY
unskipped) <- forall (p :: * -> * -> *) wX wY a.
StateT (PatchChoices p wX wY) Identity a
-> InteractiveSelectionM p wX wY a
liftChoices forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) (m :: * -> *) wX wZ.
Monad m =>
(forall wW wY. a wW wY -> m Bool)
-> FL a wX wZ -> m ((:>) (FL a) (FL a) wX wZ)
spanFL_M
                                 (forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wA wB wX wY.
Commute p =>
LabelledPatch p wA wB
-> PatchChoices p wX wY -> (Slot, PatchChoices p wX wY)
patchSlot forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Slot -> Bool
decided)
                                 FL (LabelledPatch p) wY wY
lps_todo
  let numSkipped :: Int
numSkipped = forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (LabelledPatch p) wY wZ
skipped
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
numSkipped forall a. Ord a => a -> a -> Bool
> Int
0) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall {p :: * -> * -> *} {wY} {wT}.
ShowPatch p =>
PatchSelectionOptions
-> String -> Int -> FL (LabelledPatch p) wY wT -> IO ()
show_skipped PatchSelectionOptions
o String
jn Int
numSkipped FL (LabelledPatch p) wY wZ
skipped
  let boringThenInteresting :: (:>) (FL (LabelledPatch p)) (FL (LabelledPatch p)) wZ wY
boringThenInteresting =
          if PatchSelectionOptions -> SelectDeps
selectDeps PatchSelectionOptions
o forall a. Eq a => a -> a -> Bool
== SelectDeps
AutoDeps
          then forall (a :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> Bool)
-> FL a wX wZ -> (:>) (FL a) (FL a) wX wZ
spanFL (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *).
MatchCriterion p -> forall wA wB. p wA wB -> Bool
mcFunction MatchCriterion p
crit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel) FL (LabelledPatch p) wZ wY
unskipped
          else forall (a :: * -> * -> *) wX. FL a wX wX
NilFL forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> FL (LabelledPatch p) wZ wY
unskipped
  case (:>) (FL (LabelledPatch p)) (FL (LabelledPatch p)) wZ wY
boringThenInteresting of
    FL (LabelledPatch p) wZ wZ
boring :> FL (LabelledPatch p) wZ wY
interesting ->
        do
          forall (p :: * -> * -> *) wX wY.
Int -> InteractiveSelectionM p wX wY ()
justDone forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (LabelledPatch p) wZ wZ
boring forall a. Num a => a -> a -> a
+ Int
numSkipped
          forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \InteractiveSelectionState p wX wY
isc -> InteractiveSelectionState p wX wY
isc {lps :: FZipper (LabelledPatch p) wX wY
lps = forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> FL a wY wZ -> FZipper a wX wZ
FZipper (RL (LabelledPatch p) wX wY
lps_done forall (p :: * -> * -> *) wX wY wZ.
RL p wX wY -> FL p wY wZ -> RL p wX wZ
+<<+ FL (LabelledPatch p) wY wZ
skipped forall (p :: * -> * -> *) wX wY wZ.
RL p wX wY -> FL p wY wZ -> RL p wX wZ
+<<+ FL (LabelledPatch p) wZ wZ
boring)
                                      FL (LabelledPatch p) wZ wY
interesting}
    where
      show_skipped :: PatchSelectionOptions
-> String -> Int -> FL (LabelledPatch p) wY wT -> IO ()
show_skipped PatchSelectionOptions
o String
jn Int
n FL (LabelledPatch p) wY wT
ps = do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ ShowS
_nevermind_ String
jn forall a. [a] -> [a] -> [a]
++ Int -> String
_these_ Int
n forall a. [a] -> [a] -> [a]
++ String
"."
                                  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (PatchSelectionOptions -> Verbosity
verbosity PatchSelectionOptions
o forall a. Eq a => a -> a -> Bool
== Verbosity
Verbose) forall a b. (a -> b) -> a -> b
$
                                       forall (p :: * -> * -> *) wY wT.
ShowPatch p =>
FL (LabelledPatch p) wY wT -> IO ()
showskippedpatch FL (LabelledPatch p) wY wT
ps
      _nevermind_ :: ShowS
_nevermind_ String
jn = String
"Will not ask whether to " forall a. [a] -> [a] -> [a]
++ String
jn forall a. [a] -> [a] -> [a]
++ String
" "
      _these_ :: Int -> String
_these_ Int
n  = forall a. Show a => a -> String
show Int
n forall a. [a] -> [a] -> [a]
++ String
" already decided " forall a. [a] -> [a] -> [a]
++ Int -> ShowS
_elem_ Int
n String
""
      _elem_ :: Int -> ShowS
_elem_ Int
n = forall n. Countable n => Int -> n -> ShowS
englishNum Int
n (String -> Noun
Noun String
"patch")
      showskippedpatch :: ShowPatch p => FL (LabelledPatch p) wY wT -> IO ()
      showskippedpatch :: forall (p :: * -> * -> *) wY wT.
ShowPatch p =>
FL (LabelledPatch p) wY wT -> IO ()
showskippedpatch =
        Printers -> Doc -> IO ()
putDocLnWith Printers
fancyPrinters forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc] -> Doc
vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL (forall (p :: * -> * -> *) wX wY.
ShowPatch p =>
Verbosity -> WithSummary -> p wX wY -> Doc
showFriendly Verbosity
NormalVerbosity WithSummary
NoSummary forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel)

decided :: Slot -> Bool
decided :: Slot -> Bool
decided Slot
InMiddle = Bool
False
decided Slot
_ = Bool
True

-- | The action bound to space, depending on the current status of the
-- patch.
getDefault :: Bool -> Slot -> Char
getDefault :: Bool -> Slot -> Char
getDefault Bool
_ Slot
InMiddle = Char
'w'
getDefault Bool
True Slot
InFirst  = Char
'n'
getDefault Bool
True Slot
InLast   = Char
'y'
getDefault Bool
False Slot
InFirst = Char
'y'
getDefault Bool
False Slot
InLast  = Char
'n'

askAboutDepends :: (IsRepoType rt, RepoPatch p, ApplyState p ~ Tree)
                => Repository rt p wR wU wT -> FL (PrimOf p) wT wY
                -> PatchSelectionOptions
                -> [PatchInfo] -> IO [PatchInfo]
askAboutDepends :: forall (rt :: RepoType) (p :: * -> * -> *) wR wU wT wY.
(IsRepoType rt, RepoPatch p, ApplyState p ~ Tree) =>
Repository rt p wR wU wT
-> FL (PrimOf p) wT wY
-> PatchSelectionOptions
-> [PatchInfo]
-> IO [PatchInfo]
askAboutDepends Repository rt p wR wU wT
repository FL (PrimOf p) wT wY
pa' PatchSelectionOptions
ps_opts [PatchInfo]
olddeps = do
  -- Ideally we'd just default the olddeps to yes but still ask about them.
  -- SelectChanges doesn't currently (17/12/09) offer a way to do this so would
  -- have to have this support added first.
  PatchSet rt p Origin wT
pset <- forall (rt :: RepoType) (p :: * -> * -> *) wR wU wT.
(IsRepoType rt, PatchListFormat p, ReadPatch p) =>
Repository rt p wR wU wT -> String -> IO (PatchSet rt p Origin wT)
readTentativeRepo Repository rt p wR wU wT
repository (forall (rt :: RepoType) (p :: * -> * -> *) wR wU wT.
Repository rt p wR wU wT -> String
repoLocation Repository rt p wR wU wT
repository)
  -- Let the user select only from patches after the last clean tag.
  -- We do this for efficiency, otherwise independentPatchIds can
  -- take a /very/ long time to finish. The limitation this imposes
  -- is a bit arbitrary from a user perspective. Note however that
  -- contextPatches at least gives us this latest clean tag to select.
  PatchSet rt p Origin wZ
_ :> RL (PatchInfoAnd rt p) wZ wT
untagged <- forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
contextPatches PatchSet rt p Origin wT
pset
  -- Note: using anonymous here seems to be safe since we don't store any patches
  -- and only return a list of PatchInfo
  PatchInfoAndG rt (Named p) wT wY
pa <- forall (p :: * -> * -> *) wX wY (rt :: RepoType).
(Ident p, PatchId p ~ PatchInfo) =>
p wX wY -> PatchInfoAndG rt p wX wY
n2pia forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (p :: * -> * -> *) wX wY.
Named p wX wY -> [PatchInfo] -> Named p wX wY
adddeps [PatchInfo]
olddeps forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (p :: * -> * -> *) wX wY.
FromPrim p =>
FL (PrimOf p) wX wY -> IO (Named p wX wY)
anonymous FL (PrimOf p) wT wY
pa'
  -- get rid of all (implicit and explicit) dependencies of pa
  RL (PatchInfoAnd rt p) wZ wZ
_ :> PatchInfoAnd rt p wZ wZ
_ :> RL (PatchInfoAnd rt p) wZ wY
non_deps <- forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) (RL p) p wX wY -> (:>) (RL p) (p :> RL p) wX wY
commuteWhatWeCanRL (RL (PatchInfoAnd rt p) wZ wT
untagged forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfoAndG rt (Named p) wT wY
pa)
  FL (PatchInfoAnd rt p) wZ wZ
candidates :> FL (PatchInfoAnd rt p) wZ wY
_ <-
    forall (p :: * -> * -> *) wX wY.
(MatchableRP p, ShowPatch p, ShowContextPatch p,
 ApplyState p ~ Tree, ApplyState p ~ ApplyState (PrimOf p)) =>
FL p wX wY -> SelectionConfig p -> IO ((:>) (FL p) (FL p) wX wY)
runSelection (forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wZ wY
non_deps) forall a b. (a -> b) -> a -> b
$
      forall (p :: * -> * -> *).
Matchable p =>
WhichChanges
-> String
-> PatchSelectionOptions
-> Maybe (Splitter p)
-> Maybe [AnchoredPath]
-> SelectionConfig p
selectionConfig WhichChanges
FirstReversed String
"depend on" PatchSelectionOptions
ps_opts
        { matchFlags :: [MatchFlag]
matchFlags = [], interactive :: Bool
interactive = Bool
True } forall a. Maybe a
Nothing forall a. Maybe a
Nothing
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [PatchInfo]
olddeps forall a. Eq a => [a] -> [a] -> [a]
`union` forall (p :: * -> * -> *) wX wY.
(Commute p, Ident p) =>
RL p wX wY -> [PatchId p]
independentPatchIds (forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
candidates)

-- | From an 'RL' of patches select the identities of those that are
-- not depended upon by later patches.
independentPatchIds :: (Commute p, Ident p) => RL p wX wY -> [PatchId p]
independentPatchIds :: forall (p :: * -> * -> *) wX wY.
(Commute p, Ident p) =>
RL p wX wY -> [PatchId p]
independentPatchIds RL p wX wY
NilRL = []
independentPatchIds (RL p wX wY
ps :<: p wY wY
p) =
  case forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) (RL p) p wX wY -> (:>) (RL p) (p :> RL p) wX wY
commuteWhatWeCanRL (RL p wX wY
ps forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> p wY wY
p) of
    RL p wX wZ
_ :> p wZ wZ
_ :> RL p wZ wY
non_deps ->
      forall (p :: * -> * -> *) wX wY. Ident p => p wX wY -> PatchId p
ident p wY wY
p forall a. a -> [a] -> [a]
: forall (p :: * -> * -> *) wX wY.
(Commute p, Ident p) =>
RL p wX wY -> [PatchId p]
independentPatchIds RL p wZ wY
non_deps