Skip to content

Look up the displaced action by command id in KeyBindingService - #4243

Merged
vogella merged 1 commit into
eclipse-platform:masterfrom
vogella:keybindingservice-registeraction-lookup
Aug 31, 2026
Merged

Look up the displaced action by command id in KeyBindingService#4243
vogella merged 1 commit into
eclipse-platform:masterfrom
vogella:keybindingservice-registeraction-lookup

Conversation

@vogella

@vogella vogella commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

KeyBindingService.registerAction scanned every already registered action to find the one currently holding the command id it is about to take over. AbstractTextEditor registers dozens of actions per editor via setAction, so registering n actions costs O(n^2) comparisons on every editor open. A map from command id to action turns that into a single lookup; removal takes the id from the handler activation, so no inverse map is needed. As a side effect the scan no longer removes entries from the keySet it is iterating, which previously only avoided a ConcurrentModificationException because of the break immediately after it.

The map is keyed by the command id an action was registered under rather than by its current definition id. Those differ only when getActionDefinitionId changes after registration, and in that case eviction now matches the id the handler activation actually uses, rather than one the activation was never created for.

The PR also adds KeyBindingServiceTest. Registering an action for an already bound command id displaces the previous action, and the displaced one has to be deactivated rather than shadowed so it does not resurface when the replacement is unregistered. None of that had any coverage. Two further tests pin down the changed definition id case and are the only ones that fail against the previous implementation.

To be upfront about the performance side: this is not a measurable win. Timed with OpenCloseEditorTest over three alternating runs per variant, the difference stays below the run to run spread of the baseline itself. The value here is the removed quadratic loop, the removed iteration hazard, and the new test coverage.

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Test Results

   858 files  ± 0     858 suites  ±0   48m 48s ⏱️ - 1m 14s
 8 193 tests + 8   7 950 ✅ + 8  243 💤 ±0  0 ❌ ±0 
20 481 runs  +24  19 825 ✅ +24  656 💤 ±0  0 ❌ ±0 

Results for commit bfa4da8. ± Comparison against base commit b95522c.

♻️ This comment has been updated with latest results.

@vogella
vogella requested a balanced review from Copilot August 30, 2026 15:53
@vogella
vogella force-pushed the keybindingservice-registeraction-lookup branch from e1201e2 to 47f2246 Compare August 30, 2026 15:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Optimizes key-binding action registration by replacing linear scans with command/action lookup maps and adds regression coverage.

Changes:

  • Adds bidirectional command-to-action bookkeeping.
  • Updates registration, unregistration, and disposal logic.
  • Adds and registers KeyBindingService behavior tests.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
KeyBindingService.java Implements constant-time displaced-action lookup.
KeyBindingServiceTest.java Tests registration and displacement behavior.
KeysTestSuite.java Adds the new tests to the suite.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

registerAction scanned every already registered action to find the one
holding the command id it is about to take over. AbstractTextEditor
registers dozens of actions per editor through setAction, so registering
n actions cost O(n^2) comparisons on every editor open.

Keep a map from command id to action so the lookup is a single map
access. Removal takes the id from the handler activation, which was
created for exactly that id, so no inverse map is needed. The scan also
removed entries from the keySet it was iterating and only avoided a
ConcurrentModificationException because of the break directly after,
which the map lookup makes moot.

The map is keyed by the command id an action was registered under rather
than by its current definition id. These differ only if
getActionDefinitionId changes after registration, in which case eviction
now matches the id the handler activation actually uses instead of one
the activation was never created for.

Add KeyBindingServiceTest, which pins down that registering an action for
an already bound command id displaces the previous action, and that the
displaced action is deactivated rather than shadowed, so it does not
resurface once the replacement is unregistered. That behaviour had no
coverage. Two further tests cover the changed definition id case and are
the only ones that fail against the previous implementation.

This is not a measurable speedup. Timed with OpenCloseEditorTest over
three alternating runs per variant, the difference stays under the
run to run spread of the baseline itself.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
@vogella
vogella force-pushed the keybindingservice-registeraction-lookup branch from 47f2246 to bfa4da8 Compare August 30, 2026 18:24
@vogella vogella added plan Planned bugs/enhancements for a release and removed Planned for 4.42 labels Aug 31, 2026
@vogella
vogella merged commit 822c4d1 into eclipse-platform:master Aug 31, 2026
18 checks passed
@vogella
vogella deleted the keybindingservice-registeraction-lookup branch August 31, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plan Planned bugs/enhancements for a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants