Compare commits
1 Commits
mpy_build
...
enhancemen
Author | SHA1 | Date | |
---|---|---|---|
|
9c1bd210eb |
23
.github/workflows/build.yml
vendored
23
.github/workflows/build.yml
vendored
@@ -1,23 +0,0 @@
|
||||
name: build_mpy
|
||||
on: [push]
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: run build script
|
||||
run: ./docker_mpy_build.sh
|
||||
|
||||
- name: look
|
||||
run: ls -la compiled/
|
||||
|
||||
- name: Archive
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mpy
|
||||
path: compiled
|
59
Dockerfile
59
Dockerfile
@@ -1,20 +1,39 @@
|
||||
FROM python:3.9-slim-buster
|
||||
|
||||
RUN mkdir -p /app /dist
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y curl
|
||||
|
||||
RUN curl https://adafruit-circuit-python.s3.amazonaws.com/bin/mpy-cross/linux-amd64/mpy-cross.static-amd64-linux-8.0.0 --output mpy-cross-8
|
||||
RUN curl https://adafruit-circuit-python.s3.amazonaws.com/bin/mpy-cross/linux-amd64/mpy-cross.static-amd64-linux-7.0.0 --output mpy-cross-7
|
||||
|
||||
|
||||
RUN chmod +x mpy-cross-8
|
||||
|
||||
RUN chmod +x mpy-cross-7
|
||||
|
||||
|
||||
COPY ./docker_mpy_build.sh /app/build.sh
|
||||
# COPY ./kmk /app/kmk/
|
||||
|
||||
CMD ["bash", "build.sh"]
|
||||
FROM python:3.9-slim-buster
|
||||
|
||||
ARG KMKPY_REF
|
||||
ARG KMKPY_URL
|
||||
|
||||
ENV KMKPY_REF ${KMKPY_REF}
|
||||
ENV KMKPY_URL ${KMKPY_URL}
|
||||
|
||||
RUN mkdir -p /app /dist
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y build-essential curl gettext git git-lfs rsync wget zip lbzip2
|
||||
RUN pip install pipenv
|
||||
|
||||
# Pull CircuitPython-designated ARM GCC to avoid mismatches/weird
|
||||
# inconsistencies with upstream
|
||||
RUN curl -L -o /tmp/gcc-arm.tar.bz2 https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 && \
|
||||
tar -C /usr --strip-components=1 -xaf /tmp/gcc-arm.tar.bz2 && \
|
||||
rm -rf /tmp/gcc-arm.tar.bz2
|
||||
|
||||
# Get a local copy of KMKPython and its dependencies. We don't provide MPY
|
||||
# builds for kmkpython anymore, so we can get away with being opinionated
|
||||
# here.
|
||||
RUN git init /opt/kmkpython && \
|
||||
git -C /opt/kmkpython remote add origin ${KMKPY_URL} && \
|
||||
git -C /opt/kmkpython fetch --depth 1 origin ${KMKPY_REF} && \
|
||||
git -C /opt/kmkpython checkout FETCH_HEAD && \
|
||||
git -C /opt/kmkpython submodule update --init --recursive
|
||||
|
||||
# Build the MPY compiler
|
||||
RUN make -C /opt/kmkpython/mpy-cross
|
||||
|
||||
ENV PATH=/opt/kmkpython/mpy-cross:${PATH}
|
||||
|
||||
RUN mkdir -p /opt/kmkpython/frozen/kmk/kmk
|
||||
COPY ./build_kmkpython_release.sh /app/
|
||||
COPY ./kmk /opt/kmkpython/frozen/kmk/kmk
|
||||
|
||||
CMD /app/build_kmkpython_release.sh
|
||||
|
2
Pipfile
2
Pipfile
@@ -17,6 +17,6 @@ ipython = "*"
|
||||
isort = "*"
|
||||
neovim = "*"
|
||||
s3cmd = "*"
|
||||
black = "==22.3.0"
|
||||
black = "==21.6b0"
|
||||
flake8-quotes = "*"
|
||||
flake8-black = "*"
|
||||
|
426
Pipfile.lock
generated
426
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "8c1b0ad909dc0ac0fc8013756ca7db8b5420f51c25cc1c2d1612f62fe5e19843"
|
||||
"sha256": "0a04ec24d4aef6828e4f5eefa0a7d2c312f21f2b2f18c42c7004cdbe0c02bd53"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -23,12 +23,12 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"asttokens": {
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
"sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3",
|
||||
"sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"
|
||||
"sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41",
|
||||
"sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"
|
||||
],
|
||||
"version": "==2.2.1"
|
||||
"version": "==1.4.4"
|
||||
},
|
||||
"backcall": {
|
||||
"hashes": [
|
||||
@@ -39,32 +39,11 @@
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b",
|
||||
"sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176",
|
||||
"sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09",
|
||||
"sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a",
|
||||
"sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015",
|
||||
"sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79",
|
||||
"sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb",
|
||||
"sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20",
|
||||
"sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464",
|
||||
"sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968",
|
||||
"sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82",
|
||||
"sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21",
|
||||
"sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0",
|
||||
"sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265",
|
||||
"sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b",
|
||||
"sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a",
|
||||
"sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72",
|
||||
"sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce",
|
||||
"sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0",
|
||||
"sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a",
|
||||
"sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163",
|
||||
"sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad",
|
||||
"sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"
|
||||
"sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04",
|
||||
"sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==22.3.0"
|
||||
"version": "==21.6b0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
@@ -79,152 +58,144 @@
|
||||
"sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330",
|
||||
"sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"
|
||||
],
|
||||
"markers": "python_version < '3.11' and python_version >= '3.7'",
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==5.1.1"
|
||||
},
|
||||
"executing": {
|
||||
"hashes": [
|
||||
"sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc",
|
||||
"sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"
|
||||
],
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
|
||||
"sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"
|
||||
"sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b",
|
||||
"sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==6.0.0"
|
||||
"version": "==3.9.2"
|
||||
},
|
||||
"flake8-black": {
|
||||
"hashes": [
|
||||
"sha256:0dfbca3274777792a5bcb2af887a4cad72c72d0e86c94e08e3a3de151bb41c34",
|
||||
"sha256:fe8ea2eca98d8a504f22040d9117347f6b367458366952862ac3586e7d4eeaca"
|
||||
"sha256:941514149cb8b489cb17a4bb1cf18d84375db3b34381bb018de83509437931a0",
|
||||
"sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.6"
|
||||
"version": "==0.2.1"
|
||||
},
|
||||
"flake8-commas": {
|
||||
"hashes": [
|
||||
"sha256:940441ab8ee544df564ae3b3f49f20462d75d5c7cac2463e0b27436e2050f263",
|
||||
"sha256:ebb96c31e01d0ef1d0685a21f3f0e2f8153a0381430e748bf0bbbb5d5b453d54"
|
||||
"sha256:d3005899466f51380387df7151fb59afec666a0f4f4a2c6a8995b975de0f44b7",
|
||||
"sha256:ee2141a3495ef9789a3894ed8802d03eff1eaaf98ce6d8653a7c573ef101935e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.1.0"
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"flake8-comprehensions": {
|
||||
"hashes": [
|
||||
"sha256:412052ac4a947f36b891143430fef4859705af11b2572fbb689f90d372cf26ab",
|
||||
"sha256:d763de3c74bc18a79c039a7ec732e0a1985b0c79309ceb51e56401ad0a2cd44e"
|
||||
"sha256:b07aef3277623db32310aa241a1cec67212b53c1d18e767d7e26d4d83aa05bf7",
|
||||
"sha256:f24be9032587127f7a5bc6d066bf755b6e66834f694383adb8a673e229c1f559"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.10.1"
|
||||
"version": "==3.5.0"
|
||||
},
|
||||
"flake8-isort": {
|
||||
"hashes": [
|
||||
"sha256:537f453a660d7e903f602ecfa36136b140de279df58d02eb1b6a0c84e83c528c",
|
||||
"sha256:aa0cac02a62c7739e370ce6b9c31743edac904bae4b157274511fc8a19c75bbc"
|
||||
"sha256:2b91300f4f1926b396c2c90185844eb1a3d5ec39ea6138832d119da0a208f4d9",
|
||||
"sha256:729cd6ef9ba3659512dee337687c05d79c78e1215fdf921ed67e5fe46cce2f3c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==6.0.0"
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"flake8-quotes": {
|
||||
"hashes": [
|
||||
"sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1"
|
||||
"sha256:3f1116e985ef437c130431ac92f9b3155f8f652fda7405ac22ffdfd7a9d1055e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.3.2"
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"greenlet": {
|
||||
"hashes": [
|
||||
"sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a",
|
||||
"sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a",
|
||||
"sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43",
|
||||
"sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33",
|
||||
"sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8",
|
||||
"sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088",
|
||||
"sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca",
|
||||
"sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343",
|
||||
"sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645",
|
||||
"sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db",
|
||||
"sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df",
|
||||
"sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3",
|
||||
"sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86",
|
||||
"sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2",
|
||||
"sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a",
|
||||
"sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf",
|
||||
"sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7",
|
||||
"sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394",
|
||||
"sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40",
|
||||
"sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3",
|
||||
"sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6",
|
||||
"sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74",
|
||||
"sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0",
|
||||
"sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3",
|
||||
"sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91",
|
||||
"sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5",
|
||||
"sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9",
|
||||
"sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8",
|
||||
"sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b",
|
||||
"sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6",
|
||||
"sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb",
|
||||
"sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73",
|
||||
"sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b",
|
||||
"sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df",
|
||||
"sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9",
|
||||
"sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f",
|
||||
"sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0",
|
||||
"sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857",
|
||||
"sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a",
|
||||
"sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249",
|
||||
"sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30",
|
||||
"sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292",
|
||||
"sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b",
|
||||
"sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d",
|
||||
"sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b",
|
||||
"sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c",
|
||||
"sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca",
|
||||
"sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7",
|
||||
"sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75",
|
||||
"sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae",
|
||||
"sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b",
|
||||
"sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470",
|
||||
"sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564",
|
||||
"sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9",
|
||||
"sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099",
|
||||
"sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0",
|
||||
"sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5",
|
||||
"sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19",
|
||||
"sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1",
|
||||
"sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"
|
||||
"sha256:0109af1138afbfb8ae647e31a2b1ab030f58b21dd8528c27beaeb0093b7938a9",
|
||||
"sha256:0459d94f73265744fee4c2d5ec44c6f34aa8a31017e6e9de770f7bcf29710be9",
|
||||
"sha256:04957dc96669be041e0c260964cfef4c77287f07c40452e61abe19d647505581",
|
||||
"sha256:0722c9be0797f544a3ed212569ca3fe3d9d1a1b13942d10dd6f0e8601e484d26",
|
||||
"sha256:097e3dae69321e9100202fc62977f687454cd0ea147d0fd5a766e57450c569fd",
|
||||
"sha256:0b493db84d124805865adc587532ebad30efa68f79ad68f11b336e0a51ec86c2",
|
||||
"sha256:13ba6e8e326e2116c954074c994da14954982ba2795aebb881c07ac5d093a58a",
|
||||
"sha256:13ebf93c343dd8bd010cd98e617cb4c1c1f352a0cf2524c82d3814154116aa82",
|
||||
"sha256:1407fe45246632d0ffb7a3f4a520ba4e6051fc2cbd61ba1f806900c27f47706a",
|
||||
"sha256:1bf633a50cc93ed17e494015897361010fc08700d92676c87931d3ea464123ce",
|
||||
"sha256:2d0bac0385d2b43a7bd1d651621a4e0f1380abc63d6fb1012213a401cbd5bf8f",
|
||||
"sha256:3001d00eba6bbf084ae60ec7f4bb8ed375748f53aeaefaf2a37d9f0370558524",
|
||||
"sha256:356e4519d4dfa766d50ecc498544b44c0249b6de66426041d7f8b751de4d6b48",
|
||||
"sha256:38255a3f1e8942573b067510f9611fc9e38196077b0c8eb7a8c795e105f9ce77",
|
||||
"sha256:3d75b8d013086b08e801fbbb896f7d5c9e6ccd44f13a9241d2bf7c0df9eda928",
|
||||
"sha256:41b825d65f31e394b523c84db84f9383a2f7eefc13d987f308f4663794d2687e",
|
||||
"sha256:42e602564460da0e8ee67cb6d7236363ee5e131aa15943b6670e44e5c2ed0f67",
|
||||
"sha256:4aeaebcd91d9fee9aa768c1b39cb12214b30bf36d2b7370505a9f2165fedd8d9",
|
||||
"sha256:4c8b1c43e75c42a6cafcc71defa9e01ead39ae80bd733a2608b297412beede68",
|
||||
"sha256:4d37990425b4687ade27810e3b1a1c37825d242ebc275066cfee8cb6b8829ccd",
|
||||
"sha256:4f09b0010e55bec3239278f642a8a506b91034f03a4fb28289a7d448a67f1515",
|
||||
"sha256:505138d4fa69462447a562a7c2ef723c6025ba12ac04478bc1ce2fcc279a2db5",
|
||||
"sha256:5067920de254f1a2dee8d3d9d7e4e03718e8fd2d2d9db962c8c9fa781ae82a39",
|
||||
"sha256:56961cfca7da2fdd178f95ca407fa330c64f33289e1804b592a77d5593d9bd94",
|
||||
"sha256:5a8e05057fab2a365c81abc696cb753da7549d20266e8511eb6c9d9f72fe3e92",
|
||||
"sha256:659f167f419a4609bc0516fb18ea69ed39dbb25594934bd2dd4d0401660e8a1e",
|
||||
"sha256:662e8f7cad915ba75d8017b3e601afc01ef20deeeabf281bd00369de196d7726",
|
||||
"sha256:6f61d71bbc9b4a3de768371b210d906726535d6ca43506737682caa754b956cd",
|
||||
"sha256:72b00a8e7c25dcea5946692a2485b1a0c0661ed93ecfedfa9b6687bd89a24ef5",
|
||||
"sha256:811e1d37d60b47cb8126e0a929b58c046251f28117cb16fcd371eed61f66b764",
|
||||
"sha256:81b0ea3715bf6a848d6f7149d25bf018fd24554a4be01fcbbe3fdc78e890b955",
|
||||
"sha256:88c8d517e78acdf7df8a2134a3c4b964415b575d2840a2746ddb1cc6175f8608",
|
||||
"sha256:8dca09dedf1bd8684767bc736cc20c97c29bc0c04c413e3276e0962cd7aeb148",
|
||||
"sha256:974a39bdb8c90a85982cdb78a103a32e0b1be986d411303064b28a80611f6e51",
|
||||
"sha256:9e112e03d37987d7b90c1e98ba5e1b59e1645226d78d73282f45b326f7bddcb9",
|
||||
"sha256:9e9744c657d896c7b580455e739899e492a4a452e2dd4d2b3e459f6b244a638d",
|
||||
"sha256:9ed358312e63bf683b9ef22c8e442ef6c5c02973f0c2a939ec1d7b50c974015c",
|
||||
"sha256:9f2c221eecb7ead00b8e3ddb913c67f75cba078fd1d326053225a3f59d850d72",
|
||||
"sha256:a20d33124935d27b80e6fdacbd34205732660e0a1d35d8b10b3328179a2b51a1",
|
||||
"sha256:a4c0757db9bd08470ff8277791795e70d0bf035a011a528ee9a5ce9454b6cba2",
|
||||
"sha256:afe07421c969e259e9403c3bb658968702bc3b78ec0b6fde3ae1e73440529c23",
|
||||
"sha256:b1992ba9d4780d9af9726bbcef6a1db12d9ab1ccc35e5773685a24b7fb2758eb",
|
||||
"sha256:b23d2a46d53210b498e5b701a1913697671988f4bf8e10f935433f6e7c332fb6",
|
||||
"sha256:b5e83e4de81dcc9425598d9469a624826a0b1211380ac444c7c791d4a2137c19",
|
||||
"sha256:be35822f35f99dcc48152c9839d0171a06186f2d71ef76dc57fa556cc9bf6b45",
|
||||
"sha256:be9e0fb2ada7e5124f5282d6381903183ecc73ea019568d6d63d33f25b2a9000",
|
||||
"sha256:c140e7eb5ce47249668056edf3b7e9900c6a2e22fb0eaf0513f18a1b2c14e1da",
|
||||
"sha256:c6a08799e9e88052221adca55741bf106ec7ea0710bca635c208b751f0d5b617",
|
||||
"sha256:cb242fc2cda5a307a7698c93173d3627a2a90d00507bccf5bc228851e8304963",
|
||||
"sha256:cce1e90dd302f45716a7715517c6aa0468af0bf38e814ad4eab58e88fc09f7f7",
|
||||
"sha256:cd4ccc364cf75d1422e66e247e52a93da6a9b73cefa8cad696f3cbbb75af179d",
|
||||
"sha256:d21681f09e297a5adaa73060737e3aa1279a13ecdcfcc6ef66c292cb25125b2d",
|
||||
"sha256:d38ffd0e81ba8ef347d2be0772e899c289b59ff150ebbbbe05dc61b1246eb4e0",
|
||||
"sha256:d566b82e92ff2e09dd6342df7e0eb4ff6275a3f08db284888dcd98134dbd4243",
|
||||
"sha256:d5b0ff9878333823226d270417f24f4d06f235cb3e54d1103b71ea537a6a86ce",
|
||||
"sha256:d6ee1aa7ab36475035eb48c01efae87d37936a8173fc4d7b10bb02c2d75dd8f6",
|
||||
"sha256:db38f80540083ea33bdab614a9d28bcec4b54daa5aff1668d7827a9fc769ae0a",
|
||||
"sha256:ea688d11707d30e212e0110a1aac7f7f3f542a259235d396f88be68b649e47d1",
|
||||
"sha256:f6327b6907b4cb72f650a5b7b1be23a2aab395017aa6f1adb13069d66360eb3f",
|
||||
"sha256:fb412b7db83fe56847df9c47b6fe3f13911b06339c2aa02dcc09dce8bbf582cd"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==2.0.2"
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"ipdb": {
|
||||
"hashes": [
|
||||
"sha256:c23b6736f01fd4586cc2ecbebdf79a5eb454796853e1cd8f2ed3b7b91d4a3e93",
|
||||
"sha256:f74c2f741c18b909eaf89f19fde973f745ac721744aa1465888ce45813b63a9c"
|
||||
"sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.13.11"
|
||||
"version": "==0.13.9"
|
||||
},
|
||||
"ipython": {
|
||||
"hashes": [
|
||||
"sha256:b13a1d6c1f5818bd388db53b7107d17454129a70de2b87481d555daede5eb49e",
|
||||
"sha256:b38c31e8fc7eff642fc7c597061fff462537cf2314e3225a19c906b7b0d8a345"
|
||||
"sha256:55df3e0bd0f94e715abd968bedd89d4e8a7bce4bf498fb123fed4f5398fea874",
|
||||
"sha256:b5548ec5329a4bcf054a5deed5099b0f9622eb9ea51aaa7104d215fece201d8c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==8.10.0"
|
||||
"version": "==7.31.1"
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504",
|
||||
"sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"
|
||||
"sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6",
|
||||
"sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.12.0"
|
||||
"version": "==5.8.0"
|
||||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
@@ -244,11 +215,10 @@
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
|
||||
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
|
||||
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
|
||||
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.7.0"
|
||||
"version": "==0.6.1"
|
||||
},
|
||||
"msgpack": {
|
||||
"hashes": [
|
||||
@@ -309,11 +279,10 @@
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
|
||||
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.0.0"
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"neovim": {
|
||||
"hashes": [
|
||||
@@ -332,11 +301,11 @@
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229",
|
||||
"sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"
|
||||
"sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6",
|
||||
"sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.11.0"
|
||||
"version": "==0.10.3"
|
||||
},
|
||||
"pexpect": {
|
||||
"hashes": [
|
||||
@@ -353,14 +322,6 @@
|
||||
],
|
||||
"version": "==0.7.5"
|
||||
},
|
||||
"platformdirs": {
|
||||
"hashes": [
|
||||
"sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9",
|
||||
"sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.0.0"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63",
|
||||
@@ -376,36 +337,29 @@
|
||||
],
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"pure-eval": {
|
||||
"hashes": [
|
||||
"sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350",
|
||||
"sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"
|
||||
],
|
||||
"version": "==0.2.2"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053",
|
||||
"sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"
|
||||
"sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068",
|
||||
"sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.10.0"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.7.0"
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf",
|
||||
"sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"
|
||||
"sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3",
|
||||
"sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.0.1"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.3.1"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297",
|
||||
"sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"
|
||||
"sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1",
|
||||
"sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.14.0"
|
||||
"version": "==2.13.0"
|
||||
},
|
||||
"pynvim": {
|
||||
"hashes": [
|
||||
@@ -430,27 +384,129 @@
|
||||
},
|
||||
"python-dotenv": {
|
||||
"hashes": [
|
||||
"sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49",
|
||||
"sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"
|
||||
"sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5",
|
||||
"sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.21.1"
|
||||
"version": "==0.21.0"
|
||||
},
|
||||
"python-magic": {
|
||||
"hashes": [
|
||||
"sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b",
|
||||
"sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"
|
||||
"sha256:4fec8ee805fea30c07afccd1592c0f17977089895bdfaae5fec870a84e997626",
|
||||
"sha256:de800df9fb50f8ec5974761054a708af6e4246b03b4bdaee993f948947b0ebcf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.4.27"
|
||||
"version": "==0.4.24"
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad",
|
||||
"sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4",
|
||||
"sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd",
|
||||
"sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc",
|
||||
"sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d",
|
||||
"sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066",
|
||||
"sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec",
|
||||
"sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9",
|
||||
"sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e",
|
||||
"sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8",
|
||||
"sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e",
|
||||
"sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783",
|
||||
"sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6",
|
||||
"sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1",
|
||||
"sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c",
|
||||
"sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4",
|
||||
"sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1",
|
||||
"sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1",
|
||||
"sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7",
|
||||
"sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8",
|
||||
"sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe",
|
||||
"sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d",
|
||||
"sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b",
|
||||
"sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8",
|
||||
"sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c",
|
||||
"sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af",
|
||||
"sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49",
|
||||
"sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714",
|
||||
"sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542",
|
||||
"sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318",
|
||||
"sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e",
|
||||
"sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5",
|
||||
"sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc",
|
||||
"sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144",
|
||||
"sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453",
|
||||
"sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5",
|
||||
"sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61",
|
||||
"sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11",
|
||||
"sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a",
|
||||
"sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54",
|
||||
"sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73",
|
||||
"sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc",
|
||||
"sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347",
|
||||
"sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c",
|
||||
"sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66",
|
||||
"sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c",
|
||||
"sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93",
|
||||
"sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443",
|
||||
"sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc",
|
||||
"sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1",
|
||||
"sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892",
|
||||
"sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8",
|
||||
"sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001",
|
||||
"sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa",
|
||||
"sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90",
|
||||
"sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c",
|
||||
"sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0",
|
||||
"sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692",
|
||||
"sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4",
|
||||
"sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5",
|
||||
"sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690",
|
||||
"sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83",
|
||||
"sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66",
|
||||
"sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f",
|
||||
"sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f",
|
||||
"sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4",
|
||||
"sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee",
|
||||
"sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81",
|
||||
"sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95",
|
||||
"sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9",
|
||||
"sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff",
|
||||
"sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e",
|
||||
"sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5",
|
||||
"sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6",
|
||||
"sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7",
|
||||
"sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1",
|
||||
"sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394",
|
||||
"sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6",
|
||||
"sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742",
|
||||
"sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57",
|
||||
"sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b",
|
||||
"sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7",
|
||||
"sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b",
|
||||
"sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244",
|
||||
"sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af",
|
||||
"sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185",
|
||||
"sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8",
|
||||
"sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2022.10.31"
|
||||
},
|
||||
"s3cmd": {
|
||||
"hashes": [
|
||||
"sha256:15330776e7ff993d8ae0ac213bf896f210719e9b91445f5f7626a8fa7e74e30b",
|
||||
"sha256:2204306742c33c24fbca02b78e059bacfc1bfc04af09c7e9866f267a11a9ddb2"
|
||||
"sha256:49cd23d516b17974b22b611a95ce4d93fe326feaa07320bd1d234fed68cbccfa",
|
||||
"sha256:966b0a494a916fc3b4324de38f089c86c70ee90e8e1cae6d59102103a4c0cc03"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.3.0"
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31",
|
||||
"sha256:e197a19aa8ec9722928f2206f8de752def0e4c9fc6953527360d1c36d94ddb2f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==65.5.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
@@ -460,35 +516,35 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"stack-data": {
|
||||
"testfixtures": {
|
||||
"hashes": [
|
||||
"sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815",
|
||||
"sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"
|
||||
"sha256:02dae883f567f5b70fd3ad3c9eefb95912e78ac90be6c7444b5e2f46bf572c84",
|
||||
"sha256:7de200e24f50a4a5d6da7019fb1197aaf5abd475efb2ec2422fdcf2f2eb98c1d"
|
||||
],
|
||||
"version": "==0.6.2"
|
||||
"version": "==6.18.5"
|
||||
},
|
||||
"tomli": {
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
|
||||
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
|
||||
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
|
||||
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
|
||||
],
|
||||
"markers": "python_version < '3.11'",
|
||||
"version": "==2.0.1"
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.10.2"
|
||||
},
|
||||
"traitlets": {
|
||||
"hashes": [
|
||||
"sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8",
|
||||
"sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"
|
||||
"sha256:6cc57d6dc28c85d5365961726ffd19b538739347749e13ebe34e03323a0e8f84",
|
||||
"sha256:c864831efa0ba6576d09b44884b34e41defc18c0d7e720b4a2d6698c842cab3e"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==5.9.0"
|
||||
"version": "==5.8.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e",
|
||||
"sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"
|
||||
"sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784",
|
||||
"sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"
|
||||
],
|
||||
"version": "==0.2.6"
|
||||
"version": "==0.2.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,6 @@ knob.extensions.append(media_keys)
|
||||
|
||||
# Rotary encoder that also acts as a key
|
||||
encoder_handler = EncoderHandler()
|
||||
encoder_handler.divisor = 2
|
||||
encoder_handler.pins = ((board.D1, board.D2, board.D0),)
|
||||
encoder_handler.map = (((KC.VOLD, KC.VOLU, KC.MUTE),),)
|
||||
knob.modules.append(encoder_handler)
|
||||
|
@@ -15,7 +15,6 @@ knob.extensions.append(media_keys)
|
||||
|
||||
# Rotary encoders that also acts as keys
|
||||
encoder_handler = EncoderHandler()
|
||||
encoder_handler.divisor = 2
|
||||
encoder_handler.pins = (
|
||||
(board.D1, board.D2, board.D0),
|
||||
(board.D9, board.D10, board.D3),
|
||||
|
@@ -78,7 +78,6 @@ keyboard.keymap = [
|
||||
|
||||
# Rotary encoder that also acts as a key
|
||||
encoder_handler = EncoderHandler()
|
||||
encoder_handler.divisor = 2
|
||||
encoder_handler.pins = ((board.D8, board.D7, board.D9),)
|
||||
encoder_handler.map = (((KC.VOLD, KC.VOLU, KC.MUTE),),)
|
||||
keyboard.modules.append(encoder_handler)
|
||||
|
@@ -1,12 +0,0 @@
|
||||
# ANAVI Macro Pad 12
|
||||
|
||||
ANAVI Macro Pad 12 is an open source, programmable mechanical keyboard with 9 hot-swappable mechanical switches, RGB WS2812B underlighting and yellow backlit a rotary encoder and [Seeed XIAO RP2040](https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html).
|
||||
|
||||
ANAVI Macro Pad 12 has been designed with the cross platform and open source electronics design automation suite KiCad. All KiCad [files and schematics are available at GitHub](https://github.com/anavitechnology/anavi-macro-pad-12) under [Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
|
||||
Extensions enabled by default:
|
||||
- [Encoder](/docs/en/encoder.md) Twist control for all the things
|
||||
- [LED](/docs/en/led.md) Light your keys up (for backlit)
|
||||
- [RGB](/docs/en/rgb.md) Light it up (for underlighting)
|
||||
- [MediaKeys](/docs/en/media_keys.md) Control volume and other media functions
|
||||
- [PEG_OLED](/docs/peg_oled_display.md) Show information on the mini OLED display
|
@@ -1,97 +0,0 @@
|
||||
import board
|
||||
|
||||
from kmk.extensions.LED import LED
|
||||
from kmk.extensions.media_keys import MediaKeys
|
||||
from kmk.extensions.peg_oled_Display import (
|
||||
Oled,
|
||||
OledData,
|
||||
OledDisplayMode,
|
||||
OledReactionType,
|
||||
)
|
||||
from kmk.extensions.RGB import RGB, AnimationModes
|
||||
from kmk.keys import KC
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
from kmk.scanners import DiodeOrientation
|
||||
|
||||
keyboard = KMKKeyboard()
|
||||
|
||||
# I2C pins for the mini OLED display
|
||||
keyboard.SCL = board.D5
|
||||
keyboard.SDA = board.D4
|
||||
|
||||
oled_ext = Oled(
|
||||
OledData(
|
||||
corner_one={0: OledReactionType.STATIC, 1: ['ANAVI Macro Pad 12']},
|
||||
corner_two={0: OledReactionType.STATIC, 1: [' ']},
|
||||
corner_three={0: OledReactionType.STATIC, 1: ['Open Source']},
|
||||
corner_four={0: OledReactionType.STATIC, 1: [' ']},
|
||||
),
|
||||
oWidth=128,
|
||||
oHeight=64,
|
||||
toDisplay=OledDisplayMode.TXT,
|
||||
flip=False,
|
||||
)
|
||||
keyboard.extensions.append(oled_ext)
|
||||
|
||||
led_ext = LED(
|
||||
led_pin=[
|
||||
board.D0,
|
||||
],
|
||||
brightness=100,
|
||||
brightness_step=5,
|
||||
brightness_limit=100,
|
||||
breathe_center=1.5,
|
||||
animation_mode=AnimationModes.STATIC,
|
||||
animation_speed=1,
|
||||
user_animation=None,
|
||||
val=100,
|
||||
)
|
||||
keyboard.extensions.append(led_ext)
|
||||
|
||||
# WS2812B LED strips on the back
|
||||
underglow = RGB(
|
||||
pixel_pin=board.D10,
|
||||
num_pixels=6,
|
||||
val_limit=100,
|
||||
val_default=25,
|
||||
animation_mode=AnimationModes.RAINBOW,
|
||||
)
|
||||
keyboard.extensions.append(underglow)
|
||||
|
||||
# Neopixel on XIAO RP2040
|
||||
frontglow = RGB(
|
||||
pixel_pin=board.NEOPIXEL,
|
||||
num_pixels=1,
|
||||
val_limit=100,
|
||||
val_default=25,
|
||||
animation_mode=AnimationModes.RAINBOW,
|
||||
)
|
||||
keyboard.extensions.append(frontglow)
|
||||
|
||||
keyboard.col_pins = (board.D6, board.D8, board.D9)
|
||||
keyboard.row_pins = (board.D1, board.D2, board.D3, board.D7)
|
||||
keyboard.diode_orientation = DiodeOrientation.COL2ROW
|
||||
|
||||
media_keys = MediaKeys()
|
||||
keyboard.extensions.append(media_keys)
|
||||
|
||||
# Matrix 4x3 keymap, 12 keys in total
|
||||
keyboard.keymap = [
|
||||
[
|
||||
KC.N1,
|
||||
KC.N2,
|
||||
KC.N3,
|
||||
KC.N4,
|
||||
KC.N5,
|
||||
KC.N6,
|
||||
KC.N7,
|
||||
KC.N8,
|
||||
KC.N9,
|
||||
KC.N0,
|
||||
KC.A,
|
||||
KC.B,
|
||||
]
|
||||
]
|
||||
|
||||
if __name__ == '__main__':
|
||||
keyboard.go()
|
3
boot.py
Normal file → Executable file
3
boot.py
Normal file → Executable file
@@ -0,0 +1,3 @@
|
||||
import supervisor
|
||||
|
||||
supervisor.set_next_stack_limit(4096 + 4096)
|
||||
|
@@ -1,7 +0,0 @@
|
||||
version: '3.3'
|
||||
services:
|
||||
mpy_kmk:
|
||||
build: .
|
||||
volumes:
|
||||
- ./kmk:/app/kmk
|
||||
- ./.compiled:/app/compiled
|
@@ -1,14 +0,0 @@
|
||||
|
||||
#!/bin/sh
|
||||
echo "building mpy"
|
||||
echo $(ls compiled)
|
||||
|
||||
find kmk/ -name "*.py" -exec sh -c 'mkdir -p compiled/8/$(dirname {}) &&\
|
||||
./mpy-cross-8 -O2 {} -o compiled/8/$(dirname {})/$(basename -s .py {}).mpy' \;
|
||||
|
||||
find kmk/ -name "*.py" -exec sh -c 'mkdir -p compiled/7/$(dirname {}) &&\
|
||||
./mpy-cross-7 -O2 {} -o compiled/7/$(dirname {})/$(basename -s .py {}).mpy' \;
|
||||
|
||||
echo $(ls compiled)
|
||||
|
||||
echo "done building"
|
@@ -76,10 +76,8 @@ You can also get ideas from the various [user examples](https://github.com/KMKfw
|
||||
|
||||
In case you need it, debugging help can be found [here](debugging.md)
|
||||
|
||||
For asynchronous support and chatter about KMK, [join our Zulip
|
||||
community](https://kmkfw.zulipchat.com)!
|
||||
|
||||
If you ask for help in chat or open a bug report, if possible
|
||||
If you need support with KMK or just want to say hi, find us in
|
||||
[#kmkfw:klar.sh on Matrix](https://matrix.to/#/#kmkfw:klar.sh). This channel is
|
||||
bridged to Discord [here](https://discordapp.com/widget?id=493256121075761173&theme=dark)
|
||||
for convenience. If you ask for help in chat or open a bug report, if possible
|
||||
make sure your copy of KMK is up-to-date.
|
||||
In particular, swing by the Zulip chat *before* opening a GitHub Issue about
|
||||
configuration, documentation, etc. concerns.
|
||||
|
@@ -6,7 +6,8 @@ to make contributing as easy as possible for everyone while maintaining a consis
|
||||
## Contributing Code
|
||||
The following guidelines should ensure that any code contributed can be merged in as
|
||||
painlessly as possible. If you're unsure how to set up your development environment,
|
||||
feel free to [join our Zulip community](https://kmkfw.zulipchat.com).
|
||||
feel free to join the chat, [#kmkfw:klar.sh on Matrix](https://matrix.to/#/#kmkfw:klar.sh).
|
||||
This channel is bridged to Discord [here](https://discord.gg/QBHUUpeGUd) for convenience.
|
||||
|
||||
### Code Style
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
# Stringy Keymaps
|
||||
|
||||
Enables referring to keys by `'NAME'` rather than `KC.NAME`.\
|
||||
This extension allows for a seamless integration of both string-based key references and standard keycodes.
|
||||
Enables referring to keys by `'NAME'` rather than `KC.NAME`.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -14,9 +13,6 @@ from kmk.extensions.stringy_keymaps import StringyKeymaps
|
||||
# Indexed
|
||||
# keyboard.keymap = [[ KC['A'], KC['B'], KC['RESET'] ]]
|
||||
|
||||
# String names mixed with normal keycodes
|
||||
# keyboard.keymap = [[ 'A' , KC.B, KC.RESET ]]
|
||||
|
||||
# String names
|
||||
keyboard.keymap = [[ 'A' , 'B', 'RESET' ]]
|
||||
|
||||
@@ -31,5 +27,3 @@ keyboard.extensions.append(stringyKeymaps)
|
||||
|
||||
It should be noted that these are **not** ASCII. The string is **not** what
|
||||
will be sent to the computer. The examples above have no functional difference.
|
||||
|
||||
When utilizing argumented keys, such as `KC.MO(layer)`, it's not possible to use a string like `'MO(layer)'` instead employ the standard notation of e.g. `KC.MO(1)` in your keymap.
|
@@ -9,7 +9,9 @@ Linux).
|
||||
Given `make` and `rsync` are available on your system (in `$PATH`), the
|
||||
following will copy the `kmk` tree to your CircuitPython device, and will copy
|
||||
the file defined as `USER_KEYMAP` as your `main.py`. It will also copy our
|
||||
`boot.py`. If any of these files exist on your CircuitPython device already, they
|
||||
`boot.py`, which allocates a larger stack size (simply - more of the device's
|
||||
RAM will be available to KMK and your keyboard config) than CircuitPython's
|
||||
default. If any of these files exist on your CircuitPython device already, they
|
||||
will be overwritten without a prompt.
|
||||
|
||||
If you get permissions errors here, **don't run make as root or with sudo**. See
|
||||
|
@@ -1,9 +1,9 @@
|
||||
# Support
|
||||
|
||||
For asynchronous support and chatter about KMK, [join our Zulip
|
||||
community](https://kmkfw.zulipchat.com)!
|
||||
If you need support with KMK or just want to say hi, find us in [#kmkfw:klar.sh
|
||||
on Matrix](https://matrix.to/#/#kmkfw:klar.sh). This channel is bridged to
|
||||
Discord [here](https://discordapp.com/widget?id=493256121075761173&theme=dark)
|
||||
for convenience.
|
||||
|
||||
If you ask for help in chat or open a bug report, if possible
|
||||
make sure your copy of KMK is up-to-date.
|
||||
In particular, swing by the Zulip chat *before* opening a GitHub Issue about
|
||||
configuration, documentation, etc. concerns.
|
||||
|
@@ -96,7 +96,8 @@ RGB や分裂型などの機能を楽しめたい場合は、ビルトイン[モ
|
||||
|
||||
デバッグについてのヘルプが必要な場合は[こちら](debugging.md)。
|
||||
|
||||
KMK についてサポートが必要な場合や、コミュニケーションをとりたい場合は[こちら](https://kmkfw.zulipchat.com)。
|
||||
KMK についてサポートが必要な場合や、コミュニケーションをとりたい場合は[こちら](https://matrix.to/#/#kmkfw:klar.sh)。
|
||||
このチャネルは[Discord](https://discordapp.com/widget?id=493256121075761173&theme=dark) からも見ることができます。
|
||||
|
||||
チャットで助けを求める場合やバグ レポートを開く場合は、可能であれば KMK
|
||||
のコピーが最新であることを確認してください。
|
||||
|
@@ -123,6 +123,8 @@ usuários](https://github.com/KMKfw/user_keymaps) que fornecemos e fuce nossa
|
||||
Caso precise, ajuda para depuração pode ser encontrada [aqui](debugging.md).
|
||||
|
||||
Se você precisa de suporte com o KMK ou quer somente dizer oi, encontre-nos no
|
||||
canal [kmkfw no Zulip](https://kmkfw.zulipchat.com).
|
||||
Se você precisa de ajuda ou pretende abrir um bug report, se
|
||||
canal [#kmkfw:klar.sh no Matrix](https://matrix.to/#/#kmkfw:klar.sh). Este canal
|
||||
tem uma ponte no Discord
|
||||
[aqui](https://discordapp.com/widget?id=493256121075761173&theme=dark) por
|
||||
conveniência. Se você precisa de ajuda ou pretende abrir um bug report, se
|
||||
possível se possível, verifique se sua cópia do KMK está atualizada.
|
||||
|
@@ -1,7 +1,10 @@
|
||||
# Suporte
|
||||
|
||||
Se você precisa de suporte com o KMK ou quer somente dizer oi, encontre-nos no
|
||||
canal [no Zulip](https://kmkfw.zulipchat.com).
|
||||
canal [#kmkfw:klar.sh no Matrix](https://matrix.to/#/#kmkfw:klar.sh). Este canal
|
||||
tem uma ponte no Discord
|
||||
[aqui](https://discordapp.com/widget?id=493256121075761173&theme=dark) por
|
||||
conveniência.
|
||||
|
||||
Se você precisa de ajuda ou pretende abrir um bug report, se
|
||||
possível se possível, verifique se sua cópia do KMK está atualizada.
|
||||
|
@@ -1,35 +1,42 @@
|
||||
'''Adds international keys'''
|
||||
from kmk.extensions import Extension
|
||||
from kmk.keys import make_key
|
||||
from kmk.keys import KC, make_key
|
||||
|
||||
|
||||
class International(Extension):
|
||||
'''Adds international keys'''
|
||||
|
||||
def __init__(self):
|
||||
# International
|
||||
make_key(code=50, names=('NONUS_HASH', 'NUHS'))
|
||||
make_key(code=100, names=('NONUS_BSLASH', 'NUBS'))
|
||||
make_key(code=101, names=('APP', 'APPLICATION', 'SEL', 'WINMENU'))
|
||||
KC._generators.append(self.maybe_make_media_key)
|
||||
|
||||
make_key(code=135, names=('INT1', 'RO'))
|
||||
make_key(code=136, names=('INT2', 'KANA'))
|
||||
make_key(code=137, names=('INT3', 'JYEN'))
|
||||
make_key(code=138, names=('INT4', 'HENK'))
|
||||
make_key(code=139, names=('INT5', 'MHEN'))
|
||||
make_key(code=140, names=('INT6',))
|
||||
make_key(code=141, names=('INT7',))
|
||||
make_key(code=142, names=('INT8',))
|
||||
make_key(code=143, names=('INT9',))
|
||||
make_key(code=144, names=('LANG1', 'HAEN'))
|
||||
make_key(code=145, names=('LANG2', 'HAEJ'))
|
||||
make_key(code=146, names=('LANG3',))
|
||||
make_key(code=147, names=('LANG4',))
|
||||
make_key(code=148, names=('LANG5',))
|
||||
make_key(code=149, names=('LANG6',))
|
||||
make_key(code=150, names=('LANG7',))
|
||||
make_key(code=151, names=('LANG8',))
|
||||
make_key(code=152, names=('LANG9',))
|
||||
@staticmethod
|
||||
def maybe_make_media_key(candidate):
|
||||
codes = (
|
||||
(50, ('NONUS_HASH', 'NUHS')),
|
||||
(100, ('NONUS_BSLASH', 'NUBS')),
|
||||
(101, ('APP', 'APPLICATION', 'SEL', 'WINMENU')),
|
||||
(135, ('INT1', 'RO')),
|
||||
(136, ('INT2', 'KANA')),
|
||||
(137, ('INT3', 'JYEN')),
|
||||
(138, ('INT4', 'HENK')),
|
||||
(139, ('INT5', 'MHEN')),
|
||||
(140, ('INT6',)),
|
||||
(141, ('INT7',)),
|
||||
(142, ('INT8',)),
|
||||
(143, ('INT9',)),
|
||||
(144, ('LANG1', 'HAEN')),
|
||||
(145, ('LANG2', 'HAEJ')),
|
||||
(146, ('LANG3',)),
|
||||
(147, ('LANG4',)),
|
||||
(148, ('LANG5',)),
|
||||
(149, ('LANG6',)),
|
||||
(150, ('LANG7',)),
|
||||
(151, ('LANG8',)),
|
||||
(152, ('LANG9',)),
|
||||
)
|
||||
for code, names in codes:
|
||||
if candidate in names:
|
||||
return make_key(code=code, names=names)
|
||||
|
||||
def on_runtime_enable(self, sandbox):
|
||||
return
|
||||
|
@@ -2,7 +2,8 @@ import pwmio
|
||||
from math import e, exp, pi, sin
|
||||
|
||||
from kmk.extensions import Extension, InvalidExtensionEnvironment
|
||||
from kmk.keys import make_argumented_key, make_key
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import KC, make_argumented_key, make_key
|
||||
from kmk.utils import clamp
|
||||
|
||||
|
||||
@@ -61,35 +62,51 @@ class LED(Extension):
|
||||
if user_animation is not None:
|
||||
self.user_animation = user_animation
|
||||
|
||||
make_argumented_key(
|
||||
names=('LED_TOG',),
|
||||
validator=self._led_key_validator,
|
||||
on_press=self._key_led_tog,
|
||||
KC._generators.append(self.maybe_make_led_key())
|
||||
|
||||
def maybe_make_led_key(self):
|
||||
argumented_keys = (
|
||||
(
|
||||
('LED_TOG',),
|
||||
self._key_led_tog,
|
||||
),
|
||||
(
|
||||
('LED_INC',),
|
||||
self._key_led_inc,
|
||||
),
|
||||
(
|
||||
('LED_DEC',),
|
||||
self._key_led_dec,
|
||||
),
|
||||
(
|
||||
('LED_SET',),
|
||||
self._key_led_set,
|
||||
),
|
||||
)
|
||||
make_argumented_key(
|
||||
names=('LED_INC',),
|
||||
validator=self._led_key_validator,
|
||||
on_press=self._key_led_inc,
|
||||
)
|
||||
make_argumented_key(
|
||||
names=('LED_DEC',),
|
||||
validator=self._led_key_validator,
|
||||
on_press=self._key_led_dec,
|
||||
)
|
||||
make_argumented_key(
|
||||
names=('LED_SET',),
|
||||
validator=self._led_set_key_validator,
|
||||
on_press=self._key_led_set,
|
||||
)
|
||||
make_key(names=('LED_ANI',), on_press=self._key_led_ani)
|
||||
make_key(names=('LED_AND',), on_press=self._key_led_and)
|
||||
make_key(
|
||||
names=('LED_MODE_PLAIN', 'LED_M_P'), on_press=self._key_led_mode_static
|
||||
)
|
||||
make_key(
|
||||
names=('LED_MODE_BREATHE', 'LED_M_B'), on_press=self._key_led_mode_breathe
|
||||
keys = (
|
||||
(('LED_ANI',), self._key_led_ani),
|
||||
(('LED_AND',), self._key_led_and),
|
||||
(('LED_MODE_PLAIN', 'LED_M_P'), self._key_led_mode_static),
|
||||
(('LED_MODE_BREATHE', 'LED_M_B'), self._key_led_mode_breathe),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, on_press in argumented_keys:
|
||||
if candidate in names:
|
||||
return make_argumented_key(
|
||||
names=names,
|
||||
validator=self._led_key_validator,
|
||||
on_press=on_press,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
for names, on_press in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names, on_press=on_press, on_release=handler_passthrough
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def __repr__(self):
|
||||
return f'LED({self._to_dict()})'
|
||||
|
||||
|
@@ -1,9 +1,13 @@
|
||||
from kmk.extensions import Extension
|
||||
from kmk.keys import make_consumer_key
|
||||
from kmk.keys import KC, make_consumer_key
|
||||
|
||||
|
||||
class MediaKeys(Extension):
|
||||
def __init__(self):
|
||||
KC._generators.append(self.maybe_make_media_key)
|
||||
|
||||
@staticmethod
|
||||
def maybe_make_media_key(candidate):
|
||||
# Consumer ("media") keys. Most known keys aren't supported here. A much
|
||||
# longer list used to exist in this file, but the codes were almost certainly
|
||||
# incorrect, conflicting with each other, or otherwise 'weird'. We'll add them
|
||||
@@ -14,20 +18,23 @@ class MediaKeys(Extension):
|
||||
# support PC media keys, so I don't know how much value we would get out of
|
||||
# adding the old Apple-specific consumer codes, but again, PRs welcome if the
|
||||
# lack of them impacts you.
|
||||
make_consumer_key(code=226, names=('AUDIO_MUTE', 'MUTE')) # 0xE2
|
||||
make_consumer_key(code=233, names=('AUDIO_VOL_UP', 'VOLU')) # 0xE9
|
||||
make_consumer_key(code=234, names=('AUDIO_VOL_DOWN', 'VOLD')) # 0xEA
|
||||
make_consumer_key(code=111, names=('BRIGHTNESS_UP', 'BRIU')) # 0x6F
|
||||
make_consumer_key(code=112, names=('BRIGHTNESS_DOWN', 'BRID')) # 0x70
|
||||
make_consumer_key(code=181, names=('MEDIA_NEXT_TRACK', 'MNXT')) # 0xB5
|
||||
make_consumer_key(code=182, names=('MEDIA_PREV_TRACK', 'MPRV')) # 0xB6
|
||||
make_consumer_key(code=183, names=('MEDIA_STOP', 'MSTP')) # 0xB7
|
||||
make_consumer_key(
|
||||
code=205, names=('MEDIA_PLAY_PAUSE', 'MPLY')
|
||||
) # 0xCD (this may not be right)
|
||||
make_consumer_key(code=184, names=('MEDIA_EJECT', 'EJCT')) # 0xB8
|
||||
make_consumer_key(code=179, names=('MEDIA_FAST_FORWARD', 'MFFD')) # 0xB3
|
||||
make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
|
||||
codes = (
|
||||
(226, ('AUDIO_MUTE', 'MUTE')), # 0xE2
|
||||
(233, ('AUDIO_VOL_UP', 'VOLU')), # 0xE9
|
||||
(234, ('AUDIO_VOL_DOWN', 'VOLD')), # 0xEA
|
||||
(111, ('BRIGHTNESS_UP', 'BRIU')), # 0x6F
|
||||
(112, ('BRIGHTNESS_DOWN', 'BRID')), # 0x70
|
||||
(181, ('MEDIA_NEXT_TRACK', 'MNXT')), # 0xB5
|
||||
(182, ('MEDIA_PREV_TRACK', 'MPRV')), # 0xB6
|
||||
(183, ('MEDIA_STOP', 'MSTP')), # 0xB7
|
||||
(205, ('MEDIA_PLAY_PAUSE', 'MPLY')), # 0xCD (this may not be right)
|
||||
(184, ('MEDIA_EJECT', 'EJCT')), # 0xB8
|
||||
(179, ('MEDIA_FAST_FORWARD', 'MFFD')), # 0xB3
|
||||
(180, ('MEDIA_REWIND', 'MRWD')), # 0xB4
|
||||
)
|
||||
for code, names in codes:
|
||||
if candidate in names:
|
||||
return make_consumer_key(code=code, names=names)
|
||||
|
||||
def on_runtime_enable(self, sandbox):
|
||||
return
|
||||
|
@@ -4,7 +4,7 @@ from storage import getmount
|
||||
|
||||
from kmk.extensions import Extension
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import make_key
|
||||
from kmk.keys import KC, make_key
|
||||
|
||||
|
||||
class Color:
|
||||
@@ -69,16 +69,35 @@ class Rgb_matrix(Extension):
|
||||
else:
|
||||
self.ledDisplay = ledDisplay
|
||||
|
||||
make_key(
|
||||
names=('RGB_TOG',), on_press=self._rgb_tog, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_BRI',), on_press=self._rgb_bri, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_BRD',), on_press=self._rgb_brd, on_release=handler_passthrough
|
||||
KC._generators.append(self.maybe_make_peg_rgb_key())
|
||||
|
||||
def maybe_make_peg_rgb_key(self):
|
||||
keys = (
|
||||
(
|
||||
('RGB_TOG',),
|
||||
self._rgb_tog,
|
||||
),
|
||||
(
|
||||
('RGB_BRI',),
|
||||
self._rgb_bri,
|
||||
),
|
||||
(
|
||||
('RGB_BRD',),
|
||||
self._rgb_brd,
|
||||
),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, on_press in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names,
|
||||
on_press=on_press,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def _rgb_tog(self, *args, **kwargs):
|
||||
if self.enable:
|
||||
self.off()
|
||||
|
@@ -3,7 +3,7 @@ from math import e, exp, pi, sin
|
||||
|
||||
from kmk.extensions import Extension
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import make_key
|
||||
from kmk.keys import KC, make_key
|
||||
from kmk.kmktime import PeriodicTimer
|
||||
from kmk.utils import Debug, clamp
|
||||
|
||||
@@ -157,69 +157,37 @@ class RGB(Extension):
|
||||
|
||||
self._substep = 0
|
||||
|
||||
make_key(
|
||||
names=('RGB_TOG',), on_press=self._rgb_tog, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_HUI',), on_press=self._rgb_hui, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_HUD',), on_press=self._rgb_hud, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_SAI',), on_press=self._rgb_sai, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_SAD',), on_press=self._rgb_sad, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_VAI',), on_press=self._rgb_vai, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_VAD',), on_press=self._rgb_vad, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_ANI',), on_press=self._rgb_ani, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_AND',), on_press=self._rgb_and, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_MODE_PLAIN', 'RGB_M_P'),
|
||||
on_press=self._rgb_mode_static,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_MODE_BREATHE', 'RGB_M_B'),
|
||||
on_press=self._rgb_mode_breathe,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_MODE_RAINBOW', 'RGB_M_R'),
|
||||
on_press=self._rgb_mode_rainbow,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'),
|
||||
on_press=self._rgb_mode_breathe_rainbow,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_MODE_SWIRL', 'RGB_M_S'),
|
||||
on_press=self._rgb_mode_swirl,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_MODE_KNIGHT', 'RGB_M_K'),
|
||||
on_press=self._rgb_mode_knight,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
make_key(
|
||||
names=('RGB_RESET', 'RGB_RST'),
|
||||
on_press=self._rgb_reset,
|
||||
on_release=handler_passthrough,
|
||||
KC._generators.append(self.maybe_make_rgb_key())
|
||||
|
||||
def maybe_make_rgb_key(self):
|
||||
keys = (
|
||||
(('RGB_TOG',), self._rgb_tog),
|
||||
(('RGB_HUI',), self._rgb_hui),
|
||||
(('RGB_HUD',), self._rgb_hud),
|
||||
(('RGB_SAI',), self._rgb_sai),
|
||||
(('RGB_SAD',), self._rgb_sad),
|
||||
(('RGB_VAI',), self._rgb_vai),
|
||||
(('RGB_VAD',), self._rgb_vad),
|
||||
(('RGB_ANI',), self._rgb_ani),
|
||||
(('RGB_AND',), self._rgb_and),
|
||||
(('RGB_MODE_PLAIN', 'RGB_M_P'), self._rgb_mode_static),
|
||||
(('RGB_MODE_BREATHE', 'RGB_M_B'), self._rgb_mode_breathe),
|
||||
(('RGB_MODE_RAINBOW', 'RGB_M_R'), self._rgb_mode_rainbow),
|
||||
(('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'), self._rgb_mode_breathe_rainbow),
|
||||
(('RGB_MODE_SWIRL', 'RGB_M_S'), self._rgb_mode_swirl),
|
||||
(('RGB_MODE_KNIGHT', 'RGB_M_K'), self._rgb_mode_knight),
|
||||
(('RGB_RESET', 'RGB_RST'), self._rgb_reset),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, on_press in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names, on_press=on_press, on_release=handler_passthrough
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def on_runtime_enable(self, sandbox):
|
||||
return
|
||||
|
||||
|
@@ -4,7 +4,8 @@ import pwmio
|
||||
import time
|
||||
|
||||
from kmk.extensions import Extension, InvalidExtensionEnvironment
|
||||
from kmk.keys import make_key
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import KC, make_key
|
||||
|
||||
|
||||
class statusLED(Extension):
|
||||
@@ -32,8 +33,24 @@ class statusLED(Extension):
|
||||
self.brightness_step = brightness_step
|
||||
self.brightness_limit = brightness_limit
|
||||
|
||||
make_key(names=('SLED_INC',), on_press=self._key_led_inc)
|
||||
make_key(names=('SLED_DEC',), on_press=self._key_led_dec)
|
||||
KC._generators.append(self.maybe_make_status_led_key())
|
||||
|
||||
def maybe_make_status_led_key(self):
|
||||
keys = (
|
||||
(('SLED_INC',), self._key_led_inc),
|
||||
(('SLED_DEC',), self._key_led_dec),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, on_press in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names,
|
||||
on_press=on_press,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def _layer_indicator(self, layer_active, *args, **kwargs):
|
||||
'''
|
||||
|
@@ -35,7 +35,7 @@ def simple_key_sequence(seq):
|
||||
meta=KeySequenceMeta(seq),
|
||||
on_press=sequence_press_handler,
|
||||
on_release=passthrough,
|
||||
)
|
||||
)[0]
|
||||
|
||||
|
||||
def send_string(message):
|
||||
@@ -124,7 +124,7 @@ def unicode_codepoint_sequence(codepoints):
|
||||
simple_key_sequence(_winc_unicode_sequence(kc_macros, keyboard)), True
|
||||
)
|
||||
|
||||
return make_key(on_press=_unicode_sequence)
|
||||
return make_key(on_press=_unicode_sequence)[0]
|
||||
|
||||
|
||||
def _ralt_unicode_sequence(kc_macros, keyboard):
|
||||
|
@@ -127,13 +127,3 @@ def ble_refresh(key, keyboard, *args, **kwargs):
|
||||
keyboard._hid_helper.stop_advertising()
|
||||
keyboard._hid_helper.start_advertising()
|
||||
return keyboard
|
||||
|
||||
|
||||
def ble_disconnect(key, keyboard, *args, **kwargs):
|
||||
from kmk.hid import HIDModes
|
||||
|
||||
if keyboard.hid_type != HIDModes.BLE:
|
||||
return keyboard
|
||||
|
||||
keyboard._hid_helper.clear_bonds()
|
||||
return keyboard
|
||||
|
113
kmk/hid.py
113
kmk/hid.py
@@ -4,8 +4,7 @@ from micropython import const
|
||||
|
||||
from storage import getmount
|
||||
|
||||
from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey, MouseKey
|
||||
from kmk.utils import clamp
|
||||
from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey
|
||||
|
||||
try:
|
||||
from adafruit_ble import BLERadio
|
||||
@@ -69,14 +68,6 @@ class AbstractHID:
|
||||
self.report_mods = memoryview(self._evt)[1:2]
|
||||
self.report_non_mods = memoryview(self._evt)[3:]
|
||||
|
||||
self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1)
|
||||
self._cc_report[0] = HIDReportTypes.CONSUMER
|
||||
self._cc_pending = False
|
||||
|
||||
self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.MOUSE] + 1)
|
||||
self._pd_report[0] = HIDReportTypes.MOUSE
|
||||
self._pd_pending = False
|
||||
|
||||
self.post_init()
|
||||
|
||||
def __repr__(self):
|
||||
@@ -85,27 +76,47 @@ class AbstractHID:
|
||||
def post_init(self):
|
||||
pass
|
||||
|
||||
def create_report(self, keys_pressed, axes):
|
||||
def create_report(self, keys_pressed):
|
||||
self.clear_all()
|
||||
|
||||
consumer_key = None
|
||||
for key in keys_pressed:
|
||||
if key.code >= FIRST_KMK_INTERNAL_KEY:
|
||||
continue
|
||||
if isinstance(key, ConsumerKey):
|
||||
consumer_key = key
|
||||
break
|
||||
|
||||
if isinstance(key, ModifierKey):
|
||||
self.add_modifier(key)
|
||||
elif isinstance(key, ConsumerKey):
|
||||
self.add_cc(key)
|
||||
elif isinstance(key, MouseKey):
|
||||
self.add_pd(key)
|
||||
else:
|
||||
self.add_key(key)
|
||||
if key.has_modifiers:
|
||||
for mod in key.has_modifiers:
|
||||
self.add_modifier(mod)
|
||||
reporting_device = self.report_device[0]
|
||||
needed_reporting_device = HIDReportTypes.KEYBOARD
|
||||
|
||||
for axis in axes:
|
||||
self.move_axis(axis)
|
||||
if consumer_key:
|
||||
needed_reporting_device = HIDReportTypes.CONSUMER
|
||||
|
||||
if reporting_device != needed_reporting_device:
|
||||
# If we are about to change reporting devices, release
|
||||
# all keys and close our proverbial tab on the existing
|
||||
# device, or keys will get stuck (mostly when releasing
|
||||
# media/consumer keys)
|
||||
self.send()
|
||||
|
||||
self.report_device[0] = needed_reporting_device
|
||||
|
||||
if consumer_key:
|
||||
self.add_key(consumer_key)
|
||||
else:
|
||||
for key in keys_pressed:
|
||||
if key.code >= FIRST_KMK_INTERNAL_KEY:
|
||||
continue
|
||||
|
||||
if isinstance(key, ModifierKey):
|
||||
self.add_modifier(key)
|
||||
else:
|
||||
self.add_key(key)
|
||||
|
||||
if key.has_modifiers:
|
||||
for mod in key.has_modifiers:
|
||||
self.add_modifier(mod)
|
||||
|
||||
return self
|
||||
|
||||
def hid_send(self, evt):
|
||||
# Don't raise a NotImplementedError so this can serve as our "dummy" HID
|
||||
@@ -120,24 +131,12 @@ class AbstractHID:
|
||||
self._prev_evt[:] = self._evt
|
||||
self.hid_send(self._evt)
|
||||
|
||||
if self._cc_pending:
|
||||
self.hid_send(self._cc_report)
|
||||
self._cc_pending = False
|
||||
|
||||
if self._pd_pending:
|
||||
self.hid_send(self._pd_report)
|
||||
self._pd_pending = False
|
||||
|
||||
return self
|
||||
|
||||
def clear_all(self):
|
||||
for idx, _ in enumerate(self.report_keys):
|
||||
self.report_keys[idx] = 0x00
|
||||
|
||||
self.remove_cc()
|
||||
self.remove_pd()
|
||||
self.clear_axis()
|
||||
|
||||
return self
|
||||
|
||||
def clear_non_modifiers(self):
|
||||
@@ -176,6 +175,9 @@ class AbstractHID:
|
||||
|
||||
where_to_place = self.report_non_mods
|
||||
|
||||
if self.report_device[0] == HIDReportTypes.CONSUMER:
|
||||
where_to_place = self.report_keys
|
||||
|
||||
for idx, _ in enumerate(where_to_place):
|
||||
if where_to_place[idx] == 0x00:
|
||||
where_to_place[idx] = key.code
|
||||
@@ -191,44 +193,15 @@ class AbstractHID:
|
||||
def remove_key(self, key):
|
||||
where_to_place = self.report_non_mods
|
||||
|
||||
if self.report_device[0] == HIDReportTypes.CONSUMER:
|
||||
where_to_place = self.report_keys
|
||||
|
||||
for idx, _ in enumerate(where_to_place):
|
||||
if where_to_place[idx] == key.code:
|
||||
where_to_place[idx] = 0x00
|
||||
|
||||
return self
|
||||
|
||||
def add_cc(self, cc):
|
||||
# Add (or write over) consumer control report. There can only be one CC
|
||||
# active at any time.
|
||||
memoryview(self._cc_report)[1:3] = cc.code.to_bytes(2, 'little')
|
||||
self._cc_pending = True
|
||||
|
||||
def remove_cc(self):
|
||||
# Remove consumer control report.
|
||||
report = memoryview(self._cc_report)[1:3]
|
||||
if report != b'\x00\x00':
|
||||
report[:] = b'\x00\x00'
|
||||
self._cc_pending = True
|
||||
|
||||
def add_pd(self, key):
|
||||
self._pd_report[1] |= key.code
|
||||
self._pd_pending = True
|
||||
|
||||
def remove_pd(self):
|
||||
if self._pd_report[1]:
|
||||
self._pd_pending = True
|
||||
self._pd_report[1] = 0x00
|
||||
|
||||
def move_axis(self, axis):
|
||||
delta = clamp(axis.delta, -127, 127)
|
||||
axis.delta -= delta
|
||||
self._pd_report[axis.code + 2] = 0xFF & delta
|
||||
self._pd_pending = True
|
||||
|
||||
def clear_axis(self):
|
||||
for idx in range(2, len(self._pd_report)):
|
||||
self._pd_report[idx] = 0x00
|
||||
|
||||
|
||||
class USBHID(AbstractHID):
|
||||
REPORT_BYTES = 9
|
||||
|
107
kmk/keys.py
107
kmk/keys.py
@@ -20,7 +20,6 @@ class KeyType:
|
||||
SIMPLE = const(0)
|
||||
MODIFIER = const(1)
|
||||
CONSUMER = const(2)
|
||||
MOUSE = const(3)
|
||||
|
||||
|
||||
FIRST_KMK_INTERNAL_KEY = const(1000)
|
||||
@@ -34,32 +33,9 @@ ALL_NUMBER_ALIASES = tuple(f'N{x}' for x in ALL_NUMBERS)
|
||||
debug = Debug(__name__)
|
||||
|
||||
|
||||
class Axis:
|
||||
def __init__(self, code: int) -> None:
|
||||
self.code = code
|
||||
self.delta = 0
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'Axis(code={self.code}, delta={self.delta})'
|
||||
|
||||
def move(self, keyboard: Keyboard, delta: int):
|
||||
self.delta += delta
|
||||
if self.delta:
|
||||
keyboard.axes.add(self)
|
||||
keyboard.hid_pending = True
|
||||
else:
|
||||
keyboard.axes.discard(self)
|
||||
|
||||
|
||||
class AX:
|
||||
W = Axis(2)
|
||||
X = Axis(0)
|
||||
Y = Axis(1)
|
||||
|
||||
|
||||
def maybe_make_key(
|
||||
code: Optional[int],
|
||||
names: Tuple[str, ...],
|
||||
code: Optional[int] = None,
|
||||
names: Tuple[str, ...] = tuple(), # NOQA
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> Callable[[str], Key]:
|
||||
@@ -364,7 +340,6 @@ def maybe_make_unicode_key(candidate: str) -> Optional[Key]:
|
||||
def maybe_make_firmware_key(candidate: str) -> Optional[Key]:
|
||||
keys = (
|
||||
((('BLE_REFRESH',), handlers.ble_refresh)),
|
||||
((('BLE_DISCONNECT',), handlers.ble_disconnect)),
|
||||
((('BOOTLOADER',), handlers.bootloader)),
|
||||
((('DEBUG', 'DBG'), handlers.debug_pressed)),
|
||||
((('HID_SWITCH', 'HID'), handlers.hid_switch)),
|
||||
@@ -425,51 +400,34 @@ KEY_GENERATORS = (
|
||||
|
||||
|
||||
class KeyAttrDict:
|
||||
# Instead of relying on the uncontrollable availability of a big chunk of
|
||||
# contiguous memory for key caching, we can manually fragment the cache into
|
||||
# reasonably small partitions. The partition size is chosen from the magic
|
||||
# values of CPs hash allocation sizes.
|
||||
# (https://github.com/adafruit/circuitpython/blob/main/py/map.c, 2023-02)
|
||||
__partition_size = 37
|
||||
__cache = [{}]
|
||||
__cache = {}
|
||||
_generators = list(KEY_GENERATORS)
|
||||
|
||||
def __iter__(self):
|
||||
for partition in self.__cache:
|
||||
for name in partition.__iter__():
|
||||
yield name
|
||||
return self.__cache.__iter__()
|
||||
|
||||
def __setitem__(self, name: str, key: Key):
|
||||
# Overwrite existing reference.
|
||||
for partition in self.__cache:
|
||||
if name in partition:
|
||||
partition[name] = key
|
||||
return key
|
||||
def __setitem__(self, key: str, value: Key):
|
||||
self.__cache.__setitem__(key, value)
|
||||
|
||||
# Insert new reference.
|
||||
if len(self.__cache[-1]) >= self.__partition_size:
|
||||
self.__cache.append({})
|
||||
self.__cache[-1][name] = key
|
||||
return key
|
||||
def __getattr__(self, key: Key):
|
||||
return self.__getitem__(key)
|
||||
|
||||
def __getattr__(self, name: str):
|
||||
return self.__getitem__(name)
|
||||
|
||||
def get(self, name: str, default: Optional[Key] = None):
|
||||
def get(self, key: Key, default: Optional[Key] = None):
|
||||
try:
|
||||
return self.__getitem__(name)
|
||||
return self.__getitem__(key)
|
||||
except Exception:
|
||||
return default
|
||||
|
||||
def clear(self):
|
||||
self.__cache.clear()
|
||||
self.__cache.append({})
|
||||
self._generators = list(KEY_GENERATORS)
|
||||
|
||||
def __getitem__(self, name: str):
|
||||
for partition in self.__cache:
|
||||
if name in partition:
|
||||
return partition[name]
|
||||
for names, key in self.__cache.items():
|
||||
if name in names:
|
||||
return key
|
||||
|
||||
for func in KEY_GENERATORS:
|
||||
for func in self._generators:
|
||||
maybe_key = func(name)
|
||||
if maybe_key:
|
||||
break
|
||||
@@ -477,10 +435,15 @@ class KeyAttrDict:
|
||||
if not maybe_key:
|
||||
raise ValueError(f'Invalid key: {name}')
|
||||
|
||||
if debug.enabled:
|
||||
debug(f'{name}: {maybe_key}')
|
||||
key, names = maybe_key
|
||||
|
||||
return maybe_key
|
||||
if names:
|
||||
self.__cache[names] = key
|
||||
|
||||
if debug.enabled:
|
||||
debug(f'{name}: {key}')
|
||||
|
||||
return key
|
||||
|
||||
|
||||
# Global state, will be filled in throughout this file, and
|
||||
@@ -713,13 +676,9 @@ class ConsumerKey(Key):
|
||||
pass
|
||||
|
||||
|
||||
class MouseKey(Key):
|
||||
pass
|
||||
|
||||
|
||||
def make_key(
|
||||
code: Optional[int] = None,
|
||||
names: Tuple[str, ...] = tuple(), # NOQA
|
||||
names: Optional[Tuple[str, ...]] = tuple(), # NOQA
|
||||
type: KeyType = KeyType.SIMPLE,
|
||||
**kwargs,
|
||||
) -> Key:
|
||||
@@ -747,8 +706,6 @@ def make_key(
|
||||
constructor = ModifierKey
|
||||
elif type == KeyType.CONSUMER:
|
||||
constructor = ConsumerKey
|
||||
elif type == KeyType.MOUSE:
|
||||
constructor = MouseKey
|
||||
else:
|
||||
raise ValueError('Unrecognized key type')
|
||||
|
||||
@@ -763,10 +720,7 @@ def make_key(
|
||||
|
||||
key = constructor(code=code, **kwargs)
|
||||
|
||||
for name in names:
|
||||
KC[name] = key
|
||||
|
||||
return key
|
||||
return key, names
|
||||
|
||||
|
||||
def make_mod_key(code: int, names: Tuple[str, ...], *args, **kwargs) -> Key:
|
||||
@@ -781,10 +735,6 @@ def make_consumer_key(*args, **kwargs) -> Key:
|
||||
return make_key(*args, **kwargs, type=KeyType.CONSUMER)
|
||||
|
||||
|
||||
def make_mouse_key(*args, **kwargs) -> Key:
|
||||
return make_key(*args, **kwargs, type=KeyType.MOUSE)
|
||||
|
||||
|
||||
# Argumented keys are implicitly internal, so auto-gen of code
|
||||
# is almost certainly the best plan here
|
||||
def make_argumented_key(
|
||||
@@ -816,7 +766,4 @@ def make_argumented_key(
|
||||
'should have been raised.'
|
||||
)
|
||||
|
||||
for name in names:
|
||||
KC[name] = _argumented_key
|
||||
|
||||
return _argumented_key
|
||||
return _argumented_key, names
|
||||
|
@@ -49,7 +49,6 @@ class KMKKeyboard:
|
||||
#####
|
||||
# Internal State
|
||||
keys_pressed = set()
|
||||
axes = set()
|
||||
_coordkeys_pressed = {}
|
||||
hid_type = HIDModes.USB
|
||||
secondary_hid_type = None
|
||||
@@ -89,7 +88,6 @@ class KMKKeyboard:
|
||||
f' unicode_mode={self.unicode_mode}, ',
|
||||
f'_hid_helper={self._hid_helper},\n',
|
||||
f' keys_pressed={self.keys_pressed},\n',
|
||||
f' axes={self.axes},\n',
|
||||
f' _coordkeys_pressed={self._coordkeys_pressed},\n',
|
||||
f' hid_pending={self.hid_pending}, ',
|
||||
f'active_layers={self.active_layers}, ',
|
||||
@@ -104,24 +102,15 @@ class KMKKeyboard:
|
||||
debug(f'keys_pressed={self.keys_pressed}')
|
||||
|
||||
def _send_hid(self) -> None:
|
||||
if not self._hid_send_enabled:
|
||||
return
|
||||
|
||||
if self.axes and debug.enabled:
|
||||
debug(f'axes={self.axes}')
|
||||
|
||||
self._hid_helper.create_report(self.keys_pressed, self.axes)
|
||||
try:
|
||||
self._hid_helper.send()
|
||||
except KeyError as e:
|
||||
if debug.enabled:
|
||||
debug(f'HidNotFound(HIDReportType={e})')
|
||||
|
||||
if self._hid_send_enabled:
|
||||
hid_report = self._hid_helper.create_report(self.keys_pressed)
|
||||
try:
|
||||
hid_report.send()
|
||||
except KeyError as e:
|
||||
if debug.enabled:
|
||||
debug(f'HidNotFound(HIDReportType={e})')
|
||||
self.hid_pending = False
|
||||
|
||||
for axis in self.axes:
|
||||
axis.move(self, 0)
|
||||
|
||||
def _handle_matrix_report(self, kevent: KeyEvent) -> None:
|
||||
if kevent is not None:
|
||||
self._on_matrix_changed(kevent)
|
||||
|
@@ -4,9 +4,9 @@ import microcontroller
|
||||
|
||||
import time
|
||||
|
||||
from kmk.keys import AX
|
||||
from kmk.modules import Module
|
||||
from kmk.modules.adns9800_firmware import firmware
|
||||
from kmk.modules.mouse_keys import PointingDevice
|
||||
|
||||
|
||||
class REG:
|
||||
@@ -70,6 +70,7 @@ class ADNS9800(Module):
|
||||
DIR_READ = 0x7F
|
||||
|
||||
def __init__(self, cs, sclk, miso, mosi, invert_x=False, invert_y=False):
|
||||
self.pointing_device = PointingDevice()
|
||||
self.cs = digitalio.DigitalInOut(cs)
|
||||
self.cs.direction = digitalio.Direction.OUTPUT
|
||||
self.spi = busio.SPI(clock=sclk, MOSI=mosi, MISO=miso)
|
||||
@@ -202,14 +203,27 @@ class ADNS9800(Module):
|
||||
if self.invert_y:
|
||||
delta_y *= -1
|
||||
|
||||
if delta_x:
|
||||
AX.X.move(delta_x)
|
||||
if delta_x < 0:
|
||||
self.pointing_device.report_x[0] = (delta_x & 0xFF) | 0x80
|
||||
else:
|
||||
self.pointing_device.report_x[0] = delta_x & 0xFF
|
||||
|
||||
if delta_y:
|
||||
AX.Y.move(delta_y)
|
||||
if delta_y < 0:
|
||||
self.pointing_device.report_y[0] = (delta_y & 0xFF) | 0x80
|
||||
else:
|
||||
self.pointing_device.report_y[0] = delta_y & 0xFF
|
||||
|
||||
if keyboard.debug_enabled:
|
||||
print('Delta: ', delta_x, ' ', delta_y)
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
if self.pointing_device.hid_pending:
|
||||
keyboard._hid_helper.hid_send(self.pointing_device._evt)
|
||||
self.pointing_device.hid_pending = False
|
||||
self.pointing_device.report_x[0] = 0
|
||||
self.pointing_device.report_y[0] = 0
|
||||
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
@@ -1,4 +1,5 @@
|
||||
from kmk.keys import FIRST_KMK_INTERNAL_KEY, KC, ModifierKey, make_key
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import FIRST_KMK_INTERNAL_KEY, KC, ModifierKey, maybe_make_key
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
@@ -16,12 +17,16 @@ class CapsWord(Module):
|
||||
self._timeout_key = False
|
||||
self._cw_active = False
|
||||
self.timeout = timeout
|
||||
make_key(
|
||||
KC._generators.append(self.maybe_make_capsword_key())
|
||||
|
||||
def maybe_make_capsword_key(self):
|
||||
return maybe_make_key(
|
||||
names=(
|
||||
'CAPSWORD',
|
||||
'CW',
|
||||
),
|
||||
on_press=self.cw_pressed,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
|
@@ -1,3 +1,4 @@
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import KC, ModifierKey, make_key
|
||||
from kmk.modules import Module
|
||||
|
||||
@@ -12,16 +13,26 @@ class CgSwap(Module):
|
||||
KC.LGUI: KC.LCTL,
|
||||
KC.RGUI: KC.RCTL,
|
||||
}
|
||||
make_key(
|
||||
names=('CG_SWAP',),
|
||||
)
|
||||
make_key(
|
||||
names=('CG_NORM',),
|
||||
)
|
||||
make_key(
|
||||
names=('CG_TOGG',),
|
||||
KC._generators.append(self.maybe_make_cgswap_key())
|
||||
|
||||
def maybe_make_cgswap_key(self):
|
||||
keys = (
|
||||
(('CG_SWAP',),),
|
||||
(('CG_NORM',),),
|
||||
(('CG_TOGG',),),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names,
|
||||
on_press=handler_passthrough,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
|
@@ -5,7 +5,7 @@ except ImportError:
|
||||
from micropython import const
|
||||
|
||||
import kmk.handlers.stock as handlers
|
||||
from kmk.keys import Key, make_key
|
||||
from kmk.keys import KC, Key, maybe_make_key
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
from kmk.modules import Module
|
||||
|
||||
@@ -102,11 +102,12 @@ class Combos(Module):
|
||||
def __init__(self, combos=[]):
|
||||
self.combos = combos
|
||||
self._key_buffer = []
|
||||
|
||||
make_key(
|
||||
names=('LEADER', 'LDR'),
|
||||
on_press=handlers.passthrough,
|
||||
on_release=handlers.passthrough,
|
||||
KC._generators.append(
|
||||
maybe_make_key(
|
||||
names=('LEADER', 'LDR'),
|
||||
on_press=handlers.passthrough,
|
||||
on_release=handlers.passthrough,
|
||||
)
|
||||
)
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
|
@@ -3,6 +3,7 @@ from supervisor import ticks_ms
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import KC, make_argumented_key
|
||||
from kmk.kmktime import check_deadline, ticks_diff
|
||||
from kmk.modules import Module
|
||||
@@ -45,41 +46,33 @@ class DynamicSequences(Module):
|
||||
self.index = 0
|
||||
self.start_time = 0
|
||||
self.current_repetition = 0
|
||||
self.last_config_frame = set()
|
||||
|
||||
self.timeout = timeout
|
||||
self.key_interval = key_interval
|
||||
self.use_recorded_speed = use_recorded_speed
|
||||
|
||||
# Create keycodes
|
||||
make_argumented_key(
|
||||
validator=DSMeta, names=('RECORD_SEQUENCE',), on_press=self._record_sequence
|
||||
KC._generators.append(self.maybe_make_sequence_key())
|
||||
|
||||
def maybe_make_sequence_key(self):
|
||||
keys = (
|
||||
(('RECORD_SEQUENCE',), DSMeta, self._record_sequence),
|
||||
(('PLAY_SEQUENCE',), DSMeta, self._play_sequence),
|
||||
(('SET_SEQUENCE', 'STOP_SEQUENCE'), DSMeta, self._stop_sequence),
|
||||
(('SET_SEQUENCE_REPETITIONS',), DSMeta, self._set_sequence_repetitions),
|
||||
(('SET_SEQUENCE_INTERVAL',), DSMeta, self._set_sequence_interval),
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
validator=DSMeta, names=('PLAY_SEQUENCE',), on_press=self._play_sequence
|
||||
)
|
||||
def closure(candidate):
|
||||
for names, validator, on_press in keys:
|
||||
if candidate in names:
|
||||
return make_argumented_key(
|
||||
names=names,
|
||||
validator=validator,
|
||||
on_press=on_press,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
validator=DSMeta,
|
||||
names=(
|
||||
'SET_SEQUENCE',
|
||||
'STOP_SEQUENCE',
|
||||
),
|
||||
on_press=self._stop_sequence,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
validator=DSMeta,
|
||||
names=('SET_SEQUENCE_REPETITIONS',),
|
||||
on_press=self._set_sequence_repetitions,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
validator=DSMeta,
|
||||
names=('SET_SEQUENCE_INTERVAL',),
|
||||
on_press=self._set_sequence_interval,
|
||||
)
|
||||
return closure
|
||||
|
||||
def _record_sequence(self, key, keyboard, *args, **kwargs):
|
||||
self._stop_sequence(key, keyboard)
|
||||
|
@@ -4,8 +4,8 @@ Extension handles usage of AS5013 by AMS
|
||||
|
||||
from supervisor import ticks_ms
|
||||
|
||||
from kmk.keys import AX
|
||||
from kmk.modules import Module
|
||||
from kmk.modules.mouse_keys import PointingDevice
|
||||
|
||||
I2C_ADDRESS = 0x40
|
||||
I2X_ALT_ADDRESS = 0x41
|
||||
@@ -44,6 +44,7 @@ class Easypoint(Module):
|
||||
self._i2c_bus = i2c
|
||||
|
||||
# HID parameters
|
||||
self.pointing_device = PointingDevice()
|
||||
self.polling_interval = 20
|
||||
self.last_tick = ticks_ms()
|
||||
|
||||
@@ -81,8 +82,12 @@ class Easypoint(Module):
|
||||
return
|
||||
else:
|
||||
# Set the X/Y from easypoint
|
||||
AX.X.move(keyboard, x)
|
||||
AX.Y.move(keyboard, y)
|
||||
self.pointing_device.report_x[0] = x
|
||||
self.pointing_device.report_y[0] = y
|
||||
|
||||
self.pointing_device.hid_pending = x != 0 or y != 0
|
||||
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
return
|
||||
@@ -91,6 +96,9 @@ class Easypoint(Module):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
if self.pointing_device.hid_pending:
|
||||
keyboard._hid_helper.hid_send(self.pointing_device._evt)
|
||||
self._clear_pending_hid()
|
||||
return
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
@@ -99,13 +107,20 @@ class Easypoint(Module):
|
||||
def on_powersave_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def _clear_pending_hid(self):
|
||||
self.pointing_device.hid_pending = False
|
||||
self.pointing_device.report_x[0] = 0
|
||||
self.pointing_device.report_y[0] = 0
|
||||
self.pointing_device.report_w[0] = 0
|
||||
self.pointing_device.button_status[0] = 0
|
||||
|
||||
def _read_raw_state(self):
|
||||
'''Read data from AS5013'''
|
||||
x, y = self._i2c_rdwr([X], length=2)
|
||||
return x, y
|
||||
|
||||
def getSignedNumber(self, number, bitLength=8):
|
||||
mask = (2**bitLength) - 1
|
||||
mask = (2 ** bitLength) - 1
|
||||
if number & (1 << (bitLength - 1)):
|
||||
return number | ~mask
|
||||
else:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from micropython import const
|
||||
|
||||
from kmk.keys import KC, make_argumented_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key
|
||||
from kmk.modules import Module
|
||||
from kmk.utils import Debug
|
||||
|
||||
@@ -55,11 +55,13 @@ class HoldTap(Module):
|
||||
self.key_buffer = []
|
||||
self.key_states = {}
|
||||
if not KC.get('HT'):
|
||||
make_argumented_key(
|
||||
validator=HoldTapKeyMeta,
|
||||
names=('HT',),
|
||||
on_press=self.ht_pressed,
|
||||
on_release=self.ht_released,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
validator=HoldTapKeyMeta,
|
||||
names=('HT',),
|
||||
on_press=self.ht_pressed,
|
||||
on_release=self.ht_released,
|
||||
)
|
||||
)
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
|
@@ -1,4 +1,5 @@
|
||||
'''One layer isn't enough. Adds keys to get to more of them'''
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import KC, make_argumented_key
|
||||
from kmk.modules.holdtap import HoldTap, HoldTapKeyMeta
|
||||
from kmk.utils import Debug
|
||||
@@ -39,46 +40,31 @@ class Layers(HoldTap):
|
||||
def __init__(self):
|
||||
# Layers
|
||||
super().__init__()
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('MO',),
|
||||
on_press=self._mo_pressed,
|
||||
on_release=self._mo_released,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('DF',),
|
||||
on_press=self._df_pressed,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('LM',),
|
||||
on_press=self._lm_pressed,
|
||||
on_release=self._lm_released,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('TG',),
|
||||
on_press=self._tg_pressed,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('TO',),
|
||||
on_press=self._to_pressed,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator_lt,
|
||||
names=('LT',),
|
||||
on_press=self.ht_pressed,
|
||||
on_release=self.ht_released,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator_tt,
|
||||
names=('TT',),
|
||||
on_press=self.ht_pressed,
|
||||
on_release=self.ht_released,
|
||||
KC._generators.append(self.maybe_make_layer_key())
|
||||
|
||||
def maybe_make_layer_key(self):
|
||||
keys = (
|
||||
(('MO',), layer_key_validator, self._mo_pressed, self._mo_released),
|
||||
(('DF',), layer_key_validator, self._df_pressed, handler_passthrough),
|
||||
(('LM',), layer_key_validator, self._lm_pressed, self._lm_released),
|
||||
(('TG',), layer_key_validator, self._tg_pressed, handler_passthrough),
|
||||
(('TO',), layer_key_validator, self._to_pressed, handler_passthrough),
|
||||
(('LT',), layer_key_validator_lt, self.ht_pressed, self.ht_released),
|
||||
(('TT',), layer_key_validator_tt, self.ht_pressed, self.ht_released),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, validator, on_press, on_release in keys:
|
||||
if candidate in names:
|
||||
return make_argumented_key(
|
||||
names=names,
|
||||
validator=validator,
|
||||
on_press=on_press,
|
||||
on_release=on_release,
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def _df_pressed(self, key, keyboard, *args, **kwargs):
|
||||
'''
|
||||
Switches the default layer
|
||||
@@ -114,15 +100,17 @@ class Layers(HoldTap):
|
||||
'''
|
||||
As MO(layer) but with mod active
|
||||
'''
|
||||
keyboard.hid_pending = True
|
||||
# Sets the timer start and acts like MO otherwise
|
||||
keyboard.add_key(key.meta.kc)
|
||||
keyboard.keys_pressed.add(key.meta.kc)
|
||||
self._mo_pressed(key, keyboard, *args, **kwargs)
|
||||
|
||||
def _lm_released(self, key, keyboard, *args, **kwargs):
|
||||
'''
|
||||
As MO(layer) but with mod active
|
||||
'''
|
||||
keyboard.remove_key(key.meta.kc)
|
||||
keyboard.hid_pending = True
|
||||
keyboard.keys_pressed.discard(key.meta.kc)
|
||||
self._mo_released(key, keyboard, *args, **kwargs)
|
||||
|
||||
def _tg_pressed(self, key, keyboard, *args, **kwargs):
|
||||
|
@@ -8,7 +8,8 @@ from adafruit_midi.program_change import ProgramChange
|
||||
from adafruit_midi.start import Start
|
||||
from adafruit_midi.stop import Stop
|
||||
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import KC, make_argumented_key
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
@@ -21,42 +22,6 @@ class midiNoteValidator:
|
||||
|
||||
class MidiKeys(Module):
|
||||
def __init__(self):
|
||||
make_argumented_key(
|
||||
names=('MIDI_CC',),
|
||||
validator=ControlChange,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_NOTE',),
|
||||
validator=midiNoteValidator,
|
||||
on_press=self.note_on,
|
||||
on_release=self.note_off,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_PB',),
|
||||
validator=PitchBend,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_PC',),
|
||||
validator=ProgramChange,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_START',),
|
||||
validator=Start,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_STOP',),
|
||||
validator=Stop,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
try:
|
||||
self.midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)
|
||||
@@ -65,6 +30,37 @@ class MidiKeys(Module):
|
||||
# if debug_enabled:
|
||||
print('No midi device found.')
|
||||
|
||||
KC._generators.append(self.maybe_make_midi_key())
|
||||
|
||||
def maybe_make_midi_key(self):
|
||||
keys = (
|
||||
(('MIDI_CC',), ControlChange),
|
||||
(('MIDI_PB',), PitchBend),
|
||||
(('MIDI_PC',), ProgramChange),
|
||||
(('MIDI_START',), Start),
|
||||
(('MIDI_STOP',), Stop),
|
||||
)
|
||||
note = ('MIDI_NOTE',)
|
||||
|
||||
def closure(candidate):
|
||||
if candidate in note:
|
||||
return make_argumented_key(
|
||||
names=('MIDI_NOTE',),
|
||||
validator=midiNoteValidator,
|
||||
on_press=self.note_on,
|
||||
on_release=self.note_off,
|
||||
)
|
||||
for names, validator in keys:
|
||||
if candidate in names:
|
||||
return make_argumented_key(
|
||||
names=names,
|
||||
validator=validator,
|
||||
on_press=self.on_press,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return None
|
||||
|
||||
|
@@ -1,13 +1,15 @@
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key
|
||||
from kmk.modules.holdtap import HoldTap, HoldTapKeyMeta
|
||||
|
||||
|
||||
class ModTap(HoldTap):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
make_argumented_key(
|
||||
validator=HoldTapKeyMeta,
|
||||
names=('MT',),
|
||||
on_press=self.ht_pressed,
|
||||
on_release=self.ht_released,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
validator=HoldTapKeyMeta,
|
||||
names=('MT',),
|
||||
on_press=self.ht_pressed,
|
||||
on_release=self.ht_released,
|
||||
)
|
||||
)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
from supervisor import ticks_ms
|
||||
|
||||
from kmk.hid import HID_REPORT_SIZES, HIDReportTypes
|
||||
from kmk.keys import AX, make_key, make_mouse_key
|
||||
from kmk.kmktime import PeriodicTimer
|
||||
from kmk.keys import KC, make_key
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
@@ -23,100 +24,73 @@ class PointingDevice:
|
||||
|
||||
class MouseKeys(Module):
|
||||
def __init__(self):
|
||||
self.pointing_device = PointingDevice()
|
||||
self._nav_key_activated = 0
|
||||
self._up_activated = False
|
||||
self._down_activated = False
|
||||
self._left_activated = False
|
||||
self._right_activated = False
|
||||
self._mw_up_activated = False
|
||||
self._mw_down_activated = False
|
||||
self.max_speed = 10
|
||||
self.acc_interval = 10 # Delta ms to apply acceleration
|
||||
self.ac_interval = 100 # Delta ms to apply acceleration
|
||||
self._next_interval = 0 # Time for next tick interval
|
||||
self.move_step = 1
|
||||
KC._generators.append(self.maybe_make_mouse_key())
|
||||
|
||||
make_mouse_key(
|
||||
names=('MB_LMB',),
|
||||
code=1,
|
||||
)
|
||||
make_mouse_key(
|
||||
names=('MB_MMB',),
|
||||
code=4,
|
||||
)
|
||||
make_mouse_key(
|
||||
names=('MB_RMB',),
|
||||
code=2,
|
||||
)
|
||||
make_key(
|
||||
names=('MW_UP',),
|
||||
on_press=self._mw_up_press,
|
||||
on_release=self._mw_up_release,
|
||||
)
|
||||
make_key(
|
||||
names=(
|
||||
'MW_DOWN',
|
||||
'MW_DN',
|
||||
),
|
||||
on_press=self._mw_down_press,
|
||||
on_release=self._mw_down_release,
|
||||
)
|
||||
make_key(
|
||||
names=('MS_UP',),
|
||||
on_press=self._ms_up_press,
|
||||
on_release=self._ms_up_release,
|
||||
)
|
||||
make_key(
|
||||
names=(
|
||||
'MS_DOWN',
|
||||
'MS_DN',
|
||||
),
|
||||
on_press=self._ms_down_press,
|
||||
on_release=self._ms_down_release,
|
||||
)
|
||||
make_key(
|
||||
names=(
|
||||
'MS_LEFT',
|
||||
'MS_LT',
|
||||
),
|
||||
on_press=self._ms_left_press,
|
||||
on_release=self._ms_left_release,
|
||||
)
|
||||
make_key(
|
||||
names=(
|
||||
'MS_RIGHT',
|
||||
'MS_RT',
|
||||
),
|
||||
on_press=self._ms_right_press,
|
||||
on_release=self._ms_right_release,
|
||||
def maybe_make_mouse_key(self):
|
||||
keys = (
|
||||
(('MB_LMB',), self._mb_lmb_press, self._mb_lmb_release),
|
||||
(('MB_MMB',), self._mb_mmb_press, self._mb_mmb_release),
|
||||
(('MB_RMB',), self._mb_rmb_press, self._mb_rmb_release),
|
||||
(('MW_UP',), self._mw_up_press, self._mw_up_release),
|
||||
(('MW_DOWN', 'MW_DN'), self._mw_down_press, self._mw_down_release),
|
||||
(('MS_UP',), self._ms_up_press, self._ms_up_release),
|
||||
(('MS_DOWN', 'MS_DN'), self._ms_down_press, self._ms_down_release),
|
||||
(('MS_LEFT', 'MS_LT'), self._ms_left_press, self._ms_left_release),
|
||||
(('MS_RIGHT', 'MS_RT'), self._ms_right_press, self._ms_right_release),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, on_press, on_release in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names, on_press=on_press, on_release=on_release
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
self._timer = PeriodicTimer(self.acc_interval)
|
||||
return
|
||||
|
||||
def matrix_detected_press(self, keyboard):
|
||||
return keyboard.matrix_update is None
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
if not self._timer.tick():
|
||||
return
|
||||
|
||||
if self._nav_key_activated:
|
||||
if self.move_step < self.max_speed:
|
||||
self.move_step = self.move_step + 1
|
||||
if self._next_interval <= ticks_ms():
|
||||
# print("hello: ")
|
||||
# print(ticks_ms())
|
||||
self._next_interval = ticks_ms() + self.ac_interval
|
||||
# print(self._next_interval)
|
||||
if self.move_step < self.max_speed:
|
||||
self.move_step = self.move_step + 1
|
||||
if self._right_activated:
|
||||
AX.X.move(keyboard, self.move_step)
|
||||
self.pointing_device.report_x[0] = self.move_step
|
||||
if self._left_activated:
|
||||
AX.X.move(keyboard, -self.move_step)
|
||||
self.pointing_device.report_x[0] = 0xFF & (0 - self.move_step)
|
||||
if self._up_activated:
|
||||
AX.Y.move(keyboard, -self.move_step)
|
||||
self.pointing_device.report_y[0] = 0xFF & (0 - self.move_step)
|
||||
if self._down_activated:
|
||||
AX.Y.move(keyboard, self.move_step)
|
||||
|
||||
if self._mw_up_activated:
|
||||
AX.W.move(keyboard, 1)
|
||||
if self._mw_down_activated:
|
||||
AX.W.move(keyboard, -1)
|
||||
self.pointing_device.report_y[0] = self.move_step
|
||||
self.pointing_device.hid_pending = True
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
if self.pointing_device.hid_pending and keyboard._hid_send_enabled:
|
||||
keyboard._hid_helper.hid_send(self.pointing_device._evt)
|
||||
self.pointing_device.hid_pending = False
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
@@ -128,21 +102,50 @@ class MouseKeys(Module):
|
||||
def on_powersave_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def _mb_lmb_press(self, key, keyboard, *args, **kwargs):
|
||||
self.pointing_device.button_status[0] |= self.pointing_device.MB_LMB
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mb_lmb_release(self, key, keyboard, *args, **kwargs):
|
||||
self.pointing_device.button_status[0] &= ~self.pointing_device.MB_LMB
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mb_mmb_press(self, key, keyboard, *args, **kwargs):
|
||||
self.pointing_device.button_status[0] |= self.pointing_device.MB_MMB
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mb_mmb_release(self, key, keyboard, *args, **kwargs):
|
||||
self.pointing_device.button_status[0] &= ~self.pointing_device.MB_MMB
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mb_rmb_press(self, key, keyboard, *args, **kwargs):
|
||||
self.pointing_device.button_status[0] |= self.pointing_device.MB_RMB
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mb_rmb_release(self, key, keyboard, *args, **kwargs):
|
||||
self.pointing_device.button_status[0] &= ~self.pointing_device.MB_RMB
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mw_up_press(self, key, keyboard, *args, **kwargs):
|
||||
self._mw_up_activated = True
|
||||
self.pointing_device.report_w[0] = self.move_step
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mw_up_release(self, key, keyboard, *args, **kwargs):
|
||||
self._mw_up_activated = False
|
||||
self.pointing_device.report_w[0] = 0
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mw_down_press(self, key, keyboard, *args, **kwargs):
|
||||
self._mw_down_activated = True
|
||||
self.pointing_device.report_w[0] = 0xFF
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _mw_down_release(self, key, keyboard, *args, **kwargs):
|
||||
self._mw_down_activated = False
|
||||
self.pointing_device.report_w[0] = 0
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
# Mouse movement
|
||||
def _reset_next_interval(self):
|
||||
if self._nav_key_activated == 1:
|
||||
self._next_interval = ticks_ms() + self.ac_interval
|
||||
self.move_step = 1
|
||||
|
||||
def _check_last(self):
|
||||
@@ -153,38 +156,56 @@ class MouseKeys(Module):
|
||||
self._nav_key_activated += 1
|
||||
self._reset_next_interval()
|
||||
self._up_activated = True
|
||||
self.pointing_device.report_y[0] = 0xFF & (0 - self.move_step)
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _ms_up_release(self, key, keyboard, *args, **kwargs):
|
||||
self._up_activated = False
|
||||
self._nav_key_activated -= 1
|
||||
self._check_last()
|
||||
self.pointing_device.report_y[0] = 0
|
||||
self.pointing_device.hid_pending = False
|
||||
|
||||
def _ms_down_press(self, key, keyboard, *args, **kwargs):
|
||||
self._nav_key_activated += 1
|
||||
self._reset_next_interval()
|
||||
self._down_activated = True
|
||||
# if not self.x_activated and not self.y_activated:
|
||||
# self.next_interval = ticks_ms() + self.ac_intervalle
|
||||
self.pointing_device.report_y[0] = self.move_step
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _ms_down_release(self, key, keyboard, *args, **kwargs):
|
||||
self._down_activated = False
|
||||
self._nav_key_activated -= 1
|
||||
self._check_last()
|
||||
self.pointing_device.report_y[0] = 0
|
||||
self.pointing_device.hid_pending = False
|
||||
|
||||
def _ms_left_press(self, key, keyboard, *args, **kwargs):
|
||||
self._nav_key_activated += 1
|
||||
self._reset_next_interval()
|
||||
self._left_activated = True
|
||||
self.pointing_device.report_x[0] = 0xFF & (0 - self.move_step)
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _ms_left_release(self, key, keyboard, *args, **kwargs):
|
||||
self._nav_key_activated -= 1
|
||||
self._left_activated = False
|
||||
self._check_last()
|
||||
self.pointing_device.report_x[0] = 0
|
||||
self.pointing_device.hid_pending = False
|
||||
|
||||
def _ms_right_press(self, key, keyboard, *args, **kwargs):
|
||||
self._nav_key_activated += 1
|
||||
self._reset_next_interval()
|
||||
self._right_activated = True
|
||||
self.pointing_device.report_x[0] = self.move_step
|
||||
self.pointing_device.hid_pending = True
|
||||
|
||||
def _ms_right_release(self, key, keyboard, *args, **kwargs):
|
||||
self._nav_key_activated -= 1
|
||||
self._right_activated = False
|
||||
self._check_last()
|
||||
self.pointing_device.report_x[0] = 0
|
||||
self.pointing_device.hid_pending = False
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key
|
||||
from kmk.modules.holdtap import ActivationType, HoldTap, HoldTapKeyMeta
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@ class OneShot(HoldTap):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
make_argumented_key(
|
||||
validator=oneshot_validator,
|
||||
names=('OS', 'ONESHOT'),
|
||||
on_press=self.osk_pressed,
|
||||
on_release=self.osk_released,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
validator=oneshot_validator,
|
||||
names=('OS', 'ONESHOT'),
|
||||
on_press=self.osk_pressed,
|
||||
on_release=self.osk_released,
|
||||
)
|
||||
)
|
||||
|
||||
def process_key(self, keyboard, current_key, is_pressed, int_coord):
|
||||
|
@@ -7,9 +7,10 @@ from micropython import const
|
||||
import math
|
||||
import struct
|
||||
|
||||
from kmk.keys import AX, KC, make_argumented_key, make_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key, maybe_make_key
|
||||
from kmk.kmktime import PeriodicTimer
|
||||
from kmk.modules import Module
|
||||
from kmk.modules.mouse_keys import PointingDevice
|
||||
|
||||
I2C_ADDRESS = 0x0A
|
||||
I2C_ADDRESS_ALTERNATIVE = 0x0B
|
||||
@@ -77,16 +78,29 @@ class TrackballHandler:
|
||||
|
||||
class PointingHandler(TrackballHandler):
|
||||
def handle(self, keyboard, trackball, x, y, switch, state):
|
||||
if x:
|
||||
AX.X.move(keyboard, x)
|
||||
if y:
|
||||
AX.Y.move(keyboard, y)
|
||||
if x > 0:
|
||||
trackball.pointing_device.report_x[0] = x
|
||||
elif x < 0:
|
||||
trackball.pointing_device.report_x[0] = 0xFF & x
|
||||
if y > 0:
|
||||
trackball.pointing_device.report_y[0] = y
|
||||
elif y < 0:
|
||||
trackball.pointing_device.report_y[0] = 0xFF & y
|
||||
|
||||
if x != 0 or y != 0:
|
||||
trackball.pointing_device.hid_pending = True
|
||||
|
||||
if switch == 1: # Button pressed
|
||||
keyboard.pre_process_key(KC.MB_LMB, is_pressed=True)
|
||||
trackball.pointing_device.button_status[
|
||||
0
|
||||
] |= trackball.pointing_device.MB_LMB
|
||||
trackball.pointing_device.hid_pending = True
|
||||
|
||||
if not state and trackball.previous_state is True: # Button released
|
||||
keyboard.pre_process_key(KC.MB_LMB, is_pressed=False)
|
||||
trackball.pointing_device.button_status[
|
||||
0
|
||||
] &= ~trackball.pointing_device.MB_LMB
|
||||
trackball.pointing_device.hid_pending = True
|
||||
|
||||
trackball.previous_state = state
|
||||
|
||||
@@ -100,13 +114,17 @@ class ScrollHandler(TrackballHandler):
|
||||
y = -y
|
||||
|
||||
if y != 0:
|
||||
AX.W.move(keyboard, y)
|
||||
pointing_device = trackball.pointing_device
|
||||
pointing_device.report_w[0] = 0xFF & y
|
||||
pointing_device.hid_pending = True
|
||||
|
||||
if switch == 1: # Button pressed
|
||||
keyboard.pre_process_key(KC.MB_LMB, is_pressed=True)
|
||||
pointing_device.button_status[0] |= pointing_device.MB_LMB
|
||||
pointing_device.hid_pending = True
|
||||
|
||||
if not state and trackball.previous_state is True: # Button released
|
||||
keyboard.pre_process_key(KC.MB_LMB, is_pressed=False)
|
||||
pointing_device.button_status[0] &= ~pointing_device.MB_LMB
|
||||
pointing_device.hid_pending = True
|
||||
|
||||
trackball.previous_state = state
|
||||
|
||||
@@ -167,6 +185,7 @@ class Trackball(Module):
|
||||
self._i2c_address = address
|
||||
self._i2c_bus = i2c
|
||||
|
||||
self.pointing_device = PointingDevice()
|
||||
self.mode = mode
|
||||
self.previous_state = False # click state
|
||||
self.handlers = handlers
|
||||
@@ -179,15 +198,18 @@ class Trackball(Module):
|
||||
f'Invalid chip ID: 0x{chip_id:04X}, expected 0x{CHIP_ID:04X}'
|
||||
)
|
||||
|
||||
make_key(
|
||||
names=('TB_MODE', 'TB_NEXT_HANDLER', 'TB_N'),
|
||||
on_press=self._tb_handler_next_press,
|
||||
KC._generators.append(
|
||||
maybe_make_key(
|
||||
names=('TB_MODE', 'TB_NEXT_HANDLER', 'TB_N'),
|
||||
on_press=self._tb_handler_next_press,
|
||||
)
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('TB_HANDLER', 'TB_H'),
|
||||
on_press=self._tb_handler_press,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('TB_HANDLER', 'TB_H'),
|
||||
on_press=self._tb_handler_press,
|
||||
)
|
||||
)
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
@@ -215,6 +237,9 @@ class Trackball(Module):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
if self.pointing_device.hid_pending:
|
||||
keyboard._hid_helper.hid_send(self.pointing_device._evt)
|
||||
self._clear_pending_hid()
|
||||
return
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
@@ -258,6 +283,13 @@ class Trackball(Module):
|
||||
next_index = 0
|
||||
self.activate_handler(next_index)
|
||||
|
||||
def _clear_pending_hid(self):
|
||||
self.pointing_device.hid_pending = False
|
||||
self.pointing_device.report_x[0] = 0
|
||||
self.pointing_device.report_y[0] = 0
|
||||
self.pointing_device.report_w[0] = 0
|
||||
self.pointing_device.button_status[0] = 0
|
||||
|
||||
def _read_raw_state(self):
|
||||
'''Read up, down, left, right and switch data from trackball.'''
|
||||
left, right, up, down, switch = self._i2c_rdwr([REG_LEFT], 5)
|
||||
|
@@ -5,7 +5,7 @@ from supervisor import ticks_ms
|
||||
from time import sleep
|
||||
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import make_key
|
||||
from kmk.keys import KC, make_key
|
||||
from kmk.kmktime import check_deadline
|
||||
from kmk.modules import Module
|
||||
|
||||
@@ -20,16 +20,26 @@ class Power(Module):
|
||||
self._i2c = 0
|
||||
self._loopcounter = 0
|
||||
|
||||
make_key(
|
||||
names=('PS_TOG',), on_press=self._ps_tog, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('PS_ON',), on_press=self._ps_enable, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('PS_OFF',), on_press=self._ps_disable, on_release=handler_passthrough
|
||||
KC._generators.append(self.maybe_make_power_key())
|
||||
|
||||
def maybe_make_power_key(self):
|
||||
keys = (
|
||||
(('PS_TOG',), self._ps_tog),
|
||||
(('PS_ON',), self._ps_enable),
|
||||
(('PS_OFF',), self._ps_disable),
|
||||
)
|
||||
|
||||
def closure(candidate):
|
||||
for names, on_press in keys:
|
||||
if candidate in names:
|
||||
return make_key(
|
||||
names=names,
|
||||
on_press=on_press,
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
return closure
|
||||
|
||||
def __repr__(self):
|
||||
return f'Power({self._to_dict()})'
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from random import randint
|
||||
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
@@ -28,11 +28,13 @@ class RapidFire(Module):
|
||||
_waiting_keys = []
|
||||
|
||||
def __init__(self):
|
||||
make_argumented_key(
|
||||
validator=RapidFireMeta,
|
||||
names=('RF',),
|
||||
on_press=self._rf_pressed,
|
||||
on_release=self._rf_released,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
validator=RapidFireMeta,
|
||||
names=('RF',),
|
||||
on_press=self._rf_pressed,
|
||||
on_release=self._rf_released,
|
||||
)
|
||||
)
|
||||
|
||||
def _get_repeat(self, key):
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
@@ -12,11 +12,13 @@ class StickyMod(Module):
|
||||
def __init__(self):
|
||||
self._active = False
|
||||
self._active_key = None
|
||||
make_argumented_key(
|
||||
names=('SM',),
|
||||
validator=StickyModMeta,
|
||||
on_press=self.sm_pressed,
|
||||
on_release=self.sm_released,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
names=('SM',),
|
||||
validator=StickyModMeta,
|
||||
on_press=self.sm_pressed,
|
||||
on_release=self.sm_released,
|
||||
)
|
||||
)
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from kmk.keys import KC, make_argumented_key
|
||||
from kmk.keys import KC, maybe_make_argumented_key
|
||||
from kmk.modules.holdtap import ActivationType, HoldTap, HoldTapKeyMeta
|
||||
|
||||
|
||||
@@ -30,11 +30,13 @@ class TapDanceKeyMeta:
|
||||
class TapDance(HoldTap):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
make_argumented_key(
|
||||
validator=TapDanceKeyMeta,
|
||||
names=('TD',),
|
||||
on_press=self.td_pressed,
|
||||
on_release=self.td_released,
|
||||
KC._generators.append(
|
||||
maybe_make_argumented_key(
|
||||
validator=TapDanceKeyMeta,
|
||||
names=('TD',),
|
||||
on_press=self.td_pressed,
|
||||
on_release=self.td_released,
|
||||
)
|
||||
)
|
||||
|
||||
self.td_counts = {}
|
||||
|
@@ -1,39 +0,0 @@
|
||||
FROM python:3.9-slim-buster
|
||||
|
||||
ARG KMKPY_REF
|
||||
ARG KMKPY_URL
|
||||
|
||||
ENV KMKPY_REF ${KMKPY_REF}
|
||||
ENV KMKPY_URL ${KMKPY_URL}
|
||||
|
||||
RUN mkdir -p /app /dist
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y build-essential curl gettext git git-lfs rsync wget zip lbzip2
|
||||
RUN pip install pipenv
|
||||
|
||||
# Pull CircuitPython-designated ARM GCC to avoid mismatches/weird
|
||||
# inconsistencies with upstream
|
||||
RUN curl -L -o /tmp/gcc-arm.tar.bz2 https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 && \
|
||||
tar -C /usr --strip-components=1 -xaf /tmp/gcc-arm.tar.bz2 && \
|
||||
rm -rf /tmp/gcc-arm.tar.bz2
|
||||
|
||||
# Get a local copy of KMKPython and its dependencies. We don't provide MPY
|
||||
# builds for kmkpython anymore, so we can get away with being opinionated
|
||||
# here.
|
||||
RUN git init /opt/kmkpython && \
|
||||
git -C /opt/kmkpython remote add origin ${KMKPY_URL} && \
|
||||
git -C /opt/kmkpython fetch --depth 1 origin ${KMKPY_REF} && \
|
||||
git -C /opt/kmkpython checkout FETCH_HEAD && \
|
||||
git -C /opt/kmkpython submodule update --init --recursive
|
||||
|
||||
# Build the MPY compiler
|
||||
RUN make -C /opt/kmkpython/mpy-cross
|
||||
|
||||
ENV PATH=/opt/kmkpython/mpy-cross:${PATH}
|
||||
|
||||
RUN mkdir -p /opt/kmkpython/frozen/kmk/kmk
|
||||
COPY ./build_kmkpython_release.sh /app/
|
||||
COPY ./kmk /opt/kmkpython/frozen/kmk/kmk
|
||||
|
||||
CMD /app/build_kmkpython_release.sh
|
BIN
mpy-cross-7
BIN
mpy-cross-7
Binary file not shown.
BIN
mpy-cross-8
BIN
mpy-cross-8
Binary file not shown.
@@ -9,6 +9,9 @@ from tests.keyboard_test import KeyboardTest
|
||||
|
||||
|
||||
class TestHoldTap(unittest.TestCase):
|
||||
def setUp(self):
|
||||
KC.clear()
|
||||
|
||||
def test_holdtap(self):
|
||||
keyboard = KeyboardTest(
|
||||
[Layers(), ModTap(), OneShot()],
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import unittest
|
||||
|
||||
from kmk.keys import KC, Key, ModifierKey, make_key
|
||||
from kmk.keys import KC, Key, ModifierKey, make_key, maybe_make_key
|
||||
from tests.keyboard_test import KeyboardTest
|
||||
|
||||
|
||||
@@ -131,20 +131,14 @@ class TestKeys_dot(unittest.TestCase):
|
||||
KC.invalid_key
|
||||
|
||||
def test_custom_key(self):
|
||||
created = make_key(
|
||||
KC.N2.code,
|
||||
names=(
|
||||
'EURO',
|
||||
'€',
|
||||
),
|
||||
has_modifiers={KC.LSFT.code, KC.ROPT.code},
|
||||
KC._generators.append(
|
||||
maybe_make_key(
|
||||
KC.N2.code,
|
||||
names=('EURO', '€'),
|
||||
has_modifiers={KC.LSFT.code, KC.ROPT.code},
|
||||
)
|
||||
)
|
||||
assert created is KC.get('EURO')
|
||||
assert created is KC.get('€')
|
||||
|
||||
def test_match_exactly_case(self):
|
||||
created = make_key(names=('ThIs_Is_A_StRaNgE_kEy',))
|
||||
assert created is KC.get('ThIs_Is_A_StRaNgE_kEy')
|
||||
assert KC.get('€') is KC.get('EURO')
|
||||
|
||||
|
||||
class TestKeys_index(unittest.TestCase):
|
||||
@@ -176,20 +170,14 @@ class TestKeys_index(unittest.TestCase):
|
||||
KC['not_a_valid_key']
|
||||
|
||||
def test_custom_key(self):
|
||||
created = make_key(
|
||||
KC['N2'].code,
|
||||
names=(
|
||||
'EURO',
|
||||
'€',
|
||||
),
|
||||
has_modifiers={KC['LSFT'].code, KC['ROPT'].code},
|
||||
KC._generators.append(
|
||||
maybe_make_key(
|
||||
KC.N2.code,
|
||||
names=('EURO', '€'),
|
||||
has_modifiers={KC.LSFT.code, KC.ROPT.code},
|
||||
)
|
||||
)
|
||||
assert created is KC['EURO']
|
||||
assert created is KC['€']
|
||||
|
||||
def test_match_exactly_case(self):
|
||||
created = make_key(names=('ThIs_Is_A_StRaNgE_kEy',))
|
||||
assert created is KC['ThIs_Is_A_StRaNgE_kEy']
|
||||
assert KC.get('€') is KC.get('EURO')
|
||||
|
||||
|
||||
class TestKeys_get(unittest.TestCase):
|
||||
@@ -224,20 +212,14 @@ class TestKeys_get(unittest.TestCase):
|
||||
assert KC.get('not_a_valid_key') is None
|
||||
|
||||
def test_custom_key(self):
|
||||
created = make_key(
|
||||
KC.get('N2').code,
|
||||
names=(
|
||||
'EURO',
|
||||
'€',
|
||||
),
|
||||
has_modifiers={KC.get('LSFT').code, KC.get('ROPT').code},
|
||||
KC._generators.append(
|
||||
maybe_make_key(
|
||||
KC.N2.code,
|
||||
names=('EURO', '€'),
|
||||
has_modifiers={KC.LSFT.code, KC.ROPT.code},
|
||||
)
|
||||
)
|
||||
assert created is KC.get('EURO')
|
||||
assert created is KC.get('€')
|
||||
|
||||
def test_match_exactly_case(self):
|
||||
created = make_key(names=('ThIs_Is_A_StRaNgE_kEy',))
|
||||
assert created is KC.get('ThIs_Is_A_StRaNgE_kEy')
|
||||
assert KC.get('€') is KC.get('EURO')
|
||||
|
||||
def test_underscore(self):
|
||||
assert KC.get('_')
|
||||
@@ -251,8 +233,8 @@ class TestKeys_instances(unittest.TestCase):
|
||||
KC.clear()
|
||||
|
||||
def test_make_key_new_instance(self):
|
||||
key1 = make_key(code=1)
|
||||
key2 = make_key(code=1)
|
||||
key1, _ = make_key(code=1)
|
||||
key2, _ = make_key(code=1)
|
||||
assert key1 is not key2
|
||||
assert key1.code == key2.code
|
||||
|
||||
|
@@ -7,6 +7,7 @@ from tests.keyboard_test import KeyboardTest
|
||||
|
||||
class TestLayers(unittest.TestCase):
|
||||
def setUp(self):
|
||||
KC.clear()
|
||||
self.kb = KeyboardTest(
|
||||
[Layers()],
|
||||
[
|
||||
|
@@ -9,6 +9,7 @@ from tests.keyboard_test import KeyboardTest
|
||||
|
||||
class TestTapDance(unittest.TestCase):
|
||||
def setUp(self):
|
||||
KC.clear()
|
||||
self.keyboard = KeyboardTest(
|
||||
[Layers(), HoldTap(), TapDance()],
|
||||
[
|
||||
|
Reference in New Issue
Block a user