diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/python/qmk/cli/c2json.py | 59 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/config_h.py | 59 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/keyboard_c.py | 27 | ||||
| -rw-r--r-- | lib/python/qmk/cli/generate/keycodes.py | 8 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/rules_mk.py | 26 | ||||
| -rw-r--r-- | lib/python/qmk/info.py | 68 | ||||
| -rw-r--r-- | lib/python/qmk/keymap.py | 23 | ||||
| -rw-r--r-- | lib/python/qmk/path.py | 6 | 
8 files changed, 150 insertions, 126 deletions
| diff --git a/lib/python/qmk/cli/c2json.py b/lib/python/qmk/cli/c2json.py index 7f6aca070a..f7f1f2ffba 100644 --- a/lib/python/qmk/cli/c2json.py +++ b/lib/python/qmk/cli/c2json.py @@ -1,45 +1,57 @@  """Generate a keymap.json from a keymap.c file.  """ +import re  import json  from argcomplete.completers import FilesCompleter  from milc import cli -import qmk.keymap  import qmk.path  from qmk.json_encoders import InfoJSONEncoder +from qmk.decorators import automagic_keyboard, automagic_keymap  from qmk.keyboard import keyboard_completer, keyboard_folder +from qmk.keymap import locate_keymap, find_keymap_from_dir, generate_json, c2json as c2json_impl  from qmk.errors import CppError +from qmk.commands import dump_lines  @cli.argument('--no-cpp', arg_only=True, action='store_false', help='Do not use \'cpp\' on keymap.c')  @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')  @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") [email protected]('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='The keyboard\'s name') [email protected]('-km', '--keymap', arg_only=True, required=True, help='The keymap\'s name') [email protected]('filename', arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file') [email protected]('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard\'s name') [email protected]('-km', '--keymap', help='The keymap\'s name') [email protected]('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file')  @cli.subcommand('Creates a keymap.json from a keymap.c file.') +@automagic_keyboard +@automagic_keymap  def c2json(cli):      """Generate a keymap.json from a keymap.c file.      This command uses the `qmk.keymap` module to generate a keymap.json from a keymap.c file. The generated keymap is written to stdout, or to a file if -o is provided.      """ -    if cli.args.filename != '-': -        cli.args.filename = qmk.path.normpath(cli.args.filename) +    filename = cli.args.filename +    keyboard = cli.config.c2json.keyboard +    keymap = cli.config.c2json.keymap -        # Error checking -        if not cli.args.filename.exists(): -            cli.log.error('C file does not exist!') -            cli.print_usage() -            return False +    if filename: +        if not keyboard and not keymap: +            # fallback to inferring keyboard/keymap from path +            (keymap, found_type) = find_keymap_from_dir(filename) +            if found_type == 'keymap_directory': +                keyboard = re.search(fr"keyboards/(.+)/keymaps/{keymap}/.*", filename.as_posix()).group(1) -    # Environment processing -    if cli.args.output == ('-'): -        cli.args.output = None +    elif keyboard and keymap: +        if not filename: +            # fallback to inferring keyboard/keymap from path +            filename = locate_keymap(keyboard, keymap) + +    if not all((filename, keyboard, keymap)): +        cli.log.error('You must supply keyboard and keymap, a path to a keymap.c within qmk_firmware, or absolute filename and keyboard and keymap') +        cli.print_help() +        return False -    # Parse the keymap.c      try: -        keymap_json = qmk.keymap.c2json(cli.args.keyboard, cli.args.keymap, cli.args.filename, use_cpp=cli.args.no_cpp) +        keymap_json = c2json_impl(keyboard, keymap, filename, use_cpp=cli.args.no_cpp)      except CppError as e:          if cli.config.general.verbose:              cli.log.debug('The C pre-processor ran into a fatal error: %s', e) @@ -48,19 +60,14 @@ def c2json(cli):      # Generate the keymap.json      try: -        keymap_json = qmk.keymap.generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers']) +        keymap_json = generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers'])      except KeyError:          cli.log.error('Something went wrong. Try to use --no-cpp.')          return False      if cli.args.output: -        cli.args.output.parent.mkdir(parents=True, exist_ok=True) -        if cli.args.output.exists(): -            cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak')) -        cli.args.output.write_text(json.dumps(keymap_json, cls=InfoJSONEncoder, sort_keys=True)) - -        if not cli.args.quiet: -            cli.log.info('Wrote keymap to %s.', cli.args.output) - +        keymap_lines = [json.dumps(keymap_json, cls=InfoJSONEncoder, sort_keys=True)]      else: -        print(json.dumps(keymap_json)) +        keymap_lines = [json.dumps(keymap_json)] + +    dump_lines(cli.args.output, keymap_lines, cli.args.quiet) diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index 64d4db6ffe..00fb1d9585 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -15,7 +15,12 @@ from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE  def generate_define(define, value=None): +    is_keymap = cli.args.filename      value = f' {value}' if value is not None else '' +    if is_keymap: +        return f""" +#undef {define} +#define {define}{value}"""      return f"""  #ifndef {define}  #    define {define}{value} @@ -67,6 +72,19 @@ def generate_matrix_size(kb_info_json, config_h_lines):          config_h_lines.append(generate_define('MATRIX_ROWS', kb_info_json['matrix_size']['rows'])) +def generate_matrix_masked(kb_info_json, config_h_lines): +    """"Enable matrix mask if required""" +    mask_required = False + +    if 'matrix_grid' in kb_info_json.get('dip_switch', {}): +        mask_required = True +    if 'matrix_grid' in kb_info_json.get('split', {}).get('handedness', {}): +        mask_required = True + +    if mask_required: +        config_h_lines.append(generate_define('MATRIX_MASKED')) + +  def generate_config_items(kb_info_json, config_h_lines):      """Iterate through the info_config map to generate basic config values.      """ @@ -75,9 +93,9 @@ def generate_config_items(kb_info_json, config_h_lines):      for config_key, info_dict in info_config_map.items():          info_key = info_dict['info_key']          key_type = info_dict.get('value_type', 'raw') -        to_config = info_dict.get('to_config', True) +        to_c = info_dict.get('to_c', True) -        if not to_config: +        if not to_c:              continue          try: @@ -130,23 +148,11 @@ def generate_encoder_config(encoder_json, config_h_lines, postfix=''):  def generate_split_config(kb_info_json, config_h_lines):      """Generate the config.h lines for split boards.""" -    if 'primary' in kb_info_json['split']: -        if kb_info_json['split']['primary'] in ('left', 'right'): -            config_h_lines.append('') -            config_h_lines.append('#ifndef MASTER_LEFT') -            config_h_lines.append('#    ifndef MASTER_RIGHT') -            if kb_info_json['split']['primary'] == 'left': -                config_h_lines.append('#        define MASTER_LEFT') -            elif kb_info_json['split']['primary'] == 'right': -                config_h_lines.append('#        define MASTER_RIGHT') -            config_h_lines.append('#    endif // MASTER_RIGHT') -            config_h_lines.append('#endif // MASTER_LEFT') -        elif kb_info_json['split']['primary'] == 'pin': -            config_h_lines.append(generate_define('SPLIT_HAND_PIN')) -        elif kb_info_json['split']['primary'] == 'matrix_grid': -            config_h_lines.append(generate_define('SPLIT_HAND_MATRIX_GRID', f'{{ {",".join(kb_info_json["split"]["matrix_grid"])} }}')) -        elif kb_info_json['split']['primary'] == 'eeprom': -            config_h_lines.append(generate_define('EE_HANDS')) +    if 'handedness' in kb_info_json['split']: +        # TODO: change SPLIT_HAND_MATRIX_GRID to require brackets +        handedness = kb_info_json['split']['handedness'] +        if 'matrix_grid' in handedness: +            config_h_lines.append(generate_define('SPLIT_HAND_MATRIX_GRID', ', '.join(handedness['matrix_grid'])))      if 'protocol' in kb_info_json['split'].get('transport', {}):          if kb_info_json['split']['transport']['protocol'] == 'i2c': @@ -159,10 +165,13 @@ def generate_split_config(kb_info_json, config_h_lines):          generate_encoder_config(kb_info_json['split']['encoder']['right'], config_h_lines, '_RIGHT') -def generate_led_animations_config(led_feature_json, config_h_lines, prefix): +def generate_led_animations_config(feature, led_feature_json, config_h_lines, enable_prefix, animation_prefix): +    if 'animation' in led_feature_json.get('default', {}): +        config_h_lines.append(generate_define(f'{feature.upper()}_DEFAULT_MODE', f'{animation_prefix}{led_feature_json["default"]["animation"].upper()}')) +      for animation in led_feature_json.get('animations', {}):          if led_feature_json['animations'][animation]: -            config_h_lines.append(generate_define(f'{prefix}{animation.upper()}')) +            config_h_lines.append(generate_define(f'{enable_prefix}{animation.upper()}'))  @cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.') @@ -191,6 +200,8 @@ def generate_config_h(cli):      generate_matrix_size(kb_info_json, config_h_lines) +    generate_matrix_masked(kb_info_json, config_h_lines) +      if 'matrix_pins' in kb_info_json:          config_h_lines.append(matrix_pins(kb_info_json['matrix_pins'])) @@ -201,13 +212,13 @@ def generate_config_h(cli):          generate_split_config(kb_info_json, config_h_lines)      if 'led_matrix' in kb_info_json: -        generate_led_animations_config(kb_info_json['led_matrix'], config_h_lines, 'ENABLE_LED_MATRIX_') +        generate_led_animations_config('led_matrix', kb_info_json['led_matrix'], config_h_lines, 'ENABLE_LED_MATRIX_', 'LED_MATRIX_')      if 'rgb_matrix' in kb_info_json: -        generate_led_animations_config(kb_info_json['rgb_matrix'], config_h_lines, 'ENABLE_RGB_MATRIX_') +        generate_led_animations_config('rgb_matrix', kb_info_json['rgb_matrix'], config_h_lines, 'ENABLE_RGB_MATRIX_', 'RGB_MATRIX_')      if 'rgblight' in kb_info_json: -        generate_led_animations_config(kb_info_json['rgblight'], config_h_lines, 'RGBLIGHT_EFFECT_') +        generate_led_animations_config('rgblight', kb_info_json['rgblight'], config_h_lines, 'RGBLIGHT_EFFECT_', 'RGBLIGHT_MODE_')      # Show the results      dump_lines(cli.args.output, config_h_lines, cli.args.quiet) diff --git a/lib/python/qmk/cli/generate/keyboard_c.py b/lib/python/qmk/cli/generate/keyboard_c.py index 9004b41abb..f8a2372cf3 100755 --- a/lib/python/qmk/cli/generate/keyboard_c.py +++ b/lib/python/qmk/cli/generate/keyboard_c.py @@ -57,6 +57,32 @@ def _gen_led_config(info_data):      return lines +def _gen_matrix_mask(info_data): +    """Convert info.json content to matrix_mask +    """ +    cols = info_data['matrix_size']['cols'] +    rows = info_data['matrix_size']['rows'] + +    # Default mask to everything disabled +    mask = [['0'] * cols for i in range(rows)] + +    # Mirror layout macros squashed on top of each other +    for layout_data in info_data['layouts'].values(): +        for key_data in layout_data['layout']: +            row, col = key_data['matrix'] +            mask[row][col] = '1' + +    lines = [] +    lines.append('#ifdef MATRIX_MASKED') +    lines.append('__attribute__((weak)) const matrix_row_t matrix_mask[] = {') +    for i in range(rows): +        lines.append(f'    0b{"".join(reversed(mask[i]))},') +    lines.append('};') +    lines.append('#endif') + +    return lines + +  @cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')  @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")  @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='Keyboard to generate keyboard.c for.') @@ -70,6 +96,7 @@ def generate_keyboard_c(cli):      keyboard_h_lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#include QMK_KEYBOARD_H', '']      keyboard_h_lines.extend(_gen_led_config(kb_info_json)) +    keyboard_h_lines.extend(_gen_matrix_mask(kb_info_json))      # Show the results      dump_lines(cli.args.output, keyboard_h_lines, cli.args.quiet) diff --git a/lib/python/qmk/cli/generate/keycodes.py b/lib/python/qmk/cli/generate/keycodes.py index ed8b6827bd..719fced5d5 100644 --- a/lib/python/qmk/cli/generate/keycodes.py +++ b/lib/python/qmk/cli/generate/keycodes.py @@ -94,6 +94,14 @@ def _generate_helpers(lines, keycodes):          hi = keycodes["keycodes"][f'0x{codes[1]:04X}']['key']          lines.append(f'#define IS_{ _translate_group(group).upper() }_KEYCODE(code) ((code) >= {lo} && (code) <= {hi})') +    lines.append('') +    lines.append('// Switch statement Helpers') +    for group, codes in temp.items(): +        lo = keycodes["keycodes"][f'0x{codes[0]:04X}']['key'] +        hi = keycodes["keycodes"][f'0x{codes[1]:04X}']['key'] +        name = f'{ _translate_group(group).upper() }_KEYCODE_RANGE' +        lines.append(f'#define { name.ljust(35) } {lo} ... {hi}') +  def _generate_aliases(lines, keycodes):      # Work around ChibiOS ch.h include guard diff --git a/lib/python/qmk/cli/generate/rules_mk.py b/lib/python/qmk/cli/generate/rules_mk.py index fc272da6c6..5291556109 100755 --- a/lib/python/qmk/cli/generate/rules_mk.py +++ b/lib/python/qmk/cli/generate/rules_mk.py @@ -14,6 +14,12 @@ from qmk.path import normpath, FileType  from qmk.constants import GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE +def generate_rule(rules_key, rules_value): +    is_keymap = cli.args.filename +    rule_assignment_operator = '=' if is_keymap else '?=' +    return f'{rules_key} {rule_assignment_operator} {rules_value}' + +  def process_mapping_rule(kb_info_json, rules_key, info_dict):      """Return the rules.mk line(s) for a mapping rule.      """ @@ -29,15 +35,15 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):          return None      if key_type in ['array', 'list']: -        return f'{rules_key} ?= {" ".join(rules_value)}' +        return generate_rule(rules_key, " ".join(rules_value))      elif key_type == 'bool': -        return f'{rules_key} ?= {"yes" if rules_value else "no"}' +        return generate_rule(rules_key, "yes" if rules_value else "no")      elif key_type == 'mapping': -        return '\n'.join([f'{key} ?= {value}' for key, value in rules_value.items()]) +        return '\n'.join([generate_rule(key, value) for key, value in rules_value.items()])      elif key_type == 'str': -        return f'{rules_key} ?= "{rules_value}"' +        return generate_rule(rules_key, f'"{rules_value}"') -    return f'{rules_key} ?= {rules_value}' +    return generate_rule(rules_key, rules_value)  @cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.') @@ -77,21 +83,21 @@ def generate_rules_mk(cli):          for feature, enabled in kb_info_json['features'].items():              feature = feature.upper()              enabled = 'yes' if enabled else 'no' -            rules_mk_lines.append(f'{feature}_ENABLE ?= {enabled}') +            rules_mk_lines.append(generate_rule(f'{feature}_ENABLE', enabled))      # Set SPLIT_TRANSPORT, if needed      if kb_info_json.get('split', {}).get('transport', {}).get('protocol') == 'custom': -        rules_mk_lines.append('SPLIT_TRANSPORT ?= custom') +        rules_mk_lines.append(generate_rule('SPLIT_TRANSPORT', 'custom'))      # Set CUSTOM_MATRIX, if needed      if kb_info_json.get('matrix_pins', {}).get('custom'):          if kb_info_json.get('matrix_pins', {}).get('custom_lite'): -            rules_mk_lines.append('CUSTOM_MATRIX ?= lite') +            rules_mk_lines.append(generate_rule('CUSTOM_MATRIX', 'lite'))          else: -            rules_mk_lines.append('CUSTOM_MATRIX ?= yes') +            rules_mk_lines.append(generate_rule('CUSTOM_MATRIX', 'yes'))      if converter: -        rules_mk_lines.append(f'CONVERT_TO ?= {converter}') +        rules_mk_lines.append(generate_rule('CONVERT_TO', converter))      # Show the results      dump_lines(cli.args.output, rules_mk_lines) diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 9c8521a2a3..fe829a724a 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -352,55 +352,12 @@ def _extract_secure_unlock(info_data, config_c):          info_data['secure']['unlock_sequence'] = unlock_array -def _extract_split_main(info_data, config_c): -    """Populate data about the split configuration -    """ -    # Figure out how the main half is determined -    if config_c.get('SPLIT_HAND_PIN') is True: -        if 'split' not in info_data: -            info_data['split'] = {} - -        if 'main' in info_data['split']: -            _log_warning(info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_PIN) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) - -        info_data['split']['main'] = 'pin' - -    if config_c.get('SPLIT_HAND_MATRIX_GRID'): -        if 'split' not in info_data: -            info_data['split'] = {} - -        if 'main' in info_data['split']: -            _log_warning(info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_MATRIX_GRID) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) - -        info_data['split']['main'] = 'matrix_grid' -        info_data['split']['matrix_grid'] = _extract_pins(config_c['SPLIT_HAND_MATRIX_GRID']) - -    if config_c.get('EE_HANDS') is True: -        if 'split' not in info_data: -            info_data['split'] = {} - -        if 'main' in info_data['split']: -            _log_warning(info_data, 'Split main hand is specified in both config.h (EE_HANDS) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) - -        info_data['split']['main'] = 'eeprom' - -    if config_c.get('MASTER_RIGHT') is True: -        if 'split' not in info_data: -            info_data['split'] = {} - -        if 'main' in info_data['split']: -            _log_warning(info_data, 'Split main hand is specified in both config.h (MASTER_RIGHT) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) - -        info_data['split']['main'] = 'right' - -    if config_c.get('MASTER_LEFT') is True: -        if 'split' not in info_data: -            info_data['split'] = {} - -        if 'main' in info_data['split']: -            _log_warning(info_data, 'Split main hand is specified in both config.h (MASTER_LEFT) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) - -        info_data['split']['main'] = 'left' +def _extract_split_handedness(info_data, config_c): +    # Migrate +    split = info_data.get('split', {}) +    if 'matrix_grid' in split: +        split['handedness'] = split.get('handedness', {}) +        split['handedness']['matrix_grid'] = split.pop('matrix_grid')  def _extract_split_transport(info_data, config_c): @@ -428,6 +385,15 @@ def _extract_split_transport(info_data, config_c):          if 'protocol' not in info_data['split']['transport']:              info_data['split']['transport']['protocol'] = 'serial' +    # Migrate +    transport = info_data.get('split', {}).get('transport', {}) +    if 'sync_matrix_state' in transport: +        transport['sync'] = transport.get('sync', {}) +        transport['sync']['matrix_state'] = transport.pop('sync_matrix_state') +    if 'sync_modifiers' in transport: +        transport['sync'] = transport.get('sync', {}) +        transport['sync']['modifiers'] = transport.pop('sync_modifiers') +  def _extract_split_right_pins(info_data, config_c):      # Figure out the right half matrix pins @@ -520,6 +486,8 @@ def _config_to_json(key_type, config_value):              return list(map(str.strip, config_value.split(',')))      elif key_type == 'bool': +        if isinstance(config_value, bool): +            return config_value          return config_value in true_values      elif key_type == 'hex': @@ -583,7 +551,7 @@ def _extract_config_h(info_data, config_c):      _extract_matrix_info(info_data, config_c)      _extract_audio(info_data, config_c)      _extract_secure_unlock(info_data, config_c) -    _extract_split_main(info_data, config_c) +    _extract_split_handedness(info_data, config_c)      _extract_split_transport(info_data, config_c)      _extract_split_right_pins(info_data, config_c)      _extract_encoders(info_data, config_c) diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index 11e8d39dad..281c53cfda 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -191,16 +191,15 @@ def _strip_any(keycode):      return keycode -def find_keymap_from_dir(): -    """Returns `(keymap_name, source)` for the directory we're currently in. - +def find_keymap_from_dir(*args): +    """Returns `(keymap_name, source)` for the directory provided (or cwd if not specified).      """ -    relative_cwd = qmk.path.under_qmk_firmware() +    relative_path = qmk.path.under_qmk_firmware(*args) -    if relative_cwd and len(relative_cwd.parts) > 1: +    if relative_path and len(relative_path.parts) > 1:          # If we're in `qmk_firmware/keyboards` and `keymaps` is in our path, try to find the keyboard name. -        if relative_cwd.parts[0] == 'keyboards' and 'keymaps' in relative_cwd.parts: -            current_path = Path('/'.join(relative_cwd.parts[1:]))  # Strip 'keyboards' from the front +        if relative_path.parts[0] == 'keyboards' and 'keymaps' in relative_path.parts: +            current_path = Path('/'.join(relative_path.parts[1:]))  # Strip 'keyboards' from the front              if 'keymaps' in current_path.parts and current_path.name != 'keymaps':                  while current_path.parent.name != 'keymaps': @@ -209,13 +208,13 @@ def find_keymap_from_dir():                  return current_path.name, 'keymap_directory'          # If we're in `qmk_firmware/layouts` guess the name from the community keymap they're in -        elif relative_cwd.parts[0] == 'layouts' and is_keymap_dir(relative_cwd): -            return relative_cwd.name, 'layouts_directory' +        elif relative_path.parts[0] == 'layouts' and is_keymap_dir(relative_path): +            return relative_path.name, 'layouts_directory'          # If we're in `qmk_firmware/users` guess the name from the userspace they're in -        elif relative_cwd.parts[0] == 'users': +        elif relative_path.parts[0] == 'users':              # Guess the keymap name based on which userspace they're in -            return relative_cwd.parts[1], 'users_directory' +            return relative_path.parts[1], 'users_directory'      return None, None @@ -657,7 +656,7 @@ def parse_keymap_c(keymap_file, use_cpp=True):      Returns:          a dictionary containing the parsed keymap      """ -    if keymap_file == '-': +    if not isinstance(keymap_file, (Path, str)) or keymap_file == '-':          if use_cpp:              keymap_file = _c_preprocess(None, sys.stdin)          else: diff --git a/lib/python/qmk/path.py b/lib/python/qmk/path.py index 9d248451b8..94582a05e0 100644 --- a/lib/python/qmk/path.py +++ b/lib/python/qmk/path.py @@ -19,13 +19,11 @@ def is_keyboard(keyboard_name):          return rules_mk.exists() -def under_qmk_firmware(): +def under_qmk_firmware(path=Path(os.environ['ORIG_CWD'])):      """Returns a Path object representing the relative path under qmk_firmware, or None.      """ -    cwd = Path(os.environ['ORIG_CWD']) -      try: -        return cwd.relative_to(QMK_FIRMWARE) +        return path.relative_to(QMK_FIRMWARE)      except ValueError:          return None | 
