From 0be65aab375fb3d2bfc19021c43ff452a9af2354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Thu, 15 Jan 2026 18:25:48 +0100 Subject: [PATCH] Wait for the glue jobs to be finish and allow cancel by ESC --- .../validation/BatchVerificationJob.java | 2 +- .../editor/validation/VerificationJob.java | 2 +- .../java/steps/JavaStepDefinitionOpener.java | 47 +++++++++++++++++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/BatchVerificationJob.java b/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/BatchVerificationJob.java index 36a42acf..c63794a2 100644 --- a/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/BatchVerificationJob.java +++ b/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/BatchVerificationJob.java @@ -44,7 +44,7 @@ protected IStatus run(IProgressMonitor monitor) { @Override public boolean belongsTo(Object family) { - return family == BatchVerificationJob.class; + return family == BatchVerificationJob.class || family == IGlueValidator.class; } @Override diff --git a/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/VerificationJob.java b/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/VerificationJob.java index 17a5d10c..a3268059 100644 --- a/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/VerificationJob.java +++ b/io.cucumber.eclipse.editor/src/io/cucumber/eclipse/editor/validation/VerificationJob.java @@ -55,7 +55,7 @@ abstract class VerificationJob extends Job { */ @Override public boolean belongsTo(Object family) { - return family == VerificationJob.class; + return family == VerificationJob.class || family == IGlueValidator.class; } @Override diff --git a/io.cucumber.eclipse.java/src/io/cucumber/eclipse/java/steps/JavaStepDefinitionOpener.java b/io.cucumber.eclipse.java/src/io/cucumber/eclipse/java/steps/JavaStepDefinitionOpener.java index 90517eb4..ba81596d 100644 --- a/io.cucumber.eclipse.java/src/io/cucumber/eclipse/java/steps/JavaStepDefinitionOpener.java +++ b/io.cucumber.eclipse.java/src/io/cucumber/eclipse/java/steps/JavaStepDefinitionOpener.java @@ -9,6 +9,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ICoreRunnable; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; @@ -18,8 +19,11 @@ import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; +import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PartInitException; @@ -30,6 +34,7 @@ import io.cucumber.eclipse.editor.EditorLogging; import io.cucumber.eclipse.editor.Tracing; import io.cucumber.eclipse.editor.hyperlinks.IStepDefinitionOpener; +import io.cucumber.eclipse.editor.validation.IGlueValidator; import io.cucumber.eclipse.java.JDTUtil; import io.cucumber.eclipse.java.plugins.CucumberCodeLocation; import io.cucumber.eclipse.java.plugins.MatchedPickleStep; @@ -75,14 +80,38 @@ public boolean openInEditor(ITextViewer textViewer, IResource resource, Step ste return false; } AtomicReference resolvedMethods = new AtomicReference<>(); + AtomicBoolean cancelled = new AtomicBoolean(false); Display display = textViewer.getTextWidget().getDisplay(); IDocument document = textViewer.getDocument(); BusyIndicator.showWhile(display, () -> { AtomicBoolean done = new AtomicBoolean(); - Job job = Job.create("Search for step '" + step.getText() + "'", new ICoreRunnable() { + AtomicReference jobRef = new AtomicReference<>(); + Listener escapeListener = new Listener() { + @Override + public void handleEvent(Event event) { + if (event.type == SWT.KeyDown && event.keyCode == SWT.ESC) { + Job job = jobRef.get(); + if (job != null) { + job.cancel(); + cancelled.set(true); + done.set(true); + display.wake(); + } + } + } + }; + display.addFilter(SWT.KeyDown, escapeListener); + Job job = Job.create("Search for step '" + step.getText() + "' (press ESC to cancel)", new ICoreRunnable() { @Override public void run(IProgressMonitor monitor) throws CoreException { + try { + Job.getJobManager().join(IGlueValidator.class, monitor); + } catch (OperationCanceledException | InterruptedException e) { + cancelled.set(true); + display.wake(); + return; + } try { Collection> steps = glueStore.getMatchedSteps(document); StringBuilder sb = new StringBuilder(); @@ -124,16 +153,26 @@ public void run(IProgressMonitor monitor) throws CoreException { resolvedMethods.set(JDTUtil.resolveMethod(project, location, monitor)); } } finally { + cancelled.set(cancelled.get() || monitor.isCanceled()); done.set(true); + display.wake(); } } }); + jobRef.set(job); job.schedule(); - while (!done.get() && !display.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); + try { + while (!done.get() && !display.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } finally { + display.removeFilter(SWT.KeyDown, escapeListener); } }); + if (cancelled.get()) { + return true; + } IMethod[] method = resolvedMethods.get(); if (method != null) { showMethod(method, textViewer.getTextWidget().getShell());