module Language.Haskell.Brittany.Internal.Transformations.Indent
  ( transformSimplifyIndent
  )
where



#include "prelude.inc"

import           Language.Haskell.Brittany.Internal.Utils
import           Language.Haskell.Brittany.Internal.Config.Types
import           Language.Haskell.Brittany.Internal.Types

import qualified Data.Generics.Uniplate.Direct as Uniplate



-- prepare layouting by translating BDPar's, replacing them with Indents and
-- floating those in. This gives a more clear picture of what exactly is
-- affected by what amount of indentation.
transformSimplifyIndent :: BriDoc -> BriDoc
transformSimplifyIndent :: BriDoc -> BriDoc
transformSimplifyIndent = (BriDoc -> Maybe BriDoc) -> BriDoc -> BriDoc
forall on. Uniplate on => (on -> Maybe on) -> on -> on
Uniplate.rewrite ((BriDoc -> Maybe BriDoc) -> BriDoc -> BriDoc)
-> (BriDoc -> Maybe BriDoc) -> BriDoc -> BriDoc
forall a b. (a -> b) -> a -> b
$ \case
  BDPar BrIndent
ind (BDLines [BriDoc]
lines) BriDoc
indented ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ BrIndent -> BriDoc -> BriDoc
BDEnsureIndent BrIndent
ind (BriDoc -> BriDoc) -> BriDoc -> BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> BriDoc
BDLines ([BriDoc] -> BriDoc) -> [BriDoc] -> BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc]
lines [BriDoc] -> [BriDoc] -> [BriDoc]
forall a. [a] -> [a] -> [a]
++ [BriDoc
indented]
  BDPar BrIndent
ind (BDCols ColSig
sig [BriDoc]
cols) BriDoc
indented ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ ColSig -> [BriDoc] -> BriDoc
BDCols ColSig
sig ([BriDoc] -> [BriDoc]
forall a. [a] -> [a]
List.init [BriDoc]
cols [BriDoc] -> [BriDoc] -> [BriDoc]
forall a. [a] -> [a] -> [a]
++ [BrIndent -> BriDoc -> BriDoc -> BriDoc
BDPar BrIndent
ind ([BriDoc] -> BriDoc
forall a. [a] -> a
List.last [BriDoc]
cols) BriDoc
indented])
  BDPar BrIndent
BrIndentNone BriDoc
_ BriDoc
_ -> Maybe BriDoc
forall a. Maybe a
Nothing
  BDPar BrIndent
ind BriDoc
x BriDoc
indented ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ BrIndent -> BriDoc -> BriDoc -> BriDoc
BDPar BrIndent
BrIndentNone (BrIndent -> BriDoc -> BriDoc
BDAddBaseY BrIndent
ind BriDoc
x) (BrIndent -> BriDoc -> BriDoc
BDEnsureIndent BrIndent
ind BriDoc
indented)
  -- BDPar ind x indented ->
  --   Just $ BDLines
  --     [ BDAddBaseY ind x
  --     , BDEnsureIndent ind indented
  --     ]
  BDLines [BriDoc]
lines | (BriDoc -> Bool) -> [BriDoc] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ( \case
                        BDLines{} -> Bool
True
                        BDEmpty{} -> Bool
True
                        BriDoc
_         -> Bool
False
                      )
                      [BriDoc]
lines ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> BriDoc
BDLines ([BriDoc] -> BriDoc) -> [BriDoc] -> BriDoc
forall a b. (a -> b) -> a -> b
$ (BriDoc -> Bool) -> [BriDoc] -> [BriDoc]
forall a. (a -> Bool) -> [a] -> [a]
filter BriDoc -> Bool
isNotEmpty ([BriDoc] -> [BriDoc]) -> [BriDoc] -> [BriDoc]
forall a b. (a -> b) -> a -> b
$ [BriDoc]
lines [BriDoc] -> (BriDoc -> [BriDoc]) -> [BriDoc]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      BDLines [BriDoc]
l -> [BriDoc]
l
      BriDoc
x         -> [BriDoc
x]
  BDLines [BriDoc
l] -> BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just BriDoc
l
  BDAddBaseY BrIndent
i (BDAnnotationPrior AnnKey
k BriDoc
x) ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ AnnKey -> BriDoc -> BriDoc
BDAnnotationPrior AnnKey
k (BrIndent -> BriDoc -> BriDoc
BDAddBaseY BrIndent
i BriDoc
x)
  BDAddBaseY BrIndent
i (BDAnnotationKW AnnKey
k Maybe AnnKeywordId
kw BriDoc
x) ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ AnnKey -> Maybe AnnKeywordId -> BriDoc -> BriDoc
BDAnnotationKW AnnKey
k Maybe AnnKeywordId
kw (BrIndent -> BriDoc -> BriDoc
BDAddBaseY BrIndent
i BriDoc
x)
  BDAddBaseY BrIndent
i (BDAnnotationRest AnnKey
k BriDoc
x) ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ AnnKey -> BriDoc -> BriDoc
BDAnnotationRest AnnKey
k (BrIndent -> BriDoc -> BriDoc
BDAddBaseY BrIndent
i BriDoc
x)
  BDAddBaseY BrIndent
i (BDSeq [BriDoc]
l) ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> BriDoc
BDSeq ([BriDoc] -> BriDoc) -> [BriDoc] -> BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> [BriDoc]
forall a. [a] -> [a]
List.init [BriDoc]
l [BriDoc] -> [BriDoc] -> [BriDoc]
forall a. [a] -> [a] -> [a]
++ [BrIndent -> BriDoc -> BriDoc
BDAddBaseY BrIndent
i (BriDoc -> BriDoc) -> BriDoc -> BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> BriDoc
forall a. [a] -> a
List.last [BriDoc]
l]
  BDAddBaseY BrIndent
i (BDCols ColSig
sig [BriDoc]
l) ->
    BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just (BriDoc -> Maybe BriDoc) -> BriDoc -> Maybe BriDoc
forall a b. (a -> b) -> a -> b
$ ColSig -> [BriDoc] -> BriDoc
BDCols ColSig
sig ([BriDoc] -> BriDoc) -> [BriDoc] -> BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> [BriDoc]
forall a. [a] -> [a]
List.init [BriDoc]
l [BriDoc] -> [BriDoc] -> [BriDoc]
forall a. [a] -> [a] -> [a]
++ [BrIndent -> BriDoc -> BriDoc
BDAddBaseY BrIndent
i (BriDoc -> BriDoc) -> BriDoc -> BriDoc
forall a b. (a -> b) -> a -> b
$ [BriDoc] -> BriDoc
forall a. [a] -> a
List.last [BriDoc]
l]
  BDAddBaseY BrIndent
_ lit :: BriDoc
lit@BDLit{} -> BriDoc -> Maybe BriDoc
forall a. a -> Maybe a
Just BriDoc
lit

  BriDoc
_                        -> Maybe BriDoc
forall a. Maybe a
Nothing