content: {-# LANGUAGE DeriveDataTypeable #-}
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  XMonad.Hooks.WorkspaceHistory
  -- Copyright   :  (c) 2013 Dmitri Iouchtchenko
  -- License     :  BSD3-style (see LICENSE)
  --
  -- Maintainer  :  Dmitri Iouchtchenko <johnnyspoon@gmail.com>
  -- Stability   :  unstable
  -- Portability :  unportable
  --
  -- Keeps track of workspace viewing order.
  --
  -----------------------------------------------------------------------------
  
  module XMonad.Hooks.WorkspaceHistory
      ( -- * Usage
        -- $usage
  
        -- * Hooking
        workspaceHistoryHook
  
        -- * Querying
      , workspaceHistory
  
      ) where
  
  import XMonad
  import XMonad.StackSet (currentTag)
  import qualified XMonad.Util.ExtensibleState as XS
  
  -- $usage
  -- To record the order in which you view workspaces, you can use this
  -- module with the following in your @~\/.xmonad\/xmonad.hs@:
  --
  -- > import XMonad.Hooks.WorkspaceHistory (workspaceHistoryHook)
  --
  -- Then add the hook to your 'logHook':
  --
  -- >  main = xmonad $ def
  -- >      { ...
  -- >      , logHook = ... >> workspaceHistoryHook >> ...
  -- >      , ...
  -- >      }
  --
  -- To make use of the collected data, a query function is provided.
  
  data WorkspaceHistory =
      WorkspaceHistory { history :: [WorkspaceId] -- ^ Workspaces in reverse-chronological order.
                       }
      deriving (Typeable, Read, Show)
  
  instance ExtensionClass WorkspaceHistory where
      initialValue = WorkspaceHistory []
      extensionType = PersistentExtension
  
  -- | A 'logHook' that keeps track of the order in which workspaces have
  -- been viewed.
  workspaceHistoryHook :: X ()
  workspaceHistoryHook = gets (currentTag . windowset) >>= (XS.modify . makeFirst)
  
  -- | A list of workspace tags in the order they have been viewed, with the
  -- most recent first. No duplicates are present, but not all workspaces are
  -- guaranteed to appear, and there may be workspaces that no longer exist.
  workspaceHistory :: X [WorkspaceId]
  workspaceHistory = XS.gets history
  
  
  -- | Cons the 'WorkspaceId' onto the 'WorkspaceHistory' if it is not
  -- already there, or move it to the front if it is.
  makeFirst :: WorkspaceId -> WorkspaceHistory -> WorkspaceHistory
  makeFirst w v = let (xs, ys) = break (w ==) $ history v
                  in v { history = w : (xs ++ drop 1 ys) }
  