aboutsummaryrefslogtreecommitdiffstats
path: root/XMonad/Actions/SpawnOn.hs
blob: d452cdf281d88d57bf5e843fa8bf5a1f400f8d0c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
-----------------------------------------------------------------------------
-- |
-- Module       : XMonad.Actions.SpawnOn
-- Copyright    : (c) Spencer Janssen
-- License      : BSD
--
-- Maintainer   : Spencer Janssen <spencerjanssen@gmail.com>
-- Stability    : unstable
-- Portability  : unportable
--
-- This module provides helper functions to be used in @manageHook@. Here's
-- how you might use this:
--
-- > import XMonad.Hooks.ManageHelpers
-- > main = do
-- >     sp <- mkSpawner
-- >     xmonad defaultConfig {
-- >         ...
-- >         manageHook = spawnHook sp <+> manageHook defaultConfig
-- >         ...
-- >     }

module XMonad.Actions.SpawnOn (
    Spawner,
    mkSpawner,
    manageSpawn,
    spawnHere,
    spawnOn,
    shellPromptHere,
    shellPromptOn
) where

import Data.IORef
import System.Posix.Types (ProcessID)

import XMonad
import qualified XMonad.StackSet as W

import XMonad.Hooks.ManageHelpers
import XMonad.Prompt
import XMonad.Prompt.Shell

newtype Spawner = Spawner {pidsRef :: IORef [(ProcessID, WorkspaceId)]}

maxPids :: Int
maxPids = 5

mkSpawner :: (Functor m, MonadIO m) => m Spawner
mkSpawner = io . fmap Spawner $ newIORef []

manageSpawn :: Spawner -> ManageHook
manageSpawn sp = do
    pids <- io . readIORef $ pidsRef sp
    mp <- pid
    case flip lookup pids =<< mp of
        Just w -> doF (W.shift w)
        Nothing -> doF id

mkPrompt :: (String -> X ()) -> XPConfig -> X ()
mkPrompt cb c = do
    cmds <- io $ getCommands
    mkXPrompt Shell c (getShellCompl cmds) cb

shellPromptHere :: Spawner -> XPConfig -> X ()
shellPromptHere sp = mkPrompt (spawnHere sp)

shellPromptOn :: Spawner -> WorkspaceId -> XPConfig -> X ()
shellPromptOn sp ws = mkPrompt (spawnOn sp ws)

spawnHere :: Spawner -> String -> X ()
spawnHere sp cmd = withWindowSet $ \ws -> spawnOn sp (currTag ws) cmd
 where currTag = W.tag . W.workspace . W.current

spawnOn :: Spawner -> WorkspaceId -> String -> X ()
spawnOn sp ws cmd = do
    p <- spawnPID cmd
    io $ modifyIORef (pidsRef sp) (take maxPids . ((p, ws) :))