Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow customization of which keys caps_word modifies #1742

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

joelspadin
Copy link
Collaborator

@joelspadin joelspadin commented Apr 8, 2023

Added new options to &caps_word to bring it closer to feature parity with QMK:

  • Added shift-list to include extra keys to have modifiers applied, for example to change MINUS to UNDERSCORE. Anything specified in this list is implicitly part of continue-list.
  • Added no-default-keys, which removes the implicit alphanumeric keys from continue-list and shift-list when set. This allows fully customizing the keys, for example for non-US layouts.

@Kikangh
Copy link

Kikangh commented Apr 8, 2023

WoW ! Thanks for working on the no-default-keys part, as a foreign (exotic) layout user, this should make it a wee bit easier for me to setup caps_word for my use case 🙏

@theol0403
Copy link
Contributor

How does this compare to the features added to #1451?

@joelspadin
Copy link
Collaborator Author

How does this compare to the features added to #1451?

From my understanding of that PR, they are almost completely different. That PR does the following:

  • Adds a way to activate a layer instead of/in addition to activating modifiers.
  • Adds a way to select whether alphas, numbers, and/or modifiers continue/break a word.
  • Any custom zmk,behavior-caps-word behaviors will change as follows unless they are updated:
    • No modifiers are applied unless mods is set.
    • Word break occurs on any key not in continue-list (previously alphanumeric and modifier keys would always continue a word)

To restore the original behavior of a custom caps word behavior, add:

mods = <MOD_LSFT>;
ignore-alphas;
ignore-numbers;
ignore-modifiers;

This PR does:

  • Adds a way to select the specific keys that continue/break a word (except modifiers, which still always continue, but that could be changed if necessary).
  • Adds a way to select the specific keys that have modifiers applied to them.
  • Adds a timeout where caps word will deactivate if no key is pressed for some time.
  • &caps_word now defaults to shifting '-' to underscore _ and having a 5 second idle timeout.
  • Any custom zmk,behavior-caps-word behaviors will change as follows unless they are updated:
    • A 5 second idle timeout is added.

To restore the original behavior of a custom caps word behavior, add:

idle-timeout-ms = <0>;

@theol0403
Copy link
Contributor

Thanks for the detailed explanation! Looking forward to seeing both of these merged.

@joelspadin joelspadin force-pushed the caps-word branch 2 times, most recently from a1b5b03 to 18ad62e Compare April 8, 2023 21:42
@caksoylar
Copy link
Contributor

Would you consider adding explicit modifier changes (discussed around here) to this PR, or a separate one?

@joelspadin
Copy link
Collaborator Author

I was thinking to do that in a separate change to keep this easier to review.

@joelspadin
Copy link
Collaborator Author

Fixes #1706

@theol0403
Copy link
Contributor

theol0403 commented Apr 11, 2023

Defaults to MINUS so hyphens get turned into underscores.

I would say wanting to type in UPPER-DASH-CASE is common enough that having it shift to underscore automatically might be too opinionated for a default. In my personal config, I have hyphen and underscore on separate keys in a symbol layer (pretty common), so would need to explicitly disable this default because I would then have two underscores on my symbol layer during caps word.

Perhaps I am misunderstanding, but wouldn't having hyphens in the default shift-list also require hyphens to be in the default continue-list (which is only A-Z)?

@joelspadin
Copy link
Collaborator Author

I would say wanting to type in UPPER-DASH-CASE is common enough that having it shift to underscore automatically might be too opinionated for a default. In my personal config, I have hyphen and underscore on separate keys in a symbol layer (pretty common), so would need to explicitly disable this default because I would then have two underscores on my symbol layer during caps word.

I chose this to align with QMK's default behavior. I could change it back if enough people agree that it shouldn't be the default, but it's also easy enough to disable with

&caps_word {
  shift-list = <>;
};

Perhaps I am misunderstanding, but wouldn't having hyphens in the default shift-list also require hyphens to be in the default continue-list (which is only A-Z)?

MINUS was added to the default continue list here: https://github.com/zmkfirmware/zmk/pull/1742/files#diff-315ee987c216e30d02008e39328bdb6be66f3348ad7a799468e2467de2f2f8d2R15 The default list is now A-Z, 0-9, hyphen, underscore, backspace, and delete.

@joelspadin
Copy link
Collaborator Author

Reminder to myself: this is missing a test for no-default-keys.

@infused-kim
Copy link
Contributor

I chose this to align with QMK's default behavior. I could change it back if enough people agree that it shouldn't be the default

I also agree this shouldn’t be the default for the exact same reasons @theol0403 outlines.

I think the intention of activating caps lock or caps word is to type words in caps. Symbols can be shifted with shift when necessary.

And just because qmk chose a poor default setting, it doesn’t mean that zmk should copy it.

@joelspadin joelspadin force-pushed the caps-word branch 2 times, most recently from a33d657 to 3cf9e06 Compare April 11, 2023 20:39
@joelspadin
Copy link
Collaborator Author

Added more tests, updated the documentation, and changed so that anything in shift-list will also be treated as a continue key, so you don't need to add keys to both lists for them to work.

@joelspadin
Copy link
Collaborator Author

Are you advocating for changing the default so that - continues a word but does not get shifted to _? Or, do you just mean that - should end a word, so to type out UPPER-DASH-CASE you'd press caps word again at the start of each word?

If you do think the default should change, in what situations would that be used? I can't think of any, but I'm also a primarily C/C++ programmer, so I'm much more familiar with use cases for SCREAMING_SNAKE_CASE than for SCREAMING-KEBAB-CASE.

@infused-kim
Copy link
Contributor

Are you advocating for changing the default so that - continues a word but does not get shifted to _? Or, do you just mean that - should end a word, so to type out UPPER-DASH-CASE you'd press caps word again at the start of each word?

If you do think the default should change, in what situations would that be used? I can't think of any, but I'm also a primarily C/C++ programmer, so I'm much more familiar with use cases for SCREAMING_SNAKE_CASE than for SCREAMING-KEBAB-CASE.

I see where you are coming from with these defaults. I think I am approaching it from a slightly different point of view.

1. Shifting "-" or not by default

I think caps word should behave as closely to "normal" caps lock as possible. Normal caps lock (at least on macOS) doesn't seem to shift any symbols or numbers. It seems to only affect letters.

And I think caps word should behave exactly the same way in the default config. That's the behavior a user would expect and so that's what they should get.

On top of that, only shifting one symbol, but not any of the other symbols by default is extra confusing and unexpected.

So I think it would be best to avoid that.

I do think that your use-case makes perfect sense and many programmers would probably prefer that behavior. But I think it should be an option and not a default.

And even though a portion of users would prefer that behavior, it's not like it is impossible to type a "_" without the default. Users can just type shift+- and that's what most users would expect to have to do anyways (even with normal caps lock).

2. Should "-" deactivate caps word or not by default

This one is a bit more difficult to answer, because we don't have any pre-existing behavior that users might be used to.

I think I would lean towards keeping capsword enabled on both "-" and "_". Simply, because I can't think of many instances where a user wouldn't type another deactivating character like , ., or ; after the underscore or dash.

@infused-kim
Copy link
Contributor

infused-kim commented Apr 11, 2023

I just thought of two more reason against shifting "-“ by default :). I hope you don’t mind….

Doing so also makes it impossible to actually type “-“ during caps word should the user desire to do so.

For many users that’s fine, but it should be a conscious decision and not unexpected behavior.

The beauty of caps word is that it makes your life easier and then seamlessly gets out of the way.

But users won’t use it just to type programming definitions like “FOO-BAR” or “FOO_BAR”.

Sometimes people may type a sentence like “[…] and that’s why this is BAD-- I won’t allow this.”

The expectation here is that “I can just type and don’t need to worry about turning off caps word or weird exceptions”.

@theol0403
Copy link
Contributor

theol0403 commented Apr 13, 2023

I agree with @infused-kim. Personally, the biggest issue for me with having hyphen shifted by default is the inability to type "-" during caps word, which doesn't feel like a natural default. This is extra relevant to me because I already have a dedicated "_" key on a layer and don't use shift+"-".

Another very minor point is that looking through the source code and docs, the need to make several references to "MINUS" to explain its behaviour reflects its unintuitive nature.

While it is very easy to remove the default behaviour, it is equally easy to add behaviour, and I think more users would expect the default to be unopinionated. I think it would make more sense to have "For example, to add MINUS to the shift list so it is automatically changed to UNDERSCORE, add:" in the docs (as a nice way to guide the reader towards this possibly desired feature, and show how it is used instead of how to disable).

Finally, I have fewer opinions on whether MINUS should be in continue-list by default, but I vote to keep it.

@joelspadin
Copy link
Collaborator Author

The latest version removes MINUS so the default behavior is unchanged.

@joelspadin
Copy link
Collaborator Author

Rebased and fixed whitespace issues for pre-commit.

Copy link
Contributor

@petejohanson petejohanson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple questions on the implementation. Thanks!

@@ -20,6 +22,21 @@ struct zmk_key_event {
bool pressed;
};

struct zmk_key_decoded {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I love the decoded terminology... Complete key? Key details? Full key?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is all the data from a DT parameter, how about zmk_key_param?

app/src/behaviors/behavior_caps_word.c Outdated Show resolved Hide resolved
@caksoylar caksoylar added enhancement New feature or request behaviors labels Jun 10, 2023
@joelspadin joelspadin requested a review from a team as a code owner June 11, 2023 03:19
@SebastianBehrens
Copy link

SebastianBehrens commented Aug 16, 2023

Hi @petejohanson, are you hesitant to merge this; or can one expect this to clear soon?

@ctranstrum
Copy link
Contributor

+1 on merging this one

@joelspadin joelspadin mentioned this pull request Dec 2, 2023
Changed behavior_caps_word.c to be conditionally compiled instead of
wrapping the entire contents of the file in an #if.

Renamed macros that still referred to "break" instead of "continuation".

Changed the type of the continuations count field to allow for more than
255 continuation keys.

Reordered a struct to allow for better packing.

Switched to statically initializing the devs[] array instead of using an
index field in each device's config struct and the init function.

Refactored caps_word_keycode_state_changed_listener() and
caps_word_enhance_usage() to allow for more easily changing
the conditions for what breaks a word and whether mods should be applied
in future commits.
Unified devicetree key code parameter decoding between key press and
caps word behaviors.

Reordered zmk_keycode_state_changed fields for better packing.
Added a shift-list property to caps word to allow adding more keys to
be shifted aside from alpha keys.

Added a &prog_word behavior, which is the same as &caps_word, except it
adds MINUS to shift-list (this matches QMK's caps word behavior).

Added a no-default-keys property to caps_word, which removes the
implicit alphanumeric keys from continue-list and shift-list so you can
fully customize the lists.

Also adjusted the default continue keys to include numpad numbers,
since those are numbers too.
@joelspadin joelspadin changed the title Bring caps word to feature parity with QMK Allow customization of which keys caps_word modifies Mar 20, 2024
@joelspadin
Copy link
Collaborator Author

Rebased, cleaned up and simplified the code some more, and dropped the idle timeout feature for now. Macros can cause keys to be pressed a different number of times than they are released, so counting the number of presses and releases to determine when no keys are pressed isn't reliable. Doing that correctly will require some changes to core code, so I'll handle that separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
behaviors enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants