Skip to content

Extension API: how to retrieve focused view ID during keybinding command execution? #315186

@n-gist

Description

@n-gist

Extension API: how to retrieve focused view ID during keybinding command execution?

I'm developing an extension which manages 5 views, and it needs to support keybindings for commands operating on TreeView item selections. Since there are multiple views, the extension needs to know exactly which view was focused when the keybinding was pressed, but I haven't found a reliable way to retrieve the view ID in this scenario.

The extension already has 100 commands, 56 of which are duplicates created specifically to work around this limitation (30 + 14 * 5). These are context menu commands for operations over TreeView items, with optional keybindings.

This is already becoming difficult to manage, because the duplication propagates through:

  • commands
  • commandPalette
  • keybindings
  • menus.view/item/context
  • submenus

I still need to add around 50 * 5 more commands, which would push the total above 350. At this point I decided to ask whether I missed a proper solution, or whether this is currently not supported by the Extension API.

Why command duplication is currently the only reliable solution

The extension manages a single TreeDataProvider, shared across 5 views (activitybar, explorer, scm, debug, test) so the same tree can be accessed from different workbench layouts if needed.

I tried several heuristics to determine the active view during keybinding execution, but none of them are reliable enough:

  1. TreeView.onDidChangeVisibility - multiple views can be visible simultaneously, so result depends on event ordering
  2. TreeView.onDidChangeSelection - views can be focused/switched without changing selection

Both approaches may result in executing a command against the wrong view selection, which is unsafe for destructive operations.

As a workaround, I duplicated commands, scoped each keybinding to its own view through when clauses, and subscribed them to separate handlers.

For example:

{
    "key": "shift+g",
    "command": "focus.arrange.group.activity",
    "when": "focus.activity"
},
{
    "key": "shift+g",
    "command": "focus.arrange.group.explorer",
    "when": "focus.explorer"
},
{
    "key": "shift+g",
    "command": "focus.arrange.group.scm",
    "when": "focus.scm"
},
{
    "key": "shift+g",
    "command": "focus.arrange.group.debug",
    "when": "focus.debug"
},
{
    "key": "shift+g",
    "command": "focus.arrange.group.test",
    "when": "focus.test"
}

I also considered command arguments as a workaround, but rejected that approach because it is not user-friendly:

  • arguments are not visible/manageable in Keyboard Shortcuts UI
  • users would need to manually edit keybindings.json
  • extension would need additional documentation just to explain keybinding setup, including the need to create 5 bindings per key and specify the correct command and view IDs in the arguments for each one, which is not something extension users should reasonably be expected to do

So my question is: did I miss a proper way to solve this, and is there a correct way to handle this scenario?

If not, I will probably have to drop keybinding support for some commands.

Possible API improvements

Some possible additions that could solve this cleanly:

  1. window.onDidChangeActiveView(TreeView | undefined) and window.activeView (mirroring the existing activeTextEditor API)
  2. TreeView.onDidChangeFocus(boolean) (view-local variant of 1)
  3. Passing the view ID or TreeView reference to command handlers

This is not limited to keybindings, but also affects regular tree view context menu commands. In cases where a command needs to call TreeView API methods, such as TreeView.reveal for the corresponding view, the command also needs a reliable way to determine which view invoked it. Tree items could theoretically be associated with a specific view to retrieve the corresponding TreeView reference, but this is not applicable when a single TreeDataProvider is shared across multiple views, so command duplication becomes the only reliable solution.

Another related limitation is the inability to retrieve the currently focused/highlighted tree item. For example, in Explorer view it is possible to navigate using arrow keys and then rename or delete the highlighted file using a keybinding. In extension TreeViews, only selection is exposed, but selection does not change during keyboard navigation, so it is currently not possible to retrieve the correct item for keybinding execution. Pressing Space or Enter updates the selection, but it is an extra action and also executes the assigned TreeItem.command, which may be undesired. Having access to the active/focused item would also help extensions provide more native keyboard interaction behavior.

Metadata

Metadata

Assignees

Labels

apifeature-requestRequest for new features or functionalitytree-viewsExtension tree view issues

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions