Making VS Code more accessible (and productive) with custom keybindings

Being involved in the OmniSharp project, I had the pleasure of working a lot with VS Code extension development over the past several years. Given that background, a coworker asked me recently if I had any ideas for improving his user experience with VS Code. In particular, being a screen reader user, he relies heavily on keyboard navigation and being able to quickly move focus between UI elements is critical for his productivity.

VS Code defines a very rich set of commands, to which custom key bindings can be attached, and which can be very helpful in such situations. In fact, through those commands, pretty much any task can be executed exclusively from the keyboard, which can be viewed as very positive from both accessibility and productivity standpoints.

Discovering available commands

The list of all available VS Code commands, including both those with a predefined key bindings, as well as those without an associated one, can be opened by pressing the Cmd+k and then Cmd+s key combination (replace Cmd with Ctrl on non-Macs). This opens the UI editor. Alternatively, it is possible to go to the command palette (Cmd+Shift+p) and select Preferences: Open Default Keyboard Shortcuts (JSON) to view all of them in the text format.

This lists everything that is customizable, and there is quite a lot of things there – but the list is of course searchable. The things we discussed, were debugger related – for example being able to jump to the local variables view or switch focus to the watch view (naturally, one could easily imagine this being super important when using a screen reader). For those specific ones, there indeed exist dedicated commands workbench.debug.action.focusVariablesView and workbench.debug.action.focusWatchView, but without default assigned keyboard bindings.

Contextual key bindings

Of course once we start using common simple key bindings or function keys for many tasks, we can very quickly run out of them. For that, VS Code allows applying key bindings in context only, that is, it is possible to have the key binding be active only if certain pre-conditions are fulfilled. An example could be – when the users have their current focus in the text editor window, when they are in a debug session, when they are in diff view and many more (they can also be combined).

This is of course great, because such scoping allows reuse of identical bindings, which simplifies work a lot.

Adding custom bindings

Having covered that, the only thing left is to apply the necessary bindings. This can be done either using the UI listing all the shortcuts or by going to the custom bindings JSON view, which can be triggered from the command palette (Cmd+Shift+p) and selecting there Preferences: Open Keyboard Shortcuts (JSON) (note the lack of “Default” here compared to the command we used earlier – the latter was read only, the former is editable).

This gives us a possibility to define the keyboard shortcuts using JSON declarations, in an array. In our example, we decide to attach alt+v and alt+w to the two debugger related commands we mentioned earlier:

The additional presence of the the inDebugMode qualifier, ensures that they bindings only kick in during a debug session, instead of applying globally to any VS Code usage.

This was just a simple example to get started, but it hopefully illustrates that there are a lot of possibilities to adjust the VS Code user experience, in terms of keyboard driven navigation, to one's needs. There is quite a lot of good documentation on that topic available on the VS Code docs site.