workflow-osx-0.0.0: a "Desktop Workflow" monad with Objective-C bindings

Safe HaskellSafe




type MonadWorkflow = MonadFree WorkflowF

a monad constraint for "workflow effects", (just like MonadState is a monad constraint for "state effects") can use in any monad transformer stack that handles them.

type Workflow = Free WorkflowF

a platform-agnostic free monad, which can be executed by platform-specific bindings.

type CWorkflow = F WorkflowF


data WorkflowF k

the "Workflow Functor".


SendKeyChord [Modifier] Key k 
SendText String k

a logical grouping for debugging and optimizing

GetClipboard (ClipboardText -> k) 
SetClipboard ClipboardText k 
CurrentApplication (Application -> k) 
OpenApplication Application k 
OpenURL URL k 
Delay Time k 


type URL = String

type Time = Int

type CGKeyCode = CUShort

relates a Haskell type with a Objective-C type:

type CGEventFlags = CULLong

relates a Haskell type with a Objective-C type:

type KeyRiff = [KeyChord]

an (unordered, no-duplicates) sequence of key chords make up a keyboard shortcut

type KeyChord = ([Modifier], Key)

pattern KeyChord :: t -> t -> (t, t)

pattern KeyChord ms k = (ms,k)

pattern NoMod :: t -> ([t], t)

pattern NoMod k = ([],k)

addMod :: Modifier -> KeyChord -> KeyChord

appends a modifier

data Modifier

modifier keys are keys that can be "held".

the escape key is "pressed", not "held", it seems. (possibly explains its behavior in your terminal emulator?)

alt is OptionModifier.

int2keypress :: Integer -> [KeyChord]

>>> int2keypress -12

digit2keypress :: MonadThrow m => Integer -> m KeyChord

a (base ten) digit is a number between zero and nine inclusive.

>>> digit2keypress 2
>>> digit2keypress -2
>>> digit2keypress 12

char2keypress :: MonadThrow m => Char -> m KeyChord

the keypress that would insert the character into the application.

>>> char2keypress '@' :: Maybe KeyChord
Just ([ShiftModifier], TwoKey)

some characters cannot be represented as keypresses, like some non-printable characters (in arbitrary applications, not just the terminal emulator):

>>> char2keypress '\0' :: Maybe KeyChord
case char2keypress c of {  Just ([],_) -> True;  Just ([ShiftModifier],_) -> True;  Nothing -> True;  _ -> False  }

keypress2char :: MonadThrow m => KeyChord -> m Char

the character that represents the keypress:

>>> keypress2char ([ShiftModifier], TwoKey) :: Maybe Char
Just '@'

some keypresses cannot be represented as characters, like keyboard shortcuts:

>>> keypress2char ([Command], CKey) :: Maybe Char
>>> import Data.Char
>>> import Data.Maybe
prop> maybe True isAscii (keypress2char k)
TODO replace true with redo test