diff options
author | Ryan <fauxpark@gmail.com> | 2020-11-02 19:41:01 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-02 00:41:01 -0800 |
commit | e69da2db2c59a8017f0c9dee9933dd508d22b356 (patch) | |
tree | 69dbe7f0731199331f6975df2ada13feab09eaeb | |
parent | dc40f00aafeea148d8998c594c4e414d87ee84a3 (diff) | |
download | qmk_firmware-e69da2db2c59a8017f0c9dee9933dd508d22b356.tar.gz qmk_firmware-e69da2db2c59a8017f0c9dee9933dd508d22b356.zip |
`qmk info`: Add `--ascii` flag (#10793)
* `qmk info`: Add `--ascii` flag
* Fix typo
* Force ASCII for Windows/MSYS2
* Make it gooder
* Remove redundant windows check
* ...And this too
* Make pytest work on Windows
-rwxr-xr-x | lib/python/qmk/cli/info.py | 12 | ||||
-rw-r--r-- | lib/python/qmk/keyboard.py | 37 | ||||
-rw-r--r-- | lib/python/qmk/tests/test_cli_commands.py | 17 |
3 files changed, 52 insertions, 14 deletions
diff --git a/lib/python/qmk/cli/info.py b/lib/python/qmk/cli/info.py index 44ce1186a..9ab299a21 100755 --- a/lib/python/qmk/cli/info.py +++ b/lib/python/qmk/cli/info.py | |||
@@ -3,6 +3,7 @@ | |||
3 | Compile an info.json for a particular keyboard and pretty-print it. | 3 | Compile an info.json for a particular keyboard and pretty-print it. |
4 | """ | 4 | """ |
5 | import json | 5 | import json |
6 | import platform | ||
6 | 7 | ||
7 | from milc import cli | 8 | from milc import cli |
8 | 9 | ||
@@ -12,6 +13,8 @@ from qmk.keymap import locate_keymap | |||
12 | from qmk.info import info_json | 13 | from qmk.info import info_json |
13 | from qmk.path import is_keyboard | 14 | from qmk.path import is_keyboard |
14 | 15 | ||
16 | platform_id = platform.platform().lower() | ||
17 | |||
15 | ROW_LETTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop' | 18 | ROW_LETTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop' |
16 | COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz' | 19 | COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz' |
17 | 20 | ||
@@ -36,13 +39,13 @@ def show_keymap(kb_info_json, title_caps=True): | |||
36 | else: | 39 | else: |
37 | cli.echo('{fg_cyan}layer_%s{fg_reset}:', layer_num) | 40 | cli.echo('{fg_cyan}layer_%s{fg_reset}:', layer_num) |
38 | 41 | ||
39 | print(render_layout(kb_info_json['layouts'][layout_name]['layout'], layer)) | 42 | print(render_layout(kb_info_json['layouts'][layout_name]['layout'], cli.config.info.ascii, layer)) |
40 | 43 | ||
41 | 44 | ||
42 | def show_layouts(kb_info_json, title_caps=True): | 45 | def show_layouts(kb_info_json, title_caps=True): |
43 | """Render the layouts with info.json labels. | 46 | """Render the layouts with info.json labels. |
44 | """ | 47 | """ |
45 | for layout_name, layout_art in render_layouts(kb_info_json).items(): | 48 | for layout_name, layout_art in render_layouts(kb_info_json, cli.config.info.ascii).items(): |
46 | title = layout_name.title() if title_caps else layout_name | 49 | title = layout_name.title() if title_caps else layout_name |
47 | cli.echo('{fg_cyan}%s{fg_reset}:', title) | 50 | cli.echo('{fg_cyan}%s{fg_reset}:', title) |
48 | print(layout_art) # Avoid passing dirty data to cli.echo() | 51 | print(layout_art) # Avoid passing dirty data to cli.echo() |
@@ -69,7 +72,7 @@ def show_matrix(kb_info_json, title_caps=True): | |||
69 | else: | 72 | else: |
70 | cli.echo('{fg_blue}matrix_%s{fg_reset}:', layout_name) | 73 | cli.echo('{fg_blue}matrix_%s{fg_reset}:', layout_name) |
71 | 74 | ||
72 | print(render_layout(kb_info_json['layouts'][layout_name]['layout'], labels)) | 75 | print(render_layout(kb_info_json['layouts'][layout_name]['layout'], cli.config.info.ascii, labels)) |
73 | 76 | ||
74 | 77 | ||
75 | def print_friendly_output(kb_info_json): | 78 | def print_friendly_output(kb_info_json): |
@@ -124,6 +127,7 @@ def print_text_output(kb_info_json): | |||
124 | @cli.argument('-l', '--layouts', action='store_true', help='Render the layouts.') | 127 | @cli.argument('-l', '--layouts', action='store_true', help='Render the layouts.') |
125 | @cli.argument('-m', '--matrix', action='store_true', help='Render the layouts with matrix information.') | 128 | @cli.argument('-m', '--matrix', action='store_true', help='Render the layouts with matrix information.') |
126 | @cli.argument('-f', '--format', default='friendly', arg_only=True, help='Format to display the data in (friendly, text, json) (Default: friendly).') | 129 | @cli.argument('-f', '--format', default='friendly', arg_only=True, help='Format to display the data in (friendly, text, json) (Default: friendly).') |
130 | @cli.argument('--ascii', action='store_true', default='windows' in platform_id, help='Render layout box drawings in ASCII only.') | ||
127 | @cli.subcommand('Keyboard information.') | 131 | @cli.subcommand('Keyboard information.') |
128 | @automagic_keyboard | 132 | @automagic_keyboard |
129 | @automagic_keymap | 133 | @automagic_keymap |
@@ -132,7 +136,7 @@ def info(cli): | |||
132 | """ | 136 | """ |
133 | # Determine our keyboard(s) | 137 | # Determine our keyboard(s) |
134 | if not cli.config.info.keyboard: | 138 | if not cli.config.info.keyboard: |
135 | cli.log.error('Missing paramater: --keyboard') | 139 | cli.log.error('Missing parameter: --keyboard') |
136 | cli.subcommands['info'].print_help() | 140 | cli.subcommands['info'].print_help() |
137 | return False | 141 | return False |
138 | 142 | ||
diff --git a/lib/python/qmk/keyboard.py b/lib/python/qmk/keyboard.py index 9ebb2d77d..a4c287375 100644 --- a/lib/python/qmk/keyboard.py +++ b/lib/python/qmk/keyboard.py | |||
@@ -9,6 +9,25 @@ from glob import glob | |||
9 | from qmk.c_parse import parse_config_h_file | 9 | from qmk.c_parse import parse_config_h_file |
10 | from qmk.makefile import parse_rules_mk_file | 10 | from qmk.makefile import parse_rules_mk_file |
11 | 11 | ||
12 | BOX_DRAWING_CHARACTERS = { | ||
13 | "unicode": { | ||
14 | "tl": "┌", | ||
15 | "tr": "┐", | ||
16 | "bl": "└", | ||
17 | "br": "┘", | ||
18 | "v": "│", | ||
19 | "h": "─", | ||
20 | }, | ||
21 | "ascii": { | ||
22 | "tl": " ", | ||
23 | "tr": " ", | ||
24 | "bl": "|", | ||
25 | "br": "|", | ||
26 | "v": "|", | ||
27 | "h": "_", | ||
28 | }, | ||
29 | } | ||
30 | |||
12 | base_path = os.path.join(os.getcwd(), "keyboards") + os.path.sep | 31 | base_path = os.path.join(os.getcwd(), "keyboards") + os.path.sep |
13 | 32 | ||
14 | 33 | ||
@@ -72,10 +91,12 @@ def rules_mk(keyboard): | |||
72 | return rules | 91 | return rules |
73 | 92 | ||
74 | 93 | ||
75 | def render_layout(layout_data, key_labels=None): | 94 | def render_layout(layout_data, render_ascii, key_labels=None): |
76 | """Renders a single layout. | 95 | """Renders a single layout. |
77 | """ | 96 | """ |
78 | textpad = [array('u', ' ' * 200) for x in range(50)] | 97 | textpad = [array('u', ' ' * 200) for x in range(50)] |
98 | style = 'ascii' if render_ascii else 'unicode' | ||
99 | box_chars = BOX_DRAWING_CHARACTERS[style] | ||
79 | 100 | ||
80 | for key in layout_data: | 101 | for key in layout_data: |
81 | x = ceil(key.get('x', 0) * 4) | 102 | x = ceil(key.get('x', 0) * 4) |
@@ -97,13 +118,13 @@ def render_layout(layout_data, key_labels=None): | |||
97 | label = label[:label_len] | 118 | label = label[:label_len] |
98 | 119 | ||
99 | label_blank = ' ' * label_len | 120 | label_blank = ' ' * label_len |
100 | label_border = '─' * label_len | 121 | label_border = box_chars['h'] * label_len |
101 | label_middle = label + ' '*label_leftover # noqa: yapf insists there be no whitespace around * | 122 | label_middle = label + ' '*label_leftover # noqa: yapf insists there be no whitespace around * |
102 | 123 | ||
103 | top_line = array('u', '┌' + label_border + '┐') | 124 | top_line = array('u', box_chars['tl'] + label_border + box_chars['tr']) |
104 | lab_line = array('u', '│' + label_middle + '│') | 125 | lab_line = array('u', box_chars['v'] + label_middle + box_chars['v']) |
105 | mid_line = array('u', '│' + label_blank + '│') | 126 | mid_line = array('u', box_chars['v'] + label_blank + box_chars['v']) |
106 | bot_line = array('u', '└' + label_border + "┘") | 127 | bot_line = array('u', box_chars['bl'] + label_border + box_chars['br']) |
107 | 128 | ||
108 | textpad[y][x:x + w] = top_line | 129 | textpad[y][x:x + w] = top_line |
109 | textpad[y + 1][x:x + w] = lab_line | 130 | textpad[y + 1][x:x + w] = lab_line |
@@ -119,13 +140,13 @@ def render_layout(layout_data, key_labels=None): | |||
119 | return '\n'.join(lines) | 140 | return '\n'.join(lines) |
120 | 141 | ||
121 | 142 | ||
122 | def render_layouts(info_json): | 143 | def render_layouts(info_json, render_ascii): |
123 | """Renders all the layouts from an `info_json` structure. | 144 | """Renders all the layouts from an `info_json` structure. |
124 | """ | 145 | """ |
125 | layouts = {} | 146 | layouts = {} |
126 | 147 | ||
127 | for layout in info_json['layouts']: | 148 | for layout in info_json['layouts']: |
128 | layout_data = info_json['layouts'][layout]['layout'] | 149 | layout_data = info_json['layouts'][layout]['layout'] |
129 | layouts[layout] = render_layout(layout_data) | 150 | layouts[layout] = render_layout(layout_data, render_ascii) |
130 | 151 | ||
131 | return layouts | 152 | return layouts |
diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py index 7ac0bcbde..7c261db6c 100644 --- a/lib/python/qmk/tests/test_cli_commands.py +++ b/lib/python/qmk/tests/test_cli_commands.py | |||
@@ -1,7 +1,11 @@ | |||
1 | import platform | ||
2 | |||
1 | from subprocess import STDOUT, PIPE | 3 | from subprocess import STDOUT, PIPE |
2 | 4 | ||
3 | from qmk.commands import run | 5 | from qmk.commands import run |
4 | 6 | ||
7 | is_windows = 'windows' in platform.platform().lower() | ||
8 | |||
5 | 9 | ||
6 | def check_subcommand(command, *args): | 10 | def check_subcommand(command, *args): |
7 | cmd = ['bin/qmk', command] + list(args) | 11 | cmd = ['bin/qmk', command] + list(args) |
@@ -148,7 +152,11 @@ def test_info_keymap_render(): | |||
148 | check_returncode(result) | 152 | check_returncode(result) |
149 | assert 'Keyboard Name: handwired/onekey/pytest' in result.stdout | 153 | assert 'Keyboard Name: handwired/onekey/pytest' in result.stdout |
150 | assert 'Processor: STM32F303' in result.stdout | 154 | assert 'Processor: STM32F303' in result.stdout |
151 | assert '│A │' in result.stdout | 155 | |
156 | if is_windows: | ||
157 | assert '|A |' in result.stdout | ||
158 | else: | ||
159 | assert '│A │' in result.stdout | ||
152 | 160 | ||
153 | 161 | ||
154 | def test_info_matrix_render(): | 162 | def test_info_matrix_render(): |
@@ -157,7 +165,12 @@ def test_info_matrix_render(): | |||
157 | assert 'Keyboard Name: handwired/onekey/pytest' in result.stdout | 165 | assert 'Keyboard Name: handwired/onekey/pytest' in result.stdout |
158 | assert 'Processor: STM32F303' in result.stdout | 166 | assert 'Processor: STM32F303' in result.stdout |
159 | assert 'LAYOUT_ortho_1x1' in result.stdout | 167 | assert 'LAYOUT_ortho_1x1' in result.stdout |
160 | assert '│0A│' in result.stdout | 168 | |
169 | if is_windows: | ||
170 | assert '|0A|' in result.stdout | ||
171 | else: | ||
172 | assert '│0A│' in result.stdout | ||
173 | |||
161 | assert 'Matrix for "LAYOUT_ortho_1x1"' in result.stdout | 174 | assert 'Matrix for "LAYOUT_ortho_1x1"' in result.stdout |
162 | 175 | ||
163 | 176 | ||