2020-10-07 01:10:19 +01:00
""" Generate a keymap.json from a keymap.c file.
"""
2023-11-01 22:37:05 +00:00
import re
2020-10-07 01:10:19 +01:00
import json
2021-04-14 19:00:22 -07:00
from argcomplete . completers import FilesCompleter
2020-10-07 01:10:19 +01:00
from milc import cli
import qmk . path
2021-03-25 04:38:10 -07:00
from qmk . json_encoders import InfoJSONEncoder
2023-11-01 22:37:05 +00:00
from qmk . decorators import automagic_keyboard , automagic_keymap
2021-04-14 19:00:22 -07:00
from qmk . keyboard import keyboard_completer , keyboard_folder
2023-11-01 22:37:05 +00:00
from qmk . keymap import locate_keymap , find_keymap_from_dir , generate_json , c2json as c2json_impl
2021-05-27 17:42:38 +01:00
from qmk . errors import CppError
2023-11-01 22:37:05 +00:00
from qmk . commands import dump_lines
2020-10-07 01:10:19 +01:00
@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 " )
2023-11-01 22:37:05 +00:00
@cli.argument ( ' -kb ' , ' --keyboard ' , type = keyboard_folder , completer = keyboard_completer , help = ' The keyboard \' s name ' )
@cli.argument ( ' -km ' , ' --keymap ' , help = ' The keymap \' s name ' )
@cli.argument ( ' filename ' , nargs = ' ? ' , type = qmk . path . FileType ( ' r ' ) , arg_only = True , completer = FilesCompleter ( ' .c ' ) , help = ' keymap.c file ' )
2020-10-07 01:10:19 +01:00
@cli.subcommand ( ' Creates a keymap.json from a keymap.c file. ' )
2023-11-01 22:37:05 +00:00
@automagic_keyboard
@automagic_keymap
2020-10-07 01:10:19 +01:00
def c2json ( cli ) :
""" Generate a keymap.json from a keymap.c file.
This command uses the `qmk.keymap` module to generate a keymap.json from a keymap.c file. The generated keymap is written to stdout, or to a file if -o is provided.
"""
2023-11-01 22:37:05 +00:00
filename = cli . args . filename
keyboard = cli . config . c2json . keyboard
keymap = cli . config . c2json . keymap
2020-10-07 01:10:19 +01:00
2023-11-01 22:37:05 +00:00
if filename :
if not keyboard and not keymap :
# fallback to inferring keyboard/keymap from path
( keymap , found_type ) = find_keymap_from_dir ( filename )
if found_type == ' keymap_directory ' :
keyboard = re . search ( fr " keyboards/(.+)/keymaps/ { keymap } /.* " , filename . as_posix ( ) ) . group ( 1 )
2020-10-07 01:10:19 +01:00
2023-11-01 22:37:05 +00:00
elif keyboard and keymap :
if not filename :
# fallback to inferring keyboard/keymap from path
filename = locate_keymap ( keyboard , keymap )
if not all ( ( filename , keyboard , keymap ) ) :
cli . log . error ( ' You must supply keyboard and keymap, a path to a keymap.c within qmk_firmware, or absolute filename and keyboard and keymap ' )
cli . print_help ( )
return False
2020-10-07 01:10:19 +01:00
2021-05-27 17:42:38 +01:00
try :
2023-11-01 22:37:05 +00:00
keymap_json = c2json_impl ( keyboard , keymap , filename , use_cpp = cli . args . no_cpp )
2021-05-27 17:42:38 +01:00
except CppError as e :
if cli . config . general . verbose :
cli . log . debug ( ' The C pre-processor ran into a fatal error: %s ' , e )
cli . log . error ( ' Something went wrong. Try to use --no-cpp. \n Use the CLI in verbose mode to find out more. ' )
return False
2020-10-07 01:10:19 +01:00
# Generate the keymap.json
try :
2023-11-01 22:37:05 +00:00
keymap_json = generate_json ( keymap_json [ ' keymap ' ] , keymap_json [ ' keyboard ' ] , keymap_json [ ' layout ' ] , keymap_json [ ' layers ' ] )
2020-10-07 01:10:19 +01:00
except KeyError :
cli . log . error ( ' Something went wrong. Try to use --no-cpp. ' )
2020-12-29 20:34:48 +01:00
return False
2020-10-07 01:10:19 +01:00
if cli . args . output :
2023-11-01 22:37:05 +00:00
keymap_lines = [ json . dumps ( keymap_json , cls = InfoJSONEncoder , sort_keys = True ) ]
2020-10-07 01:10:19 +01:00
else :
2023-11-01 22:37:05 +00:00
keymap_lines = [ json . dumps ( keymap_json ) ]
dump_lines ( cli . args . output , keymap_lines , cli . args . quiet )