content: -----------------------------------------------------------------------------
  -- |
  -- Module      :  XMonad.Actions.SwapWorkspaces
  -- Copyright   :  (c) Devin Mullins <me@twifkak.com>
  -- License     :  BSD3-style (see LICENSE)
  --
  -- Maintainer  :  Devin Mullins <me@twifkak.com>
  -- Stability   :  unstable
  -- Portability :  unportable
  --
  -- Lets you swap workspace tags, so you can keep related ones next to
  -- each other, without having to move individual windows.
  --
  -----------------------------------------------------------------------------
  
  module XMonad.Actions.SwapWorkspaces (
                                       -- * Usage
                                       -- $usage
                                       swapWithCurrent,
                                       swapTo,
                                       swapWorkspaces,
                                       Direction1D(..)
                                      ) where
  
  import XMonad (windows, X())
  import XMonad.StackSet
  import XMonad.Actions.CycleWS
  import XMonad.Util.WorkspaceCompare
  
  
  -- $usage
  -- Add this import to your @~\/.xmonad\/xmonad.hs@:
  --
  -- > import XMonad.Actions.SwapWorkspaces
  --
  -- Then throw something like this in your keys definition:
  --
  -- > ++
  -- > [((modm .|. controlMask, k), windows $ swapWithCurrent i)
  -- >     | (i, k) <- zip workspaces [xK_1 ..]]
  --
  -- After installing this update, if you're on workspace 1, hitting mod-ctrl-5
  -- will swap workspaces 1 and 5.
  --
  -- For detailed instructions on editing your key bindings, see
  -- "XMonad.Doc.Extending#Editing_key_bindings".
  
  -- | Swaps the currently focused workspace with the given workspace tag, via
  --   @swapWorkspaces@.
  swapWithCurrent :: Eq i => i -> StackSet i l a s sd -> StackSet i l a s sd
  swapWithCurrent t s = swapWorkspaces t (currentTag s) s
  
  -- | Say @swapTo Next@ or @swapTo Prev@ to move your current workspace.
  -- This is an @X ()@ so can be hooked up to your keybindings directly.
  swapTo :: Direction1D -> X ()
  swapTo dir = findWorkspace getSortByIndex dir AnyWS 1 >>= windows . swapWithCurrent
  
  -- | Takes two workspace tags and an existing XMonad.StackSet and returns a new
  --   one with the two corresponding workspaces' tags swapped.
  swapWorkspaces :: Eq i => i -> i -> StackSet i l a s sd -> StackSet i l a s sd
  swapWorkspaces t1 t2 = mapWorkspace swap
      where swap w = if      tag w == t1 then w { tag = t2 }
                     else if tag w == t2 then w { tag = t1 }
                     else w
  