xmonad-masser/src/XMonad/TopicUtils.hs

91 lines
3.2 KiB
Haskell

module XMonad.TopicUtils where
import Data.Maybe (fromMaybe, listToMaybe, mapMaybe)
import Data.List (isPrefixOf, sort, nub)
import XMonad.Actions.TopicSpace
import XMonad
import qualified Data.Map as M
import XMonad.Actions.GridSelect hiding (gridselectWorkspace)
import XMonad.Util.Run (safeSpawn)
import qualified XMonad.StackSet as W
import XMonad.Util.Dmenu (dmenu)
import XMonad.Actions.DynamicWorkspaces
import XMonad.Util.NamedWindows (getName)
realTopicDir :: M.Map String FilePath -> X String
realTopicDir tg = do
topic <- realTopic
return . fromMaybe "" . M.lookup topic $ tg
safeRunInTerm :: Dir -> Maybe String -> X ()
safeRunInTerm dir Nothing = safeSpawn "urxvt" ["-cd", dir]
safeRunInTerm dir (Just command) = safeSpawn "urxvt" ["-cd", dir, "-e", command]
inactiveTags :: X [WorkspaceId]
inactiveTags = map W.tag . inactive' <$> gets windowset
where
inactive' s = W.hidden s ++ map W.workspace (filter (\w -> (W.tag . W.workspace . W.current) s /= (W.tag . W.workspace) w) (W.visible s))
gridselectMove :: GSConfig WorkspaceId -> X ()
gridselectMove conf = do
topics <- inactiveTags
gridselect conf [(x,x) | x <- topics] >>= maybe (return ()) (windows . W.shift)
dmenuMove :: X ()
dmenuMove = do
topics <- inactiveTags
dmenu topics >>= \t -> windows (W.shift t)
gsConfig :: GSConfig Window
gsConfig = def{gs_navigate = navNSearch, gs_colorizer = fromClassName}
-- Copied from gridselect and modified so that it doesn't contain current and visible
-- - Doesn't contain current and visible
-- - Takes a topicspace viewfunc
gridselectWorkspace :: GSConfig WorkspaceId -> (WorkspaceId -> X ()) -> X ()
gridselectWorkspace conf viewFunc = withWindowSet $ \ws -> do
let wss = map W.tag . W.hidden $ ws
gridselect conf (zip wss wss) >>= flip whenJust viewFunc
gotoSelected' :: GSConfig Window -> X ()
gotoSelected' gsconf = do
w <- gridselectCurrentWindows gsconf
maybe (return ()) (windows . W.focusWindow) w
gridselectCurrentWindows :: GSConfig Window -> X (Maybe Window)
gridselectCurrentWindows gsconf = windowMap >>= gridselect gsconf
where
getName' = fmap show . getName
kvPair w = flip (,) w `fmap` getName' w
windowMap = do
ws <- gets (nub . W.integrate' . W.stack . W.workspace . W.current . windowset)
mapM kvPair ws
visualSelect :: TopicConfig -> X ()
visualSelect cfg = gridselectWorkspace def{gs_navigate = navNSearch, gs_colorizer = stringColorizer} (switchTopic cfg)
realTopic :: X String
realTopic = gets (real . W.tag . W.workspace . W.current . windowset)
where real = takeWhile (/= ':')
currentTopicAction' :: TopicConfig -> X ()
currentTopicAction' tg = do
topic <- realTopic
topicAction tg topic
copyTopic :: X ()
copyTopic = do
currentTopic <- realTopic
lastN <- gets (listToMaybe . reverse . sort . mapMaybe (subset currentTopic . W.tag) . W.workspaces . windowset)
addWorkspace (currentTopic ++ ":" ++ (show $ maybe 2 (+1) lastN))
where
subset :: String -> String -> Maybe Int
subset topic other = if topic `isPrefixOf` other then (readM $ tail' $ snd $ break (== ':') other) else Nothing
readM a = case reads a of
[(x,_)] -> Just x
_ -> Nothing
tail' [] = []
tail' xs = tail xs