devoxx / DevoxxGenieIDEAPlugin

DevoxxGenie is a plugin for IntelliJ IDEA that uses local LLM's (Ollama, LMStudio, GPT4All, Llama.cpp and Exo) and Cloud based LLMs to help review, test, explain your project code.
https://devoxx.com
MIT License
143 stars 23 forks source link

[BOUNTY ~ 975 € Combi ticket for Devoxx Belgium 2024] : Support Tab auto completion #2

Open stephanj opened 5 months ago

stephanj commented 5 months ago

An experimental AcceptAutocompleteAction (pressing tab key) is available and can be activated be enabling the plugin config file

<actions> 
    <action id="com.devoxx.genie.action.AcceptAutocompleteAction"
            class="com.devoxx.genie.actions.AcceptAutocompleteAction"
            text="Accept Autocomplete Suggestion"
            description="Accept autocomplete suggestion">
        <keyboard-shortcut keymap="$default" first-keystroke="TAB"/>
        <keyboard-shortcut keymap="Mac OS X" first-keystroke="TAB"/>
        </action>
</actions>

However the related prompt does not really return useable auto complete code 😂

/**
     * EXPERIMENTAL : Execute continue prompt
     * @param selectedText the selected text
     * @return the prompt
     */
    public String executeGenieContinuePrompt(String selectedText) {
        ChatLanguageModel chatLanguageModel = getChatLanguageModel();
        List<ChatMessage> messages = new ArrayList<>();
        messages.add(new dev.langchain4j.data.message.SystemMessage(
            YOU_ARE_A_SOFTWARE_DEVELOPER_WITH_EXPERT_KNOWLEDGE_IN + "JAVA" + PROGRAMMING_LANGUAGE +
                "\n\nSelected code: " + selectedText));
        messages.add(new UserMessage("Only return the code which finalises the code block."));
        Response<AiMessage> generate = chatLanguageModel.generate(messages);
        return generate.content().text();
    }

Suggestions welcome how we can accomplish this.

xdHampus commented 2 months ago

This would be a really nice addition! I find myself often opening up VSCode besides IDEA just to get auto completion in code.

I tried a Copilot replacement for VSCode(https://github.com/ex3ndr/llama-coder) that uses Ollama and it seemed to work well. Perhaps their solution could serve as an inspiration 😄

stephanj commented 1 month ago

Claude Sonnet 3.5 suggestion:

This kind of feature involves integrating with IntelliJ's code completion system and potentially using an AI model to generate suggestions. Here's a high-level approach to implement this feature:

  1. Create a Custom Completion Contributor

First, you'll need to create a custom completion contributor that integrates with IntelliJ's completion system:

import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;

public class DevoxxGenieCompletionContributor extends CompletionContributor {

    public DevoxxGenieCompletionContributor() {
        extend(CompletionType.BASIC, PlatformPatterns.psiElement(),
            new CompletionProvider<CompletionParameters>() {
                @Override
                protected void addCompletions(@NotNull CompletionParameters parameters,
                                              @NotNull ProcessingContext context,
                                              @NotNull CompletionResultSet result) {
                    // Generate and add completions here
                    String suggestion = generateCodeSuggestion(parameters);
                    if (suggestion != null) {
                        result.addElement(LookupElementBuilder.create(suggestion));
                    }
                }
            }
        );
    }

    private String generateCodeSuggestion(CompletionParameters parameters) {
        // Implement your code suggestion logic here
        // This could involve calling an AI model or using other heuristics
        return null; // Replace with actual suggestion
    }
}
  1. Register the Completion Contributor

Register your completion contributor in your plugin.xml:

<extensions defaultExtensionNs="com.intellij">
    <completion.contributor language="JAVA" 
                            implementationClass="com.devoxx.genie.DevoxxGenieCompletionContributor"/>
</extensions>
  1. Implement Code Suggestion Logic

The core of your autocompletion feature will be in the generateCodeSuggestion method. This is where you'll need to analyze the current context and generate appropriate suggestions. Here's a basic example:

private String generateCodeSuggestion(CompletionParameters parameters) {
    PsiElement element = parameters.getPosition();
    PsiFile file = element.getContainingFile();

    // Get the text up to the current caret position
    Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(file);
    if (document == null) return null;

    int offset = parameters.getOffset();
    String textUpToCaret = document.getText(new TextRange(0, offset));

    // Here you would typically send this context to an AI model or use other logic
    // to generate a suitable completion

    // For this example, let's just suggest a simple method
    return "public void exampleMethod() {\n    // TODO: Implement method\n}";
}
  1. Integrate with an AI Model (Optional)

For more advanced suggestions like those provided by GitHub Copilot, you'd need to integrate with an AI model. This could be done by sending the current code context to an API and receiving suggestions. Here's a conceptual example:

import com.devoxx.genie.service.AIModelService;

private String generateCodeSuggestion(CompletionParameters parameters) {
    // ... (previous code to get context)

    AIModelService aiService = AIModelService.getInstance(parameters.getProject());
    return aiService.generateSuggestion(textUpToCaret);
}
  1. Handle Streaming Suggestions (Optional)

For a more responsive experience, you might want to stream suggestions as they're generated:

public class DevoxxGenieCompletionContributor extends CompletionContributor {
    @Override
    public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
        CompletionResultSet resultSet = result.withPrefixMatcher(new PlainPrefixMatcher(""));
        CompletionResultSet finalResultSet = resultSet;

        ApplicationManager.getApplication().executeOnPooledThread(() -> {
            String partialSuggestion = "";
            while (!resultSet.isStopped()) {
                // Generate next part of the suggestion
                String nextPart = generateNextPartOfSuggestion();
                if (nextPart == null) break;

                partialSuggestion += nextPart;
                finalResultSet.addElement(LookupElementBuilder.create(partialSuggestion));
            }
        });
    }
}
  1. Respect IntelliJ's Coding Style

Ensure your suggestions respect the user's code style settings:

private String formatSuggestion(String suggestion, Project project) {
    CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
    PsiElementFactory factory = PsiElementFactory.getInstance(project);
    PsiJavaFile file = (PsiJavaFile) factory.createFileFromText("dummy.java", JavaFileType.INSTANCE, suggestion);
    codeStyleManager.reformat(file);
    return file.getText();
}

This approach provides a foundation for implementing Copilot-like code autocompletion in your DevoxxGenie plugin. Remember that advanced AI-powered suggestions would require integration with a sophisticated language model, which is a significant undertaking in itself. You might start with simpler heuristic-based suggestions and gradually enhance the capability as your plugin evolves.