diff options
| author | Erovia <erovia@users.noreply.github.com> | 2019-10-08 21:50:21 +0200 |
|---|---|---|
| committer | skullydazed <skullydazed@users.noreply.github.com> | 2020-02-15 15:19:03 -0800 |
| commit | 409c610543ffb62677d1162be868a2e44913a943 (patch) | |
| tree | e23421ddcaa162925be37604672da87fb5d4548c /lib/python/qmk | |
| parent | 348266bd5b6c6c79c292e3df9442a19d99873b5c (diff) | |
| download | qmk_firmware-409c610543ffb62677d1162be868a2e44913a943.tar.gz qmk_firmware-409c610543ffb62677d1162be868a2e44913a943.zip | |
CLI: add support for list_keymaps
List all the available keymaps for a given keyboard
Diffstat (limited to 'lib/python/qmk')
| -rw-r--r-- | lib/python/qmk/cli/list/__init__.py | 1 | ||||
| -rw-r--r-- | lib/python/qmk/cli/list/keymaps.py | 84 |
2 files changed, 85 insertions, 0 deletions
diff --git a/lib/python/qmk/cli/list/__init__.py b/lib/python/qmk/cli/list/__init__.py index c36ba6954..d83cd20b5 100644 --- a/lib/python/qmk/cli/list/__init__.py +++ b/lib/python/qmk/cli/list/__init__.py | |||
| @@ -1 +1,2 @@ | |||
| 1 | from . import keyboards | 1 | from . import keyboards |
| 2 | from . import keymaps | ||
diff --git a/lib/python/qmk/cli/list/keymaps.py b/lib/python/qmk/cli/list/keymaps.py new file mode 100644 index 000000000..709a5b9f9 --- /dev/null +++ b/lib/python/qmk/cli/list/keymaps.py | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | """List the keymaps for a specific keyboard | ||
| 2 | """ | ||
| 3 | import os | ||
| 4 | import re | ||
| 5 | import glob | ||
| 6 | from bs4 import UnicodeDammit | ||
| 7 | |||
| 8 | from milc import cli | ||
| 9 | |||
| 10 | def unicode_text(filename): | ||
| 11 | """Returns the contents of filename as a UTF-8 string. Tries to DTRT when it comes to encoding. | ||
| 12 | """ | ||
| 13 | with open(filename, 'rb') as fd: | ||
| 14 | text = UnicodeDammit(fd.read()) | ||
| 15 | |||
| 16 | if text.contains_replacement_characters: | ||
| 17 | log_warning('%s: Could not determine file encoding, some characters were replaced.' % (filename,)) | ||
| 18 | |||
| 19 | return text.unicode_markup or '' | ||
| 20 | |||
| 21 | |||
| 22 | def unicode_lines(filename): | ||
| 23 | """Returns the contents of filename as a UTF-8 string. Tries to DTRT when it comes to encoding. | ||
| 24 | """ | ||
| 25 | return unicode_text(filename).split('\n') | ||
| 26 | |||
| 27 | def parse_rules_mk(keyboard): | ||
| 28 | base_path = os.path.join(os.getcwd(), "keyboards", keyboard) + os.path.sep | ||
| 29 | rules_mk_path_wildcard = os.path.join(base_path, "**", "rules.mk") | ||
| 30 | paths = [path for path in glob.iglob(rules_mk_path_wildcard, recursive=True) if "keymaps" not in path] | ||
| 31 | |||
| 32 | rules_mk = list() | ||
| 33 | for file in paths: | ||
| 34 | rules_mk_content = unicode_lines(file) | ||
| 35 | parsed_file = dict() | ||
| 36 | for line in rules_mk_content: | ||
| 37 | found = re.search(r'^\s*(\w+)\s*=\s*((?:\s*\w+)+)', line) | ||
| 38 | if found: | ||
| 39 | parsed_file[found.group(1)] = found.group(2) | ||
| 40 | rules_mk.append(parsed_file) | ||
| 41 | return rules_mk | ||
| 42 | |||
| 43 | @cli.argument('-kb', '--keyboard', help='Specify keyboard name. Example: 1upkeyboards/1up60hse') | ||
| 44 | @cli.subcommand("List the keymaps for a specific keyboard") | ||
| 45 | def list_keymaps(cli): | ||
| 46 | """List the keymaps for a specific keyboard | ||
| 47 | """ | ||
| 48 | # ask for user input if keyboard was not provided in the command line | ||
| 49 | keyboard = cli.config.list_keymaps.keyboard if cli.config.list_keymaps.keyboard else input("Keyboard Name: ") | ||
| 50 | |||
| 51 | kb_base_path = os.path.join(os.getcwd(), "keyboards", keyboard) + os.path.sep | ||
| 52 | km_path_wildcard = os.path.join(kb_base_path, "**", "keymap.c") | ||
| 53 | |||
| 54 | # find everywhere we have rules.mk where keymaps isn't in the path | ||
| 55 | km_paths = [path for path in glob.iglob(km_path_wildcard, recursive=True) if 'keymaps' in path] | ||
| 56 | |||
| 57 | # replace the keyboard directory's path prefix with the keyboard's name and remove the keymap.c suffix | ||
| 58 | km_find_name = lambda path: path.replace(kb_base_path, keyboard + os.path.sep).replace("/keymaps/", ":").replace(os.path.sep + "keymap.c", "") | ||
| 59 | names = list(map(km_find_name, km_paths)) | ||
| 60 | |||
| 61 | # get all the rules.mk files for the keyboard | ||
| 62 | rules_mk = parse_rules_mk(keyboard) | ||
| 63 | |||
| 64 | # find all the supported layouts | ||
| 65 | all_supported_layouts = set() | ||
| 66 | for version in rules_mk: | ||
| 67 | if "LAYOUTS" in version: | ||
| 68 | for layout in version["LAYOUTS"].split(): | ||
| 69 | all_supported_layouts.add(layout) | ||
| 70 | |||
| 71 | for layout in all_supported_layouts: | ||
| 72 | cl_base_path = os.path.join(os.getcwd(), "layouts", "community", layout) + os.path.sep | ||
| 73 | cl_path_wildcard = os.path.join(cl_base_path, "**", "keymap.c") | ||
| 74 | # find all the keymap.c files under the community layouts | ||
| 75 | cl_paths = [path for path in glob.iglob(cl_path_wildcard, recursive=True)] | ||
| 76 | # replace the community layouts directory's path with the keyboard's name and remove the keymap.c suffix | ||
| 77 | cl_find_name = lambda path: path.replace(cl_base_path, keyboard + ":").replace(os.path.sep + "keymap.c", "") | ||
| 78 | names = names + list(map(cl_find_name, cl_paths)) | ||
| 79 | |||
| 80 | names.sort() | ||
| 81 | |||
| 82 | for name in names: | ||
| 83 | # We echo instead of cli.log.info to allow easier piping of this output | ||
| 84 | cli.echo(name) | ||
