Add CoreExpression support for handler enablement in E4 model
Overview
This PR adds support for enabledWhen core expressions to E4 handlers, bringing feature parity with E3 handlers and simplifying migration from E3 to E4. Previously, E4 handlers could only use @CanExecute annotations for enablement, while E3 handlers had rich declarative <enabledWhen> expressions. This made migration more difficult and required rewriting declarative expressions as imperative code.
Problem
In E3, handlers could use declarative core expressions for enablement:
<extension point="org.eclipse.ui.handlers">
<handler commandId="com.example.mycommand" class="com.example.handlers.MyHandler">
<enabledWhen>
<with variable="selection">
<count value="1"/>
</with>
</enabledWhen>
</handler>
</extension>
In E4, developers had to convert these to @CanExecute methods, which was problematic for complex expressions and required understanding the imperative API.
Solution
This PR adds an optional enabledWhen field to the E4 Handler model that accepts core expressions, similar to the existing visibleWhen support for menu items.
Changes Made
-
Model Definition: Added
enabledWhenreference toHandlerinUIElements.ecore- Type:
MExpression(supportsMCoreExpressionand others) - Containment reference to support inline expression definitions
- Updated all generated EMF model code (interfaces, implementations, package metadata)
- Type:
-
Expression Evaluation Infrastructure:
- Created
IHandlerWithExpressioninterface inorg.eclipse.e4.core.commandsto avoid circular dependencies - Implemented
HandlerEnabledWhenWrapperthat evaluates expressions and delegates to the wrapped handler - Modified
HandlerProcessingAddonto wrap handlers with enabledWhen expressions during activation - Updated
HandlerServiceHandlerto check enabledWhen before consulting@CanExecute
- Created
-
Documentation: Enhanced
Eclipse4_Migration.mdwith:- Step-by-step migration guide for E3
<enabledWhen>to E4 core expressions - Clear explanation of expression precedence (enabledWhen → @CanExecute)
- Examples showing both declarative (core expression) and imperative (@CanExecute) approaches
- Cross-references to
Command_Core_Expressions.mdfor expression syntax
- Step-by-step migration guide for E3
-
Tests: Added
HandlerEnabledWhenTestcovering:- Backward compatibility (handlers without enabledWhen)
- Expression evaluation with true/false results
- Precedence of enabledWhen over @CanExecute
- Integration with EHandlerService
Usage Example
Define a core expression in plugin.xml:
<extension point="org.eclipse.core.expressions.definitions">
<definition id="com.example.handler.enabled">
<with variable="selection">
<count value="1"/>
</with>
</definition>
</extension>
In the E4 Model Editor, add an "Enabled When" core expression to your handler with ID com.example.handler.enabled.
Expression Precedence
When both enabledWhen expression and @CanExecute are present:
- The
enabledWhenexpression is evaluated first - If it returns false, the handler is disabled (regardless of
@CanExecute) - If it returns true, the
@CanExecutemethod is called
This allows combining declarative expressions for complex conditions with programmatic logic when needed.
Migration Path
E3 handlers with <enabledWhen> can now migrate to E4 by:
- Converting inline expressions to core expression definitions in plugin.xml
- Referencing the definition ID in the handler's enabledWhen field in the E4 model
- Removing the E3 handler registration from plugin.xml
This approach maintains the declarative nature of E3 expressions while leveraging E4's model-based architecture.
Fixes #[issue-number]
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
repo.eclipse.org
- Triggering command:
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.11/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.11/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.11 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.11/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/eclipse.platform.ui/eclipse.platform.ui org.codehaus.plexus.classworlds.launcher.Launcher clean compile -Pbuild-individual-bundles(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to the custom allowlist in this repository's Copilot coding agent settings (admins only)
Original prompt
Add CoreExpression Support to enable handlers in the E4 Model
Currently one can perform enablement with @CanExecute annotation for E4 but old E3 model has made heavy use of <enabledWhen> element in the hnadler extension point. To make transition easier and to reach equality with the E3 model we should do the follwoing:
- Add support for an (optional) core expression to be used as enabledWhen in the E4 model, we have something similar already for menu items that can have a "Visible-When" Core expression, defaults to
. If a core expression is defined it takes precedence over the annotation - Adjust the Eclipse4_Migration.md to add a note to the handler migration recipe that any <enabledWhen> should be migrated into a core expression see https://github.com/eclipse-platform/eclipse.platform.ui/blob/master/docs/Command_Core_Expressions.md#definitions how to transform from an inlined expression to a core expression
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.