qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

decorators.py (3315B)


      1 """Helpful decorators that subcommands can use.
      2 """
      3 import functools
      4 from time import monotonic
      5 
      6 from milc import cli
      7 
      8 from qmk.keyboard import find_keyboard_from_dir, keyboard_folder
      9 from qmk.keymap import find_keymap_from_dir
     10 
     11 
     12 def _get_subcommand_name():
     13     """Handle missing cli.subcommand_name on older versions of milc
     14     """
     15     try:
     16         return cli.subcommand_name
     17     except AttributeError:
     18         return cli._subcommand.__name__
     19 
     20 
     21 def automagic_keyboard(func):
     22     """Sets `cli.config.<subcommand>.keyboard` based on environment.
     23 
     24     This will rewrite cli.config.<subcommand>.keyboard if the user did not pass `--keyboard` and the directory they are currently in is a keyboard or keymap directory.
     25     """
     26     @functools.wraps(func)
     27     def wrapper(*args, **kwargs):
     28         cmd = _get_subcommand_name()
     29 
     30         # TODO: Workaround for if config file contains "old" keyboard name
     31         #         Potential long-term fix needs to be within global cli or milc
     32         if cli.config_source[cmd]['keyboard'] == 'config_file':
     33             cli.config[cmd]['keyboard'] = keyboard_folder(cli.config[cmd]['keyboard'])
     34 
     35         # Ensure that `--keyboard` was not passed and CWD is under `qmk_firmware/keyboards`
     36         if cli.config_source[cmd]['keyboard'] != 'argument':
     37             keyboard = find_keyboard_from_dir()
     38 
     39             if keyboard:
     40                 cli.config[cmd]['keyboard'] = keyboard
     41                 cli.config_source[cmd]['keyboard'] = 'keyboard_directory'
     42 
     43         return func(*args, **kwargs)
     44 
     45     return wrapper
     46 
     47 
     48 def automagic_keymap(func):
     49     """Sets `cli.config.<subcommand>.keymap` based on environment.
     50 
     51     This will rewrite cli.config.<subcommand>.keymap if the user did not pass `--keymap` and the directory they are currently in is a keymap, layout, or user directory.
     52     """
     53     @functools.wraps(func)
     54     def wrapper(*args, **kwargs):
     55         cmd = _get_subcommand_name()
     56 
     57         # Ensure that `--keymap` was not passed and that we're under `qmk_firmware`
     58         if cli.config_source[cmd]['keymap'] != 'argument':
     59             keymap_name, keymap_type = find_keymap_from_dir()
     60 
     61             if keymap_name:
     62                 cli.config[cmd]['keymap'] = keymap_name
     63                 cli.config_source[cmd]['keymap'] = keymap_type
     64 
     65         return func(*args, **kwargs)
     66 
     67     return wrapper
     68 
     69 
     70 def lru_cache(timeout=10, maxsize=128, typed=False):
     71     """Least Recently Used Cache- cache the result of a function.
     72 
     73     Args:
     74 
     75         timeout
     76             How many seconds to cache results for.
     77 
     78         maxsize
     79             The maximum size of the cache in bytes
     80 
     81         typed
     82             When `True` argument types will be taken into consideration, for example `3` and `3.0` will be treated as different keys.
     83     """
     84     def wrapper_cache(func):
     85         func = functools.lru_cache(maxsize=maxsize, typed=typed)(func)
     86         func.expiration = monotonic() + timeout
     87 
     88         @functools.wraps(func)
     89         def wrapped_func(*args, **kwargs):
     90             if monotonic() >= func.expiration:
     91                 func.expiration = monotonic() + timeout
     92 
     93                 func.cache_clear()
     94 
     95             return func(*args, **kwargs)
     96 
     97         wrapped_func.cache_info = func.cache_info
     98         wrapped_func.cache_clear = func.cache_clear
     99 
    100         return wrapped_func
    101 
    102     return wrapper_cache