diff --git a/.editorconfig b/.editorconfig index a717ab9f..e2c8ae92 100644 --- a/.editorconfig +++ b/.editorconfig @@ -157,7 +157,7 @@ ij_java_for_statement_wrap = off ij_java_generate_final_locals = false ij_java_generate_final_parameters = false ij_java_if_brace_force = always -ij_java_imports_layout = java.**,|,javax.**,jakarta.**,|,*,|,org.springframework.**,|,$* +ij_java_imports_layout = brave.**,com.**,feign.**,io.**,|,java.**,|,javax.**,lombok.**,net.**,|,org.**,jakarta.**,|,$* ij_java_indent_case_from_switch = true ij_java_insert_inner_class_imports = false ij_java_insert_override_annotation = true @@ -202,7 +202,7 @@ ij_java_names_count_to_use_import_on_demand = 99 ij_java_new_line_after_lparen_in_annotation = false ij_java_new_line_after_lparen_in_deconstruction_pattern = true ij_java_new_line_after_lparen_in_record_header = false -ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.* +ij_java_packages_to_use_import_on_demand = ij_java_parameter_annotation_wrap = off ij_java_parameter_name_prefix = ij_java_parameter_name_suffix = diff --git a/src/main/java/com/zhongan/devpilot/actions/editor/inlay/ChatShortcutHintCollector.java b/src/main/java/com/zhongan/devpilot/actions/editor/inlay/ChatShortcutHintCollector.java index 188be04f..f97c408c 100644 --- a/src/main/java/com/zhongan/devpilot/actions/editor/inlay/ChatShortcutHintCollector.java +++ b/src/main/java/com/zhongan/devpilot/actions/editor/inlay/ChatShortcutHintCollector.java @@ -4,6 +4,8 @@ import com.intellij.codeInsight.hints.InlayHintsSink; import com.intellij.codeInsight.hints.presentation.InlayPresentation; import com.intellij.codeInsight.hints.presentation.PresentationFactory; +import com.intellij.codeInsight.hints.presentation.SequencePresentation; +import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -14,22 +16,36 @@ import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.SmartList; import com.zhongan.devpilot.DevPilotIcons; import com.zhongan.devpilot.enums.EditorActionEnum; import com.zhongan.devpilot.gui.toolwindows.chat.DevPilotChatToolWindowService; import com.zhongan.devpilot.settings.state.ChatShortcutSettingState; import com.zhongan.devpilot.util.DevPilotMessageBundle; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class ChatShortcutHintCollector extends FactoryInlayHintsCollector { @@ -51,56 +67,143 @@ public ChatShortcutHintCollector(@NotNull Editor editor, List supportedE @Override public boolean collect(@NotNull PsiElement psiElement, @NotNull Editor editor, @NotNull InlayHintsSink inlayHintsSink) { + var chatShortcutSetting = ChatShortcutSettingState.getInstance(); + if (!chatShortcutSetting.getEnable()) { + return true; + } + + boolean isSourceCode = isSourceCode(editor); var elementType = PsiUtilCore.getElementType(psiElement).toString(); - if (ChatShortcutSettingState.getInstance().getEnable()) { - - if ("CLASS".equals(elementType)) { - inlayHintsSink.addBlockElement(getAnchorOffset(psiElement), true, true, 1000, - factory.seq(factory.textSpacePlaceholder(computeInitialWhitespace(editor, psiElement), false), - factory.icon(DevPilotIcons.SYSTEM_ICON_INLAY), - buildClickableTextChatShortcutEntry(DevPilotMessageBundle.get("devpilot.inlay.shortcut.test"), - EditorActionEnum.GENERATE_TESTS, psiElement))); - } else if (supportedElementTypes.contains(elementType)) { - inlayHintsSink.addBlockElement(getAnchorOffset(psiElement), true, true, 1000, - factory.seq(factory.textSpacePlaceholder(computeInitialWhitespace(editor, psiElement), false), - factory.icon(DevPilotIcons.SYSTEM_ICON_INLAY), - buildClickableTextChatShortcutEntry(" " + DevPilotMessageBundle.get("devpilot.inlay.shortcut.explain") - + " | ", EditorActionEnum.EXPLAIN_CODE, psiElement), - buildClickableTextChatShortcutEntry(DevPilotMessageBundle.get("devpilot.inlay.shortcut.fix") - + " | ", EditorActionEnum.FIX_CODE, psiElement), - buildClickableTextChatShortcutEntry(DevPilotMessageBundle.get("devpilot.inlay.shortcut.inlineComment") - + " | ", EditorActionEnum.GENERATE_COMMENTS, psiElement), - buildClickableMethodCommentsShortcutEntry(DevPilotMessageBundle.get("devpilot.inlay.shortcut.methodComments") + - " | ", psiElement), - buildClickableTextChatShortcutEntry(DevPilotMessageBundle.get("devpilot.inlay.shortcut.test"), - EditorActionEnum.GENERATE_TESTS, psiElement))); + if ("CLASS".equals(elementType)) { + if (isSourceCode) { + inlineRenderInlayPresentation(psiElement, editor, inlayHintsSink, Collections.singletonList(EditorActionEnum.GENERATE_TESTS)); + } + return true; + } + + if (!isSourceCode && supportedElementTypes.contains(elementType)) { + inlineRenderInlayPresentation(psiElement, editor, inlayHintsSink, Collections.singletonList(EditorActionEnum.EXPLAIN_CODE)); + return true; + } + + if (isSourceCode && supportedElementTypes.contains(elementType)) { + if (chatShortcutSetting.isInlineDisplay()) { + inlineRenderInlayPresentation(psiElement, editor, inlayHintsSink, buildInlayPresentationGroupData()); + } else { + groupRenderPopupPresentation(inlayHintsSink, psiElement, editor); } } return true; } - private InlayPresentation buildClickableTextChatShortcutEntry(String text, EditorActionEnum actionEnum, PsiElement psiElement) { - return factory.seq(factory.referenceOnHover(factory.smallText(text), (mouseEvent, point) -> { - TextRange textRange = psiElement.getTextRange(); - editor.getSelectionModel().setSelection(textRange.getStartOffset(), textRange.getEndOffset()); + private InlayPresentation createInlayElement(Editor editor, PsiElement psiElement, List actions) { + List presentations = new ArrayList<>(); - service.handleActions(actionEnum, psiElement); + presentations.add(factory.textSpacePlaceholder(computeInitialWhitespace(editor, psiElement), false)); + presentations.add(factory.icon(DevPilotIcons.SYSTEM_ICON_INLAY)); + + for (int i = 0, len = actions.size(); i < len; i++) { + String prefix = (i == 0) ? " " : StringUtils.EMPTY; + String postfix = (i == len - 1) ? StringUtils.EMPTY : " | "; + presentations.add(buildClickableInlayPresentation(prefix, postfix, actions.get(i), psiElement)); + } + + return factory.seq(presentations.toArray(new InlayPresentation[0])); + } + + private void inlineRenderInlayPresentation(PsiElement psiElement, @NotNull Editor editor, @NotNull InlayHintsSink inlayHintsSink, List actions) { + inlayHintsSink.addBlockElement(getAnchorOffset(psiElement), + true, + true, + 1000, + createInlayElement(editor, psiElement, actions)); + } + + private void groupRenderPopupPresentation(InlayHintsSink inlayHintsSink, PsiElement psiElement, Editor editor) { + PresentationFactory factory = getFactory(); + Document document = editor.getDocument(); + int offset = getAnchorOffset(psiElement); + int line = document.getLineNumber(offset); + int startOffset = document.getLineStartOffset(line); + + InlayPresentation finalPresentation = createPopupPresentation(factory, editor, psiElement, startOffset, offset); + inlayHintsSink.addBlockElement(startOffset, true, true, 300, finalPresentation); + } + + private InlayPresentation createPopupPresentation(PresentationFactory factory, Editor editor, + PsiElement psiElement, int startOffset, int offset) { + String linePrefix = editor.getDocument().getText(new TextRange(startOffset, offset)); + int column = offset - startOffset + findOffsetBySpace(editor, linePrefix); + + List presentations = new SmartList<>(); + presentations.add(factory.textSpacePlaceholder(column, true)); + presentations.add(factory.smallScaledIcon(DevPilotIcons.SYSTEM_ICON_INLAY)); + presentations.add(factory.smallScaledIcon(AllIcons.Actions.FindAndShowNextMatchesSmall)); + presentations.add(factory.textSpacePlaceholder(1, true)); + + SequencePresentation shiftedPresentation = new SequencePresentation(presentations); + + return factory.referenceOnHover(shiftedPresentation, (event, translated) -> + showPopup(editor, psiElement, event) + ); + } + + private void showPopup(Editor editor, PsiElement psiElement, MouseEvent event) { + List options = buildInlayPresentationGroupData(); + JBPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(StringUtils.EMPTY, options) { + public @NotNull String getTextFor(EditorActionEnum value) { + return DevPilotMessageBundle.get(value.getInlayLabel()); + } + + public @Nullable PopupStep onChosen(EditorActionEnum selectedValue, boolean finalChoice) { + handleActionCallback(selectedValue, psiElement); + return FINAL_CHOICE; + } + }); + popup.showInScreenCoordinates(editor.getComponent(), event.getLocationOnScreen()); + } + + private List buildInlayPresentationGroupData() { + List options = new ArrayList<>(); + options.add(EditorActionEnum.EXPLAIN_CODE); + options.add(EditorActionEnum.FIX_CODE); + options.add(EditorActionEnum.GENERATE_COMMENTS); + options.add(EditorActionEnum.COMMENT_METHOD); + options.add(EditorActionEnum.GENERATE_TESTS); + return options; + } + + public static boolean isSourceCode(Editor editor) { + Document document = editor.getDocument(); + VirtualFile file = FileDocumentManager.getInstance().getFile(document); + if (file == null || !file.isWritable()) { + return false; + } + FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName()); + return !fileType.isBinary() && !document.getText().trim().isEmpty(); + } + + private InlayPresentation buildClickableInlayPresentation(String displayPrefixText, String displaySuffixText, EditorActionEnum actionEnum, PsiElement psiElement) { + return factory.seq(factory.referenceOnHover(factory.smallText(displayPrefixText + DevPilotMessageBundle.get(actionEnum.getInlayLabel()) + displaySuffixText), (mouseEvent, point) -> { + handleActionCallback(actionEnum, psiElement); })); } - private InlayPresentation buildClickableMethodCommentsShortcutEntry(String text, PsiElement psiElement) { - return factory.seq(factory.referenceOnHover(factory.smallText(text), (mouseEvent, point) -> { - TextRange textRange = psiElement.getTextRange(); - editor.getSelectionModel().setSelection(textRange.getStartOffset(), textRange.getEndOffset()); + private void handleActionCallback(EditorActionEnum actionEnum, PsiElement psiElement) { + TextRange textRange = psiElement.getTextRange(); + editor.getSelectionModel().setSelection(textRange.getStartOffset(), textRange.getEndOffset()); + if (EditorActionEnum.COMMENT_METHOD.equals(actionEnum)) { ApplicationManager.getApplication().invokeLater(() -> { moveCareToPreviousLineStart(editor, textRange.getStartOffset()); AnAction action = ActionManager.getInstance().getAction("com.zhongan.devpilot.actions.editor.generate.method.comments"); DataContext context = SimpleDataContext.getProjectContext(editor.getProject()); action.actionPerformed(new AnActionEvent(null, context, "", new Presentation(), ActionManager.getInstance(), 0)); }); - })); + } else { + service.handleActions(actionEnum, psiElement); + } } private static int getAnchorOffset(@NotNull PsiElement psiElement) { @@ -115,10 +218,22 @@ private static int getAnchorOffset(@NotNull PsiElement psiElement) { return anchorOffset; } + private int findOffsetBySpace(@NotNull Editor editor, String linePrefix) { + int tabWidth = editor.getSettings().getTabSize(editor.getProject()); + int totalOffset = 0; + + for (int i = 0; i < linePrefix.length(); ++i) { + if (linePrefix.charAt(i) == '\t') { + totalOffset += tabWidth; + } + } + return totalOffset; + } + private int computeInitialWhitespace(Editor editor, PsiElement psiElement) { int lineNum = editor.getDocument().getLineNumber(psiElement.getTextRange().getStartOffset()); String textOnLine = editor.getDocument().getText(new TextRange(editor.getDocument().getLineStartOffset(lineNum), - editor.getDocument().getLineEndOffset(lineNum))); + editor.getDocument().getLineEndOffset(lineNum))); int whitespaceCounter = 0; for (char character : textOnLine.toCharArray()) { diff --git a/src/main/java/com/zhongan/devpilot/enums/EditorActionEnum.java b/src/main/java/com/zhongan/devpilot/enums/EditorActionEnum.java index 2da21f5c..0b46e174 100644 --- a/src/main/java/com/zhongan/devpilot/enums/EditorActionEnum.java +++ b/src/main/java/com/zhongan/devpilot/enums/EditorActionEnum.java @@ -4,24 +4,27 @@ public enum EditorActionEnum { - GENERATE_COMMENTS("devpilot.action.generate.comments", "Generate comments in the following code"), + GENERATE_COMMENTS("devpilot.action.generate.comments", "devpilot.inlay.shortcut.inlineComment", "Generate comments in the following code"), - COMMENT_METHOD("devpilot.action.generate.method.comments", ""), + COMMENT_METHOD("devpilot.action.generate.method.comments", "devpilot.inlay.shortcut.methodComments", ""), - GENERATE_TESTS("devpilot.action.generate.tests", "Generate Tests in the following code"), + GENERATE_TESTS("devpilot.action.generate.tests", "devpilot.inlay.shortcut.test", "Generate Tests in the following code"), - FIX_CODE("devpilot.action.fix", "Fix This in the following code"), + FIX_CODE("devpilot.action.fix", "devpilot.inlay.shortcut.fix", "Fix This in the following code"), - EXPLAIN_CODE("devpilot.action.explain", "Explain this in the following code"), + EXPLAIN_CODE("devpilot.action.explain", "devpilot.inlay.shortcut.explain", "Explain this in the following code"), - COMPLETE_CODE("devpilot.action.completions", "code completions"); + COMPLETE_CODE("devpilot.action.completions", "", "code completions"); private final String label; + private final String inlayLabel; + private final String userMessage; - EditorActionEnum(String label, String userMessage) { + EditorActionEnum(String label, String inlayLabel, String userMessage) { this.label = label; + this.inlayLabel = inlayLabel; this.userMessage = userMessage; } @@ -41,6 +44,10 @@ public String getLabel() { return label; } + public String getInlayLabel() { + return inlayLabel; + } + public String getUserMessage() { return userMessage; } diff --git a/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsComponent.java b/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsComponent.java index 3118a7ba..2e8179d3 100644 --- a/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsComponent.java +++ b/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsComponent.java @@ -8,13 +8,17 @@ import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UI; import com.zhongan.devpilot.settings.state.AvailabilityCheck; +import com.zhongan.devpilot.settings.state.ChatShortcutSettingState; import com.zhongan.devpilot.settings.state.CompletionSettingsState; import com.zhongan.devpilot.settings.state.DevPilotLlmSettingsState; import com.zhongan.devpilot.settings.state.LanguageSettingsState; import com.zhongan.devpilot.util.DevPilotMessageBundle; +import javax.swing.JComponent; import javax.swing.JPanel; +import org.jetbrains.annotations.NotNull; + public class DevPilotSettingsComponent { private final JPanel mainPanel; @@ -27,6 +31,8 @@ public class DevPilotSettingsComponent { private Integer index; + private Integer methodInlayPresentationDisplayIndex; + public DevPilotSettingsComponent(DevPilotSettingsConfigurable devPilotSettingsConfigurable, DevPilotLlmSettingsState settings) { fullNameField = new JBTextField(settings.getFullName(), 20); @@ -41,12 +47,16 @@ public DevPilotSettingsComponent(DevPilotSettingsConfigurable devPilotSettingsCo statusCheckRadio = new JBRadioButton(DevPilotMessageBundle.get("devpilot.settings.service.status.check.enable.desc"), AvailabilityCheck.getInstance().getEnable()); + methodInlayPresentationDisplayIndex = ChatShortcutSettingState.getInstance().getDisplayIndex(); + Integer inlayPresentationDisplayIndex = ChatShortcutSettingState.getInstance().getDisplayIndex(); + mainPanel = FormBuilder.createFormBuilder() .addComponent(UI.PanelFactory.panel(fullNameField) .withLabel(DevPilotMessageBundle.get("devpilot.setting.displayNameFieldLabel")) .resizeX(false) .createPanel()) .addComponent(createLanguageSectionPanel(languageIndex)) + .addComponent(createMethodShortcutDisplayModeSectionPanel(inlayPresentationDisplayIndex)) .addComponent(new TitledSeparator( DevPilotMessageBundle.get("devpilot.settings.service.code.completion.title"))) .addComponent(autoCompletionRadio) @@ -59,6 +69,27 @@ public DevPilotSettingsComponent(DevPilotSettingsConfigurable devPilotSettingsCo .getPanel(); } + private @NotNull JComponent createMethodShortcutDisplayModeSectionPanel(Integer inlayPresentationDisplayIndex) { + var comboBox = new ComboBox<>(); + comboBox.addItem(DevPilotMessageBundle.get("devpilot.settings.methodShortcutHidden")); + comboBox.addItem(DevPilotMessageBundle.get("devpilot.settings.methodShortcutInlineDisplay")); + comboBox.addItem(DevPilotMessageBundle.get("devpilot.settings.methodShortcutGroupDisplay")); + comboBox.setSelectedIndex(inlayPresentationDisplayIndex); + + comboBox.addActionListener(e -> { + var box = (ComboBox) e.getSource(); + methodInlayPresentationDisplayIndex = box.getSelectedIndex(); + }); + + var panel = UI.PanelFactory.grid() + .add(UI.PanelFactory.panel(comboBox) + .withLabel(DevPilotMessageBundle.get("devpilot.settings.methodShortcutDisplayModeLabel")) + .resizeX(false)) + .createPanel(); + panel.setBorder(JBUI.Borders.emptyLeft(0)); + return panel; + } + public JPanel createLanguageSectionPanel(Integer languageIndex) { var comboBox = new ComboBox<>(); comboBox.addItem("English"); @@ -92,6 +123,10 @@ public Integer getLanguageIndex() { return index; } + public Integer getMethodInlayPresentationDisplayIndex() { + return methodInlayPresentationDisplayIndex; + } + public boolean getCompletionEnabled() { return autoCompletionRadio.isSelected(); } diff --git a/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsConfigurable.java b/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsConfigurable.java index cb65735e..fe248f8b 100644 --- a/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsConfigurable.java +++ b/src/main/java/com/zhongan/devpilot/settings/DevPilotSettingsConfigurable.java @@ -6,12 +6,14 @@ import com.intellij.openapi.util.NlsContexts; import com.zhongan.devpilot.actions.editor.popupmenu.PopupMenuEditorActionGroupUtil; import com.zhongan.devpilot.settings.state.AvailabilityCheck; +import com.zhongan.devpilot.settings.state.ChatShortcutSettingState; import com.zhongan.devpilot.settings.state.CompletionSettingsState; import com.zhongan.devpilot.settings.state.DevPilotLlmSettingsState; import com.zhongan.devpilot.settings.state.LanguageSettingsState; import com.zhongan.devpilot.util.ConfigChangeUtils; import com.zhongan.devpilot.util.ConfigurableUtils; import com.zhongan.devpilot.util.DevPilotMessageBundle; +import com.zhongan.devpilot.util.EditorUtils; import javax.swing.JComponent; @@ -40,12 +42,15 @@ public class DevPilotSettingsConfigurable implements Configurable, Disposable { public boolean isModified() { var settings = DevPilotLlmSettingsState.getInstance(); var languageSettings = LanguageSettingsState.getInstance(); + var chatShortcutSettings = ChatShortcutSettingState.getInstance(); var languageIndex = settingsComponent.getLanguageIndex(); + var methodInlayPresentationDisplayIndex = settingsComponent.getMethodInlayPresentationDisplayIndex(); var completionEnable = CompletionSettingsState.getInstance().getEnable(); Boolean enable = AvailabilityCheck.getInstance().getEnable(); return !settingsComponent.getFullName().equals(settings.getFullName()) || !languageIndex.equals(languageSettings.getLanguageIndex()) + || !methodInlayPresentationDisplayIndex.equals(chatShortcutSettings.getDisplayIndex()) || !settingsComponent.getCompletionEnabled() == (completionEnable) || !settingsComponent.getStatusCheckEnabled() == (enable); } @@ -65,6 +70,14 @@ public void apply() throws ConfigurationException { languageSettings.setLanguageIndex(languageIndex); + var chatShortcutSettings = ChatShortcutSettingState.getInstance(); + var methodInlayPresentationDisplayIndex = settingsComponent.getMethodInlayPresentationDisplayIndex(); + // if inlay presentation display mode changed, refresh editor + if (!methodInlayPresentationDisplayIndex.equals(chatShortcutSettings.getDisplayIndex())) { + EditorUtils.refreshInlayPresentationDisplay(methodInlayPresentationDisplayIndex); + } + chatShortcutSettings.setDisplayIndex(methodInlayPresentationDisplayIndex); + PopupMenuEditorActionGroupUtil.refreshActions(null); CompletionSettingsState completionSettings = CompletionSettingsState.getInstance(); diff --git a/src/main/java/com/zhongan/devpilot/settings/state/ChatShortcutSettingState.java b/src/main/java/com/zhongan/devpilot/settings/state/ChatShortcutSettingState.java index 6581a618..03db46b3 100644 --- a/src/main/java/com/zhongan/devpilot/settings/state/ChatShortcutSettingState.java +++ b/src/main/java/com/zhongan/devpilot/settings/state/ChatShortcutSettingState.java @@ -6,6 +6,7 @@ import com.intellij.openapi.components.Storage; import com.intellij.util.xmlb.XmlSerializerUtil; +import org.apache.commons.lang3.math.NumberUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -14,6 +15,8 @@ public class ChatShortcutSettingState implements PersistentStateComponent CompletionSettingsState.getInstance().setEnable(false) + DevPilotMessageBundle.get("devpilot.settings.service.code.completion.disabled.desc"), + event -> CompletionSettingsState.getInstance().setEnable(false) ); } else { return DumbAwareAction.create( - DevPilotMessageBundle.get("devpilot.settings.service.code.completion.enable.desc"), - event -> CompletionSettingsState.getInstance().setEnable(true) + DevPilotMessageBundle.get("devpilot.settings.service.code.completion.enable.desc"), + event -> CompletionSettingsState.getInstance().setEnable(true) ); } } @@ -67,13 +70,21 @@ private static DumbAwareAction createLoginAction() { private static DumbAwareAction createChatShortcutSwitchAction() { if (ChatShortcutSettingState.getInstance().getEnable()) { return DumbAwareAction.create( - DevPilotMessageBundle.get("devpilot.settings.service.chat.shortcut.disabled.desc"), - event -> ChatShortcutSettingState.getInstance().setEnable(false) + DevPilotMessageBundle.get("devpilot.settings.service.chat.shortcut.disabled.desc"), + event -> { + ChatShortcutSettingState.getInstance().setEnable(false); + ChatShortcutSettingState.getInstance().setDisplayIndex(NumberUtils.INTEGER_ZERO); + + } ); } else { return DumbAwareAction.create( - DevPilotMessageBundle.get("devpilot.settings.service.chat.shortcut.enable.desc"), - event -> ChatShortcutSettingState.getInstance().setEnable(true) + DevPilotMessageBundle.get("devpilot.settings.service.chat.shortcut.enable.desc"), + event -> { + ChatShortcutSettingState.getInstance().setEnable(true); + ChatShortcutSettingState.getInstance().setDisplayIndex(NumberUtils.INTEGER_ONE); + refreshInlayPresentationDisplay(NumberUtils.INTEGER_ONE); + } ); } } diff --git a/src/main/java/com/zhongan/devpilot/util/EditorUtils.java b/src/main/java/com/zhongan/devpilot/util/EditorUtils.java index 545fbfe8..b10f5373 100644 --- a/src/main/java/com/zhongan/devpilot/util/EditorUtils.java +++ b/src/main/java/com/zhongan/devpilot/util/EditorUtils.java @@ -5,15 +5,19 @@ import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.ScrollingModel; import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.jetbrains.annotations.NotNull; @@ -81,4 +85,15 @@ public static void openFileByRelativePath(String repo, @NotNull Project project, FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file), true); } + + public static void refreshInlayPresentationDisplay(Integer methodInlayPresentationDisplayIndex) { + var projects = ProjectManager.getInstance().getOpenProjects(); + + Arrays.stream(projects).sequential().forEach(project -> + Optional.ofNullable(FileEditorManager.getInstance(project)) + .flatMap(fileEditorManager -> Optional.ofNullable(fileEditorManager.getSelectedTextEditor())) + .flatMap(editor -> Optional.ofNullable(FileDocumentManager.getInstance().getFile(editor.getDocument()))) + .ifPresent(virtualFile -> FileEditorManager.getInstance(project).updateFilePresentation(virtualFile)) + ); + } } diff --git a/src/main/resources/messages/devpilot_en.properties b/src/main/resources/messages/devpilot_en.properties index 3a14f7d5..1ccbc543 100644 --- a/src/main/resources/messages/devpilot_en.properties +++ b/src/main/resources/messages/devpilot_en.properties @@ -94,3 +94,8 @@ devpilot.notification.network.setting=Go to Check Setting. devpilot.notification.version.message=Devpilot version is too old, please upgrade. devpilot.notification.upgrade.message=Go to upgrade devpilot + +devpilot.settings.methodShortcutDisplayModeLabel=Method Shortcut Display Mode +devpilot.settings.methodShortcutHidden=Hidden +devpilot.settings.methodShortcutInlineDisplay=Inline Display +devpilot.settings.methodShortcutGroupDisplay=Group Display \ No newline at end of file diff --git a/src/main/resources/messages/devpilot_zh.properties b/src/main/resources/messages/devpilot_zh.properties index b092a82e..1e9575ec 100644 --- a/src/main/resources/messages/devpilot_zh.properties +++ b/src/main/resources/messages/devpilot_zh.properties @@ -91,4 +91,9 @@ devpilot.notification.network.message=DevPilot\u8FDE\u63A5\u8D85\u65F6\uFF0C\u8B devpilot.notification.network.setting=\u72B6\u6001\u68C0\u67E5\u914D\u7F6E devpilot.notification.version.message=DevPilot\u7248\u672C\u592A\u4F4E, \u8BF7\u5347\u7EA7\u7248\u672C -devpilot.notification.upgrade.message=\u53BB\u5347\u7EA7\u63D2\u4EF6 \ No newline at end of file +devpilot.notification.upgrade.message=\u53BB\u5347\u7EA7\u63D2\u4EF6 + +devpilot.settings.methodShortcutDisplayModeLabel=\u65b9\u6cd5\u5feb\u6377\u952e\u663e\u793a\u65b9\u5f0f +devpilot.settings.methodShortcutHidden=\u4e0d\u663e\u793a +devpilot.settings.methodShortcutInlineDisplay=\u5e73\u94fa +devpilot.settings.methodShortcutGroupDisplay=\u5206\u7ec4\u4e0b\u62c9 \ No newline at end of file