Skip to content

Commit 0f9baf9

Browse files
committed
Explain with AI via Eclipse Copilot
1 parent 75910c5 commit 0f9baf9

File tree

6 files changed

+104
-4
lines changed

6 files changed

+104
-4
lines changed

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,19 @@
2727
import org.eclipse.core.net.proxy.IProxyService;
2828
import org.eclipse.core.resources.ResourcesPlugin;
2929
import org.eclipse.core.runtime.Assert;
30+
import org.eclipse.core.runtime.Platform;
3031
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
3132
import org.eclipse.jface.preference.IPreferenceStore;
3233
import org.eclipse.jface.util.IPropertyChangeListener;
3334
import org.eclipse.lsp4e.server.StreamConnectionProvider;
3435
import org.eclipse.lsp4j.DidChangeConfigurationParams;
36+
import org.eclipse.lsp4j.ExecuteCommandParams;
3537
import org.eclipse.lsp4j.InitializeResult;
3638
import org.eclipse.lsp4j.jsonrpc.messages.Message;
3739
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
3840
import org.eclipse.lsp4j.services.LanguageServer;
3941
import org.eclipse.ui.PlatformUI;
42+
import org.osgi.framework.Bundle;
4043
import org.springframework.tooling.boot.ls.prefs.CategoryProblemsSeverityPrefsPage;
4144
import org.springframework.tooling.boot.ls.prefs.FileListEditor;
4245
import org.springframework.tooling.boot.ls.prefs.ProblemCategoryData;
@@ -168,10 +171,29 @@ public void handleMessage(Message message, LanguageServer languageServer, URI ro
168171

169172
//Add remote boot apps listener
170173
RemoteBootAppsDataHolder.getDefault().getRemoteApps().addListener(remoteAppsListener);
174+
175+
if (isCopilotInstalled()) {
176+
// Enable Copilot features if the Copilot plugin is installed
177+
languageServer.getWorkspaceService().executeCommand(new ExecuteCommandParams(
178+
"sts/enable/copilot/features",
179+
List.of(true)
180+
));
181+
}
171182
}
172183
}
173184
}
174185

186+
private boolean isCopilotInstalled() {
187+
Bundle bundle = Platform.getBundle("com.microsoft.copilot.eclipse.ui");
188+
if (bundle != null) {
189+
int state = bundle.getState();
190+
return (state & Bundle.RESOLVED) != 0
191+
|| (state & Bundle.STARTING) != 0
192+
|| (state & Bundle.ACTIVE) != 0;
193+
}
194+
return false;
195+
}
196+
175197

176198
private void sendConfiguration() {
177199
Map<String, Object> settings = new HashMap<>();

eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.8.0",
2323
org.eclipse.ui.editors,
2424
org.springsource.ide.eclipse.commons.core,
2525
org.eclipse.e4.ui.css.swt.theme,
26-
org.eclipse.swt
26+
org.eclipse.swt,
27+
com.google.gson
2728
Bundle-RequiredExecutionEnvironment: JavaSE-21
2829
Bundle-ActivationPolicy: lazy
2930
Export-Package: org.springframework.tooling.ls.eclipse.commons,

eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/plugin.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
class="org.springframework.tooling.ls.eclipse.commons.commands.InvokeContentAssistCommandHandler"
100100
commandId="editor.action.triggerSuggest">
101101
</handler>
102+
<handler
103+
class="org.springframework.tooling.ls.eclipse.commons.commands.ExplainwithAi"
104+
commandId="vscode-spring-boot.query.explain">
105+
</handler>
102106
</extension>
103107
<extension
104108
point="org.eclipse.ui.commands">
@@ -157,6 +161,22 @@
157161
typeId="org.eclipse.lsp4e.commandParameterType">
158162
</commandParameter>
159163
</command>
164+
<command
165+
id="vscode-spring-boot.query.explain"
166+
name="Explain with AI">
167+
<commandParameter
168+
id="org.eclipse.lsp4e.path.param"
169+
name="Resource Path (unnecessary, only to make lsp4e happy)"
170+
optional="true"
171+
typeId="org.eclipse.lsp4e.pathParameterType">
172+
</commandParameter>
173+
<commandParameter
174+
id="org.eclipse.lsp4e.command.param"
175+
name="Command id (unnecessary, only to make lsp4e happy)"
176+
optional="true"
177+
typeId="org.eclipse.lsp4e.commandParameterType">
178+
</commandParameter>
179+
</command>
160180
</extension>
161181
<extension
162182
point="org.eclipse.e4.ui.css.swt.theme">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Broadcom, Inc.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Broadcom, Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package org.springframework.tooling.ls.eclipse.commons.commands;
12+
13+
import org.eclipse.core.commands.AbstractHandler;
14+
import org.eclipse.core.commands.ExecutionEvent;
15+
import org.eclipse.core.commands.ExecutionException;
16+
import org.eclipse.core.commands.Parameterization;
17+
import org.eclipse.core.commands.ParameterizedCommand;
18+
import org.eclipse.lsp4e.command.LSPCommandHandler;
19+
import org.eclipse.lsp4j.Command;
20+
import org.eclipse.ui.IWorkbenchWindow;
21+
import org.eclipse.ui.commands.ICommandService;
22+
import org.eclipse.ui.handlers.HandlerUtil;
23+
import org.eclipse.ui.handlers.IHandlerService;
24+
25+
import com.google.gson.Gson;
26+
27+
public class ExplainwithAi extends AbstractHandler {
28+
29+
private static final String COPILOT_CHAT_CMD = "com.microsoft.copilot.eclipse.commands.openChatView";
30+
31+
@SuppressWarnings("restriction")
32+
@Override
33+
public Object execute(ExecutionEvent event) throws ExecutionException {
34+
try {
35+
String p = event.getParameter(LSPCommandHandler.LSP_COMMAND_PARAMETER_ID);
36+
Command lspCmd = new Gson().fromJson(p, Command.class);
37+
if (lspCmd != null) {
38+
IWorkbenchWindow workbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event);
39+
final IHandlerService handlerService = workbenchWindow.getService(IHandlerService.class);
40+
ICommandService commandService = workbenchWindow.getService(ICommandService.class);
41+
if (handlerService != null && commandService != null && commandService.getCommand(COPILOT_CHAT_CMD) != null) {
42+
org.eclipse.core.commands.Command cmd = commandService.getCommand(COPILOT_CHAT_CMD);
43+
Parameterization[] params = new Parameterization[] {
44+
new Parameterization(cmd.getParameter("com.microsoft.copilot.eclipse.commands.openChatView.inputValue"), lspCmd.getArguments().get(0).toString()),
45+
new Parameterization(cmd.getParameter("com.microsoft.copilot.eclipse.commands.openChatView.autoSend"), "true")
46+
};
47+
handlerService.executeCommand(new ParameterizedCommand(cmd, params), null);
48+
}
49+
}
50+
return null;
51+
} catch (Exception e) {
52+
throw new ExecutionException("Failed to execute Explain with AI command", e);
53+
}
54+
}
55+
56+
57+
}

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/CopilotCodeLensProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017, 2024 Broadcom, Inc.
2+
* Copyright (c) 2017, 2025 Broadcom, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/ReconcileUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023 VMware, Inc.
2+
* Copyright (c) 2023, 2025 VMware, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -97,7 +97,7 @@ public static ITypeBinding getDeepErasureType(ITypeBinding type) {
9797

9898
public static boolean isApplicableTypeWithoutResolving(CompilationUnit cu, Collection<String> types, Name typeNameNode) {
9999
String typeName = typeNameNode.getFullyQualifiedName();
100-
if (cu.getPackage().getName() != null && types.contains(cu.getPackage().getName().getFullyQualifiedName() + "." + typeName)) {
100+
if (cu.getPackage() != null && cu.getPackage().getName() != null && types.contains(cu.getPackage().getName().getFullyQualifiedName() + "." + typeName)) {
101101
return true;
102102
}
103103
if (types.contains(typeName)) {

0 commit comments

Comments
 (0)