diff --git a/README.md b/README.md index 0c4b114..a10f816 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Usage: gen-compose [OPTIONS] [MAPPINGS]... Options: --key TEXT key to use as compose key [default: §] -r, --raw just keymap without prefix + -e, --escape-modifier-keys escape keys such as ^, so they're treated as the character and not a modifier --help Show this message and exit. ``` diff --git a/gencompose.py b/gencompose.py index 075f708..63699e6 100644 --- a/gencompose.py +++ b/gencompose.py @@ -66,14 +66,15 @@ def object_hook(dict_, func: Callable, types: Union[Tuple[Type], Type] = dict): @click.argument('mappings', type=click.File(), nargs=-1) @click.option('--key', default='§', show_default=True, help='key to use as compose key') @click.option('-r', '--raw', is_flag=True, help='just keymap without prefix') -def main(mappings, raw, key): +@click.option('-e', '--escape-modifier-keys', is_flag=True, help='escape modifier keys such as "^"') +def main(mappings, raw, key, escape_modifier_keys): """Generate macos rebind file from compose json mapping""" all_maps = {} for mapping in mappings: yamldata = yaml.load(mapping.read(), Loader=yaml.Loader) all_maps.update(**{str(k): str(v) for k, v in yamldata.items()}) all_maps = read_paths(all_maps) - text = data_to_mac_dict(all_maps) + text = data_to_mac_dict(all_maps, escape_modifier_keys) if raw: echo(text) else: @@ -114,7 +115,7 @@ def read_paths(data): return parsed -def data_to_mac_dict(data): +def data_to_mac_dict(data, escape_modifer_keys=False): """ converts dictionary data to macos keymap.dict format @@ -127,6 +128,10 @@ def data_to_mac_dict(data): }; }; """ + if escape_modifer_keys: + escape_special_chars = lambda c: f'\\{c}' if c in '^@~#$' else c + escape_keys = lambda d: {escape_special_chars(k): (escape_keys(v) if type(v) is dict else v) for k, v in d.items()} + data = escape_keys(data) updated = object_hook(data, lambda value: f'INSERT:{value}', str) text = json.dumps(updated, indent=2, ensure_ascii=False) repl = lambda value: f'("insertText:", "{value.groups()[0]}");' diff --git a/tests/test_gencompose.py b/tests/test_gencompose.py new file mode 100644 index 0000000..c8a0e17 --- /dev/null +++ b/tests/test_gencompose.py @@ -0,0 +1,14 @@ +from pathlib import Path + +from click.testing import CliRunner +from gencompose import main + + +def test_special_characters(): + runner = CliRunner() + file = Path(__file__).parent / 'test_special_chars.yaml' + result = runner.invoke(main, args=['--escape-modifier-keys', str(file)]) + print(result.output) + assert result.exit_code == 0 + assert '"\\\\^"' in result.output + assert '"2"' in result.output diff --git a/tests/test_special_chars.yaml b/tests/test_special_chars.yaml new file mode 100644 index 0000000..845cc31 --- /dev/null +++ b/tests/test_special_chars.yaml @@ -0,0 +1,5 @@ +^2: ² +$$: ﹩ +~~: ~ +"@@": @ +"#x": ⌧