Skip to content

Commit

Permalink
Chat reference code (openpilot-hub#83)
Browse files Browse the repository at this point in the history
* reference chat

* reference chat

* answer language will always upload

* update webview

* pure chat code ref
  • Loading branch information
xiangtianyu authored Aug 29, 2024
1 parent 5141bdc commit cbf96e5
Show file tree
Hide file tree
Showing 15 changed files with 651 additions and 1,320 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ public void actionPerformed(@NotNull AnActionEvent e) {
service.clearRequestSession();

var showText = getShowText();
var codeReference = new CodeReferenceModel(editorInfo.getFilePresentableUrl(),
editorInfo.getFileName(), editorInfo.getSelectedStartLine(), editorInfo.getSelectedEndLine(), getEditorActionEnum());
var codeReference = CodeReferenceModel.getCodeRefFromEditor(editorInfo, getEditorActionEnum());

var codeMessage = MessageModel.buildCodeMessage(
UUID.randomUUID().toString(), System.currentTimeMillis(), showText, username, codeReference);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsActions;
import com.intellij.psi.PsiElement;
import com.zhongan.devpilot.webview.model.CodeReferenceModel;

import javax.swing.Icon;

Expand All @@ -23,18 +24,18 @@ public abstract class BasicEditorAction extends AnAction {
PopupMenuEditorActionGroupUtil.registerOrReplaceAction(this);
}

protected abstract void actionPerformed(Project project, Editor editor, String selectedText, PsiElement psiElement);
protected abstract void actionPerformed(Project project, Editor editor, String selectedText, PsiElement psiElement, CodeReferenceModel codeReferenceModel);

public void actionPerformed(@NotNull AnActionEvent event) {
var project = event.getProject();
var editor = event.getData(PlatformDataKeys.EDITOR);
if (editor != null && project != null) {
actionPerformed(project, editor, editor.getSelectionModel().getSelectedText(), null);
actionPerformed(project, editor, editor.getSelectionModel().getSelectedText(), null, null);
}
}

public void fastAction(Project project, Editor editor, String selectedText, PsiElement psiElement) {
actionPerformed(project, editor, selectedText, psiElement);
public void fastAction(Project project, Editor editor, String selectedText, PsiElement psiElement, CodeReferenceModel codeReferenceModel) {
actionPerformed(project, editor, selectedText, psiElement, codeReferenceModel);
}

public void update(AnActionEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.zhongan.devpilot.gui.toolwindows.chat.DevPilotChatToolWindowService;
import com.zhongan.devpilot.gui.toolwindows.components.EditorInfo;
import com.zhongan.devpilot.util.DevPilotMessageBundle;
import com.zhongan.devpilot.webview.model.CodeReferenceModel;

import org.jetbrains.annotations.NotNull;

Expand All @@ -24,13 +28,30 @@ public void update(@NotNull AnActionEvent event) {
@Override
public void actionPerformed(@NotNull AnActionEvent event) {
var project = event.getProject();
if (project != null) {
ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("DevPilot");
if (toolWindow == null) {
return;
}
toolWindow.show();
if (project == null) {
return;
}

ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("DevPilot");
if (toolWindow == null) {
return;
}
toolWindow.show();

var editor = event.getData(PlatformDataKeys.EDITOR);
if (editor == null) {
return;
}

var editorInfo = new EditorInfo(editor);
if (editorInfo.getSourceCode() == null) {
return;
}

var codeReference = CodeReferenceModel.getCodeRefFromEditor(editorInfo, null);
var service = project.getService(DevPilotChatToolWindowService.class);
service.clearRequestSession();
service.referenceCode(codeReference);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import com.zhongan.devpilot.util.DevPilotMessageBundle;
import com.zhongan.devpilot.util.DocumentUtil;
import com.zhongan.devpilot.util.LanguageUtil;
import com.zhongan.devpilot.util.PerformanceCheckUtils;
import com.zhongan.devpilot.util.PsiElementUtils;
import com.zhongan.devpilot.util.PsiFileUtil;
import com.zhongan.devpilot.webview.model.CodeReferenceModel;
Expand All @@ -54,11 +53,9 @@
public class PopupMenuEditorActionGroupUtil {

private static final Map<String, Icon> ICONS = new LinkedHashMap<>(Map.of(
EditorActionEnum.CHECK_PERFORMANCE.getLabel(), AllIcons.Plugins.Updated,
EditorActionEnum.GENERATE_COMMENTS.getLabel(), AllIcons.Actions.InlayRenameInCommentsActive,
EditorActionEnum.GENERATE_TESTS.getLabel(), AllIcons.Modules.GeneratedTestRoot,
EditorActionEnum.FIX_CODE.getLabel(), AllIcons.Actions.QuickfixBulb,
EditorActionEnum.REVIEW_CODE.getLabel(), AllIcons.Actions.PreviewDetailsVertically,
EditorActionEnum.EXPLAIN_CODE.getLabel(), AllIcons.Actions.Preview));

public static void refreshActions(Project project) {
Expand All @@ -67,13 +64,14 @@ public static void refreshActions(Project project) {
DefaultActionGroup group = (DefaultActionGroup) actionGroup;
group.removeAll();
group.add(new NewChatAction());
group.add(new ReferenceCodeAction());
group.addSeparator();

var defaultActions = EditorActionConfigurationState.getInstance().getDefaultActions();
defaultActions.forEach((label) -> {
var action = new BasicEditorAction(DevPilotMessageBundle.get(label), DevPilotMessageBundle.get(label), ICONS.getOrDefault(label, AllIcons.FileTypes.Unknown)) {
@Override
protected void actionPerformed(Project project, Editor editor, String selectedText, PsiElement psiElement) {
protected void actionPerformed(Project project, Editor editor, String selectedText, PsiElement psiElement, CodeReferenceModel codeReferenceModel) {
ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("DevPilot");
toolWindow.show();
var editorActionEnum = EditorActionEnum.getEnumByLabel(label);
Expand All @@ -88,16 +86,8 @@ protected void actionPerformed(Project project, Editor editor, String selectedTe
return;
}

switch (editorActionEnum) {
case CHECK_PERFORMANCE:
// display result, and open diff window
PerformanceCheckUtils.showDiffWindow(selectedText, project, editor);
break;
case GENERATE_COMMENTS:
DocumentUtil.diffCommentAndFormatWindow(project, editor, result);
break;
default:
break;
if (editorActionEnum == EditorActionEnum.GENERATE_COMMENTS) {
DocumentUtil.diffCommentAndFormatWindow(project, editor, result);
}
};
Map<String, String> data = new HashMap<>();
Expand Down Expand Up @@ -142,22 +132,24 @@ protected void actionPerformed(Project project, Editor editor, String selectedTe
}
}

if (LanguageSettingsState.getInstance().getLanguageIndex() == 1
&& editorActionEnum != EditorActionEnum.GENERATE_COMMENTS) {
// todo 拿到用户真正希望回答的语言
if (LanguageSettingsState.getInstance().getLanguageIndex() == 1) {
data.put(ANSWER_LANGUAGE, "zh_CN");
} else {
data.put(ANSWER_LANGUAGE, "en_US");
}

var service = project.getService(DevPilotChatToolWindowService.class);
var username = DevPilotLlmSettingsState.getInstance().getFullName();
service.clearRequestSession();

var showText = DevPilotMessageBundle.get(label);
var codeReference = new CodeReferenceModel(editorInfo.getFilePresentableUrl(),
editorInfo.getFileName(), editorInfo.getSelectedStartLine(), editorInfo.getSelectedEndLine(), editorActionEnum);

if (codeReferenceModel == null) {
codeReferenceModel = CodeReferenceModel.getCodeRefFromEditor(editorInfo, editorActionEnum);
}

var codeMessage = MessageModel.buildCodeMessage(
UUID.randomUUID().toString(), System.currentTimeMillis(), showText, username, codeReference);
UUID.randomUUID().toString(), System.currentTimeMillis(), showText, username, codeReferenceModel);

service.sendMessage(SessionTypeEnum.MULTI_TURN.getCode(), editorActionEnum.name(), data, null, callback, codeMessage);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.zhongan.devpilot.actions.editor.popupmenu;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.zhongan.devpilot.gui.toolwindows.chat.DevPilotChatToolWindowService;
import com.zhongan.devpilot.gui.toolwindows.components.EditorInfo;
import com.zhongan.devpilot.util.DevPilotMessageBundle;
import com.zhongan.devpilot.webview.model.CodeReferenceModel;

import org.jetbrains.annotations.NotNull;

public class ReferenceCodeAction extends AnAction {

public ReferenceCodeAction() {
super(DevPilotMessageBundle.get("devpilot.action.reference.chat"), DevPilotMessageBundle.get("devpilot.action.reference.chat"), AllIcons.Actions.Find);
PopupMenuEditorActionGroupUtil.registerOrReplaceAction(this);
}

@Override
public void update(@NotNull AnActionEvent event) {
event.getPresentation().setEnabled(event.getProject() != null);
}

@Override
public void actionPerformed(@NotNull AnActionEvent event) {
var project = event.getProject();
if (project == null) {
return;
}

ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("DevPilot");
if (toolWindow == null) {
return;
}
toolWindow.show();

var editor = event.getData(PlatformDataKeys.EDITOR);
if (editor == null) {
return;
}

var editorInfo = new EditorInfo(editor);
if (editorInfo.getSourceCode() == null) {
return;
}

var codeReference = CodeReferenceModel.getCodeRefFromEditor(editorInfo, null);
var service = project.getService(DevPilotChatToolWindowService.class);
service.referenceCode(codeReference);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

public enum EditorActionEnum {

CHECK_PERFORMANCE("devpilot.action.performance.check", "Performance check in the following code"),

GENERATE_COMMENTS("devpilot.action.generate.comments", "Generate comments in the following code"),

COMMENT_METHOD("devpilot.action.generate.method.comments", ""),
Expand All @@ -14,8 +12,6 @@ public enum EditorActionEnum {

FIX_CODE("devpilot.action.fix", "Fix This in the following code"),

REVIEW_CODE("devpilot.action.review", "Review code in the following code"),

EXPLAIN_CODE("devpilot.action.explain", "Explain this in the following code"),

COMPLETE_CODE("devpilot.action.completions", "code completions");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@

import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.JComponent;

Expand All @@ -47,6 +49,15 @@ public class DevPilotChatToolWindow {

private final Project project;

private static final Map<String, EditorActionEnum> codeActionMap = new ConcurrentHashMap<>();

static {
codeActionMap.put("FixCode", EditorActionEnum.FIX_CODE);
codeActionMap.put("CommentCode", EditorActionEnum.GENERATE_COMMENTS);
codeActionMap.put("ExplainCode", EditorActionEnum.EXPLAIN_CODE);
codeActionMap.put("TestCode", EditorActionEnum.GENERATE_TESTS);
}

public DevPilotChatToolWindow(Project project) {
super();
this.project = project;
Expand Down Expand Up @@ -105,10 +116,13 @@ private void registerJsCallJavaHandler(JBCefBrowser browser) {
var time = System.currentTimeMillis();
var username = DevPilotLlmSettingsState.getInstance().getFullName();
var uuid = UUID.randomUUID().toString();
var message = messageModel.getContent();

var userMessageModel = MessageModel.buildUserMessage(uuid, time, message, username);
service.sendMessage(SessionTypeEnum.MULTI_TURN.getCode(), "PURE_CHAT", null, message, null, userMessageModel);
ApplicationManager.getApplication().invokeLater(() -> {
var message = service.getUserContentCode(messageModel);
var userMessageModel = MessageModel.buildCodeMessage(uuid, time, message.getContent(), username, message.getCodeRef());
service.sendMessage(SessionTypeEnum.MULTI_TURN.getCode(), "PURE_CHAT", null, message.getContent(), null, userMessageModel);
});

return new JBCefJSQuery.Response("success");
}
case "InterruptChatStream": {
Expand Down Expand Up @@ -179,7 +193,8 @@ private void registerJsCallJavaHandler(JBCefBrowser browser) {

ApplicationManager.getApplication().invokeLater(
() -> EditorUtils.openFileAndSelectLines(project, codeReferenceModel.getFileUrl(),
codeReferenceModel.getSelectedStartLine(), codeReferenceModel.getSelectedEndLine()));
codeReferenceModel.getSelectedStartLine(), codeReferenceModel.getSelectedStartColumn(),
codeReferenceModel.getSelectedEndLine(), codeReferenceModel.getSelectedEndColumn()));

return new JBCefJSQuery.Response("success");
}
Expand All @@ -196,16 +211,17 @@ private void registerJsCallJavaHandler(JBCefBrowser browser) {
service.regenerateMessage();
return new JBCefJSQuery.Response("success");
}
case "FixCode": {
service.handleActions(EditorActionEnum.FIX_CODE, null);
return new JBCefJSQuery.Response("success");
}
case "CommentCode": {
service.handleActions(EditorActionEnum.GENERATE_COMMENTS, null);
return new JBCefJSQuery.Response("success");
}
case "ExplainCode": {
service.handleActions(EditorActionEnum.EXPLAIN_CODE, null);
case "FixCode":
case "CommentCode":
case "ExplainCode":
case "TestCode": {
var payload = jsCallModel.getPayload();
var messageModel = JsonUtils.fromJson(JsonUtils.toJson(payload), MessageModel.class);
if (messageModel == null) {
return new JBCefJSQuery.Response("error");
}

service.handleActions(messageModel.getCodeRef(), codeActionMap.get(command), null);
return new JBCefJSQuery.Response("success");
}
case "CopyCode": {
Expand Down
Loading

0 comments on commit cbf96e5

Please sign in to comment.