    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Groups
    -- Copyright   :  Quentin Moser <moserq@gmail.com>
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :  orphaned
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Layout modifier that can modify the description of its underlying
    -- layout on a (hopefully) flexible way.
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.Renamed ( -- * Usage
                                   -- $usage
                                   renamed
                                 , Rename(..) ) where

    import XMonad
    import XMonad.Layout.LayoutModifier

    -- $usage
    -- You can use this module by adding
    --
    -- > import XMonad.Layout.Renamed
    --
    -- to your @~\/.xmonad\/xmonad.hs@.
    --
    -- You can then use 'renamed' to modify the description of your
    -- layouts. For example:
    --
    -- > myLayout = renamed [PrependWords "Awesome"] $ tiled ||| Mirror tiled ||| Full

    -- | Apply a list of 'Rename' values to a layout, from left to right.
    renamed :: [Rename a] -> l a -> ModifiedLayout Rename l a
    renamed :: [Rename a] -> l a -> ModifiedLayout Rename l a
    renamed = Rename a -> l a -> ModifiedLayout Rename l a
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (Rename a -> l a -> ModifiedLayout Rename l a)
    -> ([Rename a] -> Rename a)
    -> [Rename a]
    -> l a
    -> ModifiedLayout Rename l a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Rename a] -> Rename a
    forall a. [Rename a] -> Rename a
    Chain

    -- | The available renaming operations
    data Rename a = CutLeft Int -- ^ Remove a number of characters from the left
                  | CutRight Int -- ^ Remove a number of characters from the right
                  | Append String -- ^ Add a string on the right
                  | Prepend String -- ^ Add a string on the left
                  | CutWordsLeft Int -- ^ Remove a number of words from the left
                  | CutWordsRight Int -- ^ Remove a number of words from the right
                  | AppendWords String -- ^ Add a string to the right, prepending a space to it
                                       -- if necessary
                  | PrependWords String -- ^ Add a string to the left, appending a space to it if
                                        -- necessary
                  | Replace String -- ^ Replace with another string
                  | Chain [Rename a] -- ^ Apply a list of modifications in left-to-right order
      deriving (Int -> Rename a -> ShowS
    [Rename a] -> ShowS
    Rename a -> String
    (Int -> Rename a -> ShowS)
    -> (Rename a -> String) -> ([Rename a] -> ShowS) -> Show (Rename a)
    forall a. Int -> Rename a -> ShowS
    forall a. [Rename a] -> ShowS
    forall a. Rename a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Rename a] -> ShowS
    $cshowList :: forall a. [Rename a] -> ShowS
    show :: Rename a -> String
    $cshow :: forall a. Rename a -> String
    showsPrec :: Int -> Rename a -> ShowS
    $cshowsPrec :: forall a. Int -> Rename a -> ShowS
    Show, ReadPrec [Rename a]
    ReadPrec (Rename a)
    Int -> ReadS (Rename a)
    ReadS [Rename a]
    (Int -> ReadS (Rename a))
    -> ReadS [Rename a]
    -> ReadPrec (Rename a)
    -> ReadPrec [Rename a]
    -> Read (Rename a)
    forall a. ReadPrec [Rename a]
    forall a. ReadPrec (Rename a)
    forall a. Int -> ReadS (Rename a)
    forall a. ReadS [Rename a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Rename a]
    $creadListPrec :: forall a. ReadPrec [Rename a]
    readPrec :: ReadPrec (Rename a)
    $creadPrec :: forall a. ReadPrec (Rename a)
    readList :: ReadS [Rename a]
    $creadList :: forall a. ReadS [Rename a]
    readsPrec :: Int -> ReadS (Rename a)
    $creadsPrec :: forall a. Int -> ReadS (Rename a)
    Read, Rename a -> Rename a -> Bool
    (Rename a -> Rename a -> Bool)
    -> (Rename a -> Rename a -> Bool) -> Eq (Rename a)
    forall a. Rename a -> Rename a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Rename a -> Rename a -> Bool
    $c/= :: forall a. Rename a -> Rename a -> Bool
    == :: Rename a -> Rename a -> Bool
    $c== :: forall a. Rename a -> Rename a -> Bool
    Eq)

    apply :: Rename a -> String -> String
    apply :: Rename a -> ShowS
    apply (CutLeft i :: Int
    i) s :: String
    s = Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop Int
    i String
    s
    apply (CutRight i :: Int
    i) s :: String
    s = Int -> ShowS
    forall a. Int -> [a] -> [a]
    take (String -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length String
    s Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    i) String
    s
    apply (CutWordsLeft i :: Int
    i) s :: String
    s = [String] -> String
    unwords ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ Int -> [String] -> [String]
    forall a. Int -> [a] -> [a]
    drop Int
    i ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ String -> [String]
    words String
    s
    apply (CutWordsRight i :: Int
    i) s :: String
    s = let ws :: [String]
    ws = String -> [String]
    words String
    s
                               in [String] -> String
    unwords ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ Int -> [String] -> [String]
    forall a. Int -> [a] -> [a]
    take ([String] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [String]
    ws Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    i) [String]
    ws
    apply (Replace s :: String
    s) _ = String
    s
    apply (Append s' :: String
    s') s :: String
    s = String
    s String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    s'
    apply (Prepend s' :: String
    s') s :: String
    s = String
    s' String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    s
    apply (AppendWords s' :: String
    s') s :: String
    s = [String] -> String
    unwords ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ String -> [String]
    words String
    s [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    s']
    apply (PrependWords s' :: String
    s') s :: String
    s = [String] -> String
    unwords ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ String
    s' String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : String -> [String]
    words String
    s
    apply (Chain rs :: [Rename a]
    rs) s :: String
    s = (ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $String
    s) (ShowS -> String) -> ShowS -> String
    forall a b. (a -> b) -> a -> b
    $ (ShowS -> ShowS -> ShowS) -> ShowS -> [ShowS] -> ShowS
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ((ShowS -> ShowS -> ShowS) -> ShowS -> ShowS -> ShowS
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.)) ShowS
    forall a. a -> a
    id ([ShowS] -> ShowS) -> [ShowS] -> ShowS
    forall a b. (a -> b) -> a -> b
    $ (Rename a -> ShowS) -> [Rename a] -> [ShowS]
    forall a b. (a -> b) -> [a] -> [b]
    map Rename a -> ShowS
    forall a. Rename a -> ShowS
    apply [Rename a]
    rs

    instance LayoutModifier Rename a where
        modifyDescription :: Rename a -> l a -> String
    modifyDescription r :: Rename a
    r l :: l a
    l = Rename a -> ShowS
    forall a. Rename a -> ShowS
    apply Rename a
    r (l a -> String
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> String
    description l a
    l)