Skip to content

Commit 2003b3f

Browse files
authored
Merge pull request #521 from devoxx/feat-503
Feat #503 Showing lines of code in chat context
2 parents f7add5a + f7c2e76 commit 2003b3f

File tree

7 files changed

+86
-27
lines changed

7 files changed

+86
-27
lines changed

src/main/java/com/devoxx/genie/action/AddSnippetAction.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.intellij.openapi.actionSystem.ActionUpdateThread;
55
import com.intellij.openapi.actionSystem.AnActionEvent;
66
import com.intellij.openapi.actionSystem.CommonDataKeys;
7+
import com.intellij.openapi.diagnostic.Logger;
8+
import com.intellij.openapi.editor.Document;
79
import com.intellij.openapi.editor.Editor;
810
import com.intellij.openapi.editor.SelectionModel;
911
import com.intellij.openapi.fileTypes.FileType;
@@ -12,19 +14,22 @@
1214
import com.intellij.openapi.project.Project;
1315
import com.intellij.openapi.util.Key;
1416
import com.intellij.openapi.vfs.VirtualFile;
15-
import com.intellij.testFramework.LightVirtualFile;
1617
import org.jetbrains.annotations.NotNull;
1718
import org.jetbrains.annotations.Nullable;
1819

1920
import static com.devoxx.genie.ui.util.WindowPluginUtil.ensureToolWindowVisible;
2021

2122
public class AddSnippetAction extends DumbAwareAction {
2223

24+
private static final Logger LOG = Logger.getInstance(AddSnippetAction.class);
25+
2326
public static final String CODE_SNIPPET = "codeSnippet";
2427
public static final Key<VirtualFile> ORIGINAL_FILE_KEY = Key.create("ORIGINAL_FILE");
2528
public static final Key<String> SELECTED_TEXT_KEY = Key.create("SELECTED_TEXT");
2629
public static final Key<Integer> SELECTION_START_KEY = Key.create("SELECTION_START");
2730
public static final Key<Integer> SELECTION_END_KEY = Key.create("SELECTION_END");
31+
public static final Key<Integer> SELECTION_START_LINE_KEY = Key.create("SELECTION_START_LINE");
32+
public static final Key<Integer> SELECTION_END_LINE_KEY = Key.create("SELECTION_END_LINE");
2833

2934
// We use an unknown file type to represent code snippets
3035
private final FileType fileType =
@@ -47,7 +52,7 @@ public void actionPerformed(@NotNull AnActionEvent e) {
4752
SelectionModel selectionModel = editor.getSelectionModel();
4853
String selectedText = selectionModel.getSelectedText();
4954
if (selectedText != null) {
50-
createAndAddVirtualFile(e.getProject(), selectedFile, selectionModel, selectedText);
55+
createAndAddVirtualFile(e.getProject(), selectedFile, editor, selectedText);
5156
} else {
5257
// No text selected, add complete file
5358
addSelectedFile(e.getProject(), selectedFile);
@@ -71,23 +76,35 @@ private static void addSelectedFile(Project project, VirtualFile selectedFile) {
7176
/**
7277
* Create a virtual file and add it to the file list manager.
7378
*
74-
* @param project
79+
* @param project the project
7580
* @param originalFile the original file
76-
* @param selectionModel the selection model
81+
* @param editor the editor
7782
* @param selectedText the selected text
7883
*/
79-
private void createAndAddVirtualFile(@Nullable Project project, @NotNull VirtualFile originalFile,
80-
@NotNull SelectionModel selectionModel,
84+
private void createAndAddVirtualFile(@Nullable Project project,
85+
@NotNull VirtualFile originalFile,
86+
@NotNull Editor editor,
8187
String selectedText) {
82-
LightVirtualFile virtualFile = new LightVirtualFile(originalFile.getName(), selectedText);
83-
virtualFile.setFileType(fileType);
84-
virtualFile.putUserData(ORIGINAL_FILE_KEY, originalFile);
85-
virtualFile.putUserData(SELECTED_TEXT_KEY, selectedText);
86-
virtualFile.putUserData(SELECTION_START_KEY, selectionModel.getSelectionStart());
87-
virtualFile.putUserData(SELECTION_END_KEY, selectionModel.getSelectionEnd());
88-
FileListManager.getInstance().addFile(project, virtualFile);
89-
}
88+
if (project == null) {
89+
LOG.error("Project is null");
90+
return;
91+
}
92+
SelectionModel selectionModel = editor.getSelectionModel();
93+
Document document = editor.getDocument();
94+
95+
int startOffset = selectionModel.getSelectionStart();
96+
int endOffset = selectionModel.getSelectionEnd();
97+
int startLine = document.getLineNumber(startOffset);
98+
int endLine = document.getLineNumber(endOffset);
99+
originalFile.putUserData(ORIGINAL_FILE_KEY, originalFile);
100+
originalFile.putUserData(SELECTED_TEXT_KEY, selectedText);
101+
originalFile.putUserData(SELECTION_START_KEY, startOffset);
102+
originalFile.putUserData(SELECTION_END_KEY, endOffset);
103+
originalFile.putUserData(SELECTION_START_LINE_KEY, startLine);
104+
originalFile.putUserData(SELECTION_END_LINE_KEY, endLine);
90105

106+
FileListManager.getInstance().addFile(project, originalFile);
107+
}
91108

92109
@Override
93110
public @NotNull ActionUpdateThread getActionUpdateThread() {

src/main/java/com/devoxx/genie/ui/component/FileEntryComponent.java

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import com.intellij.openapi.vfs.LocalFileSystem;
1717
import com.intellij.openapi.vfs.VirtualFile;
1818
import com.intellij.openapi.vfs.VirtualFileManager;
19+
import com.intellij.psi.PsiFile;
20+
import com.intellij.psi.PsiManager;
1921
import com.intellij.ui.Gray;
2022
import com.intellij.util.ui.JBUI;
2123
import lombok.Getter;
@@ -25,6 +27,9 @@
2527
import javax.swing.*;
2628
import java.awt.*;
2729
import java.io.File;
30+
import java.util.Optional;
31+
import java.util.regex.Matcher;
32+
import java.util.regex.Pattern;
2833

2934
import static com.devoxx.genie.action.AddSnippetAction.*;
3035
import static com.devoxx.genie.util.ImageUtil.isImageFile;
@@ -49,27 +54,41 @@ public FileEntryComponent(Project project, @NotNull VirtualFile file, FileRemove
4954
// Create main content panel
5055
Box contentPanel = Box.createHorizontalBox();
5156

52-
// File name with icon
53-
JButton fileNameButton = new JButton(file.getName(), FileTypeIconUtil.getFileTypeIcon(file));
57+
JButton fileNameButton;
58+
if (file.getUserData(SELECTED_TEXT_KEY) != null) {
59+
fileNameButton = new JButton(file.getName(), DevoxxGenieIconsUtil.CodeSnippetIcon);
60+
} else {
61+
fileNameButton = new JButton(file.getName(), FileTypeIconUtil.getFileTypeIcon(file));
62+
}
63+
5464
fileNameButton.setBorder(JBUI.Borders.empty());
5565
fileNameButton.addActionListener(e -> openFileWithSelectedCode(project, virtualFile));
5666
fileNameButton.setFont(MONO_FONT);
67+
contentPanel.add(fileNameButton);
5768

5869
// Path label
5970
JLabel pathLabel = new JLabel();
6071
String fullPath = FileUtil.getRelativePath(project, file);
72+
6173
if (!fullPath.equals(file.getName())) {
62-
String path = fullPath.substring(0, fullPath.lastIndexOf(file.getName()));
63-
pathLabel.setText(path);
74+
pathLabel.setText(fullPath);
6475
pathLabel.setFont(MONO_FONT);
6576
pathLabel.setForeground(PATH_COLOR);
6677
}
6778

6879
// Create tooltip with full path
6980
String tooltipText = String.format("<html><body style='width: 300px'><pre>%s</pre></body></html>", file.getPath().replace("<", "&lt;").replace(">", "&gt;"));
7081

71-
// Add components to content panel
72-
contentPanel.add(fileNameButton);
82+
// Add start and end line information if available
83+
Integer startLine = file.getUserData(SELECTION_START_LINE_KEY);
84+
Integer endLine = file.getUserData(SELECTION_END_LINE_KEY);
85+
if (startLine != null && endLine != null) {
86+
JLabel lineInfoLabel = new JLabel(String.format(" (%d-%d)", startLine + 1, endLine + 1));
87+
lineInfoLabel.setFont(MONO_FONT);
88+
lineInfoLabel.setForeground(PATH_COLOR);
89+
contentPanel.add(lineInfoLabel);
90+
}
91+
7392
contentPanel.add(Box.createHorizontalStrut(5));
7493
contentPanel.add(pathLabel);
7594
contentPanel.add(Box.createHorizontalGlue());
@@ -143,9 +162,17 @@ private void openFileWithSelectedCode(@NotNull Project project, @NotNull Virtual
143162
FileEditorManagerEx.getInstance(project).openFile(freshVirtualFile, true, true);
144163
}
145164
} else {
146-
// Handle non-image files
147-
OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile);
148-
FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
165+
VirtualFile originalFile = virtualFile.getUserData(ORIGINAL_FILE_KEY);
166+
if (originalFile != null) {
167+
FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
168+
fileEditorManager.openFile(originalFile, true);
169+
Editor editor = fileEditorManager.getSelectedTextEditor();
170+
if (editor != null) {
171+
highlightSelectedText(virtualFile, editor);
172+
}
173+
} else {
174+
FileEditorManager.getInstance(project).openFile(virtualFile, true);
175+
}
149176
}
150177
} catch (Exception e) {
151178
Messages.showErrorDialog("Error opening file: " + e.getMessage(), "Error");
@@ -159,7 +186,7 @@ private void openFileWithSelectedCode(@NotNull Project project, @NotNull Virtual
159186
* @param virtualFile the virtual file
160187
* @param editor the editor
161188
*/
162-
private static void highlightSelectedText (@NotNull VirtualFile virtualFile, Editor editor){
189+
private static void highlightSelectedText(@NotNull VirtualFile virtualFile, Editor editor){
163190
String selectedText = virtualFile.getUserData(SELECTED_TEXT_KEY);
164191
Integer selectionStart = virtualFile.getUserData(SELECTION_START_KEY);
165192
Integer selectionEnd = virtualFile.getUserData(SELECTION_END_KEY);

src/main/java/com/devoxx/genie/ui/util/DevoxxGenieIconsUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public final class DevoxxGenieIconsUtil {
1919
public static final Icon InterfaceIcon = load("/icons/interface.svg");
2020
public static final Icon EnumIcon = load("/icons/enum.svg");
2121
public static final Icon ClassIcon = load("/icons/class.svg");
22+
public static final Icon RecordIcon = load("/icons/record.svg");
2223
public static final Icon ImageIcon = load("/icons/image.svg");
2324
public static final Icon TrashIcon = load("/icons/trash.svg");
2425
public static final Icon DevoxxIcon = load("/icons/pluginIcon.svg");

src/main/java/com/devoxx/genie/ui/util/FileTypeIconUtil.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.concurrent.TimeUnit;
1616
import java.util.concurrent.TimeoutException;
1717

18+
import static com.devoxx.genie.action.AddSnippetAction.SELECTED_TEXT_KEY;
1819
import static com.devoxx.genie.ui.util.DevoxxGenieIconsUtil.*;
1920

2021
public class FileTypeIconUtil {
@@ -42,8 +43,8 @@ private static Icon getIconForFile(VirtualFile virtualFile) {
4243
if (interfaceIcon != null) {
4344
return interfaceIcon;
4445
}
45-
String fileTypeName = virtualFile.getFileType().getName();
46-
return fileTypeName.equals("UNKNOWN") ? CodeSnippetIcon : ClassIcon;
46+
String selectedText = virtualFile.getUserData(SELECTED_TEXT_KEY);
47+
return (selectedText != null) ? CodeSnippetIcon : ClassIcon;
4748
}
4849

4950
private static @Nullable Icon getIcon(VirtualFile virtualFile) {
@@ -66,13 +67,15 @@ private static Icon getIconForFile(VirtualFile virtualFile) {
6667
}
6768

6869
private static @Nullable Icon getJavaFileIcon(@NotNull VirtualFile virtualFile) throws IOException {
69-
String content = new String(virtualFile.contentsToByteArray());
70+
String content = new String(virtualFile.contentsToByteArray()).toLowerCase();
7071
if (content.contains(" interface ")) {
7172
return InterfaceIcon;
7273
} else if (content.contains(" enum ")) {
7374
return EnumIcon;
7475
} else if (content.contains(" class ")) {
7576
return ClassIcon;
77+
} else if (content.contains(" record ")) {
78+
return RecordIcon;
7679
}
7780
return null;
7881
}

src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<LI>Feat #514 : Show image icon in file list when images are used by @stephanj</LI>
4343
<LI>Feat #508 : Always focus input field when chat window is opened by @stephanj</LI>
4444
<LI>Fix #506 : Show /find place holder text when RAG is enabled by @stephanj</LI>
45+
<LI>Feat #503 : Showing lines of code in chat context by @stephanj</LI>
4546
</UL>
4647
<h2>V0.4.16</h2>
4748
<UL>
Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 5 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)