module Karabiner.Config where
import Prelude hiding (mod)
import Data.Aeson
import Data.Aeson.Encode.Pretty hiding (Tab)
import qualified Data.ByteString.Lazy.Char8 as LC
import Data.Maybe
import Data.String
import Data.Text (Text)
import qualified Data.Text as T
import qualified GHC.TypeLits as TL
import GHC.TypeLits (ErrorMessage((:$$:)))
import Karabiner.Config.Internal (prettyConfig, stripNulls)
mkMain :: Root -> IO ()
mkMain :: Root -> IO ()
mkMain = ByteString -> IO ()
LC.putStrLn (ByteString -> IO ()) -> (Root -> ByteString) -> Root -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Root -> ByteString
encodeRoot
encodeRoot :: Root -> LC.ByteString
encodeRoot :: Root -> ByteString
encodeRoot Root
root = Config -> Root -> ByteString
forall a. ToJSON a => Config -> a -> ByteString
encodePretty' Config
prettyConfig Root
root ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [Char] -> ByteString
LC.pack [Char]
"\n"
litPat :: Text -> Text
litPat :: Text -> Text
litPat Text
t = Char
'^' Char -> Text -> Text
`T.cons` (Text -> Text -> Text -> Text
T.replace Text
"." Text
"\\." Text
t) Text -> Char -> Text
`T.snoc` Char
'$'
data KeyBinding a = KeyBinding [a] KeyCode
singleKey :: KeyCode -> KeyBinding PhysicalModifier
singleKey :: KeyCode -> KeyBinding PhysicalModifier
singleKey = [PhysicalModifier] -> KeyCode -> KeyBinding PhysicalModifier
forall a. [a] -> KeyCode -> KeyBinding a
KeyBinding []
(|->) :: KeyBinding a -> KeyBinding a -> [KeyBinding a]
KeyBinding a
x |-> :: KeyBinding a -> KeyBinding a -> [KeyBinding a]
|-> KeyBinding a
y = [KeyBinding a
x, KeyBinding a
y]
infix 5 |->
class ToKeyBinding a b c | a b -> c where
(|+|) :: a -> b -> KeyBinding c
infix 6 |+|
instance ToKeyBinding PhysicalModifier KeyCode PhysicalModifier where
PhysicalModifier
mod |+| :: PhysicalModifier -> KeyCode -> KeyBinding PhysicalModifier
|+| KeyCode
kc = [PhysicalModifier] -> KeyCode -> KeyBinding PhysicalModifier
forall a. [a] -> KeyCode -> KeyBinding a
KeyBinding [PhysicalModifier
mod] KeyCode
kc
instance ToKeyBinding [PhysicalModifier] KeyCode PhysicalModifier where
[PhysicalModifier]
mods |+| :: [PhysicalModifier] -> KeyCode -> KeyBinding PhysicalModifier
|+| KeyCode
kc = [PhysicalModifier] -> KeyCode -> KeyBinding PhysicalModifier
forall a. [a] -> KeyCode -> KeyBinding a
KeyBinding [PhysicalModifier]
mods KeyCode
kc
instance ToKeyBinding MetaModifier KeyCode MetaModifier where
MetaModifier
mod |+| :: MetaModifier -> KeyCode -> KeyBinding MetaModifier
|+| KeyCode
kc = [MetaModifier] -> KeyCode -> KeyBinding MetaModifier
forall a. [a] -> KeyCode -> KeyBinding a
KeyBinding [MetaModifier
mod] KeyCode
kc
instance ToKeyBinding [MetaModifier] KeyCode MetaModifier where
[MetaModifier]
mods |+| :: [MetaModifier] -> KeyCode -> KeyBinding MetaModifier
|+| KeyCode
kc = [MetaModifier] -> KeyCode -> KeyBinding MetaModifier
forall a. [a] -> KeyCode -> KeyBinding a
KeyBinding [MetaModifier]
mods KeyCode
kc
class ManipulatorBuilder a b where
(!>) :: a -> b -> Manipulator
infix 4 !>
instance AsAnyModifier a
=> ManipulatorBuilder (KeyBinding a) (KeyBinding PhysicalModifier) where
(KeyBinding [a]
fromMods KeyCode
fromK) !> :: KeyBinding a -> KeyBinding PhysicalModifier -> Manipulator
!> (KeyBinding [PhysicalModifier]
toMods KeyCode
toK) =
ManipulatorType
-> ManipulatorFrom
-> [ManipulatorTo]
-> Maybe [ManipulatorCondition]
-> Manipulator
Manipulator ManipulatorType
Basic ManipulatorFrom
mf [ManipulatorTo
mt] Maybe [ManipulatorCondition]
forall a. Maybe a
Nothing
where
mf :: ManipulatorFrom
mf = KeyCode -> FromModifiers -> ManipulatorFrom
ManipulatorFrom KeyCode
fromK ([AnyModifier] -> FromModifiers
FromModifiers ([AnyModifier] -> FromModifiers) -> [AnyModifier] -> FromModifiers
forall a b. (a -> b) -> a -> b
$ (a -> AnyModifier) -> [a] -> [AnyModifier]
forall a b. (a -> b) -> [a] -> [b]
map a -> AnyModifier
forall a. AsAnyModifier a => a -> AnyModifier
asAnyModifier [a]
fromMods)
mt :: ManipulatorTo
mt = KeyCode -> [PhysicalModifier] -> ManipulatorTo
ManipulatorTo KeyCode
toK [PhysicalModifier]
toMods
instance AsAnyModifier a
=> ManipulatorBuilder (KeyBinding a) [KeyBinding PhysicalModifier] where
(KeyBinding [a]
fromMods KeyCode
fromK) !> :: KeyBinding a -> [KeyBinding PhysicalModifier] -> Manipulator
!> [KeyBinding PhysicalModifier]
toBindingSeq =
ManipulatorType
-> ManipulatorFrom
-> [ManipulatorTo]
-> Maybe [ManipulatorCondition]
-> Manipulator
Manipulator ManipulatorType
Basic ManipulatorFrom
mf [ManipulatorTo]
mts Maybe [ManipulatorCondition]
forall a. Maybe a
Nothing
where
mf :: ManipulatorFrom
mf = KeyCode -> FromModifiers -> ManipulatorFrom
ManipulatorFrom KeyCode
fromK ([AnyModifier] -> FromModifiers
FromModifiers ([AnyModifier] -> FromModifiers) -> [AnyModifier] -> FromModifiers
forall a b. (a -> b) -> a -> b
$ (a -> AnyModifier) -> [a] -> [AnyModifier]
forall a b. (a -> b) -> [a] -> [b]
map a -> AnyModifier
forall a. AsAnyModifier a => a -> AnyModifier
asAnyModifier [a]
fromMods)
mts :: [ManipulatorTo]
mts = ((KeyBinding PhysicalModifier -> ManipulatorTo)
-> [KeyBinding PhysicalModifier] -> [ManipulatorTo])
-> [KeyBinding PhysicalModifier]
-> (KeyBinding PhysicalModifier -> ManipulatorTo)
-> [ManipulatorTo]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (KeyBinding PhysicalModifier -> ManipulatorTo)
-> [KeyBinding PhysicalModifier] -> [ManipulatorTo]
forall a b. (a -> b) -> [a] -> [b]
map [KeyBinding PhysicalModifier]
toBindingSeq ((KeyBinding PhysicalModifier -> ManipulatorTo) -> [ManipulatorTo])
-> (KeyBinding PhysicalModifier -> ManipulatorTo)
-> [ManipulatorTo]
forall a b. (a -> b) -> a -> b
$ \(KeyBinding [PhysicalModifier]
toMods KeyCode
toK) ->
KeyCode -> [PhysicalModifier] -> ManipulatorTo
ManipulatorTo KeyCode
toK [PhysicalModifier]
toMods
instance AsAnyModifier a
=> ManipulatorBuilder (KeyBinding a) KeyCode where
KeyBinding a
fromKeys !> :: KeyBinding a -> KeyCode -> Manipulator
!> KeyCode
toKey = KeyBinding a
fromKeys KeyBinding a -> KeyBinding PhysicalModifier -> Manipulator
forall a b. ManipulatorBuilder a b => a -> b -> Manipulator
!> ([] :: [PhysicalModifier]) [PhysicalModifier] -> KeyCode -> KeyBinding PhysicalModifier
forall a b c. ToKeyBinding a b c => a -> b -> KeyBinding c
|+| KeyCode
toKey
instance
TL.TypeError
( 'TL.Text "Unsupported ManipulatorBuilder (!>) usage;"
':$$: 'TL.Text "'to' binding must use a PhysicalModifier (e.g. RightControl)"
':$$: 'TL.Text "not a MetaModifier (e.g. Control)"
)
=> ManipulatorBuilder a (KeyBinding MetaModifier) where
!> :: a -> KeyBinding MetaModifier -> Manipulator
(!>) = a -> KeyBinding MetaModifier -> Manipulator
forall a. HasCallStack => a
undefined
frontmostApplicationIf :: Manipulator -> [Text] -> Manipulator
Manipulator
m frontmostApplicationIf :: Manipulator -> [Text] -> Manipulator
`frontmostApplicationIf` [Text]
ts = Manipulator
m { manipulatorConditions :: Maybe [ManipulatorCondition]
manipulatorConditions = Maybe [ManipulatorCondition]
cs }
where
c :: ManipulatorCondition
c = ManipulatorConditionType -> [Text] -> ManipulatorCondition
ManipulatorCondition ManipulatorConditionType
FrontmostApplicationIf [Text]
ts
cs :: Maybe [ManipulatorCondition]
cs = [ManipulatorCondition] -> Maybe [ManipulatorCondition]
forall a. a -> Maybe a
Just ([ManipulatorCondition] -> Maybe [ManipulatorCondition])
-> [ManipulatorCondition] -> Maybe [ManipulatorCondition]
forall a b. (a -> b) -> a -> b
$ ManipulatorCondition
c ManipulatorCondition
-> [ManipulatorCondition] -> [ManipulatorCondition]
forall a. a -> [a] -> [a]
: [ManipulatorCondition]
-> Maybe [ManipulatorCondition] -> [ManipulatorCondition]
forall a. a -> Maybe a -> a
fromMaybe [] (Manipulator -> Maybe [ManipulatorCondition]
manipulatorConditions Manipulator
m)
(?) :: Manipulator -> [Text] -> Manipulator
? :: Manipulator -> [Text] -> Manipulator
(?) = Manipulator -> [Text] -> Manipulator
frontmostApplicationIf
(??) :: [Manipulator] -> [Text] -> [Manipulator]
[Manipulator]
ms ?? :: [Manipulator] -> [Text] -> [Manipulator]
?? [Text]
ts = (Manipulator -> Manipulator) -> [Manipulator] -> [Manipulator]
forall a b. (a -> b) -> [a] -> [b]
map (Manipulator -> [Text] -> Manipulator
? [Text]
ts) [Manipulator]
ms
frontmostApplicationUnless :: Manipulator -> [Text] -> Manipulator
Manipulator
m frontmostApplicationUnless :: Manipulator -> [Text] -> Manipulator
`frontmostApplicationUnless` [Text]
ts = Manipulator
m { manipulatorConditions :: Maybe [ManipulatorCondition]
manipulatorConditions = Maybe [ManipulatorCondition]
cs }
where
c :: ManipulatorCondition
c = ManipulatorConditionType -> [Text] -> ManipulatorCondition
ManipulatorCondition ManipulatorConditionType
FrontmostApplicationUnless [Text]
ts
cs :: Maybe [ManipulatorCondition]
cs = [ManipulatorCondition] -> Maybe [ManipulatorCondition]
forall a. a -> Maybe a
Just ([ManipulatorCondition] -> Maybe [ManipulatorCondition])
-> [ManipulatorCondition] -> Maybe [ManipulatorCondition]
forall a b. (a -> b) -> a -> b
$ ManipulatorCondition
c ManipulatorCondition
-> [ManipulatorCondition] -> [ManipulatorCondition]
forall a. a -> [a] -> [a]
: [ManipulatorCondition]
-> Maybe [ManipulatorCondition] -> [ManipulatorCondition]
forall a. a -> Maybe a -> a
fromMaybe [] (Manipulator -> Maybe [ManipulatorCondition]
manipulatorConditions Manipulator
m)
(?!) :: Manipulator -> [Text] -> Manipulator
?! :: Manipulator -> [Text] -> Manipulator
(?!) = Manipulator -> [Text] -> Manipulator
frontmostApplicationUnless
infix 3 ?!
(??!) :: [Manipulator] -> [Text] -> [Manipulator]
[Manipulator]
ms ??! :: [Manipulator] -> [Text] -> [Manipulator]
??! [Text]
ts = (Manipulator -> Manipulator) -> [Manipulator] -> [Manipulator]
forall a b. (a -> b) -> [a] -> [b]
map (Manipulator -> [Text] -> Manipulator
?! [Text]
ts) [Manipulator]
ms
data Root = Root
{ Root -> Text
rootTitle :: Text
, Root -> [Rule]
rootRules :: [Rule]
}
instance ToJSON Root where
toJSON :: Root -> Value
toJSON (Root Text
title [Rule]
rules) =
[Pair] -> Value
object [Text
"title" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text
title, Text
"rules" Text -> [Rule] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Rule]
rules]
data Rule = Rule
{ Rule -> Text
ruleDescription :: Text
, Rule -> [Manipulator]
ruleManipulators :: [Manipulator]
}
instance ToJSON Rule where
toJSON :: Rule -> Value
toJSON (Rule Text
d [Manipulator]
ms) =
[Pair] -> Value
object [Text
"description" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text
d, Text
"manipulators" Text -> [Manipulator] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Manipulator]
ms]
data Manipulator = Manipulator
{ Manipulator -> ManipulatorType
manipulatorType :: ManipulatorType
, Manipulator -> ManipulatorFrom
manipulatorFrom :: ManipulatorFrom
, Manipulator -> [ManipulatorTo]
manipulatorTo :: [ManipulatorTo]
, Manipulator -> Maybe [ManipulatorCondition]
manipulatorConditions :: Maybe [ManipulatorCondition]
}
instance ToJSON Manipulator where
toJSON :: Manipulator -> Value
toJSON (Manipulator ManipulatorType
typ ManipulatorFrom
from [ManipulatorTo]
to Maybe [ManipulatorCondition]
conds) = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [Pair] -> [Pair]
stripNulls
[ Text
"type" Text -> ManipulatorType -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ManipulatorType
typ
, Text
"from" Text -> ManipulatorFrom -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ManipulatorFrom
from
, Text
"to" Text -> [ManipulatorTo] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [ManipulatorTo]
to
, Text
"conditions" Text -> Maybe [ManipulatorCondition] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Maybe [ManipulatorCondition]
conds
]
data ManipulatorType = Basic
manipulatorTypeToText :: ManipulatorType -> Text
manipulatorTypeToText :: ManipulatorType -> Text
manipulatorTypeToText = \case
ManipulatorType
Basic -> Text
"basic"
instance ToJSON ManipulatorType where
toJSON :: ManipulatorType -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value)
-> (ManipulatorType -> Text) -> ManipulatorType -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ManipulatorType -> Text
manipulatorTypeToText
data ManipulatorFrom = ManipulatorFrom
{ ManipulatorFrom -> KeyCode
fromKeyCode :: KeyCode
, ManipulatorFrom -> FromModifiers
fromModifiers :: FromModifiers
}
instance ToJSON ManipulatorFrom where
toJSON :: ManipulatorFrom -> Value
toJSON (ManipulatorFrom KeyCode
k FromModifiers
ms) =
[Pair] -> Value
object [Text
"key_code" Text -> KeyCode -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= KeyCode
k, Text
"modifiers" Text -> FromModifiers -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= FromModifiers
ms]
data ManipulatorTo = ManipulatorTo
{ ManipulatorTo -> KeyCode
toKeyCode :: KeyCode
, ManipulatorTo -> [PhysicalModifier]
toModifiers :: [PhysicalModifier]
}
instance ToJSON ManipulatorTo where
toJSON :: ManipulatorTo -> Value
toJSON (ManipulatorTo KeyCode
k [PhysicalModifier]
ms) =
[Pair] -> Value
object [Text
"key_code" Text -> KeyCode -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= KeyCode
k, Text
"modifiers" Text -> [PhysicalModifier] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [PhysicalModifier]
ms]
data ManipulatorCondition = ManipulatorCondition
{ ManipulatorCondition -> ManipulatorConditionType
conditionType :: ManipulatorConditionType
, ManipulatorCondition -> [Text]
conditionBundleIdentifiers :: [Text]
}
instance ToJSON ManipulatorCondition where
toJSON :: ManipulatorCondition -> Value
toJSON (ManipulatorCondition ManipulatorConditionType
t [Text]
bis) =
[Pair] -> Value
object [Text
"type" Text -> ManipulatorConditionType -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ManipulatorConditionType
t, Text
"bundle_identifiers" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Text]
bis]
data ManipulatorConditionType
= FrontmostApplicationUnless
| FrontmostApplicationIf
manipulatorConditionTypeToText :: ManipulatorConditionType -> Text
manipulatorConditionTypeToText :: ManipulatorConditionType -> Text
manipulatorConditionTypeToText = \case
ManipulatorConditionType
FrontmostApplicationUnless -> Text
"frontmost_application_unless"
ManipulatorConditionType
FrontmostApplicationIf -> Text
"frontmost_application_if"
instance ToJSON ManipulatorConditionType where
toJSON :: ManipulatorConditionType -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value)
-> (ManipulatorConditionType -> Text)
-> ManipulatorConditionType
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ManipulatorConditionType -> Text
manipulatorConditionTypeToText
data FromModifiers = FromModifiers
{ FromModifiers -> [AnyModifier]
modifiersMandatory :: [AnyModifier]
}
instance ToJSON FromModifiers where
toJSON :: FromModifiers -> Value
toJSON (FromModifiers [AnyModifier]
m) =
[Pair] -> Value
object [Text
"mandatory" Text -> [AnyModifier] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [AnyModifier]
m]
data PhysicalModifier
= LeftShift | RightShift
| LeftControl | RightControl
| LeftOption | RightOption
| LeftCommand | RightCommand
instance ToJSON PhysicalModifier where
toJSON :: PhysicalModifier -> Value
toJSON = \case
PhysicalModifier
LeftShift -> Value
"left_shift"
PhysicalModifier
RightShift -> Value
"right_shift"
PhysicalModifier
LeftControl -> Value
"left_control"
PhysicalModifier
RightControl -> Value
"right_control"
PhysicalModifier
LeftOption -> Value
"left_option"
PhysicalModifier
RightOption -> Value
"right_option"
PhysicalModifier
LeftCommand -> Value
"left_command"
PhysicalModifier
RightCommand -> Value
"right_command"
data MetaModifier
= Shift
| Control
| Option
| Command
instance ToJSON MetaModifier where
toJSON :: MetaModifier -> Value
toJSON = \case
MetaModifier
Shift -> Value
"shift"
MetaModifier
Control -> Value
"control"
MetaModifier
Option -> Value
"option"
MetaModifier
Command -> Value
"command"
data AnyModifier
= ModifierFromPhysical PhysicalModifier
| ModifierFromMeta MetaModifier
class AsAnyModifier a where
asAnyModifier :: a -> AnyModifier
instance AsAnyModifier PhysicalModifier where
asAnyModifier :: PhysicalModifier -> AnyModifier
asAnyModifier = PhysicalModifier -> AnyModifier
ModifierFromPhysical
instance AsAnyModifier MetaModifier where
asAnyModifier :: MetaModifier -> AnyModifier
asAnyModifier = MetaModifier -> AnyModifier
ModifierFromMeta
instance ToJSON AnyModifier where
toJSON :: AnyModifier -> Value
toJSON AnyModifier
mf = case AnyModifier
mf of
ModifierFromPhysical PhysicalModifier
m -> PhysicalModifier -> Value
forall a. ToJSON a => a -> Value
toJSON PhysicalModifier
m
ModifierFromMeta MetaModifier
m -> MetaModifier -> Value
forall a. ToJSON a => a -> Value
toJSON MetaModifier
m
data KeyCode
= A | B | C | D | E | F | G | H | I | J | K | L | M
| N | O | P | Q | R | S | T | U | V | W | X | Y | Z
| One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Zero
| Spacebar | Backspace
| OpenBracket | CloseBracket
| RightArrow | LeftArrow | UpArrow | DownArrow
| ReturnOrEnter
| Tab
| Comma | Semicolon
numbers :: [KeyCode]
numbers :: [KeyCode]
numbers = [KeyCode
One, KeyCode
Two, KeyCode
Three, KeyCode
Four, KeyCode
Five, KeyCode
Six, KeyCode
Seven, KeyCode
Eight, KeyCode
Nine, KeyCode
Zero]
keyCodeToString :: IsString a => KeyCode -> a
keyCodeToString :: KeyCode -> a
keyCodeToString = \case
KeyCode
A -> a
"a"
KeyCode
B -> a
"b"
KeyCode
C -> a
"c"
KeyCode
D -> a
"d"
KeyCode
E -> a
"e"
KeyCode
F -> a
"f"
KeyCode
G -> a
"g"
KeyCode
H -> a
"h"
KeyCode
I -> a
"i"
KeyCode
J -> a
"j"
KeyCode
K -> a
"k"
KeyCode
L -> a
"l"
KeyCode
M -> a
"m"
KeyCode
N -> a
"n"
KeyCode
O -> a
"o"
KeyCode
P -> a
"p"
KeyCode
Q -> a
"q"
KeyCode
R -> a
"r"
KeyCode
S -> a
"s"
KeyCode
T -> a
"t"
KeyCode
U -> a
"u"
KeyCode
V -> a
"v"
KeyCode
W -> a
"w"
KeyCode
X -> a
"x"
KeyCode
Y -> a
"y"
KeyCode
Z -> a
"z"
KeyCode
One -> a
"1"
KeyCode
Two -> a
"2"
KeyCode
Three -> a
"3"
KeyCode
Four -> a
"4"
KeyCode
Five -> a
"5"
KeyCode
Six -> a
"6"
KeyCode
Seven -> a
"7"
KeyCode
Eight -> a
"8"
KeyCode
Nine -> a
"9"
KeyCode
Zero -> a
"0"
KeyCode
Spacebar -> a
"spacebar"
KeyCode
Backspace -> a
"delete_or_backspace"
KeyCode
OpenBracket -> a
"open_bracket"
KeyCode
CloseBracket -> a
"close_bracket"
KeyCode
RightArrow -> a
"right_arrow"
KeyCode
LeftArrow -> a
"left_arrow"
KeyCode
DownArrow -> a
"down_arrow"
KeyCode
UpArrow -> a
"up_arrow"
KeyCode
ReturnOrEnter -> a
"return_or_enter"
KeyCode
Tab -> a
"tab"
KeyCode
Comma -> a
"comma"
KeyCode
Semicolon -> a
"semicolon"
instance ToJSON KeyCode where
toJSON :: KeyCode -> Value
toJSON = KeyCode -> Value
forall a. IsString a => KeyCode -> a
keyCodeToString