Ikcelaks / qmk_sequence_transform

Sequence-Transform is a user library for QMK that enables a rich declarative ruleset for transforming a sequence of keypresses into any output you would like.
Apache License 2.0
5 stars 3 forks source link

[FEATURE] Metacharacters #87

Closed Ikcelaks closed 5 months ago

Ikcelaks commented 5 months ago

With this PR, we can now match to a group of characters rather than exact individual characters using special characters called MetaCharacters (or metachars).

Currently, eight metacharacters are defined, but eventually this can be expanded to allow for user defined metacharacters that match using user defined predicate functions.

The most useful metacharacter is the wordbreak, which is by default matches any non-alpha character.

So, now I can type "the" in quotes using my _* -> the rule, and it triggers correctly, because " is a non-alpha character.

Importantly, you are still able to define specific behavior for keys that also match to a meta-character. For example, I have these rules:

.* -> .\
_* -> _the
_*t -> _that

If I type .*, I get .\. If I type "*, I get "the. And, importantly, if I type .*t, I get .\t and not .\at. This last issue is what drove the need for the explicit-rule-chains enhancement this feature builds on.

At the moment, there is no way to include the character matched by a metacharacter in the output if the character needs to be in the completion string. So, my _*r_ -> _there_ rule will trigger on any non-alpha character at the end, but it will always replace that character with a space. This functionality is already planned and should be fairly simple to add using the existing functionality of the cursor.

As an aside, rules that output a wordbreak character at the end of their completion will create a wordbreak if the user is using the fallback buffer, even if the triggering character is not a wordbreak character itself. I don't intend to use that functionality, but it is nice! I have really come around on the utility of the fallback to vout behavior. With the explicit-rule-chain-matching behavior, most of my objections to its behavior are neutralized. I now believe it should always be enabled except when necessary for testing.

Ikcelaks commented 5 months ago

With the latest commit, you are now able to specify a position in character in the transform by referencing a position in the sequence.

The symbols used to refer to specific spots are given by the "transform_sequence_reference_symbols" entry in the generator config. This field takes a string of symbols, and the nth symbol in the string refers to the nth character in the sequence string, starting from the right and going left. I have also added an entry in the generator config for specifying the actual space character in the transform. Right now it can be the same as the wordbreak character, but that will change in the future, because right now it is impossible to specify that you want to match on exactly the space character in the sequence.

Here are some funky rules that I played around with that should show off how to use this feature. These rules work with the sample config included in this PR.

βˆ‚πŸ‘†       β‡’ βˆ‚.
βˆ‚βˆ‚πŸ‘d       β‡’ 2024-03-β‘Άβ‘΅
28πŸ‘†        β‡’ 28today
⎡sπŸ‘        β‡’ s
⎡sπŸ‘βŽ΅       β‡’ someβ—―
⎡sπŸ‘βŽ΅c       β‡’ science

The 28today and science rules were to make sure that the virtual output / enhanced backspace kept in sync.

The code quality of the parts related to reading the completion string are pretty low. I will clean that up so that everything is less duplicated over similar usage sites and generally more organized.

The test_all_rules test also needs to be taught how to handle these rules. test_ascii_string works great though.