|
15 | 15 | */ |
16 | 16 | package io.github.jeddict.ai.actions; |
17 | 17 |
|
| 18 | +import io.github.jeddict.ai.hints.LearnFix; |
18 | 19 | import static javax.swing.Action.NAME; |
19 | 20 | import org.openide.util.NbBundle; |
20 | 21 | import java.awt.event.ActionEvent; |
21 | 22 | import java.awt.event.ActionListener; |
22 | | -import java.util.List; |
23 | 23 | import javax.swing.AbstractAction; |
24 | | -import javax.swing.Action; |
25 | | -import javax.swing.JMenu; |
26 | | -import javax.swing.JMenuItem; |
| 24 | +import javax.swing.text.BadLocationException; |
| 25 | +import javax.swing.text.JTextComponent; |
| 26 | +import javax.swing.text.StyledDocument; |
| 27 | +import org.netbeans.api.editor.EditorRegistry; |
| 28 | +import org.netbeans.modules.editor.NbEditorUtilities; |
| 29 | +import org.netbeans.modules.editor.indent.api.Reformat; |
27 | 30 | import org.openide.awt.ActionID; |
28 | 31 | import org.openide.awt.ActionReference; |
| 32 | +import org.openide.awt.ActionReferences; |
29 | 33 | import org.openide.awt.ActionRegistration; |
30 | | -import org.openide.util.Utilities; |
31 | | -import org.openide.util.actions.Presenter; |
| 34 | +import org.openide.filesystems.FileObject; |
| 35 | +import org.openide.loaders.DataObject; |
| 36 | +import org.openide.text.NbDocument; |
| 37 | +import org.openide.util.Exceptions; |
32 | 38 |
|
33 | 39 | @ActionID( |
34 | 40 | category = "Edit/Chat", |
|
37 | 43 | @ActionRegistration( |
38 | 44 | displayName = "#CTL_AIAssistantPopupAction", lazy = false |
39 | 45 | ) |
40 | | -@ActionReference(path = "Editors/Popup", position = 101) |
| 46 | +@ActionReferences({ |
| 47 | + @ActionReference(path = "Editors/Popup", position = 101), |
| 48 | + @ActionReference(path = "Shortcuts", name = "C-QUOTE") |
| 49 | +}) |
41 | 50 | @NbBundle.Messages("CTL_AIAssistantPopupAction=AI Assistant") |
42 | | -public final class AIAssistantPopupAction extends AbstractAction implements ActionListener, Presenter.Popup { |
| 51 | +public final class AIAssistantPopupAction extends AbstractAction implements ActionListener { |
43 | 52 |
|
44 | 53 | public AIAssistantPopupAction() { |
45 | 54 | putValue(NAME, Bundle.CTL_AIAssistantPopupAction()); |
46 | 55 | setEnabled(true); |
47 | 56 | } |
48 | 57 |
|
| 58 | + |
49 | 59 | @Override |
50 | 60 | public void actionPerformed(ActionEvent e) { |
51 | | - } |
52 | 61 |
|
53 | | - @Override |
54 | | - public JMenuItem getPopupPresenter() { |
55 | | - setEnabled(true); |
56 | | - JMenu main = new JMenu(this); |
57 | | - List<? extends Action> actionsForPath = Utilities.actionsForPath("Actions/Chat/SubActions"); |
58 | | - actionsForPath.forEach((action) -> { |
59 | | - main.add(action); |
| 62 | + LearnFix learnFix; |
| 63 | + JTextComponent editor = EditorRegistry.lastFocusedComponent(); |
| 64 | + String selectedText = editor.getSelectedText(); |
| 65 | + final StyledDocument document = (StyledDocument) editor.getDocument(); |
| 66 | + |
| 67 | + FileObject file = getFileObject(document); |
| 68 | + int selectionStartPosition = editor.getSelectionStart(); |
| 69 | + if (selectedText == null || selectedText.isEmpty()) { |
| 70 | + selectionStartPosition = -1; |
| 71 | + selectedText = ""; |
| 72 | + learnFix = new LearnFix(io.github.jeddict.ai.completion.Action.QUERY, file); |
| 73 | + } else { |
| 74 | + learnFix = new LearnFix(io.github.jeddict.ai.completion.Action.QUERY); |
| 75 | + } |
| 76 | + final String text = selectedText; |
| 77 | + final int startLocation = selectionStartPosition; |
| 78 | + learnFix.openChat(null, selectedText, file.getName(), "Chat with AI", content -> { |
| 79 | + NbDocument.runAtomic(document, () -> { |
| 80 | + if (!text.isEmpty()) { |
| 81 | + insertAndReformat(document, content, startLocation, text.length()); |
| 82 | + } else { |
| 83 | + JTextComponent currenteditor = EditorRegistry.lastFocusedComponent(); |
| 84 | + String currentSelectedText = currenteditor.getSelectedText(); |
| 85 | + final StyledDocument currentDocument = (StyledDocument) currenteditor.getDocument(); |
| 86 | + int currentSelectionStartPosition = currenteditor.getSelectionStart(); |
| 87 | + DataObject currentDO = NbEditorUtilities.getDataObject(currentDocument); |
| 88 | + if (currentDO != null) { |
| 89 | + FileObject currentfile = currentDO.getPrimaryFile(); |
| 90 | + if (currentfile != null) { |
| 91 | + if (currentSelectedText == null || currentSelectedText.isEmpty()) { |
| 92 | + insertAndReformat(currentDocument, content, currentSelectionStartPosition, 0); |
| 93 | + } else { |
| 94 | + insertAndReformat(currentDocument, content, currentSelectionStartPosition, currentSelectedText.length()); |
| 95 | + } |
| 96 | + } |
| 97 | + } else { |
| 98 | + javax.swing.JOptionPane.showMessageDialog(null, "Please select text in the original editor before updating."); |
| 99 | + } |
| 100 | + } |
| 101 | + }); |
60 | 102 | }); |
61 | | - return main; |
| 103 | + } |
| 104 | + |
| 105 | + private void insertAndReformat(StyledDocument document, String content, int startPosition, int lengthToRemove) { |
| 106 | + try { |
| 107 | + if (lengthToRemove > 0) { |
| 108 | + document.remove(startPosition, lengthToRemove); |
| 109 | + } |
| 110 | + document.insertString(startPosition, content, null); |
| 111 | + Reformat reformat = Reformat.get(document); |
| 112 | + reformat.lock(); |
| 113 | + try { |
| 114 | + reformat.reformat(startPosition, startPosition + content.length()); |
| 115 | + } finally { |
| 116 | + reformat.unlock(); |
| 117 | + } |
| 118 | + } catch (BadLocationException ex) { |
| 119 | + Exceptions.printStackTrace(ex); |
| 120 | + } |
| 121 | + } |
| 122 | + |
| 123 | + /** |
| 124 | + * Retrieves the FileObject associated with the given JTextComponent. |
| 125 | + * |
| 126 | + * @param editor The JTextComponent from which to derive the FileObject. |
| 127 | + * @return The FileObject associated with the document, or null if not |
| 128 | + * found. |
| 129 | + */ |
| 130 | + private FileObject getFileObject(StyledDocument document) { |
| 131 | + try { |
| 132 | + // Retrieve the DataObject directly from the document's stream property |
| 133 | + DataObject dataObject = NbEditorUtilities.getDataObject(document); |
| 134 | + if (dataObject != null) { |
| 135 | + return dataObject.getPrimaryFile(); |
| 136 | + } |
| 137 | + } catch (Exception ex) { |
| 138 | + Exceptions.printStackTrace(ex); |
| 139 | + } |
| 140 | + return null; |
62 | 141 | } |
63 | 142 |
|
64 | 143 | } |
0 commit comments