Skip to content

Commit 1ff284c

Browse files
committed
0.1.9
1 parent 4537e47 commit 1ff284c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2177
-1190
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
## [Unreleased]
66

7+
## [0.1.9]
8+
9+
### Added
10+
- Dev mode now adds a API request preview/testing UI for each request
11+
- Various UI polish
12+
- Refactored code so Actions are independent components
13+
714
## [0.1.8]
815

916
### Added

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ repositories {
2828

2929
// Set the JVM language level used to build project. Use Java 11 for 2020.3+, and Java 17 for 2022.2+.
3030
kotlin {
31+
// jvmToolchain(17)
3132
jvmToolchain(11)
3233
}
3334

gradle.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pluginGroup = com.github.simiacryptus
44
pluginName = intellij-aicoder
55
pluginRepositoryUrl = https://github.com/SimiaCryptus/intellij-aicoder
66
# SemVer format -> https://semver.org
7-
pluginVersion = 0.1.8
7+
pluginVersion = 0.1.9
88

99
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1010
pluginSinceBuild = 203
@@ -13,6 +13,7 @@ pluginUntilBuild = 223.*
1313
# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
1414
platformType = IC
1515
platformVersion = 2021.3.3
16+
#platformVersion = 2022.3.1
1617

1718
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
1819
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22

src/main/java/com/github/simiacryptus/aicoder/EditorMenu.java

Lines changed: 0 additions & 688 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.github.simiacryptus.aicoder.actions;
2+
3+
import com.github.simiacryptus.aicoder.config.AppSettingsState;
4+
import com.github.simiacryptus.aicoder.openai.CompletionRequest;
5+
import com.github.simiacryptus.aicoder.util.ComputerLanguage;
6+
import com.github.simiacryptus.aicoder.util.UITools;
7+
import com.intellij.openapi.actionSystem.AnAction;
8+
import com.intellij.openapi.actionSystem.AnActionEvent;
9+
import com.intellij.openapi.actionSystem.CommonDataKeys;
10+
import com.intellij.openapi.editor.Caret;
11+
import com.intellij.openapi.editor.CaretModel;
12+
import com.intellij.openapi.editor.Editor;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
import static com.github.simiacryptus.aicoder.util.UITools.replaceString;
16+
import static java.util.Objects.requireNonNull;
17+
18+
public class CommentsAction extends AnAction {
19+
20+
@Override
21+
public void update(@NotNull AnActionEvent e) {
22+
e.getPresentation().setEnabledAndVisible(isEnabled(e));
23+
super.update(e);
24+
}
25+
26+
private static boolean isEnabled(@NotNull AnActionEvent e) {
27+
final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
28+
final CaretModel caretModel = editor.getCaretModel();
29+
final Caret primaryCaret = caretModel.getPrimaryCaret();
30+
int selectionStart = primaryCaret.getSelectionStart();
31+
int selectionEnd = primaryCaret.getSelectionEnd();
32+
if(selectionStart == selectionEnd) return false;
33+
if (null == ComputerLanguage.getComputerLanguage(e)) return false;
34+
return true;
35+
}
36+
37+
@Override
38+
public void actionPerformed(@NotNull final AnActionEvent e) {
39+
final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
40+
final CaretModel caretModel = editor.getCaretModel();
41+
final Caret primaryCaret = caretModel.getPrimaryCaret();
42+
int selectionStart = primaryCaret.getSelectionStart();
43+
int selectionEnd = primaryCaret.getSelectionEnd();
44+
String selectedText = primaryCaret.getSelectedText();
45+
String outputHumanLanguage = AppSettingsState.getInstance().humanLanguage;
46+
ComputerLanguage language = ComputerLanguage.getComputerLanguage(e);
47+
AppSettingsState settings = AppSettingsState.getInstance();
48+
CompletionRequest request = settings.createTranslationRequest()
49+
.setInputType(requireNonNull(language).name())
50+
.setOutputType(language.name())
51+
.setInstruction(UITools.getInstruction("Rewrite to include detailed " + outputHumanLanguage + " code comments for every line"))
52+
.setInputAttribute("type", "uncommented")
53+
.setOutputAttrute("type", "commented")
54+
.setOutputAttrute("style", settings.style)
55+
.setInputText(selectedText)
56+
.buildCompletionRequest();
57+
Caret caret = e.getData(CommonDataKeys.CARET);
58+
CharSequence indent = UITools.getIndent(caret);
59+
UITools.redoableRequest(request, indent, e, newText -> replaceString(editor.getDocument(), selectionStart, selectionEnd, newText));
60+
}
61+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.github.simiacryptus.aicoder.actions;
2+
3+
import com.github.simiacryptus.aicoder.util.ComputerLanguage;
4+
import com.github.simiacryptus.aicoder.config.AppSettingsState;
5+
import com.github.simiacryptus.aicoder.openai.CompletionRequest;
6+
import com.github.simiacryptus.aicoder.util.IndentedText;
7+
import com.github.simiacryptus.aicoder.util.UITools;
8+
import com.intellij.openapi.actionSystem.AnAction;
9+
import com.intellij.openapi.actionSystem.AnActionEvent;
10+
import com.intellij.openapi.actionSystem.CommonDataKeys;
11+
import com.intellij.openapi.editor.Caret;
12+
import com.intellij.openapi.editor.CaretModel;
13+
import com.intellij.openapi.editor.Editor;
14+
import org.jetbrains.annotations.NotNull;
15+
16+
import javax.swing.*;
17+
18+
import static com.github.simiacryptus.aicoder.util.UITools.replaceString;
19+
import static java.util.Objects.requireNonNull;
20+
21+
public class CustomEditAction extends AnAction {
22+
23+
@Override
24+
public void update(@NotNull AnActionEvent e) {
25+
e.getPresentation().setEnabledAndVisible(isEnabled(e));
26+
super.update(e);
27+
}
28+
29+
private static boolean isEnabled(@NotNull AnActionEvent e) {
30+
return null != ComputerLanguage.getComputerLanguage(e);
31+
}
32+
33+
@Override
34+
public void actionPerformed(@NotNull final AnActionEvent e) {
35+
final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
36+
final CaretModel caretModel = editor.getCaretModel();
37+
final Caret primaryCaret = caretModel.getPrimaryCaret();
38+
int selectionStart = primaryCaret.getSelectionStart();
39+
int selectionEnd = primaryCaret.getSelectionEnd();
40+
String selectedText = primaryCaret.getSelectedText();
41+
String computerLanguage = requireNonNull(ComputerLanguage.getComputerLanguage(e)).name();
42+
String instruction = JOptionPane.showInputDialog(null, "Instruction:", "Edit Code", JOptionPane.QUESTION_MESSAGE);
43+
AppSettingsState settings = AppSettingsState.getInstance();
44+
settings.addInstructionToHistory(instruction);
45+
CompletionRequest request = settings.createTranslationRequest()
46+
.setInputType(computerLanguage)
47+
.setOutputType(computerLanguage)
48+
.setInstruction(instruction)
49+
.setInputAttribute("type", "before")
50+
.setOutputAttrute("type", "after")
51+
.setInputText(IndentedText.fromString(selectedText).getTextBlock())
52+
.buildCompletionRequest();
53+
Caret caret = e.getData(CommonDataKeys.CARET);
54+
CharSequence indent = UITools.getIndent(caret);
55+
UITools.redoableRequest(request, indent, e, newText -> replaceString(editor.getDocument(), selectionStart, selectionEnd, newText));
56+
}
57+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.github.simiacryptus.aicoder.actions;
2+
3+
import com.github.simiacryptus.aicoder.util.*;
4+
import com.github.simiacryptus.aicoder.config.AppSettingsState;
5+
import com.github.simiacryptus.aicoder.openai.CompletionRequest;
6+
import com.intellij.openapi.actionSystem.AnAction;
7+
import com.intellij.openapi.actionSystem.AnActionEvent;
8+
import com.intellij.openapi.actionSystem.CommonDataKeys;
9+
import com.intellij.openapi.editor.Caret;
10+
import com.intellij.openapi.editor.CaretModel;
11+
import com.intellij.openapi.editor.Document;
12+
import com.intellij.openapi.editor.Editor;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
import java.util.Objects;
16+
17+
import static com.github.simiacryptus.aicoder.util.UITools.replaceString;
18+
19+
public class DescribeAction extends AnAction {
20+
21+
@Override
22+
public void update(@NotNull AnActionEvent e) {
23+
e.getPresentation().setEnabledAndVisible(isEnabled(e));
24+
super.update(e);
25+
}
26+
27+
private static boolean isEnabled(@NotNull AnActionEvent e) {
28+
return null != ComputerLanguage.getComputerLanguage(e);
29+
}
30+
31+
@Override
32+
public void actionPerformed(@NotNull final AnActionEvent event) {
33+
final Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
34+
final CaretModel caretModel = editor.getCaretModel();
35+
final Caret primaryCaret = caretModel.getPrimaryCaret();
36+
int selectionStart = primaryCaret.getSelectionStart();
37+
int selectionEnd = primaryCaret.getSelectionEnd();
38+
String selectedText = primaryCaret.getSelectedText();
39+
ComputerLanguage language = ComputerLanguage.getComputerLanguage(event);
40+
assert language != null;
41+
42+
if(null == selectedText || selectedText.isEmpty()) {
43+
Document document = editor.getDocument();
44+
int lineNumber = document.getLineNumber(selectionStart);
45+
int lineStartOffset = document.getLineStartOffset(lineNumber);
46+
int lineEndOffset = document.getLineEndOffset(lineNumber);
47+
String currentLine = document.getText().substring(lineStartOffset, lineEndOffset);
48+
selectionStart = lineStartOffset;
49+
selectionEnd = lineEndOffset;
50+
selectedText = currentLine;
51+
}
52+
53+
actionPerformed(event, editor, selectionStart, selectionEnd, selectedText, language);
54+
}
55+
56+
private static void actionPerformed(@NotNull AnActionEvent event, Editor editor, int selectionStart, int selectionEnd, String selectedText, ComputerLanguage language) {
57+
CharSequence indent = UITools.getIndent(event);
58+
AppSettingsState settings = AppSettingsState.getInstance();
59+
CompletionRequest request = settings.createTranslationRequest()
60+
.setInputType(Objects.requireNonNull(language).name())
61+
.setOutputType(settings.humanLanguage)
62+
.setInstruction(UITools.getInstruction("Explain this " + language.name() + " in " + settings.humanLanguage))
63+
.setInputAttribute("type", "code")
64+
.setOutputAttrute("type", "description")
65+
.setOutputAttrute("style", settings.style)
66+
.setInputText(IndentedText.fromString(selectedText).getTextBlock().trim())
67+
.buildCompletionRequest();
68+
UITools.redoableRequest(request, indent, event, newText -> transformCompletion(selectedText, language, indent, newText), newText -> replaceString(editor.getDocument(), selectionStart, selectionEnd, newText));
69+
}
70+
71+
@NotNull
72+
private static CharSequence transformCompletion(String selectedText, ComputerLanguage language, CharSequence indent, CharSequence x) {
73+
String wrapping = StringTools.lineWrapping(x.toString().trim(), 120);
74+
TextBlockFactory<?> commentStyle;
75+
if(wrapping.trim().split("\n").length == 1) {
76+
commentStyle = language.lineComment;
77+
} else {
78+
commentStyle = language.blockComment;
79+
}
80+
return "\n" + indent + Objects.requireNonNull(commentStyle).fromString(wrapping).withIndent(indent) + "\n" + indent + selectedText;
81+
}
82+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.github.simiacryptus.aicoder.actions;
2+
3+
import com.github.simiacryptus.aicoder.config.AppSettingsState;
4+
import com.github.simiacryptus.aicoder.openai.CompletionRequest;
5+
import com.github.simiacryptus.aicoder.util.psi.PsiUtil;
6+
import com.github.simiacryptus.aicoder.util.*;
7+
import com.intellij.openapi.actionSystem.AnAction;
8+
import com.intellij.openapi.actionSystem.AnActionEvent;
9+
import com.intellij.openapi.actionSystem.CommonDataKeys;
10+
import com.intellij.openapi.editor.Caret;
11+
import com.intellij.openapi.editor.Document;
12+
import com.intellij.psi.PsiElement;
13+
import com.intellij.psi.PsiFile;
14+
import org.jetbrains.annotations.NotNull;
15+
16+
import java.util.Objects;
17+
18+
import static com.github.simiacryptus.aicoder.util.UITools.replaceString;
19+
20+
public class DocAction extends AnAction {
21+
22+
@Override
23+
public void update(@NotNull AnActionEvent e) {
24+
e.getPresentation().setEnabledAndVisible(isEnabled(e));
25+
super.update(e);
26+
}
27+
28+
private static boolean isEnabled(@NotNull AnActionEvent e) {
29+
ComputerLanguage computerLanguage = ComputerLanguage.getComputerLanguage(e);
30+
if (null == computerLanguage) return false;
31+
if (null == computerLanguage.docStyle || computerLanguage.docStyle.isEmpty()) return false;
32+
return true;
33+
}
34+
35+
@Override
36+
public void actionPerformed(@NotNull final AnActionEvent event) {
37+
ComputerLanguage language = ComputerLanguage.getComputerLanguage(event);
38+
Caret caret = event.getData(CommonDataKeys.CARET);
39+
PsiFile psiFile = event.getRequiredData(CommonDataKeys.PSI_FILE);
40+
PsiElement smallestIntersectingMethod = PsiUtil.getSmallestIntersecting(psiFile, Objects.requireNonNull(caret).getSelectionStart(), caret.getSelectionEnd());
41+
if (null == smallestIntersectingMethod) return;
42+
AppSettingsState settings = AppSettingsState.getInstance();
43+
String code = smallestIntersectingMethod.getText();
44+
IndentedText indentedInput = IndentedText.fromString(code);
45+
CharSequence indent = indentedInput.getIndent();
46+
int startOffset = smallestIntersectingMethod.getTextRange().getStartOffset();
47+
int endOffset = smallestIntersectingMethod.getTextRange().getEndOffset();
48+
CompletionRequest completionRequest = settings.createTranslationRequest()
49+
.setInputType(Objects.requireNonNull(language).name())
50+
.setOutputType(language.name())
51+
.setInstruction(UITools.getInstruction("Rewrite to include detailed " + language.docStyle))
52+
.setInputAttribute("type", "uncommented")
53+
.setOutputAttrute("type", "commented")
54+
.setOutputAttrute("style", settings.style)
55+
.setInputText(indentedInput.getTextBlock())
56+
.buildCompletionRequest()
57+
.addStops(Objects.requireNonNull(language.getMultilineCommentSuffix()));
58+
Document document = event.getRequiredData(CommonDataKeys.EDITOR).getDocument();
59+
UITools.redoableRequest(completionRequest, "", event, docString -> transformCompletion(language, indentedInput, indent, docString), docString -> replaceString(document, startOffset, endOffset, docString));
60+
}
61+
62+
@NotNull
63+
private static CharSequence transformCompletion(ComputerLanguage language, IndentedText indentedInput, CharSequence indent, CharSequence docString) {
64+
TextBlock reindented = Objects.requireNonNull(language.docComment).fromString(docString.toString().trim()).withIndent(indent);
65+
return reindented + "\n" + indent + StringTools.trimPrefix(indentedInput.toString());
66+
}
67+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.github.simiacryptus.aicoder.actions;
2+
3+
import com.github.simiacryptus.aicoder.util.ComputerLanguage;
4+
import com.github.simiacryptus.aicoder.config.AppSettingsState;
5+
import com.github.simiacryptus.aicoder.openai.CompletionRequest;
6+
import com.github.simiacryptus.aicoder.util.UITools;
7+
import com.intellij.openapi.actionSystem.AnAction;
8+
import com.intellij.openapi.actionSystem.AnActionEvent;
9+
import com.intellij.openapi.actionSystem.CommonDataKeys;
10+
import com.intellij.openapi.editor.Caret;
11+
import com.intellij.openapi.editor.CaretModel;
12+
import com.intellij.openapi.editor.Editor;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
import static com.github.simiacryptus.aicoder.util.UITools.replaceString;
16+
import static java.util.Objects.requireNonNull;
17+
18+
public class FromHumanLanguageAction extends AnAction {
19+
20+
public FromHumanLanguageAction() {
21+
super("", "", null);
22+
}
23+
24+
@Override
25+
public void actionPerformed(@NotNull final AnActionEvent event) {
26+
final Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
27+
final CaretModel caretModel = editor.getCaretModel();
28+
final Caret primaryCaret = caretModel.getPrimaryCaret();
29+
int selectionStart = primaryCaret.getSelectionStart();
30+
int selectionEnd = primaryCaret.getSelectionEnd();
31+
String selectedText = primaryCaret.getSelectedText();
32+
CompletionRequest request = AppSettingsState.getInstance().createTranslationRequest()
33+
.setInputType(AppSettingsState.getInstance().humanLanguage.toLowerCase())
34+
.setOutputType(requireNonNull(ComputerLanguage.getComputerLanguage(event)).name())
35+
.setInstruction("Implement this specification")
36+
.setInputAttribute("type", "input")
37+
.setOutputAttrute("type", "output")
38+
.setInputText(selectedText)
39+
.buildCompletionRequest();
40+
Caret caret = event.getData(CommonDataKeys.CARET);
41+
CharSequence indent = UITools.getIndent(caret);
42+
UITools.redoableRequest(request, indent, event, newText -> replaceString(editor.getDocument(), selectionStart, selectionEnd, newText));
43+
}
44+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.github.simiacryptus.aicoder.actions;
2+
3+
import com.github.simiacryptus.aicoder.config.AppSettingsState;
4+
import com.github.simiacryptus.aicoder.openai.CompletionRequest;
5+
import com.github.simiacryptus.aicoder.util.UITools;
6+
import com.intellij.openapi.actionSystem.AnAction;
7+
import com.intellij.openapi.actionSystem.AnActionEvent;
8+
import com.intellij.openapi.actionSystem.CommonDataKeys;
9+
import com.intellij.openapi.editor.Caret;
10+
import com.intellij.openapi.editor.Document;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import java.util.Objects;
14+
15+
public class GenericAppend extends AnAction {
16+
17+
@Override
18+
public void update(@NotNull AnActionEvent e) {
19+
e.getPresentation().setEnabledAndVisible(isEnabled(e));
20+
super.update(e);
21+
}
22+
23+
@SuppressWarnings("unused")
24+
private static boolean isEnabled(@NotNull AnActionEvent e) {
25+
Caret data = e.getData(CommonDataKeys.CARET);
26+
if (!data.hasSelection()) return false;
27+
return true;
28+
}
29+
30+
@Override
31+
public void actionPerformed(@NotNull AnActionEvent event) {
32+
Caret caret = event.getData(CommonDataKeys.CARET);
33+
CharSequence before = Objects.requireNonNull(caret).getSelectedText();
34+
AppSettingsState settings = AppSettingsState.getInstance();
35+
CompletionRequest completionRequest = settings.createCompletionRequest().appendPrompt(before);
36+
Document document = event.getRequiredData(CommonDataKeys.EDITOR).getDocument();
37+
int selectionEnd = caret.getSelectionEnd();
38+
UITools.redoableRequest(completionRequest, "", event, newText -> UITools.insertString(document, selectionEnd, newText));
39+
}
40+
}

0 commit comments

Comments
 (0)