{-# LANGUAGE FlexibleContexts #-}
module XMonad.Actions.Prefix
(
PrefixArgument(..)
, usePrefixArgument
, useDefaultPrefixArgument
, withPrefixArgument
, isPrefixRaw
, isPrefixNumeric
, ppFormatPrefix
) where
import qualified Data.Map as M
import XMonad.Prelude
import XMonad
import XMonad.Util.ExtensibleState as XS
import XMonad.Util.Paste (sendKey)
import XMonad.Actions.Submap (submapDefaultWithKey)
import XMonad.Util.EZConfig (readKeySequence)
data PrefixArgument = Raw Int | Numeric Int | None
deriving (ReadPrec [PrefixArgument]
ReadPrec PrefixArgument
Int -> ReadS PrefixArgument
ReadS [PrefixArgument]
(Int -> ReadS PrefixArgument)
-> ReadS [PrefixArgument]
-> ReadPrec PrefixArgument
-> ReadPrec [PrefixArgument]
-> Read PrefixArgument
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PrefixArgument]
$creadListPrec :: ReadPrec [PrefixArgument]
readPrec :: ReadPrec PrefixArgument
$creadPrec :: ReadPrec PrefixArgument
readList :: ReadS [PrefixArgument]
$creadList :: ReadS [PrefixArgument]
readsPrec :: Int -> ReadS PrefixArgument
$creadsPrec :: Int -> ReadS PrefixArgument
Read, Int -> PrefixArgument -> ShowS
[PrefixArgument] -> ShowS
PrefixArgument -> String
(Int -> PrefixArgument -> ShowS)
-> (PrefixArgument -> String)
-> ([PrefixArgument] -> ShowS)
-> Show PrefixArgument
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrefixArgument] -> ShowS
$cshowList :: [PrefixArgument] -> ShowS
show :: PrefixArgument -> String
$cshow :: PrefixArgument -> String
showsPrec :: Int -> PrefixArgument -> ShowS
$cshowsPrec :: Int -> PrefixArgument -> ShowS
Show)
instance ExtensionClass PrefixArgument where
initialValue :: PrefixArgument
initialValue = PrefixArgument
None
extensionType :: PrefixArgument -> StateExtension
extensionType = PrefixArgument -> StateExtension
forall a. (Read a, Show a, ExtensionClass a) => a -> StateExtension
PersistentExtension
finallyX :: X a -> X a -> X a
finallyX :: X a -> X a -> X a
finallyX X a
job X a
cleanup = X a -> X a -> X a
forall a. X a -> X a -> X a
catchX (X a
job X a -> (a -> X a) -> X a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> X a
cleanup X a -> X a -> X a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r) X a
cleanup
usePrefixArgument :: LayoutClass l Window
=> String
-> XConfig l
-> XConfig l
usePrefixArgument :: String -> XConfig l -> XConfig l
usePrefixArgument String
prefix XConfig l
conf =
XConfig l
conf{ keys :: XConfig Layout -> Map (ButtonMask, KeySym) (X ())
keys = (ButtonMask, KeySym)
-> X ()
-> Map (ButtonMask, KeySym) (X ())
-> Map (ButtonMask, KeySym) (X ())
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (ButtonMask, KeySym)
binding ([(ButtonMask, KeySym)] -> X ()
handlePrefixArg [(ButtonMask, KeySym)
binding]) (Map (ButtonMask, KeySym) (X ())
-> Map (ButtonMask, KeySym) (X ()))
-> (XConfig Layout -> Map (ButtonMask, KeySym) (X ()))
-> XConfig Layout
-> Map (ButtonMask, KeySym) (X ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConfig l -> XConfig Layout -> Map (ButtonMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> XConfig Layout -> Map (ButtonMask, KeySym) (X ())
keys XConfig l
conf }
where
binding :: (ButtonMask, KeySym)
binding = case XConfig l -> String -> Maybe [(ButtonMask, KeySym)]
forall (l :: * -> *).
XConfig l -> String -> Maybe [(ButtonMask, KeySym)]
readKeySequence XConfig l
conf String
prefix of
Just [(ButtonMask, KeySym)
key] -> (ButtonMask, KeySym)
key
Maybe [(ButtonMask, KeySym)]
_ -> (ButtonMask
controlMask, KeySym
xK_u)
useDefaultPrefixArgument :: LayoutClass l Window
=> XConfig l
-> XConfig l
useDefaultPrefixArgument :: XConfig l -> XConfig l
useDefaultPrefixArgument = String -> XConfig l -> XConfig l
forall (l :: * -> *).
LayoutClass l KeySym =>
String -> XConfig l -> XConfig l
usePrefixArgument String
"C-u"
handlePrefixArg :: [(KeyMask, KeySym)] -> X ()
handlePrefixArg :: [(ButtonMask, KeySym)] -> X ()
handlePrefixArg [(ButtonMask, KeySym)]
events = do
Map (ButtonMask, KeySym) (X ())
ks <- (XConf -> Map (ButtonMask, KeySym) (X ()))
-> X (Map (ButtonMask, KeySym) (X ()))
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks XConf -> Map (ButtonMask, KeySym) (X ())
keyActions
X ()
logger <- (XConf -> X ()) -> X (X ())
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (XConfig Layout -> X ()
forall (l :: * -> *). XConfig l -> X ()
logHook (XConfig Layout -> X ())
-> (XConf -> XConfig Layout) -> XConf -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConf -> XConfig Layout
config)
(X () -> X () -> X ()) -> X () -> X () -> X ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip X () -> X () -> X ()
forall a. X a -> X a -> X a
finallyX (PrefixArgument -> X ()
forall a (m :: * -> *). (ExtensionClass a, XLike m) => a -> m ()
XS.put PrefixArgument
None X () -> X () -> X ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> X ()
logger) (X () -> X ()) -> X () -> X ()
forall a b. (a -> b) -> a -> b
$ do
PrefixArgument
prefix <- X PrefixArgument
forall a (m :: * -> *). (ExtensionClass a, XLike m) => m a
XS.get
case PrefixArgument
prefix of
Raw Int
a -> PrefixArgument -> X ()
forall a (m :: * -> *). (ExtensionClass a, XLike m) => a -> m ()
XS.put (PrefixArgument -> X ()) -> PrefixArgument -> X ()
forall a b. (a -> b) -> a -> b
$ Int -> PrefixArgument
Raw (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
PrefixArgument
None -> PrefixArgument -> X ()
forall a (m :: * -> *). (ExtensionClass a, XLike m) => a -> m ()
XS.put (PrefixArgument -> X ()) -> PrefixArgument -> X ()
forall a b. (a -> b) -> a -> b
$ Int -> PrefixArgument
Raw Int
1
PrefixArgument
_ -> () -> X ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
X ()
logger
((ButtonMask, KeySym) -> X ())
-> Map (ButtonMask, KeySym) (X ()) -> X ()
submapDefaultWithKey (ButtonMask, KeySym) -> X ()
defaultKey Map (ButtonMask, KeySym) (X ())
ks
where defaultKey :: (ButtonMask, KeySym) -> X ()
defaultKey key :: (ButtonMask, KeySym)
key@(ButtonMask
m, KeySym
k) =
if KeySym
k KeySym -> [KeySym] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (KeySym
xK_0 KeySym -> [KeySym] -> [KeySym]
forall a. a -> [a] -> [a]
: [KeySym
xK_1 .. KeySym
xK_9]) Bool -> Bool -> Bool
&& ButtonMask
m ButtonMask -> ButtonMask -> Bool
forall a. Eq a => a -> a -> Bool
== ButtonMask
noModMask
then do
PrefixArgument
prefix <- X PrefixArgument
forall a (m :: * -> *). (ExtensionClass a, XLike m) => m a
XS.get
let x :: Int
x = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (KeySym -> [(KeySym, Int)] -> Maybe Int
forall a b. Eq a => a -> [(a, b)] -> Maybe b
Prelude.lookup KeySym
k [(KeySym, Int)]
keyToNum)
case PrefixArgument
prefix of
Raw Int
_ -> PrefixArgument -> X ()
forall a (m :: * -> *). (ExtensionClass a, XLike m) => a -> m ()
XS.put (PrefixArgument -> X ()) -> PrefixArgument -> X ()
forall a b. (a -> b) -> a -> b
$ Int -> PrefixArgument
Numeric Int
x
Numeric Int
a -> PrefixArgument -> X ()
forall a (m :: * -> *). (ExtensionClass a, XLike m) => a -> m ()
XS.put (PrefixArgument -> X ()) -> PrefixArgument -> X ()
forall a b. (a -> b) -> a -> b
$ Int -> PrefixArgument
Numeric (Int -> PrefixArgument) -> Int -> PrefixArgument
forall a b. (a -> b) -> a -> b
$ Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x
PrefixArgument
None -> () -> X ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[(ButtonMask, KeySym)] -> X ()
handlePrefixArg ((ButtonMask, KeySym)
key(ButtonMask, KeySym)
-> [(ButtonMask, KeySym)] -> [(ButtonMask, KeySym)]
forall a. a -> [a] -> [a]
:[(ButtonMask, KeySym)]
events)
else do
PrefixArgument
prefix <- X PrefixArgument
forall a (m :: * -> *). (ExtensionClass a, XLike m) => m a
XS.get
((ButtonMask, KeySym) -> X ()) -> [(ButtonMask, KeySym)] -> X ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((ButtonMask -> KeySym -> X ()) -> (ButtonMask, KeySym) -> X ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ButtonMask -> KeySym -> X ()
sendKey) ([(ButtonMask, KeySym)] -> X ()) -> [(ButtonMask, KeySym)] -> X ()
forall a b. (a -> b) -> a -> b
$ case PrefixArgument
prefix of
Raw Int
a -> Int -> (ButtonMask, KeySym) -> [(ButtonMask, KeySym)]
forall a. Int -> a -> [a]
replicate Int
a ([(ButtonMask, KeySym)] -> (ButtonMask, KeySym)
forall a. [a] -> a
head [(ButtonMask, KeySym)]
events) [(ButtonMask, KeySym)]
-> [(ButtonMask, KeySym)] -> [(ButtonMask, KeySym)]
forall a. [a] -> [a] -> [a]
++ [(ButtonMask, KeySym)
key]
PrefixArgument
_ -> [(ButtonMask, KeySym)] -> [(ButtonMask, KeySym)]
forall a. [a] -> [a]
reverse ((ButtonMask, KeySym)
key(ButtonMask, KeySym)
-> [(ButtonMask, KeySym)] -> [(ButtonMask, KeySym)]
forall a. a -> [a] -> [a]
:[(ButtonMask, KeySym)]
events)
keyToNum :: [(KeySym, Int)]
keyToNum = (KeySym
xK_0, Int
0) (KeySym, Int) -> [(KeySym, Int)] -> [(KeySym, Int)]
forall a. a -> [a] -> [a]
: [KeySym] -> [Int] -> [(KeySym, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [KeySym
xK_1 .. KeySym
xK_9] [Int
1..Int
9]
withPrefixArgument :: (PrefixArgument -> X ()) -> X ()
withPrefixArgument :: (PrefixArgument -> X ()) -> X ()
withPrefixArgument = X PrefixArgument -> (PrefixArgument -> X ()) -> X ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(>>=) X PrefixArgument
forall a (m :: * -> *). (ExtensionClass a, XLike m) => m a
XS.get
isPrefixRaw :: PrefixArgument -> Bool
isPrefixRaw :: PrefixArgument -> Bool
isPrefixRaw (Raw Int
_) = Bool
True
isPrefixRaw PrefixArgument
_ = Bool
False
isPrefixNumeric :: PrefixArgument -> Bool
isPrefixNumeric :: PrefixArgument -> Bool
isPrefixNumeric (Numeric Int
_) = Bool
True
isPrefixNumeric PrefixArgument
_ = Bool
False
ppFormatPrefix :: X (Maybe String)
ppFormatPrefix :: X (Maybe String)
ppFormatPrefix = do
PrefixArgument
prefix <- X PrefixArgument
forall a (m :: * -> *). (ExtensionClass a, XLike m) => m a
XS.get
Maybe String -> X (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe String -> X (Maybe String))
-> Maybe String -> X (Maybe String)
forall a b. (a -> b) -> a -> b
$ case PrefixArgument
prefix of
Raw Int
n -> String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ (String -> ShowS) -> [String] -> String
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\String
a String
b -> String
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
b) ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ Int -> String -> [String]
forall a. Int -> a -> [a]
replicate Int
n String
"C-u"
Numeric Int
n -> String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String
"C-u " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
PrefixArgument
None -> Maybe String
forall a. Maybe a
Nothing