From 588bcdc8ca212b195a428fc43766a59a9252c08d Mon Sep 17 00:00:00 2001 From: Zach White Date: Wed, 14 Apr 2021 19:00:22 -0700 Subject: Add support for tab completion (#12411) * Add support for tab completion * make flake8 happy * Add documentation --- lib/python/qmk/cli/__init__.py | 14 ++++++++++++-- lib/python/qmk/cli/c2json.py | 7 ++++--- lib/python/qmk/cli/cformat.py | 3 ++- lib/python/qmk/cli/compile.py | 10 ++++++---- lib/python/qmk/cli/flash.py | 7 ++++--- lib/python/qmk/cli/generate/config_h.py | 4 ++-- lib/python/qmk/cli/generate/dfu_header.py | 3 ++- lib/python/qmk/cli/generate/info_json.py | 4 ++-- lib/python/qmk/cli/generate/layouts.py | 4 ++-- lib/python/qmk/cli/generate/rules_mk.py | 4 ++-- lib/python/qmk/cli/info.py | 4 ++-- lib/python/qmk/cli/json2c.py | 3 ++- lib/python/qmk/cli/kle2json.py | 3 ++- lib/python/qmk/cli/lint.py | 3 ++- lib/python/qmk/cli/list/keymaps.py | 4 ++-- lib/python/qmk/cli/new/keymap.py | 4 ++-- 16 files changed, 50 insertions(+), 31 deletions(-) (limited to 'lib/python/qmk/cli') diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py index 1349e68a9b..f7df908119 100644 --- a/lib/python/qmk/cli/__init__.py +++ b/lib/python/qmk/cli/__init__.py @@ -4,7 +4,7 @@ We list each subcommand here explicitly because all the reliable ways of searchi """ import sys -from milc import cli +from milc import cli, __VERSION__ from . import c2json from . import cformat @@ -47,5 +47,15 @@ from . import pytest # void: 3.9 if sys.version_info[0] != 3 or sys.version_info[1] < 7: - cli.log.error('Your Python is too old! Please upgrade to Python 3.7 or later.') + print('Error: Your Python is too old! Please upgrade to Python 3.7 or later.') + exit(127) + +milc_version = __VERSION__.split('.') + +if int(milc_version[0]) < 2 and int(milc_version[1]) < 3: + from pathlib import Path + + requirements = Path('requirements.txt').resolve() + + print(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}') exit(127) diff --git a/lib/python/qmk/cli/c2json.py b/lib/python/qmk/cli/c2json.py index 1fa833b647..e66b0a1b58 100644 --- a/lib/python/qmk/cli/c2json.py +++ b/lib/python/qmk/cli/c2json.py @@ -2,20 +2,21 @@ """ 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.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder @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") -@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, required=True, help='The keyboard\'s name') +@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='The keyboard\'s name') @cli.argument('-km', '--keymap', arg_only=True, required=True, help='The keymap\'s name') -@cli.argument('filename', arg_only=True, help='keymap.c file') +@cli.argument('filename', arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file') @cli.subcommand('Creates a keymap.json from a keymap.c file.') def c2json(cli): """Generate a keymap.json from a keymap.c file. diff --git a/lib/python/qmk/cli/cformat.py b/lib/python/qmk/cli/cformat.py index c7e93b2ab6..d0d3b3b0a3 100644 --- a/lib/python/qmk/cli/cformat.py +++ b/lib/python/qmk/cli/cformat.py @@ -3,6 +3,7 @@ import subprocess from shutil import which +from argcomplete.completers import FilesCompleter from milc import cli from qmk.path import normpath @@ -33,7 +34,7 @@ def cformat_run(files, all_files): @cli.argument('-a', '--all-files', arg_only=True, action='store_true', help='Format all core files.') @cli.argument('-b', '--base-branch', default='origin/master', help='Branch to compare to diffs to.') -@cli.argument('files', nargs='*', arg_only=True, help='Filename(s) to format.') +@cli.argument('files', nargs='*', arg_only=True, completer=FilesCompleter('.c'), help='Filename(s) to format.') @cli.subcommand("Format C code according to QMK's style.", hidden=False if cli.config.user.developer else True) def cformat(cli): """Format C code according to QMK's style. diff --git a/lib/python/qmk/cli/compile.py b/lib/python/qmk/cli/compile.py index 5793e98928..23ca4e00a6 100755 --- a/lib/python/qmk/cli/compile.py +++ b/lib/python/qmk/cli/compile.py @@ -2,17 +2,19 @@ You can compile a keymap already in the repo or using a QMK Configurator export. """ +from argcomplete.completers import FilesCompleter from milc import cli import qmk.path from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder +from qmk.keymap import keymap_completer -@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), help='The configurator export to compile') -@cli.argument('-kb', '--keyboard', type=keyboard_folder, help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.') -@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Ignored when a configurator export is supplied.') +@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='The configurator export to compile') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.') +@cli.argument('-km', '--keymap', completer=keymap_completer, help='The keymap to build a firmware for. Ignored when a configurator export is supplied.') @cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.") @cli.argument('-j', '--parallel', type=int, default=1, help="Set the number of parallel make jobs to run.") @cli.argument('-e', '--env', arg_only=True, action='append', default=[], help="Set a variable to be passed to make. May be passed multiple times.") diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py index c9273c3f98..1b67840616 100644 --- a/lib/python/qmk/cli/flash.py +++ b/lib/python/qmk/cli/flash.py @@ -4,12 +4,13 @@ You can compile a keymap already in the repo or using a QMK Configurator export. A bootloader must be specified. """ +from argcomplete.completers import FilesCompleter from milc import cli import qmk.path from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder def print_bootloader_help(): @@ -30,11 +31,11 @@ def print_bootloader_help(): cli.echo('For more info, visit https://docs.qmk.fm/#/flashing') -@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), help='The configurator export JSON to compile.') +@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='The configurator export JSON to compile.') @cli.argument('-b', '--bootloaders', action='store_true', help='List the available bootloaders.') @cli.argument('-bl', '--bootloader', default='flash', help='The flash command, corresponding to qmk\'s make options of bootloaders.') @cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.') -@cli.argument('-kb', '--keyboard', type=keyboard_folder, help='The keyboard to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.') @cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.") @cli.argument('-j', '--parallel', type=int, default=1, help="Set the number of parallel make jobs to run.") @cli.argument('-e', '--env', arg_only=True, action='append', default=[], help="Set a variable to be passed to make. May be passed multiple times.") diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index ccea6d7a05..54cd5b96a8 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -8,7 +8,7 @@ from milc import cli from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.info import info_json from qmk.json_schema import json_load -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder from qmk.path import is_keyboard, normpath @@ -75,7 +75,7 @@ def matrix_pins(matrix_pins): @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', type=keyboard_folder, help='Keyboard to generate config.h for.') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate config.h for.') @cli.subcommand('Used by the make system to generate info_config.h from info.json', hidden=True) @automagic_keyboard @automagic_keymap diff --git a/lib/python/qmk/cli/generate/dfu_header.py b/lib/python/qmk/cli/generate/dfu_header.py index 6f958b3a3d..211ed9991a 100644 --- a/lib/python/qmk/cli/generate/dfu_header.py +++ b/lib/python/qmk/cli/generate/dfu_header.py @@ -6,11 +6,12 @@ from milc import cli from qmk.decorators import automagic_keyboard from qmk.info import info_json from qmk.path import is_keyboard, normpath +from qmk.keyboard import keyboard_completer @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', help='Keyboard to generate LUFA Keyboard.h for.') +@cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='Keyboard to generate LUFA Keyboard.h for.') @cli.subcommand('Used by the make system to generate LUFA Keyboard.h from info.json', hidden=True) @automagic_keyboard def generate_dfu_header(cli): diff --git a/lib/python/qmk/cli/generate/info_json.py b/lib/python/qmk/cli/generate/info_json.py index 1af7f04392..8931b68b6f 100755 --- a/lib/python/qmk/cli/generate/info_json.py +++ b/lib/python/qmk/cli/generate/info_json.py @@ -11,7 +11,7 @@ from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.info import info_json from qmk.json_encoders import InfoJSONEncoder from qmk.json_schema import load_jsonschema -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder from qmk.path import is_keyboard @@ -41,7 +41,7 @@ def strip_info_json(kb_info_json): return validator(kb_info_json) -@cli.argument('-kb', '--keyboard', type=keyboard_folder, help='Keyboard to show info for.') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='Keyboard to show info for.') @cli.argument('-km', '--keymap', help='Show the layers for a JSON keymap too.') @cli.subcommand('Generate an info.json file for a keyboard.', hidden=False if cli.config.user.developer else True) @automagic_keyboard diff --git a/lib/python/qmk/cli/generate/layouts.py b/lib/python/qmk/cli/generate/layouts.py index 7b4394291f..ad6946d6cf 100755 --- a/lib/python/qmk/cli/generate/layouts.py +++ b/lib/python/qmk/cli/generate/layouts.py @@ -5,7 +5,7 @@ from milc import cli from qmk.constants import COL_LETTERS, ROW_LETTERS from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.info import info_json -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder from qmk.path import is_keyboard, normpath usb_properties = { @@ -17,7 +17,7 @@ usb_properties = { @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', type=keyboard_folder, help='Keyboard to generate config.h for.') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate config.h for.') @cli.subcommand('Used by the make system to generate layouts.h from info.json', hidden=True) @automagic_keyboard @automagic_keymap diff --git a/lib/python/qmk/cli/generate/rules_mk.py b/lib/python/qmk/cli/generate/rules_mk.py index 91759d26c6..41c94e16b5 100755 --- a/lib/python/qmk/cli/generate/rules_mk.py +++ b/lib/python/qmk/cli/generate/rules_mk.py @@ -8,7 +8,7 @@ from milc import cli from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.info import info_json from qmk.json_schema import json_load -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder from qmk.path import is_keyboard, normpath @@ -39,7 +39,7 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict): @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('-e', '--escape', arg_only=True, action='store_true', help="Escape spaces in quiet mode") -@cli.argument('-kb', '--keyboard', type=keyboard_folder, help='Keyboard to generate config.h for.') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate config.h for.') @cli.subcommand('Used by the make system to generate info_config.h from info.json', hidden=True) @automagic_keyboard @automagic_keymap diff --git a/lib/python/qmk/cli/info.py b/lib/python/qmk/cli/info.py index aac507c1a5..572b305cac 100755 --- a/lib/python/qmk/cli/info.py +++ b/lib/python/qmk/cli/info.py @@ -10,7 +10,7 @@ from milc import cli from qmk.json_encoders import InfoJSONEncoder from qmk.constants import COL_LETTERS, ROW_LETTERS from qmk.decorators import automagic_keyboard, automagic_keymap -from qmk.keyboard import keyboard_folder, render_layouts, render_layout +from qmk.keyboard import keyboard_completer, keyboard_folder, render_layouts, render_layout from qmk.keymap import locate_keymap from qmk.info import info_json from qmk.path import is_keyboard @@ -124,7 +124,7 @@ def print_text_output(kb_info_json): show_keymap(kb_info_json, False) -@cli.argument('-kb', '--keyboard', type=keyboard_folder, help='Keyboard to show info for.') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='Keyboard to show info for.') @cli.argument('-km', '--keymap', help='Show the layers for a JSON keymap too.') @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.') diff --git a/lib/python/qmk/cli/json2c.py b/lib/python/qmk/cli/json2c.py index 5a2fb96c78..a90578c021 100755 --- a/lib/python/qmk/cli/json2c.py +++ b/lib/python/qmk/cli/json2c.py @@ -2,6 +2,7 @@ """ import json +from argcomplete.completers import FilesCompleter from milc import cli import qmk.keymap @@ -10,7 +11,7 @@ import qmk.path @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") -@cli.argument('filename', type=qmk.path.FileType('r'), arg_only=True, help='Configurator JSON file') +@cli.argument('filename', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') @cli.subcommand('Creates a keymap.c from a QMK Configurator export.') def json2c(cli): """Generate a keymap.c from a configurator export. diff --git a/lib/python/qmk/cli/kle2json.py b/lib/python/qmk/cli/kle2json.py index 91499c9af3..acb75ef4fd 100755 --- a/lib/python/qmk/cli/kle2json.py +++ b/lib/python/qmk/cli/kle2json.py @@ -4,6 +4,7 @@ import json import os from pathlib import Path +from argcomplete.completers import FilesCompleter from milc import cli from kle2xy import KLE2xy @@ -11,7 +12,7 @@ from qmk.converter import kle2qmk from qmk.json_encoders import InfoJSONEncoder -@cli.argument('filename', help='The KLE raw txt to convert') +@cli.argument('filename', completer=FilesCompleter('.json'), help='The KLE raw txt to convert') @cli.argument('-f', '--force', action='store_true', help='Flag to overwrite current info.json') @cli.subcommand('Convert a KLE layout to a Configurator JSON', hidden=False if cli.config.user.developer else True) def kle2json(cli): diff --git a/lib/python/qmk/cli/lint.py b/lib/python/qmk/cli/lint.py index 74467021e0..a164dba632 100644 --- a/lib/python/qmk/cli/lint.py +++ b/lib/python/qmk/cli/lint.py @@ -4,12 +4,13 @@ from milc import cli from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.info import info_json +from qmk.keyboard import keyboard_completer from qmk.keymap import locate_keymap from qmk.path import is_keyboard, keyboard @cli.argument('--strict', action='store_true', help='Treat warnings as errors.') -@cli.argument('-kb', '--keyboard', help='The keyboard to check.') +@cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='The keyboard to check.') @cli.argument('-km', '--keymap', help='The keymap to check.') @cli.subcommand('Check keyboard and keymap for common mistakes.') @automagic_keyboard diff --git a/lib/python/qmk/cli/list/keymaps.py b/lib/python/qmk/cli/list/keymaps.py index 7c0ad43997..d79ab75b58 100644 --- a/lib/python/qmk/cli/list/keymaps.py +++ b/lib/python/qmk/cli/list/keymaps.py @@ -4,10 +4,10 @@ from milc import cli import qmk.keymap from qmk.decorators import automagic_keyboard -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder -@cli.argument("-kb", "--keyboard", type=keyboard_folder, help="Specify keyboard name. Example: 1upkeyboards/1up60hse") +@cli.argument("-kb", "--keyboard", type=keyboard_folder, completer=keyboard_completer, help="Specify keyboard name. Example: 1upkeyboards/1up60hse") @cli.subcommand("List the keymaps for a specific keyboard") @automagic_keyboard def list_keymaps(cli): diff --git a/lib/python/qmk/cli/new/keymap.py b/lib/python/qmk/cli/new/keymap.py index ea98a287c1..60cb743cb6 100755 --- a/lib/python/qmk/cli/new/keymap.py +++ b/lib/python/qmk/cli/new/keymap.py @@ -5,11 +5,11 @@ from pathlib import Path import qmk.path from qmk.decorators import automagic_keyboard, automagic_keymap -from qmk.keyboard import keyboard_folder +from qmk.keyboard import keyboard_completer, keyboard_folder from milc import cli -@cli.argument('-kb', '--keyboard', type=keyboard_folder, help='Specify keyboard name. Example: 1upkeyboards/1up60hse') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='Specify keyboard name. Example: 1upkeyboards/1up60hse') @cli.argument('-km', '--keymap', help='Specify the name for the new keymap directory') @cli.subcommand('Creates a new keymap for the keyboard of your choosing') @automagic_keyboard -- cgit v1.2.3