-
Notifications
You must be signed in to change notification settings - Fork 309
/
Types.hs
202 lines (171 loc) · 7.01 KB
/
Types.hs
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
{-|
Module : KMonad.Args.Types
Description : The basic types of configuration parsing.
Copyright : (c) David Janssen, 2019
License : MIT
Maintainer : janssen.dhj@gmail.com
Stability : experimental
Portability : non-portable (MPTC with FD, FFI to Linux-only c-code)
-}
module KMonad.Args.Types
(
-- * $cfg
CfgToken(..)
-- * $but
, DefButton(..)
-- * $tls
, DefSetting(..)
, DefSettings
, DefAlias
, DefLayer(..)
, DefSrc(..)
, KExpr(..)
-- * $defio
, IToken(..)
, OToken(..)
-- * $lenses
, AsKExpr(..)
, AsDefSetting(..)
, HasDefSrc(..)
) where
import KMonad.Prelude
import KMonad.Model.Button
import KMonad.Keyboard
import KMonad.Keyboard.IO
import KMonad.Util
--------------------------------------------------------------------------------
-- $but
--
-- Tokens representing different types of buttons
-- FIXME: This is really broken: why are there 2 lists of 'DefButton's? There is
-- one here, and one in Parser/Types.hs
-- | Button ADT
data DefButton
= KRef Text -- ^ Reference a named button
| KEmit Keycode -- ^ Emit a keycode
| KPressOnly Keycode -- ^ Emit only the press of a keycode
| KReleaseOnly Keycode -- ^ Emit only the release of a keycode
| KLayerToggle Text -- ^ Toggle to a layer when held
| KLayerSwitch Text -- ^ Switch base-layer when pressed
| KLayerAdd Text -- ^ Add a layer when pressed
| KLayerRem Text -- ^ Remove top instance of a layer when pressed
| KTapNext DefButton DefButton -- ^ Do 2 things based on behavior
| KTapHold Int DefButton DefButton -- ^ Do 2 things based on behavior and delay
| KTapHoldNext Int DefButton DefButton (Maybe DefButton)
-- ^ Mixture between KTapNext and KTapHold
| KTapNextRelease DefButton DefButton -- ^ Do 2 things based on behavior
| KTapHoldNextRelease Int DefButton DefButton (Maybe DefButton)
-- ^ Like KTapNextRelease but with a timeout
| KTapNextPress DefButton DefButton -- ^ Like KTapNextRelease but also hold on presses
| KAroundNext DefButton -- ^ Surround a future button
| KAroundNextSingle DefButton -- ^ Surround a future button
| KMultiTap [(Int, DefButton)] DefButton -- ^ Do things depending on tap-count
| KStepped [DefButton] -- ^ Do different things, one-by-one
| KAround DefButton DefButton -- ^ Wrap 1 button around another
| KAroundNextTimeout Int DefButton DefButton
| KTapMacro [DefButton] (Maybe Int)
-- ^ Sequence of buttons to tap, possible delay between each press
| KTapMacroRelease [DefButton] (Maybe Int)
-- ^ Sequence of buttons to tap, tap last on release, possible delay between each press
| KComposeSeq [DefButton] -- ^ Compose-key sequence
| KPause Milliseconds -- ^ Pause for a period of time
| KLayerDelay Int LayerTag -- ^ Switch to a layer for a period of time
| KLayerNext LayerTag -- ^ Perform next button in different layer
| KCommand Text (Maybe Text) -- ^ Execute a shell command on press, as well
-- as possibly on release
| KStickyKey Int DefButton -- ^ Act as if a button is pressed for a period of time
| KBeforeAfterNext DefButton DefButton -- ^ Surround a future button in a before and after tap
| KTrans -- ^ Transparent button that does nothing
| KBlock -- ^ Button that catches event
deriving Show
--------------------------------------------------------------------------------
-- $cfg
--
-- The Cfg token that can be extracted from a config-text without ever enterring
-- IO. This will then directly be translated to a DaemonCfg
--
-- | The 'CfgToken' contains all the data needed to construct an
-- 'KMonad.App.AppCfg'.
data CfgToken = CfgToken
{ _src :: LogFunc -> IO (Acquire KeySource) -- ^ How to grab the source keyboard
, _snk :: LogFunc -> IO (Acquire KeySink) -- ^ How to construct the out keybboard
, _km :: LMap Button -- ^ An 'LMap' of 'Button' actions
, _fstL :: LayerTag -- ^ Name of initial layer
, _flt :: Bool -- ^ How to deal with unhandled events
, _allow :: Bool -- ^ Whether to allow shell commands
}
makeClassy ''CfgToken
--------------------------------------------------------------------------------
-- $tls
--
-- A collection of all the different top-level statements possible in a config
-- file.
-- | A list of keycodes describing the ordering used by all other layers
-- | which is associated with a name.
data DefSrc = DefSrc
{ _srcName :: Maybe Text -- ^ A unique name used to refer to this layer.
, _keycodes :: [Keycode] -- ^ Layer settings containing also the buttons.
}
deriving Show
makeClassy ''DefSrc
-- | A mapping from names to button tokens
type DefAlias = [(Text, DefButton)]
-- | A layer of buttons
data DefLayer = DefLayer
{ _layerName :: Text -- ^ A unique name used to refer to this layer
, _associatedSrcName :: Maybe Text -- ^ The source used by the layer
, _buttons :: [DefButton] -- ^ A list of button tokens
}
deriving Show
--------------------------------------------------------------------------------
-- $defcfg
--
-- Different settings
-- | All different input-tokens KMonad can take
data IToken
= KDeviceSource FilePath
| KLowLevelHookSource
| KIOKitSource (Maybe Text)
deriving Show
-- | All different output-tokens KMonad can take
data OToken
= KUinputSink Text (Maybe Text)
| KSendEventSink (Maybe (Int, Int))
| KKextSink
deriving Show
-- | All possible single settings
data DefSetting
= SIToken IToken
| SOToken OToken
| SCmpSeq DefButton
| SInitStr Text
| SFallThrough Bool
| SAllowCmd Bool
| SCmpSeqDelay Int
deriving Show
makeClassyPrisms ''DefSetting
-- | 'Eq' instance for a 'DefSetting'. Because every one of these options may be
-- given at most once, we only need to check the outermost constructor in order
-- to test for equality
instance Eq DefSetting where
SIToken{} == SIToken{} = True
SOToken{} == SOToken{} = True
SCmpSeq{} == SCmpSeq{} = True
SInitStr{} == SInitStr{} = True
SFallThrough{} == SFallThrough{} = True
SAllowCmd{} == SAllowCmd{} = True
_ == _ = False
-- | A list of different 'DefSetting' values
type DefSettings = [DefSetting]
--------------------------------------------------------------------------------
-- $tkn
-- | Any statement in a config-file must parse to a 'KExpr'
data KExpr
= KDefCfg DefSettings
| KDefSrc DefSrc
| KDefLayer DefLayer
| KDefAlias DefAlias
deriving Show
makeClassyPrisms ''KExpr
--------------------------------------------------------------------------------
-- $act