GithubHelp home page GithubHelp logo

caksoylar / keymap-drawer Goto Github PK

View Code? Open in Web Editor NEW
514.0 1.0 52.0 658 KB

Visualize keymaps that use advanced features like hold-taps and combos, with automatic parsing

Home Page: https://caksoylar.github.io/keymap-drawer

License: MIT License

Python 99.65% HTML 0.35%
keyboard keymaps qmk qmk-keymap zmk keymap-drawer

keymap-drawer's People

Contributors

art4ride avatar bryanforbes avatar caksoylar avatar calumy avatar casuanoob avatar englmaxi avatar finrod09 avatar hellothisisflo avatar jaeyounglee978 avatar jbarr21 avatar jcmkk3 avatar kilipan avatar lugoues avatar manna-harbour avatar michaelrommel avatar minusfive avatar nickcoutsos avatar sethmilliken avatar shroomist avatar stasmarkin avatar thebino avatar xudongzheng avatar yellowafterlife avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

keymap-drawer's Issues

Provide config option to enable drawing of held key's binding

My keymap has two ways of going to another layer, either through holding a key with &mo or using a combo for &tog. The &mo key on that layer has its own binding to be used for the &tog option so I would like to display it on the layer. However, the keymap drawing only highlights the held key and does not show the binding (I looked through the config options provided but could not find a relevant config). Would it be possible to provide a config option to draw the bindings of held keys?

Workflow draw_args not applied

I am trying to use the ZMK generation as part of my GitHub workflow, unfortunately the draw_args are not applied.

As you can see in my config I want to select the keybaord with --qmk-keybard or -k.
When I do this on the CLI it works as intended, when I try to apply this to the action it unfortunately does not apply the keybard. (latest log: https://github.com/Roang-zero1/zmk-soflev2/actions/runs/6095789469/job/16540062027)

PS: The sample workflow is missing the permissions to write back to the repository: e.g. https://github.com/Roang-zero1/zmk-soflev2/blob/main/.github/workflows/draw-keymaps.yml#L13-L14

Feature request: binding inheritence or aliases

I've noticed that since ZMK has so many duplicate keybind definitions, I end up with excessively large binding maps:

RET:
  type: enter
  tap: $$mdi:keyboard-return$$
RETURN:
  type: enter
  tap: $$mdi:keyboard-return$$
ENTER:
  type: enter
  tap: $$mdi:keyboard-return$$
ESC: $$mdi:keyboard-esc$$
ESCAPE: $$mdi:keyboard-esc$$
TAB: $$mdi:keyboard-tab$$
LS(TAB): $$mdi:keyboard-tab-reverse$$
SPACE: $$mdi:keyboard-space$$
BACKSPACE:
  type: backspace
  tap: $$mdi:backspace$$
BSPC:
  type: backspace
  tap: $$mdi:backspace$$
DELETE: $$mdi:backspace-reverse-outline$$
DEL: $$mdi:backspace-reverse-outline$$

LALT: 'Alt'
LEFT_ALT: 'Alt'
RALT: 'AltGr' # UK layout
RIGHT_ALT: 'AltGr' # UK layout
LCTRL: 'Ctrl'
LEFT_CONTROL: 'Ctrl'
RCTRL: 'Ctrl'
RIGHT_CONTROL: 'Ctrl'
LSHFT: $$mdi:apple-keyboard-shift$$
LSHIFT: $$mdi:apple-keyboard-shift$$
LEFT_SHIFT: $$mdi:apple-keyboard-shift$$
RSHFT: $$mdi:apple-keyboard-shift$$
RSHIFT: $$mdi:apple-keyboard-shift$$
RIGHT_SHIFT: $$mdi:apple-keyboard-shift$$
LGUI:
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info
LEFT_GUI:
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info
LMETA:
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info
LEFT_META:
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info

Solution 1: Inheritance

One strategy to to mitigate this would be an inherit, base, or extend field:

LGUI:
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info
LEFT_GUI:
  base: LGUI
LMETA: {base: LGUI}
LEFT_META: {b: LGUI}

This could also be used for similar binds, as aything defined on the inheriting bind would override the base definition.

One complexity would be recursive binds. These should produce an error:

# Recursive
LEFT_GUI:
  base: LEFT_META
LEFT_META:
  b: LEFT_GUI

Approach 2: Aliases

A different approach might be to have an "also applies to" field:

# alias field accepts a list of strings
LGUI:
  alias: [ 'LEFT_GUI', 'LMETA', 'LEFT_META' ]
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info

If a bind is defined multiple times, they could be combined (similar to inheritance) or simply let the one defined last override previous definitions (perhaps with a warning)?

# LEFT_GUI bind is defined twice
LGUI:
  alias: [ 'LEFT_GUI', 'LMETA', 'LEFT_META' ]
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info
LEFT_GUI:
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info

Approach 3: Parse map keys into lists

Another approach would be mapping list->bind instead of string->bind, however since yaml doesn't have syntax for that we'd have to invent our own:

# Space separated could work?
'LGUI LEFT_GUI LMETA LEFT_META':
  tap: $$mdi:monitor-dashboard$$
  hold: Meta
  type: info

Personally, I think the approach 2 (aliases) works best 🤔

Tabler icons are not loaded anymore

The loading of Tabler icons is failing with an not-found

 Traceback (most recent call last):
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/draw/glyph.py", line 143, in _fetch_svg_url
    with urlopen(url) as f:
  File "/usr/lib/python3.10/urllib/request.py", line 216, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.10/urllib/request.py", line 525, in open
    response = meth(req, response)
  File "/usr/lib/python3.10/urllib/request.py", line 634, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.10/urllib/request.py", line 557, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.10/urllib/request.py", line 496, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.10/urllib/request.py", line 749, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python3.10/urllib/request.py", line 525, in open
    response = meth(req, response)
  File "/usr/lib/python3.10/urllib/request.py", line 634, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.10/urllib/request.py", line 563, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.10/urllib/request.py", line 496, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.10/urllib/request.py", line 643, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/.local/bin/keymap", line 8, in <module>
    sys.exit(main())
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/__main__.py", line 178, in main
    draw(args, config.draw_config)
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/__main__.py", line 42, in draw
    drawer = KeymapDrawer(
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/draw/draw.py", line 25, in __init__
    self.init_glyphs()
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/draw/glyph.py", line 58, in init_glyphs
    self.name_to_svg |= self._fetch_glyphs(rest)
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/draw/glyph.py", line 81, in _fetch_glyphs
    return dict(zip(names, p.map(fetch_fn, names, urls, timeout=FETCH_TIMEOUT)))
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 623, in result_iterator
    yield _result_or_cancel(fs.pop(), end_time - time.monotonic())
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 319, in _result_or_cancel
    return fut.result(timeout)
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 458, in result
    return self.__get_result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/draw/glyph.py", line 151, in _fetch_svg_url
    raise ValueError(f'Could not fetch SVG from URL "{url}"') from exc
ValueError: Could not fetch SVG from URL "https://unpkg.com/@tabler/icons/icons/screenshot.svg"
ERROR: parsing or drawing failed for corne!

Parse cornish_zen.keymap

There's an example YAML for the corneish zen (https://github.com/caksoylar/keymap-drawer/blob/main/examples/corneish_zen.yaml) which is said to be parsed and tweaked from the original keymap (https://github.com/LOWPROKB/zmk-config-zen-2/blob/main/config/corneish_zen.keymap). Attempting to use the original keymap on the streamlitapp gives:
"AssertionError: Physical layout needs to be specified via the "layout" field in keymap YAML"

Is it possible to parse a ZMK keymap online?

Get help action to add to ZMK archive.

When using ZMK the workflow is that when you push it commit a github action starts that builds a zip download of the firmware. I would really love the key map image to be part of that zip archive. That way if I have multiple archives on my computer I easily tell what key map each set of firmware will use.

I don't know if this is possible, but it would be really cool if it was!

Feature request: export layout config for the GitHub action

While using the keymap-drawer action, if the draw_args are provided for type of keyboard or layout as a override, can we please put this details in the keyboard.yaml (keymap yaml) file in the output folder.

      draw_args: "lynx:'-k ferris/sweep -l LAYOUT_split_3x5_2'"

would have output in lynx.yaml config as

layout:
  qmk_keyboard: ferris/sweep
  qmk_layout: LAYOUT_split_3x5_2

This way I can just use the whole config file in the online svg editor.

Automatically determine best alignment for combos

Currently, the alignment for all combos seems to be middle, but for combos that span three keys horizontally or vertically, this ends up covering other keys.

A top or left/right default alignment for those combos would be better.

Here is an image as an example:
Screenshot 2023-03-02 at 14 14 57

Fetched SVGs not showing in web app or embedded in readme.md

When using the new feature to fetch SVG from supported sources (e.g. $$material:keyboard_return$$), they show in chrome when viewing the layout directly, but show up blank in the web app or when I embed the layout svg in my github readme. They also show up fine in inkscape.

Allow loading SVG icons from the filesystem

In addition to glyph_urls remote sources and glyphs embedded SVGs, it'd be useful to be able to load SVGs from the local filesystem.

While you could probably pass file:// URLs to glyph_urls (untested), this would only support absolute paths and would still be cached in the same way as remote SVG files.

Motivation

This would be useful to enable users to define a config that has no online dependencies (at runtime), allowing tools like nix to run keymap-drawer during a "pure" build step.

Currently this is only possible if all icons are defined in the yaml config via glyphs.

Implementation

Perhaps allow glyph_urls to also accept path values? Alternatively introduce a new glyph_paths or glyph_dirs to avoid confusion.

It may also be useful to load specific files. One approach might be to allow glyphs to also support path values. Again, this could be a new option (glyph_files?) if preferred.

Relative paths should be resolved relative to the config file, not the current working directory.

SVGs loaded from the local filesystem shouldn't be cached, regardless of use_local_cache.

View is cut off when combo description is offset

I have my combo offset like this:

 zmk_combos:
    combo_mouse:
      align: top
      offset: 0.4

and the resulting SVG is cut off at the top:
obraz

Is there a way to calculate the viewBox correctly with this or at least add some manual offset?

Populate transparent keys

My ZMK config features a lot of &trans keys. Unfortunately, keymap-drawer only shows them as blank keys. Please consider to update transparent keys from the same key position on the layer below, transitively going down to the base layer.

Thank you.

Better parsing and output of mod + key press

Currently, ZMK key presses like &kp LG(GRAVE) and &kp LS(LC(TAB)) are output verbatim. It would be nice if they were parsed and output in a prettier way. I am currently modifying my keymap YAML file so they look something like:

  - {t: GRAVE, h: LGUI}
  - {t: TAB, h: LSFT, LCTL}

I think t is supposed to be tap and h hold. maybe there's another thing, m that could place the modifier at the top of the key instead of the bottom?

bug: `draw_separate` does not work anymore

I noticed that with yesterdays commit 18e8d72, I get an error during parsing:

Traceback (most recent call last):
  File "/home/runner/.local/bin/keymap", line 8, in <module>
    sys.exit(main())
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/__main__.py", line 180, in main
    parse(args, config.parse_config)
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/__main__.py", line 70, in parse
    parsed = ZmkKeymapParser(config, args.columns, base_keymap=base, layer_names=args.layer_names).parse(
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/parse/parse.py", line 90, in parse
    layout, keymap_data = self._parse(in_buf.read(), in_buf.name)
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/parse/zmk.py", line 238, in _parse
    combos = self._get_combos(dts)
  File "/home/runner/.local/lib/python3.10/site-packages/keymap_drawer/parse/zmk.py", line 202, in _get_combos
    combos.append(ComboSpec(**(combo | cfg_combo)))
TypeError: keywords must be strings

I found that draw_separate: true on some of my combos in zmk_combos is the reason for this (It works without).

I don't know if my config is set up wrongly or if there is a mistake on my side, but I did not find anything obvious.

TRANS keys some times not picked up correctly

Hello. I have the following piece of keymap:

ZMK_LAYER(Mouse,
&trans  &trans &trans &trans &trans &trans                          &trans U_WH_L U_MS_U U_WH_R &trans    &trans
  &trans  &sk LGUI  &sk LALT  &sk LCTRL  &sk LSHFT  &trans          &trans U_MS_L U_MS_D U_MS_R  &trans &trans
        &trans &trans &trans &trans &trans &trans                    &trans U_WH_D U_WH_U &trans &trans &trans
                             &trans &trans &trans    U_BTN3 U_BTN1 U_BTN2
)

notice the three transparent keys in left side thumb cluster.

Which then gets translated to a held key for some reason:

  - - {t: '$$mdi:transfer$$', type: trans}
    - {t: '$$mdi:transfer$$', type: trans}
    - {type: held}
    - $$mdi:numeric-3-circle$$
    - $$mdi:numeric-1-circle$$
    - $$mdi:numeric-2-circle$$

obraz

There must be some relation to other keys that I can't figure out - or a bug?

My complete keymap: https://github.com/anarion80/zmk-config-corneish-zen/blob/main/config/base.keymap
My keymap_drawer_config: https://github.com/anarion80/zmk-config-corneish-zen/blob/main/keymap_drawer_config.yaml
Resulting keymap.yaml: https://github.com/anarion80/zmk-config-corneish-zen/blob/main/corneish_zen_keymap.yaml
generated using the following command: keymap -c keymap_drawer_config.yaml parse -c12 -z config/corneish_zen.keymap > corneish_zen_keymap.yaml

keymap version: 0.13.1

feature request: add support for overlaid devicetree node property values

I have a shared .dtsi file that defines most of the ZMK behaviors I use across multiple boards. But some boards require different values for specific properties in some of these behaviors, predominantly key-positions in combos. I accomplish this for ZMK by using a second local #include of an .overlay file which uses node label references to override the necessary property values. But this does not currently work for keymap-drawer, which appears to use only the original node definitions. I would like to add support for this kind of devicetree overlay to keymap-drawer.

Example:

For boards that mostly have this layout:

0 1 2 3
4 5 6 7

here is a sample shared.dtsi:

/ {
    combos {
      compatible = "zmk,combos";

      combo_delete: combo_delete {
        timeout-ms: <75>;
        slow-release;
        key-positions: <0 4>;
        bindings = <&kp DELETE>;
        layers = <0>;
      };
    };
};

And for a board having more columns, with a layout like this:

0 1 2 3  4  5
6 7 8 9 10 11

here is a sample wider.overlay:

&combo_delete {
  key-positions: <0 6>;
};

So at the top of wider.keymap there would be:

...
#include "shared.dtsi"
#include "wider.overlay"
...

which would result in a modified combo_delete node with only the key-positions property value changed.

Allow dict config for zmk_keycode_map and qmk_keycode_map

Hi,

First of all, thank you so much for creating this. It works really well and is super useful.

I have one small feature request:

The raw_binding_map allows you to specify a dict that draws multiple symbols for a key, such as

  raw_binding_map:
     &mm_grescm_gui': {t: ESC, h: ⌘, s: '` ~'}

Since default &kp keys can also have multiple binding, such as / ?, it would be great if we could assign multiple values to those too, like:

  zmk_keycode_map:
    SLASH: {t: "/", s: '?'}

But currently this raises an error:

❯ keymap -c chocofi_keymap_config.yaml parse -c 10 -z ../config/corne.keymap > chocofi_keymap.yaml && keymap -c chocofi_keymap_config.yaml draw -k crkbd/rev1 chocofi_keymap.yaml > chocofi_keymap.svg
Traceback (most recent call last):
  File "/Users/Kim/.local/bin/keymap", line 8, in <module>
    sys.exit(main())
  File "/Users/Kim/.local/pipx/venvs/keymap-drawer/lib/python3.10/site-packages/keymap_drawer/__main__.py", line 147, in main
    config = Config.parse_obj(yaml.safe_load(f))
  File "pydantic/main.py", line 527, in pydantic.main.BaseModel.parse_obj
  File "pydantic/env_settings.py", line 39, in pydantic.env_settings.BaseSettings.__init__
  File "pydantic/main.py", line 342, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 5 validation errors for Config
parse_config -> qmk_keycode_map -> COMMA
  str type expected (type=type_error.str)
parse_config -> qmk_keycode_map -> DOT
  str type expected (type=type_error.str)
parse_config -> qmk_keycode_map -> SLASH
  str type expected (type=type_error.str)
parse_config -> qmk_keycode_map -> SLSH
  str type expected (type=type_error.str)
parse_config -> zmk_keycode_map -> SINGLE_QUOTE
  str type expected (type=type_error.str)

Thank you for taking the time to consider this.

ZMK Combos with no layers show up on all layers

Hi, another small issue that I just came across.

I wanted to disable a macro in my zmk config, but keep it in case I change my mind later. So I set the layers setting to empty. This disabled the macro in the firmwar.

But when I updated my keymap image, the macros with the empty layer setting showed up on all layers.

Example config:

# Shows up on all layers
    combo_grave {
      timeout-ms = <COMBO_TERM_SLOW>;
      global-quick-tap-ms = <COMBO_GLOBAL_QUICKTAP>;

      key-positions = <RM3 RM4>;
      layers = <>;
      bindings = <&kp GRAVE>;
    };

# Shows up only on one layer
    combo_md_code_block {
      timeout-ms = <COMBO_TERM_SLOW>;
      global-quick-tap-ms = <COMBO_GLOBAL_QUICKTAP>;

      key-positions = <RM2 RM3 RM4>;
      layers = <BASE>;
      bindings = <&m_type_md_code_block>;
    };

Piping to base keymap file results in error

The following causes the parse command to fail:

$ keymap parse -b keymap.yaml -z board.keymap > keymap.yaml
Traceback (most recent call last):
  File "/Users/lilactown/Library/Caches/pypoetry/virtualenvs/keymap-drawer-BqElniGm-py3.10/bin/keymap", line 6, in <module>
    sys.exit(main())
  File "/Users/lilactown/Code/keymap-drawer/keymap_drawer/__main__.py", line 157, in main
    parse(args, config.parse_config)
  File "/Users/lilactown/Code/keymap-drawer/keymap_drawer/__main__.py", line 53, in parse
    base = KeymapData(layers=yaml_data["layers"], combos=yaml_data.get("combos", []), layout=None, config=None)
TypeError: 'NoneType' object is not subscriptable

Add symbols option for keycode mapping and convert modified keycodes to use them

If we commit to use unicode symbols in the keymap, e.g. for arrow keys or for modifiers (like for GUI, for shift), we can either default to those in the keycode conversion in parse_config.*_bindings_map or more likley add them as an alternative that can be toggled on or off (parse_config.use_symbols: bool = True).

We can also convert modified functions to automatically <symbol>keycode representations like https://github.com/infused-kim/zmk-config/blob/9f2ed72247120b9439df989bf1361a04f4646278/keymap_img/chocofi_keymap_config.yaml#L283. I think that might make @infused-kim's life easier as well!

Feature request: holds for combos

Love the new keymap-drawer! I'm using it on https://github.com/sartak/keyboard#keymap :)

One feature that would be nice to support holds for combos. This is pretty easy in ZMK with a combo that triggers a hold-tap. It's also possible in QMK though you kinda have to roll your own timers and such.

This would let me simplify my keymap - rather than having separate "Alpha" and "Alpha (hold)" layers, I could have something like:

combos:
- {"tap":"LC", "hold":"⌘LC", "p":[30,31]}
- {"tap":"AltBS", "hold":"Hyper", "p":[31,32]}

Alternatively, it might be good enough to support type styling options for combos like there are for keys:

combos:
- {"k":"LC", "p":[30,31]}
- {"k":"⌘LC", "p":[30,31], "type":"ghost or green or whatever"}

Thanks for making this tool!

parse: keyboard name detection fails for files in nix store

keymap parse tries to guess the keyboard name by looking for the keymap filename (without extension) in zmk_keyboard_layouts.yaml.

This fails when the filename has additional prefixed/suffixed text. For example, if the file is in the /nix/store the filename is likely to have a NAR hash prefix:

trace:
    basename is "glove80.keymap"
    path "/nix/store/3c3kn02n760mlhf9bn5zgbzr07ch696s-glove80.keymap"
    python `path.stem` is "3c3kn02n760mlhf9bn5zgbzr07ch696s-glove80"

(Internally, nix ignores the NAR hash when reporting basename).

Potential solutions:

  • More lenient lookup
    • use the longest matching substring found
  • Strip known prefixes/suffixes before lookup
  • Strip nix's NAR hashes specifically before lookup
  • Provide a way to override "keyboard name" without explicitly setting the layout
    • Maybe this exists and I've missed it?

QMK

I assume this also applies to QMK

Feature Request: Allow re-parsing without overwriting customizations

Sorry, but I have another feature request / suggestions... :)

My use-case is that I want to be able to edit my ZMK keymap and then generate a pretty representation of it without having to manually keep the ZMK keymap and graphics in sync.

Currently that's not possible, because reparsing overwrites whatever changes you have made in the yaml keymap.

My current workaround is to use a python script that makes my adjustments inside the keymap yaml. I imagine that I am not the only one who wants this, so perhaps that is a feature you could consider for the future.

And in the meantime, other users can use my solution as a workaround, which can be found here:

https://github.com/infused-kim/zmk-config/tree/chocofi/main/keymap_img

Preprocess keys in `raw_bindings_map` before using it

I have a behavior like this which expects two parameter, but doesn't actually use the second parameter:

        lt_num_word: lt_num_word {
            compatible = "zmk,behavior-hold-tap";
            label = "lt_num_word";
            #binding-cells = <2>;
            flavor = "balanced";
            tapping-term-ms = <200>;
            bindings = <&mo>, <&num_word>;
        };

And in my keymap I use it like &lt_num_word NUM 0. Unfortunately it shows up like this in the graphic:
Screenshot 2023-03-07 at 13 52 12

Perhaps the solution could be as simple as allowing the config to overwrite the entire behavior:

  raw_binding_map:
    '&lt_num_word NUM 0': {t: "Num\nWord", h: 'Num'}

Feature request: Alt-Gr key labels

Hi,

keymap-drawer has the the following fields that show up for a key: tap, hold and shifted. Some European keymaps make extensive use of the Alt-Gr (aka. right ALT) key to add another layer of keys. These mostly include signs like @, , [, ] or |. See the AZERTZY layout, for example.

It might be beneficial to have some of them printed on the generated keymap. Using the hold field as an alternative is not a good option, since Alt-Gr is (like the shifted state) a tap field., which is additional to all the other fields which are already present. I propose to add another field to LayoutKey, maybe called alt. It could be printed on the right side of the physical key.

MoErgo's Glove80's triggering the assert "Number of keys on layer {} does not match physical layout specification"

Steps to reproduce

  1. Git clone github.com/x10an14/glove80-layout
  2. cd glove80-layout && git checkout ce86ca203ee12b3d2af95831cd71b2432ec16f1c
  3. keymap parse --zmk-keymap config/glove80.keymap | keymap draw - > keymap.svg
The above produces the following result
-> $ keymap parse --zmk-keymap config/glove80.keymap | keymap draw - > keymap.svg
Traceback (most recent call last):
  File "/home/x10an14/.local/bin/keymap", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/x10an14/.local/pipx/venvs/keymap-drawer/lib/python3.11/site-packages/keymap_drawer/__main__.py", line 178, in main
    draw(args, config.draw_config)
  File "/home/x10an14/.local/pipx/venvs/keymap-drawer/lib/python3.11/site-packages/keymap_drawer/__main__.py", line 42, in draw
    drawer = KeymapDrawer(
             ^^^^^^^^^^^^^
  File "/home/x10an14/.local/pipx/venvs/keymap-drawer/lib/python3.11/site-packages/keymap_drawer/draw/draw.py", line 24, in __init__
    self.keymap = KeymapData(config=config, **kwargs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for KeymapData
__root__
  Number of keys on layer "Norwegian" (82) does not match physical layout specification (80) (type=assertion_error)

Potential causes (afaict)

  1. Parsing of nested custom zmk actions?
    Ref. the line/colum it complains about (afaict): &homey_left LCTRL &norwegian_ae
  2. Something similar to #21?

In any regards

I loved it when your tool worked! And I wanted to state my appreciation for this tool and your efforts =)

Feature request: render specific layer(s)

Premise

After parsing my keymap, it'd be great to have a cli arg and/or config option to specify which layer(s) to be included in the SVG.

I believe the only way to achieve this currently is to edit the generated yaml file and remove the layers that I don't want to render.

Example API

# CLI

# Stringified list approach, would need to parse into an actual list,
# trim whitespace, etc:
--include-layers "1, 2, Navigation"

# Alternative approach, no parsing needed...
--incude-layer 1 --include-layer 2 --include-layer Navigation

# Either way, single layer should work as expected:
--include-layer Navigation
# YAML
draw_config:
  included_layers:
  - 1
  - 2
  - Navigation
# YAML (can be a list or a string)
draw_config:
  included_layers: Navigation

It'd be good (but not necessary) for layer id, label, name, etc to all be understood.

Use case

I'd like to render specific layers into their own svg file, e.g. nav_layer.svg & symbols_layer.svg. It may also be useful to render a slice of layers into an svg; special_layers.svg.

This would make it easier to have an image of a specific layer included with that layer's documentation.

Also, it would simplify printing off a paper copy of the one layer I changed a bunch and need to re-learn.

I would probably split up my CI workflow

  • A commit job that depends on several render jobs - commits the rendered SVGs
  • Several render jobs that each depend on a parse job (run in parallel)
  • A parse job - generates the config.yml

kinesis zmk keymap: "default_layer" (82) does not match physical layout specification (76)

im using the default kinesis firmware. The custom keymap that i created can be seen here:
https://github.com/rtomaszewski/Adv360-Pro-ZMK

When i try to parse it using the web page im getting this error:
https://caksoylar-keymap-drawer-streamlitapp-2a0rau.streamlit.app/?example_yaml=showcase.yaml

validationError: 1 validation error for KeymapData root Number of keys on layer "default_layer" (82) does not match physical layout specification (76) (type=assertion_error)
Traceback:
File "/app/keymap-drawer/streamlit/app.py", line 327, in main
svg = draw(st.session_state.keymap_yaml, parse_config(st.session_state.kd_config).draw_config)
File "/app/keymap-drawer/streamlit/app.py", line 47, in draw
drawer = KeymapDrawer(
File "/app/keymap-drawer/keymap_drawer/draw.py", line 31, in init
self.keymap = KeymapData(config=config, **kwargs)
File "pydantic/main.py", line 341, in pydantic.main.BaseModel.init

Separate Combos on ZMK

Combos are valid across all layers so showing it multiple times is not necessary. Also, it covers the keys if someone uses combos extensively. I think having a separate draw for combo only would be a better approach
image

Feature request: local webapp with filewatch

I'm currently using the keymap-drawer webapp to design a new layout, which is very nice, but I would love to be able to start a local webapp pointing to the yaml-file, so I can edit it in an editor, and it would refresh on save. Because the online yaml-editor is a bit annoying to use for this usecase.

For example:

$ keymap serve my-keymap.yml

> Webapp available on http://localhost:7693/

I might even give this a go myself if you could provide some pointers on where to start in getting the app up and running locally.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.