diff --git a/README.md b/README.md index 2e6951c961..ed4b5c39db 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,13 @@ You can configure the plugin on three levels: 1. **Project-level** On the project level you are able to configure your default account, default branch name and remote url replacements 2. **Application-level** All other settings are stored here +## System Properties + +### Autocomplete system properties +In order to disable newly introduced features we are giving an option to disable them via system properties: + +1. **Disable formatting autocomplete elements** `cody.autocomplete.enableFormatting=false` + ## Managing Custom Keymaps ![A screenshot of the JetBrains preferences panel inside the Keymap tab](docs/keymaps.png) diff --git a/build.gradle.kts b/build.gradle.kts index c315018d96..4b8c4b4531 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -334,6 +334,9 @@ tasks { systemProperty("cody-agent.trace-path", "$buildDir/sourcegraph/cody-agent-trace.json") systemProperty("cody-agent.directory", buildCodyDir.parent) systemProperty("sourcegraph.verbose-logging", "true") + systemProperty( + "cody.autocomplete.enableFormatting", + project.property("cody.autocomplete.enableFormatting") ?: "true") } runPluginVerifier { diff --git a/gradle.properties b/gradle.properties index c5eb38eaa0..f51180ad6b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,4 +23,4 @@ gradleVersion=8.1.1 # suppress inspection "UnusedProperty" kotlin.stdlib.default.dependency=false # See https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_configure -org.gradle.caching=true +cody.autocomplete.enableFormatting=true diff --git a/src/main/kotlin/com/sourcegraph/cody/autocomplete/CodyAutocompleteManager.kt b/src/main/kotlin/com/sourcegraph/cody/autocomplete/CodyAutocompleteManager.kt index effed16c76..5bb502083a 100644 --- a/src/main/kotlin/com/sourcegraph/cody/autocomplete/CodyAutocompleteManager.kt +++ b/src/main/kotlin/com/sourcegraph/cody/autocomplete/CodyAutocompleteManager.kt @@ -42,6 +42,7 @@ import com.sourcegraph.utils.CodyEditorUtil.getTextRange import com.sourcegraph.utils.CodyEditorUtil.isCommandExcluded import com.sourcegraph.utils.CodyEditorUtil.isEditorValidForAutocomplete import com.sourcegraph.utils.CodyEditorUtil.isImplicitAutocompleteEnabledForEditor +import com.sourcegraph.utils.CodyFormatter import difflib.Delta import difflib.DiffUtils import difflib.Patch @@ -322,7 +323,7 @@ class CodyAutocompleteManager { clearAutocompleteSuggestions(editor) currentAutocompleteTelemetry?.markCompletionDisplayed() - displayAgentAutocomplete(editor, offset, items, inlayModel, triggerKind, lookupString) + displayAgentAutocomplete(editor, offset, items, inlayModel, triggerKind) } } @@ -338,8 +339,22 @@ class CodyAutocompleteManager { items: List, inlayModel: InlayModel, triggerKind: InlineCompletionTriggerKind, - lookupString: String?, ) { + val project = editor.project + if (project != null && System.getProperty("cody.autocomplete.enableFormatting") != "false") { + items.map { item -> + if (item.insertText.lines().size > 1) { + item.insertText = + item.insertText.lines()[0] + + CodyFormatter.formatStringBasedOnDocument( + item.insertText.lines().drop(1).joinToString(separator = "\n"), + project, + editor.document, + offset) + } + } + } + val defaultItem = items.firstOrNull() ?: return val range = getTextRange(editor.document, defaultItem.range) val originalText = editor.document.getText(range) diff --git a/src/main/kotlin/com/sourcegraph/cody/autocomplete/action/CycleCodyAutocompleteActionHandler.kt b/src/main/kotlin/com/sourcegraph/cody/autocomplete/action/CycleCodyAutocompleteActionHandler.kt index 15db842761..69cc24d3ae 100644 --- a/src/main/kotlin/com/sourcegraph/cody/autocomplete/action/CycleCodyAutocompleteActionHandler.kt +++ b/src/main/kotlin/com/sourcegraph/cody/autocomplete/action/CycleCodyAutocompleteActionHandler.kt @@ -44,12 +44,7 @@ class CycleCodyAutocompleteActionHandler(private val cycleDirection: CycleDirect CodyAutocompleteManager.instance.let { it.clearAutocompleteSuggestions(editor) it.displayAgentAutocomplete( - editor, - caret.offset, - newItems, - editor.inlayModel, - InlineCompletionTriggerKind.INVOKE, - null) + editor, caret.offset, newItems, editor.inlayModel, InlineCompletionTriggerKind.INVOKE) } autocompleteItemsCache[cacheKey] = newItems } diff --git a/src/main/kotlin/com/sourcegraph/utils/CodyFormatter.kt b/src/main/kotlin/com/sourcegraph/utils/CodyFormatter.kt new file mode 100644 index 0000000000..ae14202f85 --- /dev/null +++ b/src/main/kotlin/com/sourcegraph/utils/CodyFormatter.kt @@ -0,0 +1,47 @@ +package com.sourcegraph.utils + +import com.intellij.openapi.editor.Document +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiFileFactory +import com.intellij.psi.codeStyle.CodeStyleManager +import com.intellij.refactoring.suggested.endOffset + +class CodyFormatter { + companion object { + /** + * Formatting used to format inlay text inserted by Cody, based on the surrounding code style in + * the document. + */ + fun formatStringBasedOnDocument( + originalText: String, + project: Project, + document: Document, + offset: Int + ): String { + + val appendedString = + document.text.substring(0, offset) + originalText + document.text.substring(offset) + + val file = FileDocumentManager.getInstance().getFile(document)!! + val psiFile = + PsiFileFactory.getInstance(project) + .createFileFromText("TEMP", file.fileType, appendedString) + + val codeStyleManager = CodeStyleManager.getInstance(project) + + var i = offset + var startRefactoringPosition = offset + while ((document.text.elementAt(i - 1) == ' ' || + document.text.elementAt(i - 1) == '\n' || + document.text.elementAt(i - 1) == '\t') && i > 0) { + startRefactoringPosition = i + i-- + } + var endOffset = offset + psiFile.endOffset - document.textLength + codeStyleManager.reformatText(psiFile, startRefactoringPosition, endOffset) + endOffset = offset + psiFile.endOffset - document.textLength + return psiFile.text.substring(startRefactoringPosition, endOffset) + } + } +}