packages feed

robot 1.1 → 1.2

raw patch · 5 files changed

+122/−24 lines, 5 files

Files

Test/Robot.hs view
@@ -11,12 +11,9 @@     , module Test.Robot.Types        -- * Doing things-      -- ** Basic operations-    , Pressable(press, release)+    , Pressable(press, release, hold)     , moveBy     , moveTo-      -- ** Derived operations-    , hold     , tap        -- * Miscellaneous@@ -33,6 +30,9 @@ import Test.Robot.Types  +infixr 4 `hold`  -- Allow e.g. xs ++ ys `hold` m++ -- | Represents things that can be pressed: either a key on a keyboard -- or a button on a mouse. class Pressable x where@@ -43,6 +43,19 @@     -- | Release a key or button.     release :: x -> Robot () +    -- | @hold x act@ holds down @x@ while executing @act@. It is+    -- equivalent to:+    --+    -- @+    -- press x >> act >> release x+    -- @+    --+    -- except @hold@ ensures that the argument is released in the event+    -- of an exception.+    --+    hold :: x -> Robot a -> Robot a+    hold = bracketRobot_ <$> press <*> release+ instance Pressable Key where     press = keyboard True     release = keyboard False@@ -51,7 +64,25 @@     press = button True     release = button False +-- | Press items from left-to-right, but release from right-to-left.+--+-- This behavior ensures the following equivalence holds:+--+-- @+-- press xs >> act >> release xs+--   === xs \`hold\` act+--   === x1 \`hold\` x2 \`hold\` ... xn \`hold\` act+-- @+--+instance Pressable x => Pressable [x] where+    press = mapM_ press+    release = mapM_ release . reverse +    hold = foldr (.) id . map hold+    --hold [] = id+    --hold (x:xs) = hold x . hold xs++ -- | Move the pointer by an offset. moveBy :: Int -> Int -> Robot () moveBy = motion True@@ -60,24 +91,6 @@ moveTo :: Int -> Int -> Robot () moveTo = motion False ---- | @hold x act@ holds down @x@ while executing @act@. It is equivalent--- to the code:------ @--- press x--- act--- release x--- @------ For example, you type some text in ALL CAPS using:------ @--- hold _Shift $ mapM_ tap [_D, _U, _C, _K, _S]--- @----hold :: Pressable x => x -> Robot a -> Robot a-hold = bracketRobot_ <$> press <*> release  -- | Press the argument, then release it. tap :: Pressable x => x -> Robot ()
Test/Robot/Internal.hs view
@@ -68,7 +68,8 @@ keyboard :: Bool -> Key -> Robot () keyboard press key = mkRobot $ \(c, keymap) -> do     case M.lookup (rawKey key) keymap of-        Nothing -> error $ "Unknown keysym: " ++ show (rawKey key)+        Nothing -> error $ "keysym " ++ show (rawKey key)+                            ++ " does not exist on keyboard layout"         Just keycode -> X.keyboard c press keycode  button :: Bool -> Button -> Robot ()
+ examples/Jack.hs view
@@ -0,0 +1,46 @@+-- | A simple typing automaton. Supports ASCII letters, spaces and newlines.++import Control.Applicative+import Control.Monad+import Control.Monad.IO.Class (liftIO)+import Data.Ratio ((%))+import System.Random (randomRIO)+import Test.Robot++main :: IO ()+main = runRobot . forever $ do+    typeText fudge "All work and no play makes Jack a dull boy\n"+    sleep . (% 5) =<< rand (1, 10)+  where+    -- This program is a horrible typist+    fudge = do+        sleep . (1 %) =<< rand (2, 10)+        roll <- rand (0, 100)+        when (roll `elem` [0..3]) $ tap _Space+        when (roll == 4) $ tap _Return++typeText+    :: Robot ()  -- ^ Action to perform between each key press+    -> String    -- ^ Input string+    -> Robot ()+typeText pause = foldr combine (return ()) . map (tapShift . charToKey)+  where+    combine a b = a >> pause >> b++tapShift :: (Bool, Key) -> Robot ()+tapShift (False, k) = tap k+tapShift (True , k) = _Shift `hold` tap k++charToKey :: Char -> (Bool, Key)+charToKey c+  | 'A' <= c && c <= 'Z' = (True, k)+  | 'a' <= c && c <= 'z' = (False, k)+  | otherwise = (False, case c of+        ' ' -> _Space+        '\n' -> _Return+        _ -> error $ "key conversion not implemented for " ++ show c)+  where+    k = customKey $ fromIntegral (fromEnum c)++rand :: (Integer, Integer) -> Robot Integer+rand = liftIO . randomRIO
+ examples/Vim.hs view
@@ -0,0 +1,38 @@+-- | Do some funny things with the keyboard.++import Control.Monad (replicateM_)+import Test.Robot++main = runRobot $ do++    pause++    -- Let's open Vim!+    mapM_ t [_V, _I, _M]+    t _Return++    pause++    -- Enter some text...+    t _I; sleep 1+    _Shift `hold` do+        mapM_ t [_D, _U, _C, _K, _S]+    t _Escape++    pause++    -- Undo and redo+    replicateM_ 3 $ do+        t _U+        t [_Ctrl, _R]  -- Alternatively: _Ctrl `hold` tap _R++    pause++    -- Quit+    _Shift `hold` do+        t _Z+        t _Q++  where+    t k = sleep 0.25 >> tap k+    pause = sleep 2
robot.cabal view
@@ -1,5 +1,5 @@ Name:                robot-Version:             1.1+Version:             1.2 Synopsis:            Simulate keyboard and mouse events Homepage:            https://github.com/lfairy/robot License:             OtherLicense