This is a follow-up to https://github.com/jwilm/alacritty/pull/2642.
Currently the idea is that whenever a user defines a binding with a bigger scope mode, that the default binding is overwritten. The idea behind this is that the user's binding will always work for all scopes he has defined, while default bindings are left untouched as much as possible.
This already works well when staying either only in positive, or in negative modes, but as soon as modes are mixed like Alt and ~Alt things get messed up. Overwriting a default binding by only overwriting the ~Alt one for example, will currently also disable the Alt binding. This is inconsistent with what would be expected by the user, since he has only requested a change in Alacritty's behavior in this specific mode.
I think to make sure that we do not create a regression in another area by fixing this, it's probably useful to lay out a table with all possible relevant combinations and creating dedicated tests for them to assure that the specification and implementation match up properly this time.
Here's a table of the currently intended overwriting behavior:
ALL: All terminal modes.
A: A terminal mode other than B.
B: A terminal mode other than A.
~Y: Mode Y not set.
X: Replace binding.
0: Keep binding.
| | ALL | A | ~A | B | ~B | A + B | ~A + B | A + ~B | ~A + ~B |
|---------|-----|---|-----|---|-----|-------|---------|---------|---------|
| ALL | X | X | X | X | X | X | X | X | X |
| A | X | X | 0 | 0 | 0 | X | 0 | X | 0 |
| ~A | X | 0 | X | 0 | 0 | 0 | X | 0 | X |
| B | X | 0 | 0 | X | 0 | X | X | 0 | 0 |
| ~B | X | 0 | 0 | 0 | X | 0 | 0 | X | X |
| A + B | X | X | 0 | X | 0 | X | X | X | 0 |
| ~A + B | X | 0 | X | X | 0 | X | X | 0 | X |
| A + ~B | X | X | 0 | 0 | X | X | 0 | X | X |
| ~A + ~B | X | 0 | X | 0 | X | 0 | X | X | X |
A short summary would be that a binding is removed, when either of the bindings contains any mode of the opposing binding.
Most helpful comment
Here's a table of the currently intended overwriting behavior:
ALL: All terminal modes.
A: A terminal mode other than B.
B: A terminal mode other than A.
~Y: Mode Y not set.
X: Replace binding.
0: Keep binding.
| | ALL | A | ~A | B | ~B | A + B | ~A + B | A + ~B | ~A + ~B |
|---------|-----|---|-----|---|-----|-------|---------|---------|---------|
| ALL | X | X | X | X | X | X | X | X | X |
| A | X | X | 0 | 0 | 0 | X | 0 | X | 0 |
| ~A | X | 0 | X | 0 | 0 | 0 | X | 0 | X |
| B | X | 0 | 0 | X | 0 | X | X | 0 | 0 |
| ~B | X | 0 | 0 | 0 | X | 0 | 0 | X | X |
| A + B | X | X | 0 | X | 0 | X | X | X | 0 |
| ~A + B | X | 0 | X | X | 0 | X | X | 0 | X |
| A + ~B | X | X | 0 | 0 | X | X | 0 | X | X |
| ~A + ~B | X | 0 | X | 0 | X | 0 | X | X | X |
A short summary would be that a binding is removed, when either of the bindings contains any mode of the opposing binding.