al-ce/karaml

Descriptions

Opened this issue · 8 comments

Have you thought at all about supporting rule descriptions for? I'm not sure how I'd implement them since I don't think I'd want to have to turn /layer/ into a dictionary with descriptions (string) and items (list). However, some way to support it might make things a little easier to work with in Karabiner's UI itself.

al-ce commented

Yes, you're right, I've been thinking about adding some way to add descriptions to individual complex mods but I didn't think about adding them to layers. I'll think about it but if you come up with a sample syntax please share!

I'll keep thinking about it, it's a bit of a tough one.

What about:

/LayerName | Optional description/:

The regex shouldn't be difficult to implement but I'm not sure if it really adheres to the intent of YAML conventions.

Also, I'm not sure if this is valid in Karabiner but it would be nice if Layer names allowed spaces.

al-ce commented

Just checking in, been working on some other things.

The first step was to address your last suggestion about allowing spaces in layer names. tldr, you can add spaces 33211d2

Next we'll add a regex for descriptions. I like your suggestion. Whatever syntax we go with, I'd like it to be somewhat similar to a syntax that adds descriptions to individual rules as well. I'll get around to it hopefully this week. I somewhat purposely didn't implement descriptions because I thought of just letting YAML comments be the stand-in for that, but you're right that it would be a good idea to have descriptions interact with the KE UI.

Also, just a quick thanks for your suggestions and requests, I didn't realize how much I was taking for granted and how much cleaner the config syntax could be (and still). Wish I'd had a collaborator from the start, or at least that I would have planned better.

al-ce commented

With commit f16f5c5, I went with this syntax:

/mouse/           A layer for mouse events:
  ⌥ quote : var(mouse_layer, 0) + notify(idmouse)  # Turn off mouse layer
  m       : mouse(x, -2000)
  n       : mouse(y, 2000)

/symnum/+/nav/    Sym & Nav Multi-layer:
  m   : left
  n   : down

This just uses a regex to caputre everything up to the final forward slash / and the everything after (stripping excess space). If the layer name is for a multi-condition layer, that will get parsed appropriately later. The only restriction for the description is that it can't contain a forward slash. This was done to resolve issues with descriptions for multi-conditional layers like the above.

With commit a741766, the parsing function will correctly interpret complex, multi-line YAML keys (using the ? indicator YAML syntax)

? /symnum/

  Numpad + Symbols Layer
:
  (x) j: "0"
  (x) k: ","

? /symnum/ +
  /nav/

  Sym & Nav Multi-layer
:
  m   : left
  n   : down
  e   : up
  i   : right

The parser will replace all the newline chars in the complex key with a space and parse it as if it were a single line, as above.

Your suggestion to use the pipe was much simpler, and I implemented it in this branch 071f038. I eventually realized there was no need to keep the delimiter within the surrounding forward slashes, and then that we could get rid of it altogether.

If you like having the visual for the delimiter, let me know and I can make it an option. Having it would also allow having forward slashes in the description.

Would you mind letting me know if you have a preference for description formatting? For example, if you'd prefer prefixing the layer name to the user defined description by default (with or without forward slashes), and, if no description is provided, what your preferred format might be? Currently it's /layer name/ layer The relevant lines are

for layer_key, layer_maps in yaml_data.items():
name, description = parse_layer_key(layer_key)
manipulators: list = self.get_manipulators(name, layer_maps)
layer = {"description": description,
"manipulators": manipulators}
layers_list.append(layer)

# Remove newlines from the layer name in case the user formatted the YAML
# key with the `? |` syntax to allow a multi-line string in the key.
layer_name = layer_name.replace("\n", " ")
layer_info = re.search(r"^(/.+/)(.*)", layer_name)
if not layer_info:
invalidLayerName(layer_name)
layer_name, description = map(str.strip, layer_info.groups())
if not description:
description = f"{layer_name} layer"
return layer_name, description

Hey, just wanted to say this looks great and I'll try to test out as soon as I figure out some other challenges with my config. Sorry for the slow replies, I've been in the process of moving and have had little free time the last couple of weeks.

al-ce commented

@ChristinWhite No problem! I like this flow where we can take our time and think things through. I really really appreciate your input, I've learned a lot about how I could/should things through in future projects, and just personally I'm very happy with the new features that have come out of it. Hope moving goes well.

al-ce commented

Also lmk if I can help with any config issues, I know my docs aren't the most concise