diff options
Diffstat (limited to 'lib/python/qmk/info.py')
-rw-r--r-- | lib/python/qmk/info.py | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 2accaba9e..cf5dc6640 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py | |||
@@ -45,7 +45,12 @@ def info_json(keyboard): | |||
45 | info_data['keymaps'][keymap.name] = {'url': f'https://raw.githubusercontent.com/qmk/qmk_firmware/master/{keymap}/keymap.json'} | 45 | info_data['keymaps'][keymap.name] = {'url': f'https://raw.githubusercontent.com/qmk/qmk_firmware/master/{keymap}/keymap.json'} |
46 | 46 | ||
47 | # Populate layout data | 47 | # Populate layout data |
48 | for layout_name, layout_json in _find_all_layouts(info_data, keyboard).items(): | 48 | layouts, aliases = _find_all_layouts(info_data, keyboard) |
49 | |||
50 | if aliases: | ||
51 | info_data['layout_aliases'] = aliases | ||
52 | |||
53 | for layout_name, layout_json in layouts.items(): | ||
49 | if not layout_name.startswith('LAYOUT_kc'): | 54 | if not layout_name.startswith('LAYOUT_kc'): |
50 | layout_json['c_macro'] = True | 55 | layout_json['c_macro'] = True |
51 | info_data['layouts'][layout_name] = layout_json | 56 | info_data['layouts'][layout_name] = layout_json |
@@ -92,7 +97,7 @@ def _json_load(json_file): | |||
92 | Note: file must be a Path object. | 97 | Note: file must be a Path object. |
93 | """ | 98 | """ |
94 | try: | 99 | try: |
95 | return hjson.load(json_file.open()) | 100 | return hjson.load(json_file.open(encoding='utf-8')) |
96 | 101 | ||
97 | except json.decoder.JSONDecodeError as e: | 102 | except json.decoder.JSONDecodeError as e: |
98 | cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e) | 103 | cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e) |
@@ -415,21 +420,28 @@ def _merge_layouts(info_data, new_info_data): | |||
415 | 420 | ||
416 | def _search_keyboard_h(path): | 421 | def _search_keyboard_h(path): |
417 | current_path = Path('keyboards/') | 422 | current_path = Path('keyboards/') |
423 | aliases = {} | ||
418 | layouts = {} | 424 | layouts = {} |
425 | |||
419 | for directory in path.parts: | 426 | for directory in path.parts: |
420 | current_path = current_path / directory | 427 | current_path = current_path / directory |
421 | keyboard_h = '%s.h' % (directory,) | 428 | keyboard_h = '%s.h' % (directory,) |
422 | keyboard_h_path = current_path / keyboard_h | 429 | keyboard_h_path = current_path / keyboard_h |
423 | if keyboard_h_path.exists(): | 430 | if keyboard_h_path.exists(): |
424 | layouts.update(find_layouts(keyboard_h_path)) | 431 | new_layouts, new_aliases = find_layouts(keyboard_h_path) |
432 | layouts.update(new_layouts) | ||
433 | |||
434 | for alias, alias_text in new_aliases.items(): | ||
435 | if alias_text in layouts: | ||
436 | aliases[alias] = alias_text | ||
425 | 437 | ||
426 | return layouts | 438 | return layouts, aliases |
427 | 439 | ||
428 | 440 | ||
429 | def _find_all_layouts(info_data, keyboard): | 441 | def _find_all_layouts(info_data, keyboard): |
430 | """Looks for layout macros associated with this keyboard. | 442 | """Looks for layout macros associated with this keyboard. |
431 | """ | 443 | """ |
432 | layouts = _search_keyboard_h(Path(keyboard)) | 444 | layouts, aliases = _search_keyboard_h(Path(keyboard)) |
433 | 445 | ||
434 | if not layouts: | 446 | if not layouts: |
435 | # If we don't find any layouts from info.json or keyboard.h we widen our search. This is error prone which is why we want to encourage people to follow the standard above. | 447 | # If we don't find any layouts from info.json or keyboard.h we widen our search. This is error prone which is why we want to encourage people to follow the standard above. |
@@ -437,11 +449,15 @@ def _find_all_layouts(info_data, keyboard): | |||
437 | 449 | ||
438 | for file in glob('keyboards/%s/*.h' % keyboard): | 450 | for file in glob('keyboards/%s/*.h' % keyboard): |
439 | if file.endswith('.h'): | 451 | if file.endswith('.h'): |
440 | these_layouts = find_layouts(file) | 452 | these_layouts, these_aliases = find_layouts(file) |
453 | |||
441 | if these_layouts: | 454 | if these_layouts: |
442 | layouts.update(these_layouts) | 455 | layouts.update(these_layouts) |
443 | 456 | ||
444 | return layouts | 457 | if these_aliases: |
458 | aliases.update(these_aliases) | ||
459 | |||
460 | return layouts, aliases | ||
445 | 461 | ||
446 | 462 | ||
447 | def _log_error(info_data, message): | 463 | def _log_error(info_data, message): |
@@ -540,11 +556,19 @@ def merge_info_jsons(keyboard, info_data): | |||
540 | cli.log.error('\t%s: %s', json_path, e.message) | 556 | cli.log.error('\t%s: %s', json_path, e.message) |
541 | continue | 557 | continue |
542 | 558 | ||
543 | # Mark the layouts as coming from json | 559 | # Merge layout data in |
544 | for layout in new_info_data.get('layouts', {}).values(): | 560 | for layout_name, layout in new_info_data.get('layouts', {}).items(): |
545 | layout['c_macro'] = False | 561 | if layout_name in info_data['layouts']: |
562 | for new_key, existing_key in zip(layout['layout'], info_data['layouts'][layout_name]['layout']): | ||
563 | existing_key.update(new_key) | ||
564 | else: | ||
565 | layout['c_macro'] = False | ||
566 | info_data['layouts'][layout_name] = layout | ||
546 | 567 | ||
547 | # Update info_data with the new data | 568 | # Update info_data with the new data |
569 | if 'layouts' in new_info_data: | ||
570 | del (new_info_data['layouts']) | ||
571 | |||
548 | deep_update(info_data, new_info_data) | 572 | deep_update(info_data, new_info_data) |
549 | 573 | ||
550 | return info_data | 574 | return info_data |