diff --git a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java index fdb6fb58..5f1f447f 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java @@ -58,8 +58,8 @@ public class MethodNameLookupListener implements LookupManagerListener { lookup.addItem( LookupElementBuilder.create(value.trim()).withIcon(Icons.Sparkle), PrefixMatcher.ALWAYS_TRUE); + application.invokeLater(() -> lookup.refreshUi(true, true)); }); - application.invokeLater(() -> lookup.refreshUi(true, true)); } }); } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java index fbd97a31..33f6ba6a 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java @@ -73,7 +73,7 @@ abstract class ToolWindowCompletionResponseEventListener implements } }); } catch (Exception e) { - responseContainer.displayDefaultError(); + responseContainer.displayError("Something went wrong."); throw new RuntimeException("Error while updating the content", e); } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/components/ChatMessageResponseBody.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/components/ChatMessageResponseBody.java index 8af06774..2664dd96 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/components/ChatMessageResponseBody.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/components/ChatMessageResponseBody.java @@ -1,35 +1,30 @@ package ee.carlrobert.codegpt.toolwindow.chat.components; +import static ee.carlrobert.codegpt.toolwindow.chat.StreamResponseType.CODE; +import static ee.carlrobert.codegpt.util.MarkdownUtil.convertMdToHtml; import static java.lang.String.format; import static javax.swing.event.HyperlinkEvent.EventType.ACTIVATED; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.JBColor; import com.intellij.util.ui.JBUI; import com.vladsch.flexmark.ast.FencedCodeBlock; -import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.parser.Parser; -import com.vladsch.flexmark.util.data.MutableDataSet; import ee.carlrobert.codegpt.actions.ActionType; import ee.carlrobert.codegpt.settings.SettingsConfigurable; import ee.carlrobert.codegpt.telemetry.TelemetryAction; -import ee.carlrobert.codegpt.toolwindow.chat.ResponseNodeRenderer; import ee.carlrobert.codegpt.toolwindow.chat.StreamParser; -import ee.carlrobert.codegpt.toolwindow.chat.StreamResponseType; import ee.carlrobert.codegpt.toolwindow.chat.editor.ResponseEditorPanel; +import ee.carlrobert.codegpt.util.EditorUtil; import ee.carlrobert.codegpt.util.MarkdownUtil; import ee.carlrobert.codegpt.util.UIUtil; import ee.carlrobert.llm.client.you.completion.YouSerpResult; import java.awt.BorderLayout; -import java.awt.Color; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -43,7 +38,7 @@ public class ChatMessageResponseBody extends JPanel { private final Disposable parentDisposable; private final StreamParser streamParser; private final boolean readOnly; - private ResponseEditorPanel currentlyProcessedEditor; + private ResponseEditorPanel currentlyProcessedEditorPanel; private JTextPane currentlyProcessedTextPane; private boolean responseReceived; @@ -72,7 +67,7 @@ public class ChatMessageResponseBody extends JPanel { setOpaque(false); if (withGhostText) { - prepareProcessingTextResponse(!readOnly); + prepareProcessingText(!readOnly); currentlyProcessedTextPane.setText( "

"); } @@ -88,7 +83,7 @@ public class ChatMessageResponseBody extends JPanel { public void update(String partialMessage) { for (var item : streamParser.parse(partialMessage)) { - processResponse(item.getResponse(), StreamResponseType.CODE.equals(item.getType()), true); + processResponse(item.getResponse(), CODE.equals(item.getType()), true); } } @@ -139,10 +134,6 @@ public class ChatMessageResponseBody extends JPanel { } } - public void displayDefaultError() { - displayError("Something went wrong."); - } - public void displaySerpResults(List serpResults) { var html = getSearchResultsHtml(serpResults); if (responseReceived) { @@ -157,7 +148,7 @@ public class ChatMessageResponseBody extends JPanel { streamParser.clear(); // TODO: First message might be code block - prepareProcessingTextResponse(true); + prepareProcessingText(true); currentlyProcessedTextPane.setText( "

"); @@ -167,14 +158,17 @@ public class ChatMessageResponseBody extends JPanel { private String getSearchResultsHtml(List serpResults) { var titles = serpResults.stream() - .map(result -> format("
  • %s
  • ", - result.getUrl(), result.getName())) + .map(result -> format( + "
  • %s
  • ", + result.getUrl(), + result.getName())) .collect(Collectors.joining()); return format( "" + "

    Search results:

    " + "
      %s
    " - + "", titles); + + "", + titles); } private void processResponse(String markdownInput, boolean codeResponse, boolean caretVisible) { @@ -194,53 +188,33 @@ public class ChatMessageResponseBody extends JPanel { var codeBlock = ((FencedCodeBlock) child); var code = codeBlock.getContentChars().unescape(); if (!code.isEmpty()) { - if (currentlyProcessedEditor == null) { - prepareProcessingCodeResponse(code, codeBlock.getInfo().unescape()); + if (currentlyProcessedEditorPanel == null) { + prepareProcessingCode(code, codeBlock.getInfo().unescape()); } - updateEditorDocument(code); + EditorUtil.updateEditorDocument(currentlyProcessedEditorPanel.getEditor(), code); } } } private void processText(String markdownText, boolean caretVisible) { if (currentlyProcessedTextPane == null) { - prepareProcessingTextResponse(caretVisible); + prepareProcessingText(caretVisible); } currentlyProcessedTextPane.setText(convertMdToHtml(markdownText)); } - private void prepareProcessingTextResponse(boolean caretVisible) { - currentlyProcessedEditor = null; + private void prepareProcessingText(boolean caretVisible) { + currentlyProcessedEditorPanel = null; currentlyProcessedTextPane = createTextPane("", caretVisible); add(currentlyProcessedTextPane); } - private void prepareProcessingCodeResponse(String code, String markdownLanguage) { - if (currentlyProcessedTextPane != null) { - currentlyProcessedTextPane.getCaret().setVisible(false); - } + private void prepareProcessingCode(String code, String markdownLanguage) { + hideCaret(); currentlyProcessedTextPane = null; - currentlyProcessedEditor = + currentlyProcessedEditorPanel = new ResponseEditorPanel(project, code, markdownLanguage, readOnly, parentDisposable); - add(currentlyProcessedEditor); - } - - private void updateEditorDocument(String code) { - var editor = currentlyProcessedEditor.getEditor(); - var document = editor.getDocument(); - var application = ApplicationManager.getApplication(); - Runnable updateDocumentRunnable = () -> application.runWriteAction(() -> - WriteCommandAction.runWriteCommandAction(project, () -> { - document.replaceString(0, document.getTextLength(), code); - editor.getComponent().repaint(); - editor.getComponent().revalidate(); - })); - - if (application.isUnitTestMode()) { - application.invokeAndWait(updateDocumentRunnable); - } else { - application.invokeLater(updateDocumentRunnable); - } + add(currentlyProcessedEditorPanel); } private JTextPane createTextPane(String text, boolean caretVisible) { @@ -260,13 +234,4 @@ public class ChatMessageResponseBody extends JPanel { textPane.setBorder(JBUI.Borders.empty()); return textPane; } - - private String convertMdToHtml(String message) { - MutableDataSet options = new MutableDataSet(); - var document = Parser.builder(options).build().parse(message); - return HtmlRenderer.builder(options) - .nodeRendererFactory(new ResponseNodeRenderer.Factory()) - .build() - .render(document); - } } diff --git a/src/main/java/ee/carlrobert/codegpt/util/EditorUtil.java b/src/main/java/ee/carlrobert/codegpt/util/EditorUtil.java index 1b41c55a..cd4997c1 100644 --- a/src/main/java/ee/carlrobert/codegpt/util/EditorUtil.java +++ b/src/main/java/ee/carlrobert/codegpt/util/EditorUtil.java @@ -43,6 +43,23 @@ public final class EditorUtil { EditorKind.MAIN_EDITOR); } + public static void updateEditorDocument(Editor editor, String content) { + var document = editor.getDocument(); + var application = ApplicationManager.getApplication(); + Runnable updateDocumentRunnable = () -> application.runWriteAction(() -> + WriteCommandAction.runWriteCommandAction(editor.getProject(), () -> { + document.replaceString(0, document.getTextLength(), content); + editor.getComponent().repaint(); + editor.getComponent().revalidate(); + })); + + if (application.isUnitTestMode()) { + application.invokeAndWait(updateDocumentRunnable); + } else { + application.invokeLater(updateDocumentRunnable); + } + } + public static boolean hasSelection(@Nullable Editor editor) { return editor != null && editor.getSelectionModel().hasSelection(); } diff --git a/src/main/java/ee/carlrobert/codegpt/util/MarkdownUtil.java b/src/main/java/ee/carlrobert/codegpt/util/MarkdownUtil.java index 0bca505b..641fdc74 100644 --- a/src/main/java/ee/carlrobert/codegpt/util/MarkdownUtil.java +++ b/src/main/java/ee/carlrobert/codegpt/util/MarkdownUtil.java @@ -2,6 +2,10 @@ package ee.carlrobert.codegpt.util; import static java.util.stream.Collectors.toList; +import com.vladsch.flexmark.html.HtmlRenderer; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.util.data.MutableDataSet; +import ee.carlrobert.codegpt.toolwindow.chat.ResponseNodeRenderer; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -30,4 +34,13 @@ public class MarkdownUtil { result.add(inputMarkdown.substring(start)); return result.stream().filter(item -> !item.isBlank()).collect(toList()); } + + public static String convertMdToHtml(String message) { + MutableDataSet options = new MutableDataSet(); + var document = Parser.builder(options).build().parse(message); + return HtmlRenderer.builder(options) + .nodeRendererFactory(new ResponseNodeRenderer.Factory()) + .build() + .render(document); + } } diff --git a/src/main/resources/messages/codegpt.properties b/src/main/resources/messages/codegpt.properties index 1d460c60..f606c3e1 100644 --- a/src/main/resources/messages/codegpt.properties +++ b/src/main/resources/messages/codegpt.properties @@ -40,11 +40,11 @@ settingsConfigurable.service.llama.downloadModelLink.label=Download Model settingsConfigurable.service.llama.cancelDownloadLink.label=Cancel Downloading settingsConfigurable.service.llama.linkToModel.label=Link to model settingsConfigurable.service.llama.contextSize.label=Prompt context size: -settingsConfigurable.service.llama.contextSize.comment=The size of the prompt context. LLaMA models were built with a context of 2048, which will provide better results for longer input/inference +settingsConfigurable.service.llama.contextSize.comment=The size of the prompt context. LLaMA models were built with a context of 2048, which will provide better results for longer input/inference. settingsConfigurable.service.llama.threads.label=Threads: settingsConfigurable.service.llama.threads.comment=The number of threads available to execute the model. It is not recommended to specify a number greater than the number of processor cores. settingsConfigurable.service.llama.additionalParameters.label=Additional parameters -settingsConfigurable.service.llama.additionalParameters.comment=Additional command-line parameters for the server startup process, separated by commas. See the full list of options

    Example: "--n-gpu-layers, 1, --no-mmap, --mlock"

    +settingsConfigurable.service.llama.additionalParameters.comment=Additional command-line parameters for the server startup process, separated by commas. See the full list of options.

    Example: "--n-gpu-layers, 1, --no-mmap, --mlock"

    settingsConfigurable.service.llama.port.label=Port: settingsConfigurable.service.llama.startServer.label=Start server settingsConfigurable.service.llama.stopServer.label=Stop server