From 1f446e8163b51d9930940ccb772b853d38252cca Mon Sep 17 00:00:00 2001 From: Manfred Kral Date: Thu, 1 Feb 2024 12:23:38 +0100 Subject: [PATCH 1/2] Changed InlineProvider to Debounced version, to avoid unnecessary completion requests. --- .../llmintellij/LlmLsCompletionProvider.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt b/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt index 756c1e3..8884041 100644 --- a/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt +++ b/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt @@ -6,7 +6,7 @@ import co.huggingface.llmintellij.lsp.LlmLsServerSupportProvider import co.huggingface.llmintellij.lsp.Position import com.intellij.codeInsight.inline.completion.InlineCompletionElement import com.intellij.codeInsight.inline.completion.InlineCompletionEvent -import com.intellij.codeInsight.inline.completion.InlineCompletionProvider +import com.intellij.codeInsight.inline.completion.DebouncedInlineCompletionProvider import com.intellij.codeInsight.inline.completion.InlineCompletionRequest import com.intellij.openapi.diagnostic.Logger import com.intellij.platform.lsp.api.LspServerManager @@ -16,11 +16,18 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.launch +import kotlin.time.Duration +import kotlin.time.DurationUnit +import kotlin.time.toDuration -class LlmLsCompletionProvider: InlineCompletionProvider { +class LlmLsCompletionProvider : DebouncedInlineCompletionProvider() { + override val delay: Duration = 500.toDuration(DurationUnit.MILLISECONDS) private val logger = Logger.getInstance("inlineCompletion") + override fun force(request: InlineCompletionRequest): Boolean { + return false + } - override suspend fun getProposals(request: InlineCompletionRequest): Flow = + override suspend fun getProposalsDebounced(request: InlineCompletionRequest): Flow = channelFlow { val project = request.editor.project if (project == null) { From d26ec5396c9ede7a37d8a1e9b5f41eb0efd5a343 Mon Sep 17 00:00:00 2001 From: Manfred Kral Date: Thu, 1 Feb 2024 14:41:09 +0100 Subject: [PATCH 2/2] Configurable debounce delay --- .../llmintellij/LlmLsCompletionProvider.kt | 3 ++- .../llmintellij/LlmSettingsComponent.kt | 18 ++++++++++++++++++ .../llmintellij/LlmSettingsConfigurable.kt | 5 +++++ .../llmintellij/LlmSettingsState.kt | 3 +++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt b/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt index 8884041..df46816 100644 --- a/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt +++ b/src/main/kotlin/co/huggingface/llmintellij/LlmLsCompletionProvider.kt @@ -21,7 +21,7 @@ import kotlin.time.DurationUnit import kotlin.time.toDuration class LlmLsCompletionProvider : DebouncedInlineCompletionProvider() { - override val delay: Duration = 500.toDuration(DurationUnit.MILLISECONDS) + override var delay: Duration = 500.toDuration(DurationUnit.MILLISECONDS) private val logger = Logger.getInstance("inlineCompletion") override fun force(request: InlineCompletionRequest): Boolean { return false @@ -34,6 +34,7 @@ class LlmLsCompletionProvider : DebouncedInlineCompletionProvider() { logger.error("could not find project") } else { val settings = LlmSettingsState.instance + delay = settings.debounceDelay val secrets = SecretsService.instance val lspServer = LspServerManager.getInstance(project).getServersForProvider(LlmLsServerSupportProvider::class.java).firstOrNull() if (lspServer != null) { diff --git a/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsComponent.kt b/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsComponent.kt index 77cc91b..9f5ec4f 100644 --- a/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsComponent.kt +++ b/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsComponent.kt @@ -16,6 +16,9 @@ import javax.swing.JComponent import javax.swing.JPanel import javax.swing.event.DocumentEvent import javax.swing.event.DocumentListener +import kotlin.time.Duration +import kotlin.time.DurationUnit +import kotlin.time.toDuration class LlmSettingsComponent { val rootPanel: JPanel = JPanel() @@ -41,6 +44,8 @@ class LlmSettingsComponent { private val fimSuffixLabel: JBLabel private val fimSuffix: JBTextField private val tlsSkipVerifyInsecure: JBCheckBox + private val debounceDelayLabel: JBLabel + private val debounceDelay: JBTextField private val lspBinaryPath: TextFieldWithBrowseButton private val lspVersionLabel: JBLabel private val lspVersion: JBTextField @@ -218,6 +223,11 @@ class LlmSettingsComponent { llmLsSubsectionPanel.add(lspLogLevelLabel) llmLsSubsectionPanel.add(lspLogLevel) + val pluginSettingsPanel = createSectionPanel("Plugin settings", rootPanel) + debounceDelayLabel = JBLabel("Debounce delay in milliseconds") + debounceDelay = JBTextField("500") + pluginSettingsPanel.add(debounceDelayLabel) + pluginSettingsPanel.add(debounceDelay) } val preferredFocusedComponent: JComponent @@ -353,6 +363,14 @@ class LlmSettingsComponent { lspLogLevel.text = value } + fun getDebounceDelay(): Duration { + return debounceDelay.text.toInt().toDuration(DurationUnit.MILLISECONDS) + } + + fun setDebounceDelay(value: Duration) { + debounceDelay.text = value.inWholeMilliseconds.toString() + } + fun getLspBinaryPath(): String? { val binaryPath = lspBinaryPath.text return if (binaryPath == "") { diff --git a/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsConfigurable.kt b/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsConfigurable.kt index 04002e8..d516797 100644 --- a/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsConfigurable.kt +++ b/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsConfigurable.kt @@ -3,6 +3,8 @@ package co.huggingface.llmintellij import com.intellij.openapi.options.Configurable import org.jetbrains.annotations.Nls import javax.swing.JComponent +import kotlin.time.DurationUnit +import kotlin.time.toDuration class LlmSettingsConfigurable : Configurable { @@ -38,6 +40,7 @@ class LlmSettingsConfigurable : Configurable { modified = modified or (settingsComponent?.getFimMiddle() != settings.fim.middle) modified = modified or (settingsComponent?.getFimSuffix() != settings.fim.suffix) modified = modified or (settingsComponent?.isTlsSkipVerifyInsecureEnabled() != settings.tlsSkipVerifyInsecure) + modified = modified or (settingsComponent?.getDebounceDelay() != settings.debounceDelay) modified = modified or (settingsComponent?.getLspBinaryPath() != settings.lsp.binaryPath) modified = modified or (settingsComponent?.getLspVersion() != settings.lsp.version) modified = modified or (settingsComponent?.getLspLogLevel() != settings.lsp.logLevel) @@ -60,6 +63,7 @@ class LlmSettingsConfigurable : Configurable { settings.fim.middle = settingsComponent?.getFimMiddle() ?: "" settings.fim.suffix = settingsComponent?.getFimSuffix() ?: "" settings.tlsSkipVerifyInsecure = settingsComponent?.isTlsSkipVerifyInsecureEnabled() ?: false + settings.debounceDelay = settingsComponent?.getDebounceDelay() ?: 500.toDuration(DurationUnit.MILLISECONDS) settings.lsp.binaryPath = settingsComponent?.getLspBinaryPath() settings.lsp.version = settingsComponent?.getLspVersion() ?: "" settings.lsp.logLevel = settingsComponent?.getLspLogLevel() ?: "" @@ -81,6 +85,7 @@ class LlmSettingsConfigurable : Configurable { settingsComponent?.setFimMiddle(settings.fim.middle) settingsComponent?.setFimSuffix(settings.fim.suffix) settingsComponent?.setTlsSkipVerifyInsecureStatus(settings.tlsSkipVerifyInsecure) + settingsComponent?.setDebounceDelay(settings.debounceDelay) settingsComponent?.setLspBinaryPath(settings.lsp.binaryPath ?: "") settingsComponent?.setLspVersion(settings.lsp.version) settingsComponent?.setLspLogLevel(settings.lsp.logLevel) diff --git a/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsState.kt b/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsState.kt index e4757bc..52862ec 100644 --- a/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsState.kt +++ b/src/main/kotlin/co/huggingface/llmintellij/LlmSettingsState.kt @@ -5,6 +5,8 @@ import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.util.xmlb.XmlSerializerUtil +import kotlin.time.DurationUnit +import kotlin.time.toDuration class LspSettings { @@ -45,6 +47,7 @@ class LlmSettingsState: PersistentStateComponent { var queryParams = QueryParams() var fim = FimParams() var tlsSkipVerifyInsecure = false + var debounceDelay = 500.toDuration(DurationUnit.MILLISECONDS) var lsp = LspSettings() var tokenizer: TokenizerConfig? = TokenizerConfig.HuggingFace("bigcode/starcoder") var contextWindow = 8192u