From 367e73c9f82a7babc44390659acae878073bb9e4 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 23 Nov 2022 14:26:39 -0700 Subject: Fully persistent macro settings. Stores the macros in a file --- src/Rahm/Desktop/Keys/Wml.hs | 85 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Rahm/Desktop/Keys/Wml.hs b/src/Rahm/Desktop/Keys/Wml.hs index 52c5e28..0311c97 100644 --- a/src/Rahm/Desktop/Keys/Wml.hs +++ b/src/Rahm/Desktop/Keys/Wml.hs @@ -113,18 +113,26 @@ import Rahm.Desktop.XMobarLog.PendingBuffer ( addStringToPendingBuffer, setPendingBuffer, ) +import System.Directory (doesFileExist) import System.Exit (ExitCode (..), exitSuccess, exitWith) +import System.FilePath (()) +import System.IO (readFile) import Text.Printf (printf) +import Text.Read (readMaybe) import XMonad ( Default (def), + Directories' (dataDir), ExtensionClass (..), KeyMask, KeySym, + MonadReader (ask), StateExtension (PersistentExtension), Typeable, Window, WorkspaceId, X, + asks, + directories, io, killWindow, windows, @@ -133,20 +141,69 @@ import XMonad xK_Return, ) import XMonad.Prompt.ConfirmPrompt (confirmPrompt) -import qualified XMonad.Util.ExtensibleState as XS (get, modify) +import qualified XMonad.Util.ExtensibleState as XS (get, modify, put) import Prelude hiding (head, last) type KeyString = [(KeyMask, KeySym, String)] +data MaybeMacros = NoMacros | YesMacros Macros + deriving (Read, Show) + data Macros = Macros { workspaceMacros :: Map (KeyMask, KeySym) KeyString, windowsetMacros :: Map (KeyMask, KeySym) KeyString } deriving (Read, Show) -instance ExtensionClass Macros where - initialValue = Macros Map.empty Map.empty - extensionType = PersistentExtension +getMacroDataFile :: X FilePath +getMacroDataFile = asks (( "rde-recorded-macros") . dataDir . directories) + +getMacros :: X Macros +getMacros = do + XS.get + >>= ( \case + NoMacros -> do + file <- getMacroDataFile + exists <- io $ doesFileExist file + if exists + then + io (readFile file) + >>= ( \s -> + let macros = fromMaybe (Macros mempty mempty) (readMaybe s :: Maybe Macros) + in XS.put (YesMacros macros) >> return macros + ) + else return $ Macros mempty mempty + YesMacros macros -> return macros + ) + +saveMacros :: X () +saveMacros = do + dataFile <- getMacroDataFile + macros <- getMacros + io $ writeFile dataFile $ show macros + +insertWorkspaceMacroString :: (KeyMask, KeySym) -> KeyString -> X () +insertWorkspaceMacroString k ks = do + macros <- getMacros + XS.put $ + YesMacros $ + macros + { workspaceMacros = Map.insert k ks (workspaceMacros macros) + } + saveMacros + +insertWindowSetMacroString :: (KeyMask, KeySym) -> KeyString -> X () +insertWindowSetMacroString k ks = do + macros <- getMacros + XS.put $ + YesMacros $ + macros + { windowsetMacros = Map.insert k ks (windowsetMacros macros) + } + saveMacros + +instance ExtensionClass MaybeMacros where + initialValue = NoMacros data Workspace = forall a. (Typeable a) => @@ -165,11 +222,7 @@ readWorkspaceMacro = lift $ setPendingBuffer $ printf "Rec %s " s macro <- readMacroString - lift $ - XS.modify $ \m -> - m - { workspaceMacros = Map.insert (mask, sym) macro (workspaceMacros m) - } + lift $ insertWorkspaceMacroString (mask, sym) macro readWindowsetMacro :: MaybeT X () readWindowsetMacro = @@ -179,11 +232,7 @@ readWindowsetMacro = lift $ setPendingBuffer $ printf "Rec %s " s macro <- readMacroString - lift $ - XS.modify $ \m -> - m - { windowsetMacros = Map.insert (mask, sym) macro (windowsetMacros m) - } + lift $ insertWindowSetMacroString (mask, sym) macro readMacroString :: MaybeT X KeyString readMacroString = do @@ -336,7 +385,7 @@ readNextWorkspaceName = joinMaybe $ workspaceName <$> readNextWorkspace readNextWorkspace :: (KeyFeeder m) => MaybeT m Workspace readNextWorkspace = readNextKey $ \mask sym str -> do - macros <- (lift . fromX) $ workspaceMacros <$> XS.get + macros <- (lift . fromX) $ workspaceMacros <$> getMacros case (mask, sym, str) of -- Escape kills the "readNextWorkspace" and returns nothing. @@ -473,6 +522,7 @@ readNextWorkspace = if null l1 then ws2 else ws1 + _ -> MaybeT (return Nothing) where mt :: (KeyFeeder m) => X a -> MaybeT m a mt = lift . fromX @@ -480,15 +530,13 @@ readNextWorkspace = readNextLocationSet :: (KeyFeeder m) => MaybeT m [Location] readNextLocationSet = readNextKey $ \mask sym str -> do - macros <- (lift . fromX) $ windowsetMacros <$> XS.get + macros <- (lift . fromX) $ windowsetMacros <$> getMacros case (mask, sym, str) of -- Escape returns nothing and aborts reading the next location. (_, e, _) | e == xK_Escape -> MaybeT $ return Nothing -- Macros takes precedence. (mask, keysym, _) | (Just macro) <- Map.lookup (mask, keysym) macros -> do - macro <- (MaybeT . fromX) (Map.lookup (mask, keysym) . windowsetMacros <$> XS.get) - lift $ fromX $ logs Info "Executing Macro: %s" (show macro) fromMaybeTX $ locationSetForKeysT macro -- A character is the base-case. Refers to a collection of windows. @@ -575,6 +623,7 @@ readNextLocationSet = l1 <- readNextLocationSet l2 <- readNextLocationSet return $ filter (`elem` l2) l1 + _ -> MaybeT (return Nothing) where mt :: (KeyFeeder m) => X a -> MaybeT m a mt = lift . fromX -- cgit