Merge pull request #139 from KMKfw/topic-try-black

Enforce the Black autoformatter and code style
This commit is contained in:
Josh Klar 2019-07-24 23:19:28 -07:00 committed by GitHub
commit 5a43bc291d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 286 additions and 227 deletions

View File

@ -89,8 +89,12 @@ docker-base-deploy: docker-base
devdeps: .devdeps
lint: devdeps
@$(PIPENV) run black --check
@$(PIPENV) run flake8
fix-formatting: devdeps
@$(PIPENV) run black .
fix-isort: devdeps
@find kmk/ tests/ user_keymaps/ -name "*.py" | xargs $(PIPENV) run isort

View File

@ -18,6 +18,8 @@ ipython = "*"
isort = "*"
neovim = "*"
s3cmd = "*"
black = "==19.3b0"
flake8-quotes = "*"
[requires]
python_version = "3.7"

38
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "8f51706fcfb278497a6d3083109744210150dc3c644ead11eda3e3cd806e2e14"
"sha256": "019b67ce05e7e68766ba54ddbfd3e2faf5dd81c7ded79f80ff3ef85b0017c99d"
},
"pipfile-spec": 6,
"requires": {
@ -25,6 +25,20 @@
"index": "pypi",
"version": "==1.0.7"
},
"appdirs": {
"hashes": [
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
],
"version": "==1.4.3"
},
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"backcall": {
"hashes": [
"sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4",
@ -32,6 +46,14 @@
],
"version": "==0.1.0"
},
"black": {
"hashes": [
"sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf",
"sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"
],
"index": "pypi",
"version": "==19.3b0"
},
"click": {
"hashes": [
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
@ -86,6 +108,13 @@
"index": "pypi",
"version": "==0.8.1"
},
"flake8-quotes": {
"hashes": [
"sha256:10c9af6b472d4302a8e721c5260856c3f985c5c082b04841aefd2f808ac02038"
],
"index": "pypi",
"version": "==2.0.1"
},
"greenlet": {
"hashes": [
"sha256:000546ad01e6389e98626c1367be58efa613fa82a1be98b0c6fc24b563acc6d0",
@ -304,6 +333,13 @@
],
"version": "==6.10.0"
},
"toml": {
"hashes": [
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
],
"version": "==0.10.0"
},
"traitlets": {
"hashes": [
"sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835",

View File

@ -120,6 +120,17 @@ below (we'll try to keep this up to date!):
> their help has been crucial to KMK's success, KMK is not an official Adafruit
> project, and the Core team is not compensated by Adafruit for its development.
## Code Style
KMK uses [Black](https://github.com/psf/black) with a Python 3.6 target and,
[(controversially?)](https://github.com/psf/black/issues/594) single quotes.
Further code styling is enforced with isort and flake8 with several plugins.
`make fix-isort fix-formatting` before a commit is a good idea, and CI will fail
if inbound code does not adhere to these formatting rules. Some exceptions are
found in `setup.cfg` loosening the rules in isolated cases, notably
`user_keymaps` (which is *also* not subject to Black formatting for reasons
documented in `pyproject.toml`).
## License, Copyright, and Legal
All software in this repository is licensed under the [GNU Public License,

View File

@ -7,14 +7,7 @@ from kmk.util import intify_coordinate as ic
# board, by flipping various row3 (bottom physical row) keys so their
# coord_mapping matches what the user pressed (even if the wiring
# underneath is sending different coordinates)
_r3_swap_conversions = {
3: 9,
4: 10,
5: 11,
9: 3,
10: 4,
11: 5,
}
_r3_swap_conversions = {3: 9, 4: 10, 5: 11, 9: 3, 10: 4, 11: 5}
def r3_swap(col):

View File

@ -2,13 +2,17 @@ from kmk.kmktime import ticks_diff, ticks_ms
def df_pressed(key, state, *args, **kwargs):
"""Switches the default layer"""
'''
Switches the default layer
'''
state.active_layers[-1] = key.meta.layer
return state
def mo_pressed(key, state, *args, **kwargs):
"""Momentarily activates layer, switches off when you let go"""
'''
Momentarily activates layer, switches off when you let go
'''
state.active_layers.insert(0, key.meta.layer)
return state
@ -32,7 +36,9 @@ def mo_released(key, state, KC, *args, **kwargs):
def lm_pressed(key, state, *args, **kwargs):
"""As MO(layer) but with mod active"""
'''
As MO(layer) but with mod active
'''
state.hid_pending = True
# Sets the timer start and acts like MO otherwise
state.start_time['lm'] = ticks_ms()
@ -41,7 +47,9 @@ def lm_pressed(key, state, *args, **kwargs):
def lm_released(key, state, *args, **kwargs):
"""As MO(layer) but with mod active"""
'''
As MO(layer) but with mod active
'''
state.hid_pending = True
state.keys_pressed.discard(key.meta.kc)
state.start_time['lm'] = None
@ -68,8 +76,9 @@ def lt_released(key, state, *args, **kwargs):
def tg_pressed(key, state, *args, **kwargs):
"""Toggles the layer (enables it if not active, and vise versa)"""
'''
Toggles the layer (enables it if not active, and vise versa)
'''
# See mo_released for implementation details around this
try:
del_idx = state.active_layers.index(key.meta.layer)
@ -81,7 +90,9 @@ def tg_pressed(key, state, *args, **kwargs):
def to_pressed(key, state, *args, **kwargs):
"""Activates layer and deactivates all other layers"""
'''
Activates layer and deactivates all other layers
'''
state.active_layers.clear()
state.active_layers.insert(0, key.meta.layer)
@ -89,7 +100,9 @@ def to_pressed(key, state, *args, **kwargs):
def tt_pressed(key, state, *args, **kwargs):
"""Momentarily activates layer if held, toggles it if tapped repeatedly"""
'''
Momentarily activates layer if held, toggles it if tapped repeatedly
'''
# TODO Make this work with tap dance to function more correctly, but technically works.
if state.start_time['tt'] is None:
# Sets the timer start and acts like MO otherwise
@ -101,7 +114,9 @@ def tt_pressed(key, state, *args, **kwargs):
def tt_released(key, state, *args, **kwargs):
tap_timed_out = ticks_diff(ticks_ms(), state.start_time['tt']) >= state.config.tap_time
tap_timed_out = (
ticks_diff(ticks_ms(), state.start_time['tt']) >= state.config.tap_time
)
if state.start_time['tt'] is None or tap_timed_out:
# On first press, works like MO. On second press, does nothing unless let up within
# time window, then acts like TG.

View File

@ -14,7 +14,7 @@ def mt_released(key, state, *args, **kwargs):
state.keys_pressed.discard(key.meta.mods)
timer_name = 'mod_tap'
if state.start_time[timer_name] and (
ticks_diff(ticks_ms(), state.start_time[timer_name]) < state.config.tap_time
ticks_diff(ticks_ms(), state.start_time[timer_name]) < state.config.tap_time
):
state.hid_pending = True
state.tap_key(key.meta.kc)

View File

@ -64,10 +64,7 @@ def unicode_string_sequence(unistring):
Allows sending things like (°° directly, without
manual conversion to Unicode codepoints.
'''
return unicode_codepoint_sequence([
hex(get_wide_ordinal(s))[2:]
for s in unistring
])
return unicode_codepoint_sequence([hex(get_wide_ordinal(s))[2:] for s in unistring])
def generate_codepoint_keysym_seq(codepoint, expected_length=4):
@ -95,31 +92,22 @@ def generate_leader_dictionary_seq(string):
def unicode_codepoint_sequence(codepoints):
kc_seqs = (
generate_codepoint_keysym_seq(codepoint)
for codepoint in codepoints
)
kc_seqs = (generate_codepoint_keysym_seq(codepoint) for codepoint in codepoints)
kc_macros = [
simple_key_sequence(kc_seq)
for kc_seq in kc_seqs
]
kc_macros = [simple_key_sequence(kc_seq) for kc_seq in kc_seqs]
def _unicode_sequence(key, state, *args, **kwargs):
if state.config.unicode_mode == UnicodeMode.IBUS:
state.process_key(
simple_key_sequence(_ibus_unicode_sequence(kc_macros, state)),
True,
simple_key_sequence(_ibus_unicode_sequence(kc_macros, state)), True
)
elif state.config.unicode_mode == UnicodeMode.RALT:
state.process_key(
simple_key_sequence(_ralt_unicode_sequence(kc_macros, state)),
True,
simple_key_sequence(_ralt_unicode_sequence(kc_macros, state)), True
)
elif state.config.unicode_mode == UnicodeMode.WINC:
state.process_key(
simple_key_sequence(_winc_unicode_sequence(kc_macros, state)),
True,
simple_key_sequence(_winc_unicode_sequence(kc_macros, state)), True
)
return make_key(on_press=_unicode_sequence)

View File

@ -22,10 +22,7 @@ class USB_HID:
self.post_init()
def __repr__(self):
return '{}(REPORT_BYTES={})'.format(
self.__class__.__name__,
self.REPORT_BYTES,
)
return '{}(REPORT_BYTES={})'.format(self.__class__.__name__, self.REPORT_BYTES)
def post_init(self):
pass
@ -157,10 +154,12 @@ class USB_HID:
try:
import usb_hid
PLATFORM_CIRCUITPYTHON = True
except ImportError:
PLATFORM_CIRCUITPYTHON = False
else:
class CircuitPythonUSB_HID(USB_HID):
REPORT_BYTES = 9
@ -192,5 +191,5 @@ else:
reporting_device_const = self.report_device[0]
return self.devices[reporting_device_const].send_report(
evt[1:HID_REPORT_SIZES[reporting_device_const] + 1],
evt[1 : HID_REPORT_SIZES[reporting_device_const] + 1]
)

View File

@ -18,13 +18,7 @@ class InternalState:
# overhead (the underlying list was never used anyway)
active_layers = [0]
start_time = {
'lt': None,
'tg': None,
'tt': None,
'lm': None,
'leader': None,
}
start_time = {'lt': None, 'tg': None, 'tt': None, 'lm': None, 'leader': None}
timeouts = {}
tapping = False
tap_dance_counts = {}
@ -72,11 +66,7 @@ class InternalState:
except ValueError:
if self.config.debug_enabled:
print(
'CoordMappingNotFound(ic={}, row={}, col={})'.format(
ic,
row,
col,
),
'CoordMappingNotFound(ic={}, row={}, col={})'.format(ic, row, col)
)
return None
@ -128,11 +118,7 @@ class InternalState:
def matrix_changed(self, row, col, is_pressed):
if self.config.debug_enabled:
print('MatrixChange(col={} row={} pressed={})'.format(
col,
row,
is_pressed,
))
print('MatrixChange(col={} row={} pressed={})'.format(col, row, is_pressed))
int_coord = intify_coordinate(row, col)
kc_changed = self._find_key_in_map(row, col)
@ -189,10 +175,13 @@ class InternalState:
return self
if (
changed_key not in self.tap_dance_counts or not self.tap_dance_counts[changed_key]
changed_key not in self.tap_dance_counts
or not self.tap_dance_counts[changed_key]
):
self.tap_dance_counts[changed_key] = 1
self.set_timeout(self.config.tap_time, lambda: self._end_tap_dance(changed_key))
self.set_timeout(
self.config.tap_time, lambda: self._end_tap_dance(changed_key)
)
self.tapping = True
else:
self.tap_dance_counts[changed_key] += 1
@ -201,7 +190,9 @@ class InternalState:
self.tap_side_effects[changed_key] = None
else:
has_side_effects = self.tap_side_effects[changed_key] is not None
hit_max_defined_taps = self.tap_dance_counts[changed_key] == len(changed_key.codes)
hit_max_defined_taps = self.tap_dance_counts[changed_key] == len(
changed_key.codes
)
if has_side_effects or hit_max_defined_taps:
self._end_tap_dance(changed_key)
@ -241,7 +232,9 @@ class InternalState:
self.config.leader_mode += 1
if self.config.leader_mode == LeaderMode.TIMEOUT_ACTIVE:
self.set_timeout(self.config.leader_timeout, self._handle_leader_sequence)
self.set_timeout(
self.config.leader_timeout, self._handle_leader_sequence
)
return self
@ -256,8 +249,7 @@ class InternalState:
self.process_key(self.config.leader_dictionary[lmh], True)
self.set_timeout(
False,
lambda: self.remove_key(self.config.leader_dictionary[lmh]),
False, lambda: self.remove_key(self.config.leader_dictionary[lmh])
)
return self
@ -273,9 +265,7 @@ class InternalState:
self.leader_last_len = len(self.keys_pressed)
for key in keys_pressed:
if (
self.config.leader_mode == LeaderMode.ENTER_ACTIVE and key == KC.ENT
):
if self.config.leader_mode == LeaderMode.ENTER_ACTIVE and key == KC.ENT:
self._handle_leader_sequence()
break
elif key == KC.ESC or key == KC.GESC:

View File

@ -1,5 +1,10 @@
from kmk.types import (KeySeqSleepMeta, LayerKeyMeta, ModTapKeyMeta,
TapDanceKeyMeta, UnicodeModeKeyMeta)
from kmk.types import (
KeySeqSleepMeta,
LayerKeyMeta,
ModTapKeyMeta,
TapDanceKeyMeta,
UnicodeModeKeyMeta,
)
def key_seq_sleep_validator(ms):

View File

@ -156,12 +156,11 @@ class KeyboardConfig:
print(self)
print(self._state)
print('GCStats(pre_alloc={} pre_free={} alloc={} free={})'.format(
pre_alloc,
pre_free,
gc.mem_alloc(),
gc.mem_free(),
))
print(
'GCStats(pre_alloc={} pre_free={} alloc={} free={})'.format(
pre_alloc, pre_free, gc.mem_alloc(), gc.mem_free()
)
)
def _send_hid(self):
self._hid_helper_inst.create_report(self._state.keys_pressed).send()
@ -183,11 +182,7 @@ class KeyboardConfig:
'''
if update is not None:
self._state.matrix_changed(
update[0],
update[1],
update[2],
)
self._state.matrix_changed(update[0], update[1], update[2])
def _send_to_master(self, update):
if self.split_master_left:
@ -202,6 +197,7 @@ class KeyboardConfig:
if self.uart.in_waiting >= 60:
# This is a dirty hack to prevent crashes in unrealistic cases
import microcontroller
microcontroller.reset()
while self.uart.in_waiting >= 3:
@ -274,10 +270,9 @@ class KeyboardConfig:
if self.split_flip and not self.is_master:
self.col_pins = list(reversed(self.col_pins))
if self.split_side == "Left":
if self.split_side == 'Left':
self.split_master_left = self.is_master
elif self.split_side == "Right":
elif self.split_side == 'Right':
self.split_master_left = not self.is_master
else:
self.is_master = True

View File

@ -4,9 +4,13 @@ import kmk.handlers.layers as layers
import kmk.handlers.modtap as modtap
import kmk.handlers.stock as handlers
from kmk.consts import UnicodeMode
from kmk.key_validators import (key_seq_sleep_validator, layer_key_validator,
mod_tap_validator, tap_dance_key_validator,
unicode_mode_key_validator)
from kmk.key_validators import (
key_seq_sleep_validator,
layer_key_validator,
mod_tap_validator,
tap_dance_key_validator,
unicode_mode_key_validator,
)
from kmk.types import AttrDict, UnicodeModeKeyMeta
FIRST_KMK_INTERNAL_KEY = 1000
@ -231,16 +235,14 @@ class ModifierKey(Key):
if modified_code.has_modifiers:
new_keycode.has_modifiers |= modified_code.has_modifiers
else:
new_keycode = Key(
self.code,
no_press=no_press,
no_release=no_release,
)
new_keycode = Key(self.code, no_press=no_press, no_release=no_release)
return new_keycode
def __repr__(self):
return 'ModifierKey(code={}, has_modifiers={})'.format(self.code, self.has_modifiers)
return 'ModifierKey(code={}, has_modifiers={})'.format(
self.code, self.has_modifiers
)
class ConsumerKey(Key):
@ -268,12 +270,7 @@ def register_key_names(key, names=tuple()): # NOQA
return key
def make_key(
code=None,
names=tuple(), # NOQA
type=KEY_SIMPLE,
**kwargs,
):
def make_key(code=None, names=tuple(), type=KEY_SIMPLE, **kwargs): # NOQA
'''
Create a new key, aliased by `names` in the KC lookup table.
@ -348,10 +345,7 @@ def make_argumented_key(
if meta:
key = Key(
NEXT_AVAILABLE_KEY,
meta=meta,
*constructor_args,
**constructor_kwargs,
NEXT_AVAILABLE_KEY, meta=meta, *constructor_args, **constructor_kwargs
)
NEXT_AVAILABLE_KEY += 1
@ -361,8 +355,8 @@ def make_argumented_key(
else:
raise ValueError(
'Argumented key validator failed for unknown reasons. '
'This may not be the keymap\'s fault, as a more specific error '
'should have been raised.',
"This may not be the keymap's fault, as a more specific error "
'should have been raised.'
)
for name in names:
@ -439,7 +433,7 @@ make_key(code=47, names=('LBRACKET', 'LBRC', '['))
make_key(code=48, names=('RBRACKET', 'RBRC', ']'))
make_key(code=49, names=('BACKSLASH', 'BSLASH', 'BSLS', '\\'))
make_key(code=51, names=('SEMICOLON', 'SCOLON', 'SCLN', ';'))
make_key(code=52, names=('QUOTE', 'QUOT', '\''))
make_key(code=52, names=('QUOTE', 'QUOT', "'"))
make_key(code=53, names=('GRAVE', 'GRV', 'ZKHK', '`'))
make_key(code=54, names=('COMMA', 'COMM', ','))
make_key(code=55, names=('DOT', '.'))
@ -539,7 +533,7 @@ make_shifted_key('LBRACKET', names=('LEFT_CURLY_BRACE', 'LCBR', '{'))
make_shifted_key('RBRACKET', names=('RIGHT_CURLY_BRACE', 'RCBR', '}'))
make_shifted_key('BACKSLASH', names=('PIPE', '|'))
make_shifted_key('SEMICOLON', names=('COLON', 'COLN', ':'))
make_shifted_key('QUOTE', names=('DOUBLE_QUOTE', 'DQUO', 'DQT', '\''))
make_shifted_key('QUOTE', names=('DOUBLE_QUOTE', 'DQUO', 'DQT', '"'))
make_shifted_key('COMMA', names=('LEFT_ANGLE_BRACKET', 'LABK', '<'))
make_shifted_key('DOT', names=('RIGHT_ANGLE_BRACKET', 'RABK', '>'))
make_shifted_key('SLSH', names=('QUESTION', 'QUES', '?'))
@ -584,7 +578,9 @@ make_consumer_key(code=234, names=('AUDIO_VOL_DOWN', 'VOLD')) # 0xEA
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=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
@ -596,19 +592,28 @@ make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
# two keys with the exact same functionality
for names in (('NO',), ('TRANSPARENT', 'TRNS')):
make_key(
names=names,
on_press=handlers.passthrough,
on_release=handlers.passthrough,
names=names, on_press=handlers.passthrough, on_release=handlers.passthrough
)
make_key(names=('RESET',), on_press=handlers.reset)
make_key(names=('BOOTLOADER',), on_press=handlers.bootloader)
make_key(names=('DEBUG', 'DBG'), on_press=handlers.debug_pressed, on_release=handlers.passthrough)
make_key(
names=('DEBUG', 'DBG'),
on_press=handlers.debug_pressed,
on_release=handlers.passthrough,
)
make_key(names=('GESC',), on_press=handlers.gesc_pressed, on_release=handlers.gesc_released)
make_key(names=('BKDL',), on_press=handlers.bkdl_pressed, on_release=handlers.bkdl_released)
make_key(names=('GESC', 'GRAVE_ESC'), on_press=handlers.gesc_pressed,
on_release=handlers.gesc_released)
make_key(
names=('GESC',), on_press=handlers.gesc_pressed, on_release=handlers.gesc_released
)
make_key(
names=('BKDL',), on_press=handlers.bkdl_pressed, on_release=handlers.bkdl_released
)
make_key(
names=('GESC', 'GRAVE_ESC'),
on_press=handlers.gesc_pressed,
on_release=handlers.gesc_released,
)
make_key(names=('RGB_TOG',), on_press=handlers.rgb_tog)
make_key(names=('RGB_HUI',), on_press=handlers.rgb_hui)
make_key(names=('RGB_HUD',), on_press=handlers.rgb_hud)
@ -621,8 +626,10 @@ make_key(names=('RGB_AND',), on_press=handlers.rgb_and)
make_key(names=('RGB_MODE_PLAIN', 'RGB_M_P'), on_press=handlers.rgb_mode_static)
make_key(names=('RGB_MODE_BREATHE', 'RGB_M_B'), on_press=handlers.rgb_mode_breathe)
make_key(names=('RGB_MODE_RAINBOW', 'RGB_M_R'), on_press=handlers.rgb_mode_rainbow)
make_key(names=('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'),
on_press=handlers.rgb_mode_breathe_rainbow)
make_key(
names=('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'),
on_press=handlers.rgb_mode_breathe_rainbow,
)
make_key(names=('RGB_MODE_SWIRL', 'RGB_M_S'), on_press=handlers.rgb_mode_swirl)
make_key(names=('RGB_MODE_KNIGHT', 'RGB_M_K'), on_press=handlers.rgb_mode_knight)
@ -650,9 +657,7 @@ make_argumented_key(
on_release=layers.mo_released,
)
make_argumented_key(
validator=layer_key_validator,
names=('DF',),
on_press=layers.df_pressed,
validator=layer_key_validator, names=('DF',), on_press=layers.df_pressed
)
make_argumented_key(
validator=layer_key_validator,
@ -667,14 +672,10 @@ make_argumented_key(
on_release=layers.lt_released,
)
make_argumented_key(
validator=layer_key_validator,
names=('TG',),
on_press=layers.tg_pressed,
validator=layer_key_validator, names=('TG',), on_press=layers.tg_pressed
)
make_argumented_key(
validator=layer_key_validator,
names=('TO',),
on_press=layers.to_pressed,
validator=layer_key_validator, names=('TO',), on_press=layers.to_pressed
)
make_argumented_key(
validator=layer_key_validator,

View File

@ -35,7 +35,7 @@ class led:
self.animation_mode = const(config['animation_mode'])
self.animation_speed = const(config['animation_speed'])
self.breathe_center = const(config['breathe_center'])
if config['user_animation']:
if config.get('user_animation'):
self.user_animation = config['user_animation']
def __repr__(self):
@ -88,20 +88,20 @@ class led:
self.set_brightness(0)
def increase_ani(self):
"""
'''
Increases animation speed by 1 amount stopping at 10
:param step:
"""
'''
if (self.animation_speed + 1) >= 10:
self.animation_speed = 10
else:
self.val += 1
def decrease_ani(self):
"""
'''
Decreases animation speed by 1 amount stopping at 0
:param step:
"""
'''
if (self.val - 1) <= 0:
self.val = 0
else:
@ -127,10 +127,10 @@ class led:
return self
def animate(self):
"""
'''
Activates a "step" in the animation based on the active mode
:return: Returns the new state in animation
"""
'''
if self.effect_init:
self._init_effect()
if self.enabled:

View File

@ -5,7 +5,9 @@ from kmk.consts import DiodeOrientation
class MatrixScanner:
def __init__(
self, cols, rows,
self,
cols,
rows,
diode_orientation=DiodeOrientation.COLUMNS,
rollover_cols_every_rows=None,
):
@ -33,9 +35,9 @@ class MatrixScanner:
self.inputs = self.cols
self.translate_coords = False
else:
raise ValueError('Invalid DiodeOrientation: {}'.format(
self.diode_orientation,
))
raise ValueError(
'Invalid DiodeOrientation: {}'.format(self.diode_orientation)
)
for pin in self.outputs:
pin.switch_to_output()
@ -81,7 +83,9 @@ class MatrixScanner:
if old_val != new_val:
if self.translate_coords:
new_oidx = oidx + self.len_cols * (iidx // self.rollover_cols_every_rows)
new_oidx = oidx + self.len_cols * (
iidx // self.rollover_cols_every_rows
)
new_iidx = iidx - self.rollover_cols_every_rows * (
iidx // self.rollover_cols_every_rows
)

View File

@ -51,10 +51,13 @@ class RGB:
def __init__(self, config, pixel_pin):
try:
import neopixel
self.neopixel = neopixel.NeoPixel(pixel_pin,
config['num_pixels'],
pixel_order=config['rgb_order'],
auto_write=False)
self.neopixel = neopixel.NeoPixel(
pixel_pin,
config['num_pixels'],
pixel_order=config['rgb_order'],
auto_write=False,
)
if len(config['rgb_order']) == 4:
self.rgbw = True
self.num_pixels = const(config['num_pixels'])
@ -97,13 +100,13 @@ class RGB:
return int(time.monotonic() * 1000)
def hsv_to_rgb(self, hue, sat, val):
"""
'''
Converts HSV values, and returns a tuple of RGB values
:param hue:
:param sat:
:param val:
:return: (r, g, b)
"""
'''
r = 0
g = 0
b = 0
@ -149,24 +152,24 @@ class RGB:
return int(r), int(g), int(b)
def hsv_to_rgbw(self, hue, sat, val):
"""
'''
Converts HSV values, and returns a tuple of RGBW values
:param hue:
:param sat:
:param val:
:return: (r, g, b, w)
"""
'''
rgb = self.hsv_to_rgb(hue, sat, val)
return rgb[0], rgb[1], rgb[2], min(rgb)
def set_hsv(self, hue, sat, val, index):
"""
'''
Takes HSV values and displays it on a single LED/Neopixel
:param hue:
:param sat:
:param val:
:param index: Index of LED/Pixel
"""
'''
if self.neopixel:
if self.rgbw:
self.set_rgb(self.hsv_to_rgbw(hue, sat, val), index)
@ -176,12 +179,12 @@ class RGB:
return self
def set_hsv_fill(self, hue, sat, val):
"""
'''
Takes HSV values and displays it on all LEDs/Neopixels
:param hue:
:param sat:
:param val:
"""
'''
if self.neopixel:
if self.rgbw:
self.set_rgb_fill(self.hsv_to_rgbw(hue, sat, val))
@ -190,11 +193,11 @@ class RGB:
return self
def set_rgb(self, rgb, index):
"""
'''
Takes an RGB or RGBW and displays it on a single LED/Neopixel
:param rgb: RGB or RGBW
:param index: Index of LED/Pixel
"""
'''
if self.neopixel and 0 <= index <= self.num_pixels - 1:
self.neopixel[index] = rgb
if not self.disable_auto_write:
@ -203,10 +206,10 @@ class RGB:
return self
def set_rgb_fill(self, rgb):
"""
'''
Takes an RGB or RGBW and displays it on all LEDs/Neopixels
:param rgb: RGB or RGBW
"""
'''
if self.neopixel:
self.neopixel.fill(rgb)
if not self.disable_auto_write:
@ -215,10 +218,10 @@ class RGB:
return self
def increase_hue(self, step=None):
"""
'''
Increases hue by step amount rolling at 360 and returning to 0
:param step:
"""
'''
if not step:
step = self.hue_step
@ -230,10 +233,10 @@ class RGB:
return self
def decrease_hue(self, step=None):
"""
'''
Decreases hue by step amount rolling at 0 and returning to 360
:param step:
"""
'''
if not step:
step = self.hue_step
@ -248,10 +251,10 @@ class RGB:
return self
def increase_sat(self, step=None):
"""
'''
Increases saturation by step amount stopping at 100
:param step:
"""
'''
if not step:
step = self.sat_step
@ -266,10 +269,10 @@ class RGB:
return self
def decrease_sat(self, step=None):
"""
'''
Decreases saturation by step amount stopping at 0
:param step:
"""
'''
if not step:
step = self.sat_step
@ -284,10 +287,10 @@ class RGB:
return self
def increase_val(self, step=None):
"""
'''
Increases value by step amount stopping at 100
:param step:
"""
'''
if not step:
step = self.val_step
if (self.val + step) >= 100:
@ -301,10 +304,10 @@ class RGB:
return self
def decrease_val(self, step=None):
"""
'''
Decreases value by step amount stopping at 0
:param step:
"""
'''
if not step:
step = self.val_step
if (self.val - step) <= 0:
@ -318,20 +321,20 @@ class RGB:
return self
def increase_ani(self):
"""
'''
Increases animation speed by 1 amount stopping at 10
:param step:
"""
'''
if (self.animation_speed + 1) >= 10:
self.animation_speed = 10
else:
self.val += 1
def decrease_ani(self):
"""
'''
Decreases animation speed by 1 amount stopping at 0
:param step:
"""
'''
if (self.val - 1) <= 0:
self.val = 0
else:
@ -340,28 +343,28 @@ class RGB:
return self
def off(self):
"""
'''
Turns off all LEDs/Neopixels without changing stored values
"""
'''
if self.neopixel:
self.set_hsv_fill(0, 0, 0)
return self
def show(self):
"""
'''
Turns on all LEDs/Neopixels without changing stored values
"""
'''
if self.neopixel:
self.neopixel.show()
return self
def animate(self):
"""
'''
Activates a "step" in the animation based on the active mode
:return: Returns the new state in animation
"""
'''
if self.effect_init:
self._init_effect()
@ -398,7 +401,10 @@ class RGB:
return False
def _init_effect(self):
if self.animation_mode == 'breathing' or self.animation_mode == 'breathing_rainbow':
if (
self.animation_mode == 'breathing'
or self.animation_mode == 'breathing_rainbow'
):
self.intervals = (30, 20, 10, 5)
elif self.animation_mode == 'swirl':
self.intervals = (50, 50)
@ -451,10 +457,8 @@ class RGB:
self.disable_auto_write = True # Turn off instantly showing
for i in range(0, self.num_pixels):
self.set_hsv(
(self.hue - (i * self.num_pixels)) % 360,
self.sat,
self.val,
i)
(self.hue - (i * self.num_pixels)) % 360, self.sat, self.val, i
)
# Show final results
self.disable_auto_write = False # Resume showing changes

View File

@ -6,6 +6,7 @@ class AttrDict(dict):
This is read-only on purpose.
'''
def __getattr__(self, key):
return self[key]
@ -14,6 +15,7 @@ class Anything:
'''
A stub class which will repr as a provided name
'''
def __init__(self, name):
self.name = name

View File

@ -24,19 +24,23 @@ def flatten_dict(d):
def reset_keyboard():
try:
import machine
machine.reset()
except ImportError:
import microcontroller
microcontroller.reset()
def reset_bootloader():
try:
import machine
machine.bootloader()
except ImportError:
import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()

22
pyproject.toml Normal file
View File

@ -0,0 +1,22 @@
[tool.black]
# since black refuses to allow single-quotes... see locked conversation at
# https://github.com/psf/black/issues/594
skip-string-normalization = true
target = "py36"
# explicitly exculde user_keymaps from black formatting rules
# because a visually-appealing keymap list will be flattened
# by black into a much harder to understand format
exclude = '''
/(
\.git
| \.mypy_cache
| \.tox
| \.venv
| \.pytest_cache
| \.compiled
| dist
| build
| docs
| user_keymaps
)/
'''

View File

@ -1,6 +1,13 @@
[flake8]
exclude = .git,__pycache__,vendor,.venv,build
max_line_length = 99
# match black expectations
max_line_length = 88
# enforce single quotes
select = Q0
docstring-quotes = '''
multiline-quotes = '''
ignore = X100, E262
per-file-ignores =
# Allow crazy line lengths, unused variables, and multiple spaces after commas in lists (for grid alignment)
@ -11,3 +18,8 @@ per-file-ignores =
[isort]
known_third_party = analogio,bitbangio,bleio,board,busio,digitalio,framebuf,gamepad,gc,microcontroller,micropython,pulseio,pyb,pydux,uio,ubluepy,machine,pyb,uos
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88

View File

@ -16,14 +16,6 @@ keymap = [
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[
[KC.TRNS, KC.B, KC.C],
[KC.NO, KC.D, KC.E],
[KC.F, KC.G, KC.H],
],
[
[KC.X, KC.Y, KC.Z],
[KC.TRNS, KC.N, KC.O],
[KC.R, KC.P, KC.Q],
],
[[KC.TRNS, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -16,14 +16,6 @@ keymap = [
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[
[KC.TRNS, KC.B, KC.C],
[KC.NO, KC.D, KC.E],
[KC.F, KC.G, KC.H],
],
[
[KC.X, KC.Y, KC.Z],
[KC.TRNS, KC.N, KC.O],
[KC.R, KC.P, KC.Q],
],
[[KC.TRNS, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -16,14 +16,6 @@ keymap = [
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[
[KC.A, KC.B, KC.C],
[KC.NO, KC.D, KC.E],
[KC.F, KC.G, KC.H],
],
[
[KC.X, KC.Y, KC.Z],
[KC.TRNS, KC.N, KC.O],
[KC.R, KC.P, KC.Q],
],
[[KC.A, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -16,14 +16,6 @@ keymap = [
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[
[KC.TRNS, KC.B, KC.C],
[KC.NO, KC.D, KC.E],
[KC.F, KC.G, KC.H],
],
[
[KC.X, KC.Y, KC.Z],
[KC.TRNS, KC.N, KC.O],
[KC.R, KC.P, KC.Q],
],
[[KC.TRNS, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -70,7 +70,7 @@ keyboard.leader_dictionary = {
'yay': emoticons.YAY,
}
WPM = send_string("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.")
WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.')
# ---------------------- Keymap ---------------------------------------------------------

View File

@ -43,7 +43,7 @@ keyboard.leader_dictionary = {
'yay': emoticons.YAY,
}
WPM = send_string("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.")
WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.')
# ---------------------- Keymap ---------------------------------------------------------

View File

@ -41,7 +41,7 @@ emoticons = cuss({
'TABLE_FLIP': r'(╯°□°)╯︵ ┻━┻',
})
WPM = send_string("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.")
WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.')
keyboard.leader_mode = LeaderMode.ENTER
keyboard.leader_dictionary = {

View File

@ -40,7 +40,7 @@ emoticons = cuss({
'TABLE_FLIP': r'(╯°□°)╯︵ ┻━┻',
})
WPM = send_string("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.")
WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.')
keyboard.leader_mode = LeaderMode.TIMEOUT
keyboard.leader_dictionary = {

View File

@ -1,8 +1,10 @@
try:
import machine
machine.bootloader()
except ImportError:
import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()

View File

@ -1,7 +1,9 @@
try:
import machine
machine.reset()
except ImportError:
import microcontroller
microcontroller.reset()