aboutsummaryrefslogtreecommitdiff
path: root/src/Internal/Marking.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Internal/Marking.hs')
-rw-r--r--src/Internal/Marking.hs77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/Internal/Marking.hs b/src/Internal/Marking.hs
new file mode 100644
index 0000000..352131b
--- /dev/null
+++ b/src/Internal/Marking.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+module Internal.Marking where
+
+import XMonad
+import Data.IORef
+import Data.Map (Map)
+
+import System.FilePath
+import System.IO
+import Control.Exception
+
+import qualified Data.Map as Map
+
+{- Submodule that handles marking windows so they can be jumped back to. -}
+
+type Mark = Char
+
+data MarkState =
+ MarkState {
+ markStateMap :: Map Mark Window
+ , markLast :: Maybe Window
+ } deriving (Read, Show)
+
+data MarkContext = MarkContext (IORef MarkState)
+
+readMarkState :: IO MarkState
+readMarkState = do
+ dir <- getXMonadDir
+ let markstate = dir </> "markstate"
+ catch
+ (read <$> (hGetContents =<< openFile markstate ReadMode))
+ (\(e :: IOError) -> return (MarkState mempty Nothing))
+
+saveMarkState :: MarkState -> X ()
+saveMarkState ms = do
+ dir <- getXMonadDir
+ let markstate = dir </> "markstate"
+ liftIO $ writeFile markstate (show ms)
+
+
+withNewMarkContext :: (MarkContext -> IO a) -> IO a
+withNewMarkContext fn = do
+ ioref <- newIORef =<< readMarkState
+ fn (MarkContext ioref)
+
+markCurrentWindow :: MarkContext -> Mark -> X ()
+markCurrentWindow (MarkContext ioref) mark = do
+ withFocused $ \win ->
+ liftIO $
+ modifyIORef ioref $ \state@(MarkState {markStateMap = ms}) ->
+ state {
+ markStateMap = Map.insert mark win ms
+ }
+
+ saveMarkState =<< liftIO (readIORef ioref)
+
+jumpToLast :: MarkContext -> X ()
+jumpToLast (MarkContext ioref) = do
+ withFocused $ \win -> do
+ m <- markLast <$> (liftIO $ readIORef ioref)
+ liftIO $ modifyIORef ioref (\state -> state { markLast = Just win })
+ mapM_ focus m
+
+ saveMarkState =<< liftIO (readIORef ioref)
+
+jumpToMark :: MarkContext -> Mark -> X ()
+jumpToMark (MarkContext ioref) mark = do
+ withFocused $ \win -> do
+ MarkState {markStateMap = m} <- liftIO $ readIORef ioref
+ case Map.lookup mark m of
+ Nothing -> return ()
+ Just w -> do
+ liftIO $ modifyIORef ioref $ \state ->
+ state { markLast = Just win }
+ focus w
+
+ saveMarkState =<< liftIO (readIORef ioref)