Skip to content

Commit 390786c

Browse files
authored
Merge pull request #591 from devoxx/feat-586
Feat 586
2 parents 4343576 + 8b868ae commit 390786c

File tree

4 files changed

+52
-82
lines changed

4 files changed

+52
-82
lines changed

src/main/java/com/devoxx/genie/service/LLMModelRegistryService.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ private void addGeminiModels() {
507507
.build());
508508

509509
String gemini2Pro = "gemini-2.0-pro-exp-02-05";
510-
models.put(ModelProvider.Google.getName() + ":" + gemini2FlashLite,
510+
models.put(ModelProvider.Google.getName() + ":" + gemini2Pro,
511511
LanguageModel.builder()
512512
.provider(ModelProvider.Google)
513513
.modelName(gemini2Pro)
@@ -518,6 +518,19 @@ private void addGeminiModels() {
518518
.outputMaxTokens(64_000)
519519
.apiKeyUsed(true)
520520
.build());
521+
522+
String gemini2dot5Pro = "gemini-2.5-pro-exp-03-25";
523+
models.put(ModelProvider.Google.getName() + ":" + gemini2dot5Pro,
524+
LanguageModel.builder()
525+
.provider(ModelProvider.Google)
526+
.modelName(gemini2dot5Pro)
527+
.displayName("Gemini 2.5 Pro Exp. 03-05")
528+
.inputCost(0)
529+
.outputCost(0)
530+
.inputMaxTokens(1_048_576)
531+
.outputMaxTokens(64_000)
532+
.apiKeyUsed(true)
533+
.build());
521534
}
522535

523536
private void addGroqModels() {

src/main/java/com/devoxx/genie/service/analyzer/util/GitignoreParser.java

Lines changed: 20 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.devoxx.genie.service.analyzer.util;
22

33
import com.devoxx.genie.service.analyzer.tools.GlobTool;
4-
import com.intellij.openapi.vfs.VfsUtil;
4+
import com.intellij.openapi.vfs.VfsUtilCore;
55
import com.intellij.openapi.vfs.VirtualFile;
66
import lombok.extern.slf4j.Slf4j;
77
import org.jetbrains.annotations.NotNull;
@@ -17,7 +17,7 @@
1717
*/
1818
@Slf4j
1919
public class GitignoreParser {
20-
20+
2121
// Root patterns that apply to the entire project
2222
private final List<Pattern> rootExcludePatterns = new ArrayList<>();
2323
private final List<Pattern> rootIncludePatterns = new ArrayList<>();
@@ -29,6 +29,12 @@ public class GitignoreParser {
2929
// The project root directory
3030
private final VirtualFile baseDir;
3131

32+
/**
33+
* Fast lookup map for top-level directories that are directly excluded
34+
* This avoids regex matching for common cases like "build/" and ".gradle/"
35+
*/
36+
private final Set<String> directlyExcludedDirs = new HashSet<>();
37+
3238
/**
3339
* Initializes the parser by reading and parsing .gitignore files from the given directory
3440
* and its subdirectories
@@ -53,10 +59,10 @@ private void parseRootGitignore() {
5359
}
5460

5561
try {
56-
String content = VfsUtil.loadText(gitignoreFile);
62+
String content = VfsUtilCore.loadText(gitignoreFile);
5763
parseGitignoreContent(content, rootExcludePatterns, rootIncludePatterns, "");
5864
} catch (IOException e) {
59-
log.error("Error reading root .gitignore file: " + e.getMessage());
65+
log.error("Error reading root .gitignore file: {}", e.getMessage());
6066
}
6167
}
6268

@@ -66,7 +72,7 @@ private void parseRootGitignore() {
6672
private void parseNestedGitignores() {
6773

6874
// Use a file visitor to find all nested .gitignore files
69-
VfsUtil.visitChildrenRecursively(baseDir, new com.intellij.openapi.vfs.VirtualFileVisitor<Void>() {
75+
VfsUtilCore.visitChildrenRecursively(baseDir, new com.intellij.openapi.vfs.VirtualFileVisitor<Void>() {
7076
@Override
7177
public boolean visitFile(@NotNull VirtualFile file) {
7278
// Skip the root .gitignore as it's already processed
@@ -81,7 +87,7 @@ public boolean visitFile(@NotNull VirtualFile file) {
8187
nestedIncludePatterns.putIfAbsent(relativeDirPath, new ArrayList<>());
8288

8389
// Parse the content
84-
String content = VfsUtil.loadText(file);
90+
String content = VfsUtilCore.loadText(file);
8591
parseGitignoreContent(
8692
content,
8793
nestedExcludePatterns.get(relativeDirPath),
@@ -113,7 +119,6 @@ private void parseGitignoreContent(
113119
@NotNull String relativeDir) {
114120

115121
String[] lines = content.split("\\r?\\n");
116-
String logPrefix = relativeDir.isEmpty() ? "" : "[" + relativeDir + "] ";
117122

118123
for (String line : lines) {
119124
// Skip empty lines and comments
@@ -124,9 +129,6 @@ private void parseGitignoreContent(
124129
// Check if it's a negation pattern (inclusion)
125130
boolean isNegation = line.startsWith("!");
126131
String pattern = isNegation ? line.substring(1).trim() : line.trim();
127-
128-
// Store the original pattern for optimization checks
129-
String originalPattern = pattern;
130132

131133
// Handle directory-only patterns that end with /
132134
boolean directoryOnly = pattern.endsWith("/");
@@ -171,16 +173,13 @@ private void parseGitignoreContent(
171173
*/
172174
@NotNull
173175
private String convertGitignoreToRegex(@NotNull String pattern, boolean directoryOnly, @NotNull String relativeDir) {
174-
// Make a copy to preserve the original pattern for logging
176+
175177
String modifiedPattern = pattern;
176178

177179
// For nested .gitignore files, patterns are relative to that directory
178-
if (!relativeDir.isEmpty()) {
179-
// If it's an absolute path (starts with /), it's relative to project root instead
180-
if (!modifiedPattern.startsWith("/")) {
181-
// For nested .gitignore files, prepend the relative directory path
182-
modifiedPattern = relativeDir + "/" + modifiedPattern;
183-
}
180+
if (!relativeDir.isEmpty() && !modifiedPattern.startsWith("/")) {
181+
// For nested .gitignore files, prepend the relative directory path
182+
modifiedPattern = relativeDir + "/" + modifiedPattern;
184183
}
185184

186185
// 1. Remove leading / if present - it represents the project root directory
@@ -247,12 +246,6 @@ private String getRelativePath(@NotNull VirtualFile baseDir, @NotNull VirtualFil
247246
return null;
248247
}
249248

250-
/**
251-
* Fast lookup map for top-level directories that are directly excluded
252-
* This avoids regex matching for common cases like "build/" and ".gradle/"
253-
*/
254-
private final Set<String> directlyExcludedDirs = new HashSet<>();
255-
256249
/**
257250
* Checks if a file or directory should be ignored based on gitignore rules
258251
*
@@ -287,27 +280,22 @@ public boolean shouldIgnore(@NotNull String path, boolean isDirectory) {
287280
List<String> parentDirs = getParentDirectories(normalizedPath);
288281
for (String parentDir : parentDirs) {
289282
// Don't check the path itself, just its parents
290-
if (!parentDir.equals(normalizedPath)) {
291-
// If the parent directory is ignored, then this path should also be ignored
292-
// We use true for isDirectory since we're checking parent directories
293-
if (isPathIgnored(parentDir, true)) {
294-
return true;
295-
}
283+
if (!parentDir.equals(normalizedPath) && isPathIgnored(parentDir)) {
284+
return true;
296285
}
297286
}
298287

299288
// If no parent directory is ignored, check this path directly
300-
return isPathIgnored(normalizedPath, isDirectory);
289+
return isPathIgnored(normalizedPath);
301290
}
302291

303292
/**
304293
* Internal method to check if a specific path should be ignored, without checking parent directories
305294
*
306295
* @param normalizedPath The normalized path to check
307-
* @param isDirectory Whether the path represents a directory
308296
* @return true if the path should be ignored, false otherwise
309297
*/
310-
private boolean isPathIgnored(@NotNull String normalizedPath, boolean isDirectory) {
298+
private boolean isPathIgnored(@NotNull String normalizedPath) {
311299
// First check against root .gitignore patterns
312300

313301
// Check if the path matches any root include patterns (negations)
@@ -378,36 +366,4 @@ private List<String> getParentDirectories(@NotNull String path) {
378366
Collections.reverse(parents);
379367
return parents;
380368
}
381-
382-
/**
383-
* Gets all patterns that are used to exclude files and directories at the root level
384-
*
385-
* @return A list of compiled regex patterns
386-
*/
387-
@NotNull
388-
public List<Pattern> getRootExcludePatterns() {
389-
return Collections.unmodifiableList(rootExcludePatterns);
390-
}
391-
392-
/**
393-
* Gets all nested exclusion patterns for a specific directory path
394-
*
395-
* @param dirPath The relative directory path
396-
* @return A list of compiled regex patterns, or an empty list if none exist
397-
*/
398-
@NotNull
399-
public List<Pattern> getNestedExcludePatterns(@NotNull String dirPath) {
400-
List<Pattern> patterns = nestedExcludePatterns.get(dirPath);
401-
return patterns != null ? Collections.unmodifiableList(patterns) : Collections.emptyList();
402-
}
403-
404-
/**
405-
* Gets a map of all nested exclusion patterns
406-
*
407-
* @return A map of directory paths to their exclusion patterns
408-
*/
409-
@NotNull
410-
public Map<String, List<Pattern>> getAllNestedExcludePatterns() {
411-
return Collections.unmodifiableMap(nestedExcludePatterns);
412-
}
413369
}

src/main/java/com/devoxx/genie/service/prompt/PromptExecutionService.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ public PromptExecutionService(Project project) {
5656
public void executePrompt(@NotNull ChatMessageContext context,
5757
@NotNull PromptOutputPanel panel,
5858
@NotNull Runnable enableButtons) {
59-
60-
Project project = context.getProject();
61-
59+
6260
// Cancel any running executions for this project
6361
if (cancellationService.cancelAllExecutions(project) > 0) {
6462
log.debug("Cancelled all existing executions for project");
@@ -103,20 +101,19 @@ public void onCancel() {
103101
// Store context with the task for cancellation handling
104102
task.putUserData(PromptTask.CONTEXT_KEY, context);
105103

106-
task.whenComplete((result, error) -> {
107-
ApplicationManager.getApplication().invokeLater(() -> {
108-
if (error != null) {
109-
handleExecutionError(error, context);
110-
} else if (result != null) {
111-
log.debug("Prompt execution completed with result: {}", result);
112-
}
113-
114-
// Unregister from cancellation service upon completion
115-
cancellationService.unregisterExecution(project, context.getId());
116-
117-
cleanupAfterExecution(project, enableButtons);
118-
});
119-
});
104+
task.whenComplete((result, error) ->
105+
ApplicationManager.getApplication().invokeLater(() -> {
106+
if (error != null) {
107+
handleExecutionError(error, context);
108+
} else if (result != null) {
109+
log.debug("Prompt execution completed with result: {}", result);
110+
}
111+
112+
// Unregister from cancellation service upon completion
113+
cancellationService.unregisterExecution(project, context.getId());
114+
115+
cleanupAfterExecution(project, enableButtons);
116+
}));
120117
}
121118

122119
/**

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
]]></description>
3636

3737
<change-notes><![CDATA[
38+
<h2>v0.5.3</h2>
39+
<UL>
40+
<Li>Feat #586 : Added Gemini 2.5 Pro model by @stephanj</LI>
41+
</UL>
3842
<h2>v0.5.2</h2>
3943
<UL>
4044
<LI>Fix #582 : Reuse existing MCP clients and close them when IDEA stops by @stephanj</LI>

0 commit comments

Comments
 (0)