Keybinding Conventions for Packages


#1

Atom needs some guidelines for keybindings, analogous to the ctrl-c bindings in Emacs.


Source language based keymap
Share/Browse/optimize Keybindings with others and discover/install related packages
Published incremental-search, an incremental search package
#2

But having a lot of commands is OK, right? On some of my packages I just use ctrl-shift-P for seldom used commands and assign global keys for the ones I use a lot. Avoiding a lot of keys in a package is just a convenience to avoid users having to edit their personal bindings file all the time.


#3

I think @mkleehammer said “all Atom packages should try to use 1 or 2 global keys max”, not me. Perhaps it was a misattribution caused by the quote button…

I agree with you, @mark_hahn – lots of commands should work very well.

Also, I don’t fully agree with @mkleehammer, I think that it’s possible to come up with a convention for key bindings.


#4

I, personally, think that packages should be very, very careful about assigning keybindings. And I also personally feel that any change to keybindings in a package is a breaking change, necessitating a major version number bump according to SemVer, which all of our packages should be using. Here’s why:

  1. I have a keybinding for lee-dohm:awesome-command-number-5 that maps to Cmd+Shift+Y
  2. Jane Programmer decides to add Cmd+Shift+Y to a command in her package, creating a more specific selector for it
  3. Jane Programmer doesn’t mention this in her package’s CHANGELOG (or I don’t read it)
  4. I upgrade to v0.3.0 of Jane’s package which contains the new keybinding (probably with a couple other packages)
  5. My keybinding now doesn’t work (or even worse, only works intermittently) and I have to go digging and debugging when I’d really rather be getting work done

One of the options I’ve thought of trying out is to create a package, but then create a separate package that contains what I think should be the default keybindings for the first package. (For instance, package foo and package foo-keymap containing just the keybindings for foo.) I think it will work, but like I say, I haven’t tried it yet.


#5

I have some ideas regarding a community driven process to find nice keybindings.

In short:

  • enable default keybindings for absolute beginners
  • once beginners want to become serious, they could search public sets of keybindings which match there current style closely and “fork” it, or just start there personal keybinding set from scratch (deactivating all the defaults first), which also installs the necessary packages
  • through sharing and browsing other peoples keybindings + charts/trends the community can come up with best practice keybindings.

#6

FOCUS NAVIGATION

I would like to be able to use hotkeys to focus certain components.

  1. focus menu bar (File, Edit, View, Selection, …)
  2. focus tree-view
  3. focus panes
  4. focus next tab

I feel there is a certain hierarchy in atom

  • menu bar (root level)
  • tree view (root level)
  • status bar (root level)
  • panes (root level)
    (I want to be able to cycle previous/next between them)

menu bar
STATE: when menu bar gets the focus, there is also a currently selected or default menu focused

  • menu (now hotkeys can be used to open/close menus and choose whatever)
    If i “select” it with my focus => go down one level in focus to menu
    If i “deselect” it OR use a hotkey to go to the root level => go up one level in focus to menu bar

tree view
STATE: when tree view gets the focus, there is also a currently selected or default file/folder focused

  • files/folders (now hotkeys can be used to open/close/…)
    If i “select” it with my focus => go down one level in focus to files/folders
    If i “deselect” it with my focus OR use a hotkey to go to the root level => go up one level in focus to tree view

panes
STATE: when panes gets the focus, there is also a currently selected or default pane focused

  • pane (now hotkeys can be used to travel between panes, create new panes, re-organize them, …)
    If i “select” it with my focus => go down one level in focus to pane
    If i “deselect” it with my focus OR use a hotkey to go to the root level => go up one level in focus to panes

pane
STATE: when pane gets the focus, there is also a currently selected or default tab focused

  • tab (now hotkeys can be used to travel between tabs, create new tabs, re-organize them, …)
    If i “select” it with my focus => go down one level in focus to tab
    If i “deselect” it with my focus OR use a hotkey to go to the root level => go up one level in focus to pane

tab
STATE: when tab gets the focus, there is also a currently selected or default cursor focused

  • cursor (now hotkeys can be used to travel between characters/words/… create new text/code, re-organize, …)

… and so on …

There might be different types of “tabs” for which different hotkeys apply or again, more “sub levels” regarding “keybindings scoping” might become available and it needs to be navigated.

Next to the general navigation, it should always be possible to “JUMP” to different control levels by defining special hotkeys and/or having some kind of autocomplete over all the focus-navigation-options.


#7

The way Emacs does it is to depend on “modes” (similar to Atom grammars, I guess). Each file can be in at most one mode. And bindings like Ctrl+C, Ctrl+A through Ctrl+C, Ctrl+Z are reserved for modes.

C mode says that Ctrl+C, Ctrl+X should do one thing.
Python mode says that Ctrl+C, Ctrl+X should do something different.
They don’t clash because we know that everything starting with Ctrl+C is reserved for the mode.

Of course, the real situation is more complex because there are things in life that do not depend on a mode. But perhaps it helps if we create more namespaces. Say we want to navigate, then we dedicate a specific set of keybindings to navigation, and whoever wants to navigate, they choose a keybinding from that set (a keybinding that is still available, of course). Navigate to a file, navigate to a line, navigate to a symbol, …

Another thing we can learn from Emacs is to rely on conventions. The idea is to document conventions, and then we gently nudge people to comply to them, and because we all understand that overall we’re better off if the conventions work, it will work.


#8

I don’t know about anyone else but my muscle memory doesn’t budge.


#9

Maybe I am too late now. My comment was directed at new packages, and new functions. Of course, it will be difficult to change existing keybindings. But we might be able to establish a policy for new keybindings, and then we track the existing ones as exceptions from the rule. The good news is that the existing keybindings don’t change, and thus the number of exceptions is fixed and won’t grow. This means that the issue @leedohm mentioned about five comments up will be sidestepped.


#10

I was thinking the other day that we could add a “keybinding signifier” to the workspace. So like .platform-darwin or .platform-windows, we could have a .keybinding-emacs on the workspace to signify that we want Emacs-style key bindings. This way packages could have multiple sets of non-conflicting key bindings. There could even be a “mode signifier” on text editors.


#11

I am real late to this party, but I am facing a similar dilemma right now. Should I assign a “default” keymap for my package, or leave it blank and let user decide which keymap they prefer?


#12

You should write up a default. It’s easy to override or disable that.


#13

Between my last post here and now, a feature was added to easily disable all of a package’s keybindings. So it is safer to include default keybindings with your packages.


#14

Awesome :slight_smile:

You are in the know of my issue anyway, and I am good to go!