rvaiya / keyd

A key remapping daemon for linux.
MIT License
2.99k stars 175 forks source link

Request: Multiple actions for a binding #590

Open Vosjedev opened 1 year ago

Vosjedev commented 1 year ago

I am trying to make a navigation layer which updates my panel when active.

[main]
capslock = overload(nav, toggle(nav))

[nav]
j=left
k=down
l=up
;=right

d=home
f=end

I can execute commands by using command(<command>), and toggle a layer using toggle(<layer>). I would like something like actions(<action1>, <action2>) to do something like

# if capslock held: use nav layer until released. if pressed: toggle nav layer and tell polybar to update an indicator
capslock = overload(nav, actions(toggle(nav),command(polybar-msg action '#navindicator.hook.1'))

Maybe it can have even more actions chained, but I don't really know when you would need more than 2 actions, and using actions(<action1>,actions(<action2>,<action3>)) is also fine.

Oh, and thanks for making keyd, it is so usefull to be able to just switch around keys in an eazy way!

rvaiya commented 1 year ago

command is run as root, and is probably not what you want. You probably want a script tied to your X session which monitors the output of keyd listen and updates your indicator accordingly.

Vosjedev commented 1 year ago

Ah, that seams like a better solution for this specific case. (It seems like I was using an older version which didn't have a note saying command was run as root in the man). For some usecases it may still be usefull. You can decide if you want to still implement this, or close this issue. Thanks!

jytou commented 1 year ago

I would definitely be interested in executing more than one action for a given input.

Here is my use case: I am using keyd for chording.

Typically, I would like to chord p+r+t+a ⇒ 'participat' and then switch to a “endings” layer to finish the word with, for instance:

I understand that it is actually possible currently : don’t type anything on the first chord and only switch to the “endings” layer for that word, and then type the full corresponding word during the second input.

However, I see two main drawbacks to doing it that way. First, not seeing anything appear on the screen until the second series of strokes could be quite confusing, although I suppose one might get used to it after a while. But, moreover, it seems logical to me that such an “ending” layer could actually be reusable for a lot of words. Instead of having a lot of layers (one per word containing all its possible endings), it would be a lot simpler to have a single “endings” layer, with all relevant words referring to it (think of 'paint', 'mitigate', pretty much all English verbs that are also nouns and sometimes adjectives - and that also applies to French, Esperanto, etc.). Of course, there are irregular verbs, etc, which might require other solutions.

jytou commented 1 year ago

Actually found out that my use case is already covered: https://github.com/rvaiya/keyd/blob/master/docs/keyd.scdoc#L662

So the case of multiple actions remains when they are not “macro followed by layer”.

Vosjedev commented 11 months ago

I found another usecase... It is clearing the layers before toggling one.

rvaiya commented 11 months ago

I would definitely be interested in executing more than one action for a given input.

This is non trivial to implement without breaking current semantics, but is planned for the next major release, which will likely break backward compatibility. Having said that, I believe what you want to achieve can already be done by making use of the existing compound actions (layerm and friends).

I'm not sure what you mean by this:

 don’t type anything on the first chord and only switch to the “endings” layer for that word, and then type the full corresponding word during the second input.

Unless by 'chord' you mean typing 'p' then 't' then 'r' etc, rather than holding them down simultaneously (what keyd refers to as a chord). If this is indeed what you mean (something like vim abbreviations), it can be somewhat cumbersomely achieved by abusing layers like so:

[main]
p = swapm(pr, r)

[pr]
t = swapm(prt, t)

[prt]
a = swapm(prta_completion, t)

[prta_completion]
e = macro(backspace backspace backspace backspace participate)
d = macro(backspace backspace backspace backspace participated)
s = macro(backspace backspace backspace backspace participates)
g = macro(backspace backspace backspace backspace participating)
o = macro(backspace backspace backspace backspace participation)

But, moreover, it seems logical to me that such an “ending” layer could actually be reusable for a lot of words.

I have toyed with the idea of adding first class support for something like this, but if it ends up getting implemented, it will probably be part of the next major release.

@Vosjedev

I found another usecase... It is clearing the layers before toggling one.

This is what swap is for.