Reformat type hints to use comment style syntax
Update Pipfile to add typing module and pyright Update pyproject.toml for pyright and mypy configs
This commit is contained in:
parent
9fc431e0a7
commit
b202dc77d1
2
Pipfile
2
Pipfile
@ -21,4 +21,6 @@ black = "==21.6b0"
|
|||||||
flake8-quotes = "*"
|
flake8-quotes = "*"
|
||||||
flake8-black = "*"
|
flake8-black = "*"
|
||||||
circuitpython-stubs = "==7.0.0a6.dev195"
|
circuitpython-stubs = "==7.0.0a6.dev195"
|
||||||
|
pyright = "*"
|
||||||
|
typing = "*"
|
||||||
mypy = "*"
|
mypy = "*"
|
||||||
|
131
Pipfile.lock
generated
131
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "e80d827684ac8c56b762a74548440c5b371c5b3ee5fcb5b74e68ae6d9bff0665"
|
"sha256": "cee0eeba8c8dad66dccffe0935656829132f7ca928569e3aa957f278e6e92da6"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {},
|
"requires": {},
|
||||||
@ -94,11 +94,11 @@
|
|||||||
},
|
},
|
||||||
"flake8-comprehensions": {
|
"flake8-comprehensions": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:b07aef3277623db32310aa241a1cec67212b53c1d18e767d7e26d4d83aa05bf7",
|
"sha256:4888de89248b7f7535159189ff693c77f8354f6d37a02619fa28c9921a913aa0",
|
||||||
"sha256:f24be9032587127f7a5bc6d066bf755b6e66834f694383adb8a673e229c1f559"
|
"sha256:e9a010b99aa90c05790d45281ad9953df44a4a08a1a8f6cd41f98b4fc6a268a0"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.5.0"
|
"version": "==3.6.1"
|
||||||
},
|
},
|
||||||
"flake8-isort": {
|
"flake8-isort": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -110,10 +110,10 @@
|
|||||||
},
|
},
|
||||||
"flake8-quotes": {
|
"flake8-quotes": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:3f1116e985ef437c130431ac92f9b3155f8f652fda7405ac22ffdfd7a9d1055e"
|
"sha256:f1dd87830ed77ff2ce47fc0ee0fd87ae20e8f045355354ffbf4dcaa18d528217"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.2.0"
|
"version": "==3.3.0"
|
||||||
},
|
},
|
||||||
"greenlet": {
|
"greenlet": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -300,6 +300,13 @@
|
|||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.3.1"
|
"version": "==0.3.1"
|
||||||
},
|
},
|
||||||
|
"nodeenv": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b",
|
||||||
|
"sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"
|
||||||
|
],
|
||||||
|
"version": "==1.6.0"
|
||||||
|
},
|
||||||
"parso": {
|
"parso": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398",
|
"sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398",
|
||||||
@ -332,11 +339,11 @@
|
|||||||
},
|
},
|
||||||
"prompt-toolkit": {
|
"prompt-toolkit": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f",
|
"sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c",
|
||||||
"sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"
|
"sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c"
|
||||||
],
|
],
|
||||||
"markers": "python_full_version >= '3.6.1'",
|
"markers": "python_full_version >= '3.6.2'",
|
||||||
"version": "==3.0.19"
|
"version": "==3.0.20"
|
||||||
},
|
},
|
||||||
"ptyprocess": {
|
"ptyprocess": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -363,11 +370,11 @@
|
|||||||
},
|
},
|
||||||
"pygments": {
|
"pygments": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f",
|
"sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380",
|
||||||
"sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"
|
"sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.5'",
|
"markers": "python_version >= '3.5'",
|
||||||
"version": "==2.9.0"
|
"version": "==2.10.0"
|
||||||
},
|
},
|
||||||
"pynvim": {
|
"pynvim": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -375,6 +382,14 @@
|
|||||||
],
|
],
|
||||||
"version": "==0.4.3"
|
"version": "==0.4.3"
|
||||||
},
|
},
|
||||||
|
"pyright": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:dd8e18c54321340be44a708b6037c0b967486c32b3f492741fffdc205cb82f15",
|
||||||
|
"sha256:e2668730cddf580e696d4a11946e740e2f5647df1eb45f7c55b7029376eac5a1"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.0.9"
|
||||||
|
},
|
||||||
"pyserial": {
|
"pyserial": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb",
|
"sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb",
|
||||||
@ -408,41 +423,49 @@
|
|||||||
},
|
},
|
||||||
"regex": {
|
"regex": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:026beb631097a4a3def7299aa5825e05e057de3c6d72b139c37813bfa351274b",
|
"sha256:0696eb934dee723e3292056a2c046ddb1e4dd3887685783a9f4af638e85dee76",
|
||||||
"sha256:14caacd1853e40103f59571f169704367e79fb78fac3d6d09ac84d9197cadd16",
|
"sha256:105122fa63da98d8456d5026bc6ac5a1399fd82fa6bad22c6ea641b1572c9142",
|
||||||
"sha256:16d9eaa8c7e91537516c20da37db975f09ac2e7772a0694b245076c6d68f85da",
|
"sha256:116c277774f84266044e889501fe79cfd293a8b4336b7a5e89b9f20f1e5a9f21",
|
||||||
"sha256:18fdc51458abc0a974822333bd3a932d4e06ba2a3243e9a1da305668bd62ec6d",
|
"sha256:12eaf0bbe568bd62e6cade7937e0bf01a2a4cef49a82f4fd204401e78409e158",
|
||||||
"sha256:28e8af338240b6f39713a34e337c3813047896ace09d51593d6907c66c0708ba",
|
"sha256:1401cfa4320691cbd91191ec678735c727dee674d0997b0902a5a38ad482faf5",
|
||||||
"sha256:3835de96524a7b6869a6c710b26c90e94558c31006e96ca3cf6af6751b27dca1",
|
"sha256:19acdb8831a4e3b03b23369db43178d8fee1f17b99c83af6cd907886f76bd9d4",
|
||||||
"sha256:3905c86cc4ab6d71635d6419a6f8d972cab7c634539bba6053c47354fd04452c",
|
"sha256:208851a2f8dd31e468f0b5aa6c94433975bd67a107a4e7da3bdda947c9f85e25",
|
||||||
"sha256:3c09d88a07483231119f5017904db8f60ad67906efac3f1baa31b9b7f7cca281",
|
"sha256:24d68499a27b2d93831fde4a9b84ea5b19e0ab141425fbc9ab1e5b4dad179df7",
|
||||||
"sha256:4551728b767f35f86b8e5ec19a363df87450c7376d7419c3cac5b9ceb4bce576",
|
"sha256:2778c6cb379d804e429cc8e627392909e60db5152b42c695c37ae5757aae50ae",
|
||||||
"sha256:459bbe342c5b2dec5c5223e7c363f291558bc27982ef39ffd6569e8c082bdc83",
|
"sha256:2a0a5e323cf86760784ce2b91d8ab5ea09d0865d6ef4da0151e03d15d097b24e",
|
||||||
"sha256:4f421e3cdd3a273bace013751c345f4ebeef08f05e8c10757533ada360b51a39",
|
"sha256:2d9cbe0c755ab8b6f583169c0783f7278fc6b195e423b09c5a8da6f858025e96",
|
||||||
"sha256:577737ec3d4c195c4aef01b757905779a9e9aee608fa1cf0aec16b5576c893d3",
|
"sha256:2de1429e4eeab799c168a4f6e6eecdf30fcaa389bba4039cc8a065d6b7aad647",
|
||||||
"sha256:57fece29f7cc55d882fe282d9de52f2f522bb85290555b49394102f3621751ee",
|
"sha256:32753eda8d413ce4f208cfe01dd61171a78068a6f5d5f38ccd751e00585cdf1d",
|
||||||
"sha256:7976d410e42be9ae7458c1816a416218364e06e162b82e42f7060737e711d9ce",
|
"sha256:3ee8ad16a35c45a5bab098e39020ecb6fec3b0e700a9d88983d35cbabcee79c8",
|
||||||
"sha256:85f568892422a0e96235eb8ea6c5a41c8ccbf55576a2260c0160800dbd7c4f20",
|
"sha256:4f03fc0a25122cdcbf39136510d4ea7627f732206892db522adf510bc03b8c67",
|
||||||
"sha256:8764a78c5464ac6bde91a8c87dd718c27c1cabb7ed2b4beaf36d3e8e390567f9",
|
"sha256:4f3e36086d6631ceaf468503f96a3be0d247caef0660c9452fb1b0c055783851",
|
||||||
"sha256:8935937dad2c9b369c3d932b0edbc52a62647c2afb2fafc0c280f14a8bf56a6a",
|
"sha256:503c1ba0920a46a1844363725215ef44d59fcac2bd2c03ae3c59aa9d08d29bd6",
|
||||||
"sha256:8fe58d9f6e3d1abf690174fd75800fda9bdc23d2a287e77758dc0e8567e38ce6",
|
"sha256:507861cf3d97a86fbe26ea6cc04660ae028b9e4080b8290e28b99547b4e15d89",
|
||||||
"sha256:937b20955806381e08e54bd9d71f83276d1f883264808521b70b33d98e4dec5d",
|
"sha256:56ae6e3cf0506ec0c40b466e31f41ee7a7149a2b505ae0ee50edd9043b423d27",
|
||||||
"sha256:9569da9e78f0947b249370cb8fadf1015a193c359e7e442ac9ecc585d937f08d",
|
"sha256:6530b7b9505123cdea40a2301225183ca65f389bc6129f0c225b9b41680268d8",
|
||||||
"sha256:a3b73390511edd2db2d34ff09aa0b2c08be974c71b4c0505b4a048d5dc128c2b",
|
"sha256:6729914dd73483cd1c8aaace3ac082436fc98b0072743ac136eaea0b3811d42f",
|
||||||
"sha256:a4eddbe2a715b2dd3849afbdeacf1cc283160b24e09baf64fa5675f51940419d",
|
"sha256:7406dd2e44c7cfb4680c0a45a03264381802c67890cf506c147288f04c67177d",
|
||||||
"sha256:a5c6dbe09aff091adfa8c7cfc1a0e83fdb8021ddb2c183512775a14f1435fe16",
|
"sha256:7684016b73938ca12d160d2907d141f06b7597bd17d854e32bb7588be01afa1d",
|
||||||
"sha256:b63e3571b24a7959017573b6455e05b675050bbbea69408f35f3cb984ec54363",
|
"sha256:7db58ad61f3f6ea393aaf124d774ee0c58806320bc85c06dc9480f5c7219c250",
|
||||||
"sha256:bb350eb1060591d8e89d6bac4713d41006cd4d479f5e11db334a48ff8999512f",
|
"sha256:83946ca9278b304728b637bc8d8200ab1663a79de85e47724594917aeed0e892",
|
||||||
"sha256:bf6d987edd4a44dd2fa2723fca2790f9442ae4de2c8438e53fcb1befdf5d823a",
|
"sha256:84057cfae5676f456b03970eb78b7e182fddc80c2daafd83465a3d6ca9ff8dbf",
|
||||||
"sha256:bfa6a679410b394600eafd16336b2ce8de43e9b13f7fb9247d84ef5ad2b45e91",
|
"sha256:862b6164e9a38b5c495be2c2854e75fd8af12c5be4c61dc9b42d255980d7e907",
|
||||||
"sha256:c856ec9b42e5af4fe2d8e75970fcc3a2c15925cbcc6e7a9bcb44583b10b95e80",
|
"sha256:8ddb4f9ce6bb388ecc97b4b3eb37e786f05d7d5815e8822e0d87a3dbd7100649",
|
||||||
"sha256:cea56288eeda8b7511d507bbe7790d89ae7049daa5f51ae31a35ae3c05408531",
|
"sha256:92eb03f47427fea452ff6956d11f5d5a3f22a048c90a0f34fa223e6badab6c85",
|
||||||
"sha256:ea212df6e5d3f60341aef46401d32fcfded85593af1d82b8b4a7a68cd67fdd6b",
|
"sha256:a5f3bc727fea58f21d99c22e6d4fca652dc11dbc2a1e7cfc4838cd53b2e3691f",
|
||||||
"sha256:f35567470ee6dbfb946f069ed5f5615b40edcbb5f1e6e1d3d2b114468d505fc6",
|
"sha256:a6180dbf5945b27e9420e1b58c3cacfc79ad5278bdad3ea35109f5680fbe16d1",
|
||||||
"sha256:fbc20975eee093efa2071de80df7f972b7b35e560b213aafabcec7c0bd00bd8c",
|
"sha256:b158f673ae6a6523f13704f70aa7e4ce875f91e379bece4362c89db18db189d5",
|
||||||
"sha256:ff4a8ad9638b7ca52313d8732f37ecd5fd3c8e3aff10a8ccb93176fd5b3812f6"
|
"sha256:cd45b4542134de63e7b9dd653e0a2d7d47ffed9615e3637c27ca5f6b78ea68bb",
|
||||||
|
"sha256:d2404336fd16788ea757d4218a2580de60adb052d9888031e765320be8884309",
|
||||||
|
"sha256:db888d4fb33a2fd54b57ac55d5015e51fa849f0d8592bd799b4e47f83bd04e00",
|
||||||
|
"sha256:dde0ac721c7c5bfa5f9fc285e811274dec3c392f2c1225f7d07ca98a8187ca84",
|
||||||
|
"sha256:de0d06ccbc06af5bf93bddec10f4f80275c5d74ea6d28b456931f3955f58bc8c",
|
||||||
|
"sha256:e02dad60e3e8442eefd28095e99b2ac98f2b8667167493ac6a2f3aadb5d84a17",
|
||||||
|
"sha256:e960fe211496333b2f7e36badf4c22a919d740386681f79139ee346b403d1ca1",
|
||||||
|
"sha256:e9700c52749cb3e90c98efd72b730c97b7e4962992fca5fbcaf1363be8e3b849",
|
||||||
|
"sha256:ee318974a1fdacba1701bc9e552e9015788d6345416364af6fa987424ff8df53"
|
||||||
],
|
],
|
||||||
"version": "==2021.8.3"
|
"version": "==2021.8.27"
|
||||||
},
|
},
|
||||||
"s3cmd": {
|
"s3cmd": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -462,10 +485,10 @@
|
|||||||
},
|
},
|
||||||
"testfixtures": {
|
"testfixtures": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:9bddf79b2dddb36420a20c25a65c827a8e7398c6ed4e2c75c2697857cb006be9",
|
"sha256:0a6422737f6d89b45cdef1e2df5576f52ad0f507956002ce1020daa9f44211d6",
|
||||||
"sha256:d4bd1c4f90eac90a73e1bdc59c31d03943f218d687f3c5a09e48478841a8af5f"
|
"sha256:486be7b01eb71326029811878a3317b7e7994324621c0ec633c8e24499d8d5b3"
|
||||||
],
|
],
|
||||||
"version": "==6.18.0"
|
"version": "==6.18.1"
|
||||||
},
|
},
|
||||||
"toml": {
|
"toml": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -483,6 +506,14 @@
|
|||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==5.0.5"
|
"version": "==5.0.5"
|
||||||
},
|
},
|
||||||
|
"typing": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9",
|
||||||
|
"sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==3.7.4.3"
|
||||||
|
},
|
||||||
"typing-extensions": {
|
"typing-extensions": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
|
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
|
||||||
|
@ -11,3 +11,17 @@ class UnicodeMode:
|
|||||||
LINUX = IBUS = const(1)
|
LINUX = IBUS = const(1)
|
||||||
MACOS = OSX = RALT = const(2)
|
MACOS = OSX = RALT = const(2)
|
||||||
WINC = const(3)
|
WINC = const(3)
|
||||||
|
|
||||||
|
|
||||||
|
TYPING_PLATFORMS = [
|
||||||
|
'linux',
|
||||||
|
'linux2',
|
||||||
|
'win32',
|
||||||
|
'cygwin',
|
||||||
|
'msys',
|
||||||
|
'darwin',
|
||||||
|
'freebsd7',
|
||||||
|
'freebsd8',
|
||||||
|
'freebsdN',
|
||||||
|
'openbsd6',
|
||||||
|
]
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
|
from kmk.kmk_keyboard import KMKKeyboard
|
||||||
|
|
||||||
|
|
||||||
class InvalidExtensionEnvironment(Exception):
|
class InvalidExtensionEnvironment(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Extension:
|
class Extension:
|
||||||
_enabled = True
|
_enabled = True # type: bool
|
||||||
|
|
||||||
def enable(self, keyboard):
|
def enable(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
self._enabled = True
|
self._enabled = True
|
||||||
|
|
||||||
self.on_runtime_enable(keyboard)
|
self.on_runtime_enable(keyboard)
|
||||||
|
|
||||||
def disable(self, keyboard):
|
def disable(self, keyboard):
|
||||||
|
# type (KMKKeyboard) -> None
|
||||||
self._enabled = False
|
self._enabled = False
|
||||||
|
|
||||||
self.on_runtime_disable(keyboard)
|
self.on_runtime_disable(keyboard)
|
||||||
@ -18,34 +23,43 @@ class Extension:
|
|||||||
# The below methods should be implemented by subclasses
|
# The below methods should be implemented by subclasses
|
||||||
|
|
||||||
def on_runtime_enable(self, keyboard):
|
def on_runtime_enable(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def on_runtime_disable(self, keyboard):
|
def on_runtime_disable(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def during_bootup(self, keyboard):
|
def during_bootup(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def before_matrix_scan(self, keyboard):
|
def before_matrix_scan(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
'''
|
'''
|
||||||
Return value will be injected as an extra matrix update
|
Return value will be injected as an extra matrix update
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def after_matrix_scan(self, keyboard):
|
def after_matrix_scan(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
'''
|
'''
|
||||||
Return value will be replace matrix update if supplied
|
Return value will be replace matrix update if supplied
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def before_hid_send(self, keyboard):
|
def before_hid_send(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def after_hid_send(self, keyboard):
|
def after_hid_send(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def on_powersave_enable(self, keyboard):
|
def on_powersave_enable(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def on_powersave_disable(self, keyboard):
|
def on_powersave_disable(self, keyboard):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'''Adds international keys'''
|
'''Adds international keys'''
|
||||||
from kmk.extensions import Extension
|
from kmk.extensions import Extension
|
||||||
from kmk.keys import make_key
|
from kmk.keys import make_key
|
||||||
|
from kmk.kmk_keyboard import KMKKeyboard
|
||||||
|
|
||||||
|
|
||||||
class International(Extension):
|
class International(Extension):
|
||||||
@ -32,28 +33,37 @@ class International(Extension):
|
|||||||
make_key(code=152, names=('LANG9',))
|
make_key(code=152, names=('LANG9',))
|
||||||
|
|
||||||
def on_runtime_enable(self, sandbox):
|
def on_runtime_enable(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_runtime_disable(self, sandbox):
|
def on_runtime_disable(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def during_bootup(self, sandbox):
|
def during_bootup(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def before_matrix_scan(self, sandbox):
|
def before_matrix_scan(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def after_matrix_scan(self, sandbox):
|
def after_matrix_scan(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def before_hid_send(self, sandbox):
|
def before_hid_send(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def after_hid_send(self, sandbox):
|
def after_hid_send(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_powersave_enable(self, sandbox):
|
def on_powersave_enable(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_powersave_disable(self, sandbox):
|
def on_powersave_disable(self, sandbox):
|
||||||
|
# type: (KMKKeyboard) -> None
|
||||||
return
|
return
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
from typing import Any, Optional
|
import sys
|
||||||
|
|
||||||
from kmk.keys import Key, KeyAttrDict
|
from kmk.consts import TYPING_PLATFORMS
|
||||||
from kmk.kmk_keyboard import KMKKeyboard
|
|
||||||
from kmk.kmktime import sleep_ms
|
from kmk.kmktime import sleep_ms
|
||||||
|
|
||||||
|
if sys.platform in TYPING_PLATFORMS:
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from kmk.keys import Key, KeyAttrDict
|
||||||
|
from kmk.kmk_keyboard import KMKKeyboard # Avoid cyclical imports
|
||||||
|
|
||||||
|
|
||||||
def passthrough(key, keyboard, *args, **kwargs):
|
def passthrough(key, keyboard, *args, **kwargs):
|
||||||
return keyboard
|
return keyboard
|
||||||
|
|
||||||
|
|
||||||
def default_pressed(
|
def default_pressed(
|
||||||
key: Key,
|
key, # type: Key
|
||||||
keyboard: KMKKeyboard,
|
keyboard, # type: KMKKeyboard
|
||||||
KC: KeyAttrDict,
|
KC, # type: KeyAttrDict
|
||||||
coord_int: Optional[int] = None,
|
coord_int=None, # type: Optional[int]
|
||||||
coord_raw: Optional[str] = None,
|
coord_raw=None, # type: Optional[str]
|
||||||
*args: Any,
|
*args, # type: Any
|
||||||
**kwargs: Any,
|
**kwargs, # type: Any
|
||||||
) -> KMKKeyboard:
|
):
|
||||||
|
# type: (...) -> KMKKeyboard
|
||||||
keyboard.hid_pending = True
|
keyboard.hid_pending = True
|
||||||
|
|
||||||
if coord_int is not None:
|
if coord_int is not None:
|
||||||
@ -29,14 +35,15 @@ def default_pressed(
|
|||||||
|
|
||||||
|
|
||||||
def default_released(
|
def default_released(
|
||||||
key: Key,
|
key, # type: Key
|
||||||
keyboard: KMKKeyboard,
|
keyboard, # type: KMKKeyboard
|
||||||
KC: KeyAttrDict,
|
KC, # type: KeyAttrDict
|
||||||
coord_int: Optional[int] = None,
|
coord_int=None, # type: Optional[int]
|
||||||
coord_raw: Optional[str] = None,
|
coord_raw=None, # type: Optional[str]
|
||||||
*args: Any,
|
*args, # type: Any
|
||||||
**kwargs: Any, # NOQA
|
**kwargs, # type: Any # NOQA
|
||||||
):
|
):
|
||||||
|
# type: (...) -> KMKKeyboard
|
||||||
keyboard.hid_pending = True
|
keyboard.hid_pending = True
|
||||||
keyboard.keys_pressed.discard(key)
|
keyboard.keys_pressed.discard(key)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from typing import List, Optional
|
import sys
|
||||||
|
|
||||||
from kmk.keys import Key
|
from kmk.consts import TYPING_PLATFORMS
|
||||||
from kmk.types import (
|
from kmk.types import (
|
||||||
KeySeqSleepMeta,
|
KeySeqSleepMeta,
|
||||||
LayerKeyMeta,
|
LayerKeyMeta,
|
||||||
@ -9,12 +9,20 @@ from kmk.types import (
|
|||||||
UnicodeModeKeyMeta,
|
UnicodeModeKeyMeta,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if sys.platform in TYPING_PLATFORMS:
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
def key_seq_sleep_validator(ms: float) -> KeySeqSleepMeta:
|
# Avoid cyclical imports
|
||||||
|
from kmk.keys import Key
|
||||||
|
|
||||||
|
|
||||||
|
def key_seq_sleep_validator(ms):
|
||||||
|
# type: (float) -> KeySeqSleepMeta
|
||||||
return KeySeqSleepMeta(ms)
|
return KeySeqSleepMeta(ms)
|
||||||
|
|
||||||
|
|
||||||
def layer_key_validator(layer: int, kc: Key = None) -> LayerKeyMeta:
|
def layer_key_validator(layer, kc=None):
|
||||||
|
# type: (int, Optional[Key]) -> LayerKeyMeta
|
||||||
'''
|
'''
|
||||||
Validates the syntax (but not semantics) of a layer key call. We won't
|
Validates the syntax (but not semantics) of a layer key call. We won't
|
||||||
have access to the keymap here, so we can't verify much of anything useful
|
have access to the keymap here, so we can't verify much of anything useful
|
||||||
@ -25,16 +33,19 @@ def layer_key_validator(layer: int, kc: Key = None) -> LayerKeyMeta:
|
|||||||
return LayerKeyMeta(layer=layer, kc=kc)
|
return LayerKeyMeta(layer=layer, kc=kc)
|
||||||
|
|
||||||
|
|
||||||
def mod_tap_validator(kc: Key, mods: Optional[List[Key]] = None) -> ModTapKeyMeta:
|
def mod_tap_validator(kc, mods):
|
||||||
|
# type: (Key, Optional[List[Key]]) -> ModTapKeyMeta
|
||||||
'''
|
'''
|
||||||
Validates that mod tap keys are correctly used
|
Validates that mod tap keys are correctly used
|
||||||
'''
|
'''
|
||||||
return ModTapKeyMeta(kc=kc, mods=mods)
|
return ModTapKeyMeta(kc=kc, mods=mods)
|
||||||
|
|
||||||
|
|
||||||
def tap_dance_key_validator(*codes: Key) -> TapDanceKeyMeta:
|
def tap_dance_key_validator(*codes):
|
||||||
|
# type: (*Key) -> TapDanceKeyMeta
|
||||||
return TapDanceKeyMeta(codes)
|
return TapDanceKeyMeta(codes)
|
||||||
|
|
||||||
|
|
||||||
def unicode_mode_key_validator(mode: int) -> UnicodeModeKeyMeta:
|
def unicode_mode_key_validator(mode):
|
||||||
|
# type: (int) -> UnicodeModeKeyMeta
|
||||||
return UnicodeModeKeyMeta(mode)
|
return UnicodeModeKeyMeta(mode)
|
||||||
|
253
kmk/keys.py
253
kmk/keys.py
@ -1,43 +1,37 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import gc
|
import gc
|
||||||
from micropython import const
|
from micropython import const
|
||||||
|
|
||||||
from typing import Any, Callable, List, Optional, Protocol, Set, Tuple, Union
|
import sys
|
||||||
|
|
||||||
import kmk.handlers.stock as handlers
|
import kmk.handlers.stock as handlers
|
||||||
from kmk.consts import UnicodeMode
|
from kmk.consts import TYPING_PLATFORMS, UnicodeMode
|
||||||
from kmk.key_validators import (
|
from kmk.key_validators import (
|
||||||
key_seq_sleep_validator,
|
key_seq_sleep_validator,
|
||||||
tap_dance_key_validator,
|
tap_dance_key_validator,
|
||||||
unicode_mode_key_validator,
|
unicode_mode_key_validator,
|
||||||
)
|
)
|
||||||
from kmk.kmk_keyboard import KMKKeyboard
|
|
||||||
from kmk.types import AttrDict, UnicodeModeKeyMeta
|
from kmk.types import AttrDict, UnicodeModeKeyMeta
|
||||||
|
|
||||||
DEBUG_OUTPUT: bool = False
|
if sys.platform in TYPING_PLATFORMS:
|
||||||
|
from typing import Any, Callable, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
FIRST_KMK_INTERNAL_KEY: int = const(1000)
|
# Avoid cyclical imports
|
||||||
NEXT_AVAILABLE_KEY: int = 1000
|
from kmk.kmk_keyboard import KMKKeyboard
|
||||||
|
|
||||||
KEY_SIMPLE: int = const(0)
|
|
||||||
KEY_MODIFIER: int = const(1)
|
|
||||||
KEY_CONSUMER: int = const(2)
|
|
||||||
|
|
||||||
ALL_ALPHAS: str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
DEBUG_OUTPUT = False # type: bool
|
||||||
ALL_NUMBERS: str = '1234567890'
|
|
||||||
|
FIRST_KMK_INTERNAL_KEY = const(1000) # type: int
|
||||||
|
NEXT_AVAILABLE_KEY = 1000 # type: int
|
||||||
|
|
||||||
|
KEY_SIMPLE = const(0) # type: int
|
||||||
|
KEY_MODIFIER = const(1) # type: int
|
||||||
|
KEY_CONSUMER = const(2) # type: int
|
||||||
|
|
||||||
|
ALL_ALPHAS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # type: str
|
||||||
|
ALL_NUMBERS = '1234567890' # type: str
|
||||||
# since KC.1 isn't valid Python, alias to KC.N1
|
# since KC.1 isn't valid Python, alias to KC.N1
|
||||||
ALL_NUMBER_ALIASES: Tuple[str, ...] = tuple(f'N{x}' for x in ALL_NUMBERS)
|
ALL_NUMBER_ALIASES = tuple(f'N{x}' for x in ALL_NUMBERS) # type: Tuple[str, ...]
|
||||||
|
|
||||||
|
|
||||||
KeyReturn = Union[Key, ModifierKey, ConsumerKey, None]
|
|
||||||
|
|
||||||
|
|
||||||
class LeftPipeCallback(Protocol):
|
|
||||||
def __call__(
|
|
||||||
self, candidate: str, code: Union[str, int], names: Tuple[str, ...]
|
|
||||||
) -> KeyReturn:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class InfiniteLoopDetected(Exception):
|
class InfiniteLoopDetected(Exception):
|
||||||
@ -47,10 +41,11 @@ class InfiniteLoopDetected(Exception):
|
|||||||
# this is a bit of an FP style thing - combining a pipe operator a-la F# with
|
# this is a bit of an FP style thing - combining a pipe operator a-la F# with
|
||||||
# a bootleg Maybe monad to clean up these make_key sequences
|
# a bootleg Maybe monad to clean up these make_key sequences
|
||||||
def left_pipe_until_some(
|
def left_pipe_until_some(
|
||||||
candidate: str,
|
candidate, # type: str
|
||||||
functor: LeftPipeCallback,
|
functor, # type: Callable[[str, Union[str, int], Tuple[str, ...]], Optional[Union[Key, ModifierKey, ConsumerKey]]]
|
||||||
*args_iter: Tuple[Union[str, int], Tuple[str, ...]],
|
*args_iter, # type: Tuple[Union[str, int], Tuple[str, ...]]
|
||||||
) -> KeyReturn:
|
):
|
||||||
|
# type: (...) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
for args in args_iter:
|
for args in args_iter:
|
||||||
result = functor(candidate, *args)
|
result = functor(candidate, *args)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
@ -58,41 +53,43 @@ def left_pipe_until_some(
|
|||||||
|
|
||||||
|
|
||||||
def first_truthy(
|
def first_truthy(
|
||||||
candidate: str,
|
candidate, # type: str
|
||||||
*funcs: Callable[[str], Union[Key, ModifierKey, ConsumerKey, None]],
|
*funcs, # type: Callable[[str], Union[Key, ModifierKey, ConsumerKey, None]]
|
||||||
) -> KeyReturn:
|
):
|
||||||
|
# type: (...) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
result = func(candidate)
|
result = func(candidate)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def maybe_make_mod_key(candidate: str, code: int, names: Tuple[str, ...]) -> KeyReturn:
|
def maybe_make_mod_key(candidate, code, names):
|
||||||
|
# type: (str, int, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
if candidate in names:
|
if candidate in names:
|
||||||
return make_mod_key(code=code, names=names)
|
return make_mod_key(code=code, names=names)
|
||||||
|
|
||||||
|
|
||||||
def maybe_make_key(candidate: str, code: int, names: Tuple[str, ...]) -> KeyReturn:
|
def maybe_make_key(candidate, code, names):
|
||||||
|
# type: (str, int, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
if candidate in names:
|
if candidate in names:
|
||||||
return make_key(code=code, names=names)
|
return make_key(code=code, names=names)
|
||||||
|
|
||||||
|
|
||||||
def maybe_make_shifted_key(
|
def maybe_make_shifted_key(candidate, target_name, names):
|
||||||
candidate: str, target_name: str, names: Tuple[str, ...]
|
# type: (str, str, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
) -> KeyReturn:
|
|
||||||
if candidate in names:
|
if candidate in names:
|
||||||
return make_shifted_key(target_name=target_name, names=names)
|
return make_shifted_key(target_name=target_name, names=names)
|
||||||
|
|
||||||
|
|
||||||
def maybe_make_consumer_key(
|
def maybe_make_consumer_key(candidate, code, names):
|
||||||
candidate: str, code: int, names: Tuple[str, ...]
|
# type: (str, int, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
) -> KeyReturn:
|
|
||||||
if candidate in names:
|
if candidate in names:
|
||||||
return make_consumer_key(code=code, names=names)
|
return make_consumer_key(code=code, names=names)
|
||||||
|
|
||||||
|
|
||||||
class KeyAttrDict(AttrDict):
|
class KeyAttrDict(AttrDict):
|
||||||
def __getattr__(self, key: str, depth: int = 0) -> KeyReturn:
|
def __getattr__(self, key, depth=0):
|
||||||
|
# type: (str, int) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
if depth > 1:
|
if depth > 1:
|
||||||
raise InfiniteLoopDetected()
|
raise InfiniteLoopDetected()
|
||||||
|
|
||||||
@ -410,54 +407,46 @@ class KeyAttrDict(AttrDict):
|
|||||||
KC = KeyAttrDict()
|
KC = KeyAttrDict()
|
||||||
|
|
||||||
|
|
||||||
class DefaultPressRelease(Protocol):
|
|
||||||
def __call__(
|
|
||||||
self,
|
|
||||||
key: Key,
|
|
||||||
keyboard: KMKKeyboard,
|
|
||||||
KC: KeyAttrDict,
|
|
||||||
coord_int: Optional[int],
|
|
||||||
coord_raw: Optional[str],
|
|
||||||
*args: Any,
|
|
||||||
**kwargs: Any,
|
|
||||||
) -> KMKKeyboard:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
Handler = Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]
|
|
||||||
|
|
||||||
|
|
||||||
HandlerList = List[Handler]
|
|
||||||
|
|
||||||
|
|
||||||
class Key:
|
class Key:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
code: int,
|
code, # type: int
|
||||||
has_modifiers: Optional[Set[int]] = None,
|
has_modifiers=None, # type: Optional[Set[int]]
|
||||||
no_press: Optional[bool] = False,
|
no_press=False, # type: bool
|
||||||
no_release: Optional[bool] = False,
|
no_release=False, # type: bool
|
||||||
on_press: DefaultPressRelease = handlers.default_pressed,
|
on_press=handlers.default_pressed, # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
|
||||||
on_release: DefaultPressRelease = handlers.default_released,
|
on_release=handlers.default_released, # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
|
||||||
meta: object = object(),
|
meta=object(), # type: object
|
||||||
) -> None:
|
):
|
||||||
self.code: int = code
|
# type: (...) -> None
|
||||||
self.has_modifiers: Optional[Set[int]] = has_modifiers
|
self.code = code # type: int
|
||||||
|
self.has_modifiers = has_modifiers # type: Optional[Set[int]]
|
||||||
# cast to bool() in case we get a None value
|
# cast to bool() in case we get a None value
|
||||||
self.no_press: bool = bool(no_press)
|
self.no_press = bool(no_press) # type: bool
|
||||||
self.no_release: bool = bool(no_press)
|
self.no_release = bool(no_press) # type: bool
|
||||||
|
|
||||||
self._pre_press_handlers: HandlerList = []
|
self._pre_press_handlers = (
|
||||||
self._post_press_handlers: HandlerList = []
|
[]
|
||||||
self._pre_release_handlers: HandlerList = []
|
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
|
||||||
self._post_release_handlers: HandlerList = []
|
self._post_press_handlers = (
|
||||||
self._handle_press: DefaultPressRelease = on_press
|
[]
|
||||||
self._handle_release: DefaultPressRelease = on_release
|
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
|
||||||
self.meta: object = meta
|
self._pre_release_handlers = (
|
||||||
|
[]
|
||||||
|
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
|
||||||
|
self._post_release_handlers = (
|
||||||
|
[]
|
||||||
|
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
|
||||||
|
self._handle_press = (
|
||||||
|
on_press
|
||||||
|
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
|
||||||
|
self._handle_release = (
|
||||||
|
on_release
|
||||||
|
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
|
||||||
|
self.meta = meta # type: object
|
||||||
|
|
||||||
def __call__(
|
def __call__(self, no_press, no_release):
|
||||||
self, no_press: Optional[bool] = None, no_release: Optional[bool] = None
|
# type: (Optional[bool], Optional[bool]) -> Key
|
||||||
) -> Key:
|
|
||||||
if no_press is None and no_release is None:
|
if no_press is None and no_release is None:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -469,37 +458,43 @@ class Key:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# type: () -> str
|
||||||
return 'Key(code={}, has_modifiers={})'.format(self.code, self.has_modifiers)
|
return 'Key(code={}, has_modifiers={})'.format(self.code, self.has_modifiers)
|
||||||
|
|
||||||
def on_press(
|
def on_press(self, state, coord_int, coord_raw):
|
||||||
self, state: KMKKeyboard, coord_int: int, coord_raw: str
|
# type: (KMKKeyboard, int, str) -> Optional[Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]]
|
||||||
) -> Union[KMKKeyboard, None]:
|
|
||||||
for fn in self._pre_press_handlers:
|
for fn in self._pre_press_handlers:
|
||||||
if not fn(self, state, KC, coord_int, coord_raw):
|
if not fn(self, state, KC, coord_int, coord_raw):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
ret = self._handle_press(self, state, KC, coord_int, coord_raw)
|
# TODO -- SOFUBI -- look into way to type hint *args and **kwargs of a Callable signature
|
||||||
|
ret = self._handle_press(
|
||||||
|
self, state, KC, coord_int, coord_raw
|
||||||
|
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
|
||||||
|
|
||||||
for fn in self._post_press_handlers:
|
for fn in self._post_press_handlers:
|
||||||
fn(self, state, KC, coord_int, coord_raw)
|
fn(self, state, KC, coord_int, coord_raw)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def on_release(
|
def on_release(self, state, coord_int, coord_raw):
|
||||||
self, state: KMKKeyboard, coord_int: int, coord_raw: str
|
# type: (KMKKeyboard, int, str) -> Optional[Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]]
|
||||||
) -> Union[KMKKeyboard, None]:
|
|
||||||
for fn in self._pre_release_handlers:
|
for fn in self._pre_release_handlers:
|
||||||
if not fn(self, state, KC, coord_int, coord_raw):
|
if not fn(self, state, KC, coord_int, coord_raw):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
ret = self._handle_release(self, state, KC, coord_int, coord_raw)
|
# TODO -- SOFUBI -- look into way to type hint *args and **kwargs of a Callable signature
|
||||||
|
ret = self._handle_release(
|
||||||
|
self, state, KC, coord_int, coord_raw
|
||||||
|
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
|
||||||
|
|
||||||
for fn in self._post_release_handlers:
|
for fn in self._post_release_handlers:
|
||||||
fn(self, state, KC, coord_int, coord_raw)
|
fn(self, state, KC, coord_int, coord_raw)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def clone(self) -> Key:
|
def clone(self):
|
||||||
|
# type: () -> Key
|
||||||
'''
|
'''
|
||||||
Return a shallow clone of the current key without any pre/post press/release
|
Return a shallow clone of the current key without any pre/post press/release
|
||||||
handlers attached. Almost exclusively useful for creating non-colliding keys
|
handlers attached. Almost exclusively useful for creating non-colliding keys
|
||||||
@ -516,7 +511,8 @@ class Key:
|
|||||||
meta=self.meta,
|
meta=self.meta,
|
||||||
)
|
)
|
||||||
|
|
||||||
def before_press_handler(self, fn: Handler) -> Key:
|
def before_press_handler(self, fn):
|
||||||
|
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
|
||||||
'''
|
'''
|
||||||
Attach a callback to be run prior to the on_press handler for this key.
|
Attach a callback to be run prior to the on_press handler for this key.
|
||||||
Receives the following:
|
Receives the following:
|
||||||
@ -540,7 +536,8 @@ class Key:
|
|||||||
self._pre_press_handlers.append(fn)
|
self._pre_press_handlers.append(fn)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def after_press_handler(self, fn: Handler) -> Key:
|
def after_press_handler(self, fn):
|
||||||
|
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
|
||||||
'''
|
'''
|
||||||
Attach a callback to be run after the on_release handler for this key.
|
Attach a callback to be run after the on_release handler for this key.
|
||||||
Receives the following:
|
Receives the following:
|
||||||
@ -563,7 +560,8 @@ class Key:
|
|||||||
self._post_press_handlers.append(fn)
|
self._post_press_handlers.append(fn)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def before_release_handler(self, fn: Handler) -> Key:
|
def before_release_handler(self, fn):
|
||||||
|
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
|
||||||
'''
|
'''
|
||||||
Attach a callback to be run prior to the on_release handler for this
|
Attach a callback to be run prior to the on_release handler for this
|
||||||
key. Receives the following:
|
key. Receives the following:
|
||||||
@ -587,7 +585,8 @@ class Key:
|
|||||||
self._pre_release_handlers.append(fn)
|
self._pre_release_handlers.append(fn)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def after_release_handler(self, fn: Handler) -> Key:
|
def after_release_handler(self, fn):
|
||||||
|
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
|
||||||
'''
|
'''
|
||||||
Attach a callback to be run after the on_release handler for this key.
|
Attach a callback to be run after the on_release handler for this key.
|
||||||
Receives the following:
|
Receives the following:
|
||||||
@ -615,14 +614,15 @@ class ModifierKey(Key):
|
|||||||
# FIXME this is atrocious to read. Please, please, please, strike down upon
|
# FIXME this is atrocious to read. Please, please, please, strike down upon
|
||||||
# this with great vengeance and furious anger.
|
# this with great vengeance and furious anger.
|
||||||
|
|
||||||
FAKE_CODE: int = const(-1)
|
FAKE_CODE = const(-1) # type: int
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self,
|
self,
|
||||||
modified_code: Optional[Key] = None,
|
modified_code=None, # type: Optional[Key]
|
||||||
no_press: Optional[bool] = None,
|
no_press=None, # type: Optional[bool]
|
||||||
no_release: Optional[bool] = None,
|
no_release=None, # type: Optional[bool]
|
||||||
) -> Union[Key, ModifierKey]:
|
):
|
||||||
|
# type: (...) -> Union[Key, ModifierKey]
|
||||||
if modified_code is None and no_press is None and no_release is None:
|
if modified_code is None and no_press is None and no_release is None:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -655,7 +655,8 @@ class ModifierKey(Key):
|
|||||||
|
|
||||||
return new_keycode
|
return new_keycode
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self):
|
||||||
|
# () -> str
|
||||||
return 'ModifierKey(code={}, has_modifiers={})'.format(
|
return 'ModifierKey(code={}, has_modifiers={})'.format(
|
||||||
self.code, self.has_modifiers
|
self.code, self.has_modifiers
|
||||||
)
|
)
|
||||||
@ -665,7 +666,8 @@ class ConsumerKey(Key):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def register_key_names(key: Key, names: Tuple[str, ...] = tuple()): # NOQA
|
def register_key_names(key, names=tuple()): # NOQA
|
||||||
|
# type: (Key, Tuple[str, ...]) -> Key
|
||||||
'''
|
'''
|
||||||
Names are globally unique. If a later key is created with
|
Names are globally unique. If a later key is created with
|
||||||
the same name as an existing entry in `KC`, it will overwrite
|
the same name as an existing entry in `KC`, it will overwrite
|
||||||
@ -686,12 +688,8 @@ def register_key_names(key: Key, names: Tuple[str, ...] = tuple()): # NOQA
|
|||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
def make_key(
|
def make_key(code=None, names=tuple(), type=KEY_SIMPLE, **kwargs): # NOQA
|
||||||
code: Optional[int] = None,
|
# type: (Optional[int], Tuple[str, ...], int, **Any) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
names: Tuple[str, ...] = tuple(),
|
|
||||||
type: int = KEY_SIMPLE,
|
|
||||||
**kwargs: Any,
|
|
||||||
) -> KeyReturn: # NOQA
|
|
||||||
'''
|
'''
|
||||||
Create a new key, aliased by `names` in the KC lookup table.
|
Create a new key, aliased by `names` in the KC lookup table.
|
||||||
|
|
||||||
@ -733,16 +731,13 @@ def make_key(
|
|||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
def make_mod_key(
|
def make_mod_key(code, names, *args, **kwargs):
|
||||||
code: Optional[int],
|
# type: (Optional[int], Tuple[str, ...], *Any, **Any) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
names: Tuple[str, ...],
|
|
||||||
*args: Any,
|
|
||||||
**kwargs: Any,
|
|
||||||
):
|
|
||||||
return make_key(code, names, *args, **kwargs, type=KEY_MODIFIER)
|
return make_key(code, names, *args, **kwargs, type=KEY_MODIFIER)
|
||||||
|
|
||||||
|
|
||||||
def make_shifted_key(target_name, names=tuple()): # NOQA
|
def make_shifted_key(target_name, names=tuple()): # NOQA
|
||||||
|
# type: (str, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
# For... probably a few years, a bug existed here where keys were looked
|
# For... probably a few years, a bug existed here where keys were looked
|
||||||
# up by `KC[...]`, but that's incorrect: an AttrDit exposes a dictionary
|
# up by `KC[...]`, but that's incorrect: an AttrDit exposes a dictionary
|
||||||
# with attributes, but key-based dictionary access with brackets does
|
# with attributes, but key-based dictionary access with brackets does
|
||||||
@ -757,34 +752,28 @@ def make_shifted_key(target_name, names=tuple()): # NOQA
|
|||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
def make_consumer_key(*args: Any, **kwargs: Any):
|
def make_consumer_key(*args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
return make_key(*args, **kwargs, type=KEY_CONSUMER)
|
return make_key(*args, **kwargs, type=KEY_CONSUMER)
|
||||||
|
|
||||||
|
|
||||||
class ArgumentedKey(Protocol):
|
|
||||||
def __call__(self, *user_args: Any, **user_kwargs: Any) -> Key:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class Validator(Protocol):
|
|
||||||
def __call__(self, *validator_args: Any, **validator_kwargs: Any) -> object:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Argumented keys are implicitly internal, so auto-gen of code
|
# Argumented keys are implicitly internal, so auto-gen of code
|
||||||
# is almost certainly the best plan here
|
# is almost certainly the best plan here
|
||||||
def make_argumented_key(
|
def make_argumented_key(
|
||||||
validator: Validator = lambda *validator_args, **validator_kwargs: object(),
|
validator=lambda *validator_args, **validator_kwargs: object(), # type: object
|
||||||
names: Tuple = tuple(), # NOQA
|
names=tuple(), # type: Tuple[str, ...] # NOQA
|
||||||
*constructor_args: Any,
|
*constructor_args, # type; Any
|
||||||
**constructor_kwargs: Any,
|
**constructor_kwargs, # type: Any
|
||||||
) -> Optional[ArgumentedKey]:
|
):
|
||||||
global NEXT_AVAILABLE_KEY
|
global NEXT_AVAILABLE_KEY
|
||||||
|
|
||||||
def _argumented_key(*user_args: Any, **user_kwargs: Any):
|
def _argumented_key(*user_args, **user_kwargs):
|
||||||
|
# type: (*Any, **Any) -> Union[Key, ModifierKey, ConsumerKey]
|
||||||
global NEXT_AVAILABLE_KEY
|
global NEXT_AVAILABLE_KEY
|
||||||
|
|
||||||
meta = validator(*user_args, **user_kwargs)
|
meta = validator(
|
||||||
|
*user_args, **user_kwargs
|
||||||
|
) # type: Callable[[Any, Any], object]
|
||||||
|
|
||||||
if meta:
|
if meta:
|
||||||
key = Key(
|
key = Key(
|
||||||
|
@ -1,77 +1,80 @@
|
|||||||
from __future__ import annotations
|
import sys
|
||||||
|
|
||||||
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
|
from kmk.consts import KMK_RELEASE, TYPING_PLATFORMS, UnicodeMode
|
||||||
|
|
||||||
from kmk.consts import KMK_RELEASE, UnicodeMode
|
|
||||||
from kmk.hid import BLEHID, USBHID, AbstractHID, HIDModes
|
from kmk.hid import BLEHID, USBHID, AbstractHID, HIDModes
|
||||||
from kmk.keys import KC, Key, KeyAttrDict
|
from kmk.keys import KC, Key, KeyAttrDict
|
||||||
from kmk.kmktime import ticks_ms
|
from kmk.kmktime import ticks_ms
|
||||||
from kmk.matrix import MatrixScanner, intify_coordinate
|
from kmk.matrix import MatrixScanner, intify_coordinate
|
||||||
from kmk.types import TapDanceKeyMeta
|
from kmk.types import TapDanceKeyMeta
|
||||||
|
|
||||||
|
if sys.platform in TYPING_PLATFORMS:
|
||||||
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
|
||||||
|
|
||||||
|
|
||||||
class Sandbox:
|
class Sandbox:
|
||||||
matrix_update: Optional[bytearray] = None
|
matrix_update = None # type: Optional[bytearray]
|
||||||
secondary_matrix_update: Optional[bytearray] = None
|
secondary_matrix_update = None # type: Optional[bytearray]
|
||||||
active_layers: Optional[List[int]] = None
|
active_layers = None # type: Optional[List[int]]
|
||||||
|
|
||||||
|
|
||||||
class KMKKeyboard:
|
class KMKKeyboard:
|
||||||
#####
|
#####
|
||||||
# User-configurable
|
# User-configurable
|
||||||
debug_enabled: bool = False
|
debug_enabled = False # type: bool
|
||||||
|
|
||||||
keymap: List[KeyAttrDict] = []
|
keymap = [] # type: List[KeyAttrDict]
|
||||||
coord_mapping: Optional[List[int]] = None
|
coord_mapping = None # type: Optional[List[int]]
|
||||||
|
|
||||||
row_pins: Optional[Tuple[Any, ...]] = None
|
row_pins = None # type: Optional[Tuple[Any, ...]]
|
||||||
col_pins: Optional[Tuple[Any, ...]] = None
|
col_pins = None # type: Optional[Tuple[Any, ...]]
|
||||||
diode_orientation: Optional[int] = None
|
diode_orientation = None # type: Optional[int]
|
||||||
matrix: Optional[MatrixScanner] = None
|
matrix = None # type: Optional[MatrixScanner]
|
||||||
matrix_scanner: Type[MatrixScanner] = MatrixScanner
|
matrix_scanner = MatrixScanner # type: Type[MatrixScanner]
|
||||||
uart_buffer: List[Any] = []
|
uart_buffer = [] # type: List[Any]
|
||||||
|
|
||||||
unicode_mode: int = UnicodeMode.NOOP
|
unicode_mode = UnicodeMode.NOOP # type: int
|
||||||
tap_time: int = 300
|
tap_time = 300 # type: int
|
||||||
|
|
||||||
modules: List[Type[Any]] = []
|
modules = [] # type: List[Type[Any]]
|
||||||
extensions: List[Type[Any]] = []
|
extensions = [] # type: List[Type[Any]]
|
||||||
sandbox: Sandbox = Sandbox()
|
sandbox = Sandbox() # type: Sandbox
|
||||||
|
|
||||||
#####
|
#####
|
||||||
# Internal State
|
# Internal State
|
||||||
keys_pressed: Set[Key] = set()
|
keys_pressed = set() # type: Set[Key]
|
||||||
_coordkeys_pressed: Dict[Any, Any] = {}
|
_coordkeys_pressed = {} # type: Dict[Any, Any]
|
||||||
hid_type: int = HIDModes.USB
|
hid_type = HIDModes.USB # type: int
|
||||||
secondary_hid_type: Optional[int] = None
|
secondary_hid_type = None # type: Optional[int]
|
||||||
_hid_helper: Optional[Union[Type[AbstractHID], Type[BLEHID], Type[USBHID]]] = None
|
_hid_helper = (
|
||||||
hid_pending: bool = False
|
None
|
||||||
state_layer_key: Optional[Key] = None
|
) # type: Optional[Union[Type[AbstractHID], Type[BLEHID], Type[USBHID]]]
|
||||||
matrix_update: Optional[Union[bytearray, None]] = None
|
hid_pending = False # type: bool
|
||||||
secondary_matrix_update: Optional[Union[bytearray, None]] = None
|
state_layer_key = None # type: Optional[Key]
|
||||||
_matrix_modify: Optional[Any] = None
|
matrix_update = None # type: Optional[Union[bytearray, None]]
|
||||||
state_changed: bool = False
|
secondary_matrix_update = None # type: Optional[Union[bytearray, None]]
|
||||||
_old_timeouts_len: Optional[int] = None
|
_matrix_modify = None # type: Optional[Any]
|
||||||
_new_timeouts_len: Optional[int] = None
|
state_changed = False # type: bool
|
||||||
_trigger_powersave_enable: bool = False
|
_old_timeouts_len = None # type: Optional[int]
|
||||||
_trigger_powersave_disable: bool = False
|
_new_timeouts_len = None # type: Optional[int]
|
||||||
i2c_deinit_count: int = 0
|
_trigger_powersave_enable = False # type: bool
|
||||||
|
_trigger_powersave_disable = False # type: bool
|
||||||
|
i2c_deinit_count = 0 # type: int
|
||||||
|
|
||||||
# this should almost always be PREpended to, replaces
|
# this should almost always be PREpended to, replaces
|
||||||
# former use of reversed_active_layers which had pointless
|
# former use of reversed_active_layers which had pointless
|
||||||
# overhead (the underlying list was never used anyway)
|
# overhead (the underlying list was never used anyway)
|
||||||
active_layers: List[int] = [0]
|
active_layers = [0] # type: List[int]
|
||||||
|
|
||||||
_timeouts: Dict[float, Callable[[], Key]] = {}
|
_timeouts = {} # type: Dict[float, Callable[[], Key]]
|
||||||
_tapping: bool = False
|
_tapping = False # type: bool
|
||||||
_tap_dance_counts: Dict[Union[Key, TapDanceKeyMeta], Union[int, None]] = {}
|
_tap_dance_counts = {} # type: Dict[Union[Key, TapDanceKeyMeta], Union[int, None]]
|
||||||
_tap_side_effects: Dict[Union[Key, TapDanceKeyMeta], Union[Key, None]] = {}
|
_tap_side_effects = {} # type: Dict[Union[Key, TapDanceKeyMeta], Union[int, None]]
|
||||||
|
|
||||||
# on some M4 setups (such as klardotsh/klarank_feather_m4, CircuitPython
|
# on some M4 setups (such as klardotsh/klarank_feather_m4, CircuitPython
|
||||||
# 6.0rc1) this runs out of RAM every cycle and takes down the board. no
|
# 6.0rc1) this runs out of RAM every cycle and takes down the board. no
|
||||||
# real known fix yet other than turning off debug, but M4s have always been
|
# real known fix yet other than turning off debug, but M4s have always been
|
||||||
# tight on RAM so....
|
# tight on RAM so....
|
||||||
def __repr__(self) -> str:
|
def __repr__(self): # type: () -> str
|
||||||
return (
|
return (
|
||||||
'KMKKeyboard('
|
'KMKKeyboard('
|
||||||
'debug_enabled={} '
|
'debug_enabled={} '
|
||||||
@ -107,22 +110,26 @@ class KMKKeyboard:
|
|||||||
self._tap_side_effects,
|
self._tap_side_effects,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _print_debug_cycle(self, init: bool = False) -> None:
|
def _print_debug_cycle(self, init=False):
|
||||||
|
# type: (bool) -> None
|
||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
if init:
|
if init:
|
||||||
print('KMKInit(release={})'.format(KMK_RELEASE))
|
print('KMKInit(release={})'.format(KMK_RELEASE))
|
||||||
print(self)
|
print(self)
|
||||||
|
|
||||||
def _send_hid(self) -> None:
|
def _send_hid(self):
|
||||||
|
# type: () -> None
|
||||||
self._hid_helper.create_report(self.keys_pressed).send()
|
self._hid_helper.create_report(self.keys_pressed).send()
|
||||||
self.hid_pending = False
|
self.hid_pending = False
|
||||||
|
|
||||||
def _handle_matrix_report(self, update: bytearray = None) -> None:
|
def _handle_matrix_report(self, update=None):
|
||||||
|
# type: (Optional[bytearray]) -> None
|
||||||
if update is not None:
|
if update is not None:
|
||||||
self._on_matrix_changed(update[0], update[1], update[2])
|
self._on_matrix_changed(update[0], update[1], update[2])
|
||||||
self.state_changed = True
|
self.state_changed = True
|
||||||
|
|
||||||
def _find_key_in_map(self, int_coord: int, row: int, col: int) -> Union[Key, None]:
|
def _find_key_in_map(self, int_coord, row, col):
|
||||||
|
# type: (int, int, int) -> Optional[Key]
|
||||||
self.state_layer_key = None
|
self.state_layer_key = None
|
||||||
try:
|
try:
|
||||||
idx = self.coord_mapping.index(int_coord)
|
idx = self.coord_mapping.index(int_coord)
|
||||||
@ -147,7 +154,8 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self.state_layer_key
|
return self.state_layer_key
|
||||||
|
|
||||||
def _on_matrix_changed(self, row: int, col: int, is_pressed: int) -> KMKKeyboard:
|
def _on_matrix_changed(self, row, col, is_pressed):
|
||||||
|
# type: (int, int, int) -> KMKKeyboard
|
||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
print('MatrixChange(col={} row={} pressed={})'.format(col, row, is_pressed))
|
print('MatrixChange(col={} row={} pressed={})'.format(col, row, is_pressed))
|
||||||
|
|
||||||
@ -162,11 +170,12 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
def process_key(
|
def process_key(
|
||||||
self,
|
self,
|
||||||
key: Union[Key, TapDanceKeyMeta],
|
key, # type: Union[Key, TapDanceKeyMeta]
|
||||||
is_pressed: int,
|
is_pressed, # type: int
|
||||||
coord_int: Optional[int] = None,
|
coord_int=None, # type: Optional[int]
|
||||||
coord_raw: Tuple[int, int] = None,
|
coord_raw=None, # type: Optional[Tuple[int, int]]
|
||||||
) -> KMKKeyboard:
|
):
|
||||||
|
# (...) -> KMKKeyboard
|
||||||
if self._tapping and not isinstance(key.meta, TapDanceKeyMeta):
|
if self._tapping and not isinstance(key.meta, TapDanceKeyMeta):
|
||||||
self._process_tap_dance(key, is_pressed)
|
self._process_tap_dance(key, is_pressed)
|
||||||
else:
|
else:
|
||||||
@ -177,24 +186,26 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def remove_key(self, keycode: Key) -> KMKKeyboard:
|
def remove_key(self, keycode):
|
||||||
|
# type: (Key) -> KMKKeyboard
|
||||||
self.keys_pressed.discard(keycode)
|
self.keys_pressed.discard(keycode)
|
||||||
return self.process_key(keycode, False)
|
return self.process_key(keycode, False)
|
||||||
|
|
||||||
def add_key(self, keycode: Key) -> KMKKeyboard:
|
def add_key(self, keycode):
|
||||||
|
# type: (Key) -> KMKKeyboard
|
||||||
self.keys_pressed.add(keycode)
|
self.keys_pressed.add(keycode)
|
||||||
return self.process_key(keycode, True)
|
return self.process_key(keycode, True)
|
||||||
|
|
||||||
def tap_key(self, keycode: Key) -> KMKKeyboard:
|
def tap_key(self, keycode):
|
||||||
|
# type: (Key) -> KMKKeyboard
|
||||||
self.add_key(keycode)
|
self.add_key(keycode)
|
||||||
# On the next cycle, we'll remove the key.
|
# On the next cycle, we'll remove the key.
|
||||||
self.set_timeout(False, lambda: self.remove_key(keycode))
|
self.set_timeout(False, lambda: self.remove_key(keycode))
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _process_tap_dance(
|
def _process_tap_dance(self, changed_key, is_pressed):
|
||||||
self, changed_key: Union[Key, TapDanceKeyMeta], is_pressed: int
|
# type: (Union[Key, TapDanceKeyMeta], int) -> KMKKeyboard
|
||||||
) -> KMKKeyboard:
|
|
||||||
if is_pressed:
|
if is_pressed:
|
||||||
if not isinstance(changed_key.meta, TapDanceKeyMeta):
|
if not isinstance(changed_key.meta, TapDanceKeyMeta):
|
||||||
# If we get here, changed_key is not a TapDanceKey and thus
|
# If we get here, changed_key is not a TapDanceKey and thus
|
||||||
@ -231,7 +242,8 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _end_tap_dance(self, td_key: Union[Key, TapDanceKeyMeta]) -> KMKKeyboard:
|
def _end_tap_dance(self, td_key):
|
||||||
|
# type: (Union[Key, TapDanceKeyMeta]) -> KMKKeyboard
|
||||||
v = self._tap_dance_counts[td_key] - 1
|
v = self._tap_dance_counts[td_key] - 1
|
||||||
|
|
||||||
if v >= 0:
|
if v >= 0:
|
||||||
@ -252,12 +264,14 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _cleanup_tap_dance(self, td_key: Union[Key, TapDanceKeyMeta]) -> KMKKeyboard:
|
def _cleanup_tap_dance(self, td_key):
|
||||||
|
# type: (Union[Key, TapDanceKeyMeta]) -> KMKKeyboard
|
||||||
self._tap_dance_counts[td_key] = 0
|
self._tap_dance_counts[td_key] = 0
|
||||||
self._tapping = any(count > 0 for count in self._tap_dance_counts.values())
|
self._tapping = any(count > 0 for count in self._tap_dance_counts.values())
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_timeout(self, after_ticks: float, callback: Callable[[], Key]) -> float:
|
def set_timeout(self, after_ticks, callback):
|
||||||
|
# type: (float, Callable[[], Key]) -> float
|
||||||
if after_ticks is False:
|
if after_ticks is False:
|
||||||
# We allow passing False as an implicit "run this on the next process timeouts cycle"
|
# We allow passing False as an implicit "run this on the next process timeouts cycle"
|
||||||
timeout_key = ticks_ms()
|
timeout_key = ticks_ms()
|
||||||
@ -270,11 +284,13 @@ class KMKKeyboard:
|
|||||||
self._timeouts[timeout_key] = callback
|
self._timeouts[timeout_key] = callback
|
||||||
return timeout_key
|
return timeout_key
|
||||||
|
|
||||||
def _cancel_timeout(self, timeout_key: float) -> None:
|
def _cancel_timeout(self, timeout_key):
|
||||||
|
# type: (float) -> None
|
||||||
if timeout_key in self._timeouts:
|
if timeout_key in self._timeouts:
|
||||||
del self._timeouts[timeout_key]
|
del self._timeouts[timeout_key]
|
||||||
|
|
||||||
def _process_timeouts(self) -> KMKKeyboard:
|
def _process_timeouts(self):
|
||||||
|
# type: () -> KMKKeyboard
|
||||||
if not self._timeouts:
|
if not self._timeouts:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -291,7 +307,8 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _init_sanity_check(self) -> KMKKeyboard:
|
def _init_sanity_check(self):
|
||||||
|
# type: () -> KMKKeyboard
|
||||||
'''
|
'''
|
||||||
Ensure the provided configuration is *probably* bootable
|
Ensure the provided configuration is *probably* bootable
|
||||||
'''
|
'''
|
||||||
@ -305,7 +322,8 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _init_coord_mapping(self) -> None:
|
def _init_coord_mapping(self):
|
||||||
|
# () -> None
|
||||||
'''
|
'''
|
||||||
Attempt to sanely guess a coord_mapping if one is not provided. No-op
|
Attempt to sanely guess a coord_mapping if one is not provided. No-op
|
||||||
if `kmk.extensions.split.Split` is used, it provides equivalent
|
if `kmk.extensions.split.Split` is used, it provides equivalent
|
||||||
@ -327,7 +345,8 @@ class KMKKeyboard:
|
|||||||
for cidx in range(cols_to_calc):
|
for cidx in range(cols_to_calc):
|
||||||
self.coord_mapping.append(intify_coordinate(ridx, cidx))
|
self.coord_mapping.append(intify_coordinate(ridx, cidx))
|
||||||
|
|
||||||
def _init_hid(self) -> None:
|
def _init_hid(self):
|
||||||
|
# type: () -> None
|
||||||
if self.hid_type == HIDModes.NOOP:
|
if self.hid_type == HIDModes.NOOP:
|
||||||
self._hid_helper = AbstractHID
|
self._hid_helper = AbstractHID
|
||||||
elif self.hid_type == HIDModes.USB:
|
elif self.hid_type == HIDModes.USB:
|
||||||
@ -338,7 +357,8 @@ class KMKKeyboard:
|
|||||||
self._hid_helper = AbstractHID
|
self._hid_helper = AbstractHID
|
||||||
self._hid_helper = self._hid_helper()
|
self._hid_helper = self._hid_helper()
|
||||||
|
|
||||||
def _init_matrix(self) -> KMKKeyboard:
|
def _init_matrix(self):
|
||||||
|
# type: () -> KMKKeyboard
|
||||||
self.matrix = MatrixScanner(
|
self.matrix = MatrixScanner(
|
||||||
cols=self.col_pins,
|
cols=self.col_pins,
|
||||||
rows=self.row_pins,
|
rows=self.row_pins,
|
||||||
@ -348,7 +368,8 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def before_matrix_scan(self) -> None:
|
def before_matrix_scan(self):
|
||||||
|
# type: () -> None
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
try:
|
try:
|
||||||
module.before_matrix_scan(self)
|
module.before_matrix_scan(self)
|
||||||
@ -363,7 +384,8 @@ class KMKKeyboard:
|
|||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
print('Failed to run pre matrix function in extension: ', err, ext)
|
print('Failed to run pre matrix function in extension: ', err, ext)
|
||||||
|
|
||||||
def after_matrix_scan(self) -> None:
|
def after_matrix_scan(self):
|
||||||
|
# type: () -> None
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
try:
|
try:
|
||||||
module.after_matrix_scan(self)
|
module.after_matrix_scan(self)
|
||||||
@ -378,7 +400,8 @@ class KMKKeyboard:
|
|||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
print('Failed to run post matrix function in extension: ', err, ext)
|
print('Failed to run post matrix function in extension: ', err, ext)
|
||||||
|
|
||||||
def before_hid_send(self) -> None:
|
def before_hid_send(self):
|
||||||
|
# type: () -> None
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
try:
|
try:
|
||||||
module.before_hid_send(self)
|
module.before_hid_send(self)
|
||||||
@ -393,7 +416,8 @@ class KMKKeyboard:
|
|||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
print('Failed to run pre hid function in extension: ', err, ext)
|
print('Failed to run pre hid function in extension: ', err, ext)
|
||||||
|
|
||||||
def after_hid_send(self) -> None:
|
def after_hid_send(self):
|
||||||
|
# type: () -> None
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
try:
|
try:
|
||||||
module.after_hid_send(self)
|
module.after_hid_send(self)
|
||||||
@ -408,7 +432,8 @@ class KMKKeyboard:
|
|||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
print('Failed to run post hid function in extension: ', err, ext)
|
print('Failed to run post hid function in extension: ', err, ext)
|
||||||
|
|
||||||
def powersave_enable(self) -> None:
|
def powersave_enable(self):
|
||||||
|
# type: () -> None
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
try:
|
try:
|
||||||
module.on_powersave_enable(self)
|
module.on_powersave_enable(self)
|
||||||
@ -423,7 +448,8 @@ class KMKKeyboard:
|
|||||||
if self.debug_enabled:
|
if self.debug_enabled:
|
||||||
print('Failed to run post hid function in extension: ', err, ext)
|
print('Failed to run post hid function in extension: ', err, ext)
|
||||||
|
|
||||||
def powersave_disable(self) -> None:
|
def powersave_disable(self):
|
||||||
|
# type: () -> None
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
try:
|
try:
|
||||||
module.on_powersave_disable(self)
|
module.on_powersave_disable(self)
|
||||||
@ -439,10 +465,11 @@ class KMKKeyboard:
|
|||||||
|
|
||||||
def go(
|
def go(
|
||||||
self,
|
self,
|
||||||
hid_type: int = HIDModes.USB,
|
hid_type=HIDModes.USB, # type: int
|
||||||
secondary_hid_type: Optional[int] = None,
|
secondary_hid_type=None, # type: Optional[int]
|
||||||
**kwargs: Dict[Any, Any],
|
**kwargs, # type: Dict[Any, Any]
|
||||||
) -> None:
|
):
|
||||||
|
# (...) -> None
|
||||||
self.hid_type = hid_type
|
self.hid_type = hid_type
|
||||||
self.secondary_hid_type = secondary_hid_type
|
self.secondary_hid_type = secondary_hid_type
|
||||||
|
|
||||||
|
@ -1,23 +1,28 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
def sleep_ms(ms: float) -> None:
|
def sleep_ms(ms):
|
||||||
|
# type: (float) -> None
|
||||||
return time.sleep(ms / 1000)
|
return time.sleep(ms / 1000)
|
||||||
|
|
||||||
|
|
||||||
def ticks_ms() -> float:
|
def ticks_ms():
|
||||||
|
# type: () -> float
|
||||||
'''Has .25s granularity, but is cheap'''
|
'''Has .25s granularity, but is cheap'''
|
||||||
return time.monotonic() * 1000
|
return time.monotonic() * 1000
|
||||||
|
|
||||||
|
|
||||||
def ticks_diff(new: float, old: float) -> float:
|
def ticks_diff(new, old):
|
||||||
|
# type: (float, float) -> float
|
||||||
return new - old
|
return new - old
|
||||||
|
|
||||||
|
|
||||||
def accurate_ticks() -> int:
|
def accurate_ticks():
|
||||||
|
# type: () -> int
|
||||||
'''Is more expensive, but good for time critical things'''
|
'''Is more expensive, but good for time critical things'''
|
||||||
return time.monotonic_ns()
|
return time.monotonic_ns()
|
||||||
|
|
||||||
|
|
||||||
def accurate_ticks_diff(new: float, old: float, ms: float) -> bool:
|
def accurate_ticks_diff(new, old, ms):
|
||||||
|
# type: (float, float, float) -> bool
|
||||||
return bool(new - old < ms * 1000000)
|
return bool(new - old < ms * 1000000)
|
||||||
|
49
kmk/types.py
49
kmk/types.py
@ -1,6 +1,12 @@
|
|||||||
from typing import List, Optional, Tuple
|
import sys
|
||||||
|
|
||||||
from kmk.keys import Key
|
from kmk.consts import TYPING_PLATFORMS
|
||||||
|
|
||||||
|
if sys.platform in TYPING_PLATFORMS:
|
||||||
|
from typing import List, Optional, Tuple, Union
|
||||||
|
|
||||||
|
# Avoid cyclical imports
|
||||||
|
from kmk.keys import ConsumerKey, Key, ModifierKey
|
||||||
|
|
||||||
|
|
||||||
class AttrDict(dict):
|
class AttrDict(dict):
|
||||||
@ -12,39 +18,44 @@ class AttrDict(dict):
|
|||||||
This is read-only on purpose.
|
This is read-only on purpose.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __getattr__(self, key: str) -> str:
|
def __getattr__(self, key):
|
||||||
|
# type: (str) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||||
return self[key]
|
return self[key]
|
||||||
|
|
||||||
|
|
||||||
class LayerKeyMeta:
|
class LayerKeyMeta:
|
||||||
def __init__(self, layer: int, kc: Optional[Key] = None) -> None:
|
def __init__(self, layer, kc=None):
|
||||||
self.layer: int = layer
|
# type: (int, Optional[Key]) -> None
|
||||||
self.kc: Optional[Key] = kc
|
self.layer = layer # type: int
|
||||||
|
self.kc = kc # type: Optional[Key]
|
||||||
|
|
||||||
|
|
||||||
class ModTapKeyMeta:
|
class ModTapKeyMeta:
|
||||||
def __init__(
|
def __init__(self, kc=None, mods=None):
|
||||||
self, kc: Optional[Key] = None, mods: Optional[List[Key]] = None
|
# type: (Optional[Key], Optional[List[Key]]) -> None
|
||||||
) -> None:
|
self.mods = mods # type: Optional[List[Key]]
|
||||||
self.mods: Optional[List[Key]] = mods
|
self.kc = kc # type: Optional[Key]
|
||||||
self.kc: Optional[Key] = kc
|
|
||||||
|
|
||||||
|
|
||||||
class KeySequenceMeta:
|
class KeySequenceMeta:
|
||||||
def __init__(self, seq: List[Key]):
|
def __init__(self, seq):
|
||||||
self.seq: List[Key] = seq
|
# type: (List[Key]) -> None
|
||||||
|
self.seq = seq # type: List[Key]
|
||||||
|
|
||||||
|
|
||||||
class KeySeqSleepMeta:
|
class KeySeqSleepMeta:
|
||||||
def __init__(self, ms: float):
|
def __init__(self, ms):
|
||||||
self.ms: float = ms
|
# type: (float) -> None
|
||||||
|
self.ms = ms # type: float
|
||||||
|
|
||||||
|
|
||||||
class UnicodeModeKeyMeta:
|
class UnicodeModeKeyMeta:
|
||||||
def __init__(self, mode: int):
|
def __init__(self, mode):
|
||||||
self.mode: int = mode
|
# type: (int) -> None
|
||||||
|
self.mode = mode # type: int
|
||||||
|
|
||||||
|
|
||||||
class TapDanceKeyMeta:
|
class TapDanceKeyMeta:
|
||||||
def __init__(self, codes: Tuple[Key, ...]):
|
def __init__(self, codes):
|
||||||
self.codes: Tuple[Key, ...] = codes
|
# type: (Tuple[Key, ...]) -> None
|
||||||
|
self.codes = codes # type: Tuple[Key, ...]
|
||||||
|
@ -24,18 +24,25 @@ exclude = '''
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
[tool.pyright]
|
[tool.pyright]
|
||||||
|
strict = ["kmk"]
|
||||||
|
typeCheckingMode = "strict"
|
||||||
include = ["kmk"]
|
include = ["kmk"]
|
||||||
exclude = [
|
exclude = [
|
||||||
"hardware",
|
"hardware",
|
||||||
".venv",
|
".venv",
|
||||||
"user_keymaps",
|
"user_keymaps",
|
||||||
"boards"
|
"boards",
|
||||||
|
".git"
|
||||||
]
|
]
|
||||||
|
venvPath = ".venv"
|
||||||
|
# stops constant reporting of missing board module etc.
|
||||||
reportMissingModuleSource = false
|
reportMissingModuleSource = false
|
||||||
# reports missing typestubs allowing for a code action to
|
# reports missing typestubs allowing for a code action to
|
||||||
# create new library typestubs
|
# create new library typestubs
|
||||||
reportMissingTypeStubs = true
|
reportMissingTypeStubs = true
|
||||||
|
pythonVersion = "3.6"
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
exclude = "boards/|user_keymaps/"
|
exclude = "boards/|user_keymaps/"
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
|
python_version = "3.6"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user