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 @@ Compile an info.json for a particular keyboard and pretty-print it. """ import json +import platform from milc import cli @@ -12,6 +13,8 @@ from qmk.keymap import locate_keymap from qmk.info import info_json from qmk.path import is_keyboard +platform_id = platform.platform().lower() + ROW_LETTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop' COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz' @@ -36,13 +39,13 @@ def show_keymap(kb_info_json, title_caps=True): else: cli.echo('{fg_cyan}layer_%s{fg_reset}:', layer_num) - print(render_layout(kb_info_json['layouts'][layout_name]['layout'], layer)) + print(render_layout(kb_info_json['layouts'][layout_name]['layout'], cli.config.info.ascii, layer)) def show_layouts(kb_info_json, title_caps=True): """Render the layouts with info.json labels. """ - for layout_name, layout_art in render_layouts(kb_info_json).items(): + for layout_name, layout_art in render_layouts(kb_info_json, cli.config.info.ascii).items(): title = layout_name.title() if title_caps else layout_name cli.echo('{fg_cyan}%s{fg_reset}:', title) print(layout_art) # Avoid passing dirty data to cli.echo() @@ -69,7 +72,7 @@ def show_matrix(kb_info_json, title_caps=True): else: cli.echo('{fg_blue}matrix_%s{fg_reset}:', layout_name) - print(render_layout(kb_info_json['layouts'][layout_name]['layout'], labels)) + print(render_layout(kb_info_json['layouts'][layout_name]['layout'], cli.config.info.ascii, labels)) def print_friendly_output(kb_info_json): @@ -124,6 +127,7 @@ def print_text_output(kb_info_json): @cli.argument('-l', '--layouts', action='store_true', help='Render the layouts.') @cli.argument('-m', '--matrix', action='store_true', help='Render the layouts with matrix information.') @cli.argument('-f', '--format', default='friendly', arg_only=True, help='Format to display the data in (friendly, text, json) (Default: friendly).') +@cli.argument('--ascii', action='store_true', default='windows' in platform_id, help='Render layout box drawings in ASCII only.') @cli.subcommand('Keyboard information.') @automagic_keyboard @automagic_keymap @@ -132,7 +136,7 @@ def info(cli): """ # Determine our keyboard(s) if not cli.config.info.keyboard: - cli.log.error('Missing paramater: --keyboard') + cli.log.error('Missing parameter: --keyboard') cli.subcommands['info'].print_help() return False 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 from qmk.c_parse import parse_config_h_file from qmk.makefile import parse_rules_mk_file +BOX_DRAWING_CHARACTERS = { + "unicode": { + "tl": "┌", + "tr": "┐", + "bl": "└", + "br": "┘", + "v": "│", + "h": "─", + }, + "ascii": { + "tl": " ", + "tr": " ", + "bl": "|", + "br": "|", + "v": "|", + "h": "_", + }, +} + base_path = os.path.join(os.getcwd(), "keyboards") + os.path.sep @@ -72,10 +91,12 @@ def rules_mk(keyboard): return rules -def render_layout(layout_data, key_labels=None): +def render_layout(layout_data, render_ascii, key_labels=None): """Renders a single layout. """ textpad = [array('u', ' ' * 200) for x in range(50)] + style = 'ascii' if render_ascii else 'unicode' + box_chars = BOX_DRAWING_CHARACTERS[style] for key in layout_data: x = ceil(key.get('x', 0) * 4) @@ -97,13 +118,13 @@ def render_layout(layout_data, key_labels=None): label = label[:label_len] label_blank = ' ' * label_len - label_border = '─' * label_len + label_border = box_chars['h'] * label_len label_middle = label + ' '*label_leftover # noqa: yapf insists there be no whitespace around * - top_line = array('u', '┌' + label_border + '┐') - lab_line = array('u', '│' + label_middle + '│') - mid_line = array('u', '│' + label_blank + '│') - bot_line = array('u', '└' + label_border + "┘") + top_line = array('u', box_chars['tl'] + label_border + box_chars['tr']) + lab_line = array('u', box_chars['v'] + label_middle + box_chars['v']) + mid_line = array('u', box_chars['v'] + label_blank + box_chars['v']) + bot_line = array('u', box_chars['bl'] + label_border + box_chars['br']) textpad[y][x:x + w] = top_line textpad[y + 1][x:x + w] = lab_line @@ -119,13 +140,13 @@ def render_layout(layout_data, key_labels=None): return '\n'.join(lines) -def render_layouts(info_json): +def render_layouts(info_json, render_ascii): """Renders all the layouts from an `info_json` structure. """ layouts = {} for layout in info_json['layouts']: layout_data = info_json['layouts'][layout]['layout'] - layouts[layout] = render_layout(layout_data) + layouts[layout] = render_layout(layout_data, render_ascii) 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 @@ +import platform + from subprocess import STDOUT, PIPE from qmk.commands import run +is_windows = 'windows' in platform.platform().lower() + def check_subcommand(command, *args): cmd = ['bin/qmk', command] + list(args) @@ -148,7 +152,11 @@ def test_info_keymap_render(): check_returncode(result) assert 'Keyboard Name: handwired/onekey/pytest' in result.stdout assert 'Processor: STM32F303' in result.stdout - assert '│A │' in result.stdout + + if is_windows: + assert '|A |' in result.stdout + else: + assert '│A │' in result.stdout def test_info_matrix_render(): @@ -157,7 +165,12 @@ def test_info_matrix_render(): assert 'Keyboard Name: handwired/onekey/pytest' in result.stdout assert 'Processor: STM32F303' in result.stdout assert 'LAYOUT_ortho_1x1' in result.stdout - assert '│0A│' in result.stdout + + if is_windows: + assert '|0A|' in result.stdout + else: + assert '│0A│' in result.stdout + assert 'Matrix for "LAYOUT_ortho_1x1"' in result.stdout