Key-binding hell


#22

I’m in the same boat. No amount of overriding has helped. It doesn’t matter if I use the same selectors or even edit the darwin.json file. Heck, I even tried deleting the core keymaps I didn’t want and it still didn’t work…


#23

The more packages I add, the more I find I’m fiddling with this stuff too. Has there been any thought given to how things could be made a little more usable in core?

I think the problem is that there are two ways I want to control key binding precedence:

  • As a package author, binding keys to DOM elements is great and intuitive. However, I only want to have to think about one binding’s precedence relative to other bindings my package offers.
  • As a user, composing multiple packages into a cohesive experience, I hate fiddling with CSS selectors and would rather be able to say “I want this package’s bindings to override that one’s”, and possibly “disable this package’s binding for alt->”.

So what if it were to work like this:

  • Rather than having a single keymap, Atom maintains one keymap per package, plus the built-in keymap and a user keymap.
  • By default, the built-in keymap has lowest priority, then core packages (alphabetically), then 3rd party packages (alphabetically), then the user keymap.
  • A user can reorder the precedence list via a drag-and-drop UI giving precedence to their favorite packages.
  • A user can also toggle on/off a particular binding in any keymap.

Thoughts?


#24

Hi,

Has there been any progress on that front? Have you guys found workarounds?

G.


#25

This is absolutely an issue. All packages should be required to implement method that provides toggle for enable/disable of keybindings.

Two there should be a registry of keybindings to validate against when pushing a new package. At the very least a warning after installing a package that there are conflicts and then the user can decide to add new bindings disable another package whatever.

Most using Atom I suspect are fair well versed in the programming world. As such it isn’t that we can’t sort it out it’s that no IDE/program ever has allowed multiple key binding for the same combination. Not reasonable so I see no reason why packages should be allowed to step on others.

To me this issue is one of high importance. As it is less experienced devs will run into this issue and just move on to another IDE.

Just my .02.


#26

The latest version of Atom (v1.0.19) provides an “Enabled” checkbox on packages that provide keybindings so that you can disable all of them in one go:

You can find it by going to the package’s settings page and scrolling down to the Keybindings section.

There are all kinds of reasons why this is problematic:

  1. What if package X uses keybinding Y but nobody ever installs it?
  2. What if package X uses keybinding Y but only people on Linux install it and your package isn’t designed for Linux use?
  3. What if package X uses keybinding Y but it is only enabled in certain circumstances or within certain views?
  4. etc

The thing is, there just isn’t a simple answer for this question. If there was, then it would be solved already.


#27

Not talking Global registry. talking local to your machine which would be trivial to check. Bottom line if you have a keybinding that’s about to get clobbered by another package it should default to the previously installed keybinding flag you with a warning and let you choose how to proceed.

Not talking about toggling keybindings as a whole talking about individual keybindings.

Bottom line giving autonomy to devs to use whatever keybindings they want with no validation or checks is just asking for trouble.

Validating the keybindings on the LOCAL machine NOT a global registry should in large part should be no more difficult than caching the last state of the keybindings (so you don’t have to lookup on new package install) then validate the new package against that cached dataset. If a conflict flag with warning and let the user decide how to proceed.

I don’t see how this wouldn’t work as it’s completely relative to your local experience. There’s zero chance you want to allow conflicting keybindings…none.


#28

I look forward to your pull request that can detect whether key bindings actually conflict in more than a naïve way.


#29

…you could have just replied “yeah that would probably work” there Mr. smarty pants.

Once I get a weekend without the fam or something I’ll absolutely look into creating that feature.

Why would it need to be part of the Core? Why couldn’t it just be a package that can listen for package installs. Don’t know enough about the code base yet so I’ll poke around this weekend but seems to me that everything even internally is a package for the most part.


#30

It wouldn’t need to be part of Core. I don’t believe that there is an event for package installs but I believe there is one for package activations which, after startup, amounts to roughly the same thing.

If I recall correctly, @mark_hahn started or created a package that did something like this.


#31

Yes I just looked at that and you’re correct I don’t see an onInstallPackage event to hook to. That might be a good event to add I would imagine. That would have to be added to the core obviously.

see https://atom.io/docs/api/v1.0.19/PackageManager

At first blush looks like maybe the

::onDidActivateInitialPackages 

event might be the ticket. You’d also have to watch on packages enabled/disabled too I would imagine.

The event to get the current list of commands appears to be

atom.commands.registeredCommands

#32

If any of the team guys can confirm that as a starting point that would be great (Lumburgh voice).

Absolutely look into this sort of package. Even if on activate as you’re suggesting if you get a popup flag that alone would be hella useful IMO.


#33

My package-cop looks at what is activated and reports it, along with other stuff. If I remember correctly it is pretty easy to use a hook to watch each one get activated.

The tricky part of this package you are talking about is making it logical and easy for the user. I would stick to something simple like warning on a conflict and giving the user a set of checkboxes to easily resolve the conflict. It could modify the keybinding init file and include a comment explaining that the package did the modification.


#34

Thanks, yeah that’s to my earlier point. If your using this editor chances are you know you’re way around things. Meaning this doesn’t need to be some convoluted wizardy deal.

Simply flag with list of offending commands. Toggle off the ones you want then reload Atom (again new to Atom but thinking this would be required).

…and I think what you’re getting at is rather than try to provide way to enter a alternate command for one of the offenders let the user use the standard methods provided in Atom to add a custom key binding.

So to be clear and at least to me it should be no more than toggle off the command, comment out as you suggested with note reload done.

Let me know your thoughts…


#35

As a matter of completeness for the thread the method to get list of keybindings is:

 atom.keymaps.getKeyBindings()

Looks like the best way to extrapolate all core commands is to check if it’s source keymap path is in app.asar (or equivalent windows/linux path). This should exclude all core/native commands which should likely be ignored.

keyBindings = atom.keymaps.getKeyBindings()
keyBindings = keyBindings.filter((b) ->
  if /app.asar/gi.test(b.source)
    return false
  true
)

#36

Why not make it so that user keymaps always have one more level of specificity than package keymaps? If I use the same selector in my user keymap as the package, that should always disable the package keymap.


#37

Specificity is calculated using the CSS rules by the Chromium engine. I think it would be best to not rewrite all that code unless absolutely necessary.


#38

We could add an id on the root element, then automatically prepend that id to every user selector. As long as package authors know not to include that id in their selectors, all user selectors should have higher specificity (if I understand correctly).


#39

Feel free to submit a pull request and we can test it out :grinning: