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

Feature request: unmod action to temporarily release mods #615

Closed
Vermoot opened this issue Nov 8, 2023 · 19 comments
Closed

Feature request: unmod action to temporarily release mods #615

Vermoot opened this issue Nov 8, 2023 · 19 comments
Labels
enhancement New feature or request

Comments

@Vermoot
Copy link

Vermoot commented Nov 8, 2023

Is your feature request related to a problem? Please describe.

My OS-side layout is US-intl, and I often write in French so I write accent with dead keys. For example, I type 'e to get é.
To that effect I made some aliases for accents, like this:
(defalias é (macro ' e))
This works great, but if I want to get a capitalized accented E (É) I can't just use that alias with shift held down, because the shifted version of ' e is " E, and I get an Ë.

Describe the solution you'd like.

The way I dealt with that on my QMK boards was to save the held down mods, clear them, write the ' and then re-enable the saved mods. You can see my actual implementation here, along with the accented_letter function making use of it just below.

The way I see this looking like in a kanata config is this:
(defalias é (macro (unmod ') e).
This way, if you use the alias without having shift held down you get é, and if you do with shift held down, only the e gets affected by it and you get É as intended.

Describe alternatives you've considered.

None I could think of. In my case I guess I could keep a dead quote key somewhere in my keymap, but the one on my main layer is usually replaced with an "un-dead" quote ((defalias apo (macro ' spc))).

Additional context

I'm not sure if the right route for this is actually an unmod action, or an unshift action, or even throwing in unalt, unmeta and unctrl actions as well, because why not. Or all of the above.
In my case at least, would be the most useful one, but I could see every variant being useful to someone.

@Vermoot Vermoot added the enhancement New feature or request label Nov 8, 2023
@rszyma
Copy link
Contributor

rszyma commented Nov 9, 2023

An alternative would be to:

  1. Add aliases for all uppercase accented keys (defalias É (macro ' E)) etc,
  2. Define a new layer, let's call it uppercase-accented that contains those uppercase accented keys.
  3. Map lsft and rsft to switch to this layer using (layer-while-held uppercase-accented)

Edit: on the second thought, this is not a good idea, because it will break shift for all other keys, unless they are added S- manually to each individual key.

@rszyma
Copy link
Contributor

rszyma commented Nov 9, 2023

Another alternative:
Use fork action on each accented key alias.

(defalias é (fork (macro ' e) (macro ' E) (lsft rsft)))

Edit: actually, this will not work correctly due to the same reason you've posted this issue...

@jtroo jtroo mentioned this issue Nov 9, 2023
4 tasks
@jtroo
Copy link
Owner

jtroo commented Nov 9, 2023

Interesting use case! I can't think of any workarounds, so the action is added, I think pretty much as-suggested.

Out of simplicity, unmod will unmodify everything for now. If someone needs to keep some modifiers but not others, the PR should be a good reference for how to implement it.


Sample mini-config that I tested and works:

(defcfg
  process-unmapped-keys yes
)
(defsrc a b)
(deflayer base (unmod a) (macro (unmod b) e))

@gerhard-h
Copy link
Contributor

gerhard-h commented Nov 9, 2023

 e (switch
    ((key-history ' 1))  (fork (macro (unicode é) f17) (macro (unicode É) f17) (lsft rsft)) break
    () e break
  )

there is the brand new key-history feature you can use.
The F17 does nothing it only there to consume the dead key, to get ée instead of éé.

side effect ' ' e will now be ''é instead of ''e could be prevented with ...(key-history ' 2)(key-history ' 1)...

@Vermoot
Copy link
Author

Vermoot commented Nov 9, 2023

As an additional note, one reason this feature is needed and I can't use most workarounds is that the accented letters aliases I make are used in other macros or chords.

For example, if I use chords to write whole words of phrases, like
(defchords base 100 (c ' a) (macro c ' spc @é t a i t))
to write c'était when I chord c ' and a, I get multiple issues.

The first one is related to accented letters as described above, turning était into ËTAIT, and the second one is the apostrophe itself, turning c'était into C"ËTAIT.

With unmod I can use
(defchords base 100 (c ' a) (macro c (unmod ') spc @é t a i t))
(with making use of it aleardy), and that way the apostrophe doesn't get capitalized either.

Thank you @jtroo for making this so quickly, and thanks for kanata as a whole. I've been using QMK keyboards for years and being finally able to use home row mods and combos on my laptop keyboard is super nice.

@Fred-Vatin
Copy link
Contributor

key-history

Where is this feature documented ? I can not see here : https://github.com/jtroo/kanata/blob/v1.5.0-prerelease-2/docs/config.adoc

@rszyma
Copy link
Contributor

rszyma commented Nov 9, 2023

https://github.com/jtroo/kanata/blob/main/docs/config.adoc#key-history

@gerhard-h
Copy link
Contributor

I think an explicit unshift is a good idea, for handling all the RA- characters.

@jtroo
Copy link
Owner

jtroo commented Nov 11, 2023

@gerhard-h can you show a practical example of how unshift would be used? So I can put it in the docs.

@gerhard-h
Copy link
Contributor

  ~ (macro RA-+ )
  | (macro RA-102d ) 

With these aliases, when holding shift and typing ~ONE||~TOW I only get ONETWO but replaceing macro with unshift would solve it.

  { (unshift RA-7 )
  [ (unshift RA-8 )

It also enables shift forking on all tap holds (tap-hold 1 300 e (fork @{ @[ (lsft)) )

I tried to achieve this with only unmod but neither (fork RA-8 (multi lalt lctl (unmod 7)) (rsft lsft)) nor (fork RA-8 (unmod (multi lalt lctl 7)) (rsft lsft)) nor `RA-(unmod 7) achieve the goal.

@santhoshr

This comment was marked as off-topic.

@jtroo

This comment was marked as off-topic.

@santhoshr
Copy link

santhoshr commented Nov 20, 2023

It worked after build from source, thanks.

sm (fork @nv (fork S-; (unmod ;) (rsft)) (lsft rsft))

I use fork in a nested way, it works as intended, on semicolon press it shifts navigation layer; on using with left shift it emits colon and on right shift emits semicolon, few things I noted,

  1. using unmod loses key repeat
  2. at times secondary action gets missed first time, it is not consistent, so I'm not sure at this point, just bringing it so if anyone elso have problems then it can be looked into, this could be due to nested use as well

switch makes this scenario easier

      sm (switch 
        (lsft) S-; break
        (rsft) (unmod ;) break
        () @nv break
      )

Still no key repeat with unmod

@santhoshr

This comment was marked as off-topic.

@santhoshr

This comment was marked as off-topic.

@rszyma

This comment was marked as off-topic.

@jtroo

This comment was marked as off-topic.

@jtroo
Copy link
Owner

jtroo commented Nov 22, 2023

Key repeat is fixed, and unshift added, in #638.

jtroo added a commit that referenced this issue Nov 24, 2023
Implement unshift and make unmod+unshift key repeat work. Implements
#615.
@jtroo jtroo closed this as completed Nov 24, 2023
@gerhard-h
Copy link
Contributor

gerhard-h commented Dec 16, 2023

@gerhard-h can you show a practical example of how unshift would be used? So I can put it in the docs.

When building an upper case layer, you want shift to revert back to lower case like

C (fork S-c (unshift c) (rsft lsft))
V (fork S-v (unshift v) (rsft lsft))

This can be achieved with unmod or unicode too. But only with unshift Shortcuts like keep working Ctl+C, Ctl+V,... keep working

jtroo pushed a commit that referenced this issue Sep 11, 2024
It has taken me a while to figure out why `unmod` had no effect in my
mappings. After running in debug mode I realized that the events sent by
the modifiers are not tracked at all, since they are not part of my
source mapping. When seeing this I remembered seeing
`process-unmapped-keys` enabled in [this comment](#615 (comment))
while digging through some issues. Doing so resulted in the expected
behavior.
eugenesvk pushed a commit to eugenesvk/kanata that referenced this issue Sep 12, 2024
It has taken me a while to figure out why `unmod` had no effect in my
mappings. After running in debug mode I realized that the events sent by
the modifiers are not tracked at all, since they are not part of my
source mapping. When seeing this I remembered seeing
`process-unmapped-keys` enabled in [this comment](jtroo#615 (comment))
while digging through some issues. Doing so resulted in the expected
behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants