Skip to content

Commit

Permalink
Fix project build with platformVersion >= 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
pkukielka committed Oct 21, 2024
1 parent 96ea1c6 commit a2e8220
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 39 deletions.
7 changes: 7 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ plugins {
val platformVersion: String by project
val platformType: String by project
val javaVersion: String by project
val majorPlatformVersion = platformVersion.split(".").first()

group = properties("pluginGroup")!!

Expand Down Expand Up @@ -126,6 +127,10 @@ dependencies {
instrumentationTools()
pluginVerifier()
testFramework(TestFrameworkType.Platform)

if (majorPlatformVersion.toInt() >= 2024) {
bundledModule("intellij.platform.vcs.dvcs.impl")
}
}

implementation("org.commonmark:commonmark:0.22.0")
Expand Down Expand Up @@ -586,6 +591,8 @@ tasks {
test { dependsOn(project.tasks.getByPath("buildCody")) }

sourceSets {
main { kotlin.srcDir("src/intellij${majorPlatformVersion}/kotlin") }

create("integrationTest") {
kotlin.srcDir("src/integrationTest/kotlin")
compileClasspath += main.get().output + configurations.testCompileClasspath.get()
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ javaVersion=17
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
# suppress inspection "UnusedProperty"
kotlin.stdlib.default.dependency=false
kotlin.daemon.jvmargs=-Xmx2g -Xms500m
kotlin.daemon.jvmargs=-Xmx4g -Xms500m
# See https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_configure
nodeBinaries.commit=8755ae4c05fd476cd23f2972049111ba436c86d4
nodeBinaries.version=v20.12.2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.intellij.codeInsight.inline.completion.suggestion

import com.intellij.codeInsight.inline.completion.elements.InlineCompletionElement
import com.intellij.openapi.util.UserDataHolderBase
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector

interface InlineCompletionSuggestion {

object Empty : InlineCompletionSuggestion {}
}

interface InlineCompletionSingleSuggestion : InlineCompletionSuggestion {

companion object {

/** @see [InlineCompletionVariant.build] */
fun build(
data: UserDataHolderBase = UserDataHolderBase(),
buildElements:
suspend FlowCollector<InlineCompletionElement>.(data: UserDataHolderBase) -> Unit
): InlineCompletionSingleSuggestion {
return object : InlineCompletionSingleSuggestion {}
}

/** @see InlineCompletionVariant.build */
fun build(
data: UserDataHolderBase = UserDataHolderBase(),
elements: Flow<InlineCompletionElement>
): InlineCompletionSingleSuggestion {
return object : InlineCompletionSingleSuggestion {}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.sourcegraph.cody.autocomplete

import com.intellij.codeInsight.inline.completion.*
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionGrayTextElement
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSingleSuggestion
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestion
import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction
Expand Down Expand Up @@ -36,9 +38,9 @@ class CodyInlineCompletionProvider : InlineCompletionProvider {
suspend fun getSuggestion(request: InlineCompletionRequest): InlineCompletionSuggestion {
ApplicationManager.getApplication().assertIsNonDispatchThread()
val editor = request.editor
val project = editor.project ?: return InlineCompletionSuggestion.empty()
val project = editor.project ?: return InlineCompletionSuggestion.Empty
if (!isImplicitAutocompleteEnabledForEditor(editor)) {
return InlineCompletionSuggestion.empty()
return InlineCompletionSuggestion.Empty
}
val lookupString: String? = null // todo: can we use this provider for lookups?

Expand All @@ -56,9 +58,9 @@ class CodyInlineCompletionProvider : InlineCompletionProvider {
val completions =
fetchCompletions(project, editor, triggerKind, cancellationToken, lookupString)
.completeOnTimeout(null, 1, TimeUnit.SECONDS)
.get() ?: return InlineCompletionSuggestion.empty()
.get() ?: return InlineCompletionSuggestion.Empty

return InlineCompletionSuggestion.withFlow {
return InlineCompletionSingleSuggestion.build {
completions.items
.firstNotNullOfOrNull {
WriteCommandAction.runWriteCommandAction<InlineCompletionGrayTextElement?>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package com.sourcegraph.cody.autocomplete

import com.intellij.codeInsight.inline.completion.*
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionGrayTextElement
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSingleSuggestion
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestion
import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.client.ClientSessionsManager
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.util.concurrency.annotations.RequiresReadLock
import com.sourcegraph.cody.agent.CodyAgentService
import com.sourcegraph.cody.agent.protocol.AutocompleteResult
import com.sourcegraph.cody.agent.protocol.CompletionItemParams
import com.sourcegraph.cody.statusbar.CodyStatusService.Companion.resetApplication
import com.sourcegraph.cody.vscode.CancellationToken
import com.sourcegraph.cody.vscode.InlineCompletionTriggerKind
import com.sourcegraph.cody.vscode.IntelliJTextDocument
import com.sourcegraph.config.ConfigUtil
import com.sourcegraph.utils.CodyEditorUtil.getTextRange
import com.sourcegraph.utils.CodyEditorUtil.isImplicitAutocompleteEnabledForEditor
import com.sourcegraph.utils.CodyFormatter
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference

class CodyInlineCompletionProvider : InlineCompletionProvider {
private val logger = Logger.getInstance(CodyInlineCompletionProvider::class.java)
private val currentJob = AtomicReference(CancellationToken())
override val id = InlineCompletionProviderID("Cody")

override suspend fun getSuggestion(request: InlineCompletionRequest): InlineCompletionSuggestion {
ApplicationManager.getApplication().assertIsNonDispatchThread()
val editor = request.editor
val project = editor.project ?: return InlineCompletionSuggestion.Empty
if (!isImplicitAutocompleteEnabledForEditor(editor)) {
return InlineCompletionSuggestion.Empty
}
val lookupString: String? = null // todo: can we use this provider for lookups?

cancelCurrentJob(project)
val cancellationToken = CancellationToken()
currentJob.set(cancellationToken)

val triggerKind =
if (request.event is InlineCompletionEvent.DirectCall) {
InlineCompletionTriggerKind.INVOKE
} else {
InlineCompletionTriggerKind.AUTOMATIC
}

val completions =
fetchCompletions(project, editor, triggerKind, cancellationToken, lookupString)
.completeOnTimeout(null, 1, TimeUnit.SECONDS)
.get() ?: return InlineCompletionSuggestion.Empty

return InlineCompletionSingleSuggestion.build {
completions.items
.firstNotNullOfOrNull {
WriteCommandAction.runWriteCommandAction<InlineCompletionGrayTextElement?>(
editor.project) {
val range = getTextRange(editor.document, it.range)
val originalText = editor.document.getText(range)

val formattedCompletionText: String =
if (System.getProperty("cody.autocomplete.enableFormatting") == "false") {
it.insertText
} else {
CodyFormatter.formatStringBasedOnDocument(
it.insertText, project, editor.document, range, request.endOffset)
}

val completionText = formattedCompletionText.removeSuffix(originalText)
if (completionText.trim().isBlank()) {
null
} else {

CodyAgentService.withAgent(project) { agent ->
agent.server.completionSuggested(CompletionItemParams(it.id))
}

InlineCompletionGrayTextElement(completionText)
}
}
}
?.let { emit(it) }
}
}

@RequiresReadLock
private fun fetchCompletions(
project: Project,
editor: Editor,
triggerKind: InlineCompletionTriggerKind,
cancellationToken: CancellationToken,
lookupString: String?,
): CompletableFuture<AutocompleteResult?> {
val textDocument = IntelliJTextDocument(editor, project)
val offset = ReadAction.compute<Int, Throwable> { editor.caretModel.offset }
val lineNumber = editor.document.getLineNumber(offset)
val caretPositionInLine = offset - editor.document.getLineStartOffset(lineNumber)
val originalText = editor.document.getText(TextRange(offset - caretPositionInLine, offset))

val result = CompletableFuture<AutocompleteResult?>()
Utils.triggerAutocompleteAsync(
project,
editor,
offset,
textDocument,
triggerKind,
cancellationToken,
lookupString,
originalText,
logger) { autocompleteResult ->
result.complete(autocompleteResult)
}
return result
}

private fun cancelCurrentJob(project: Project?) {
currentJob.get().abort()
project?.let { resetApplication(it) }
}

override fun isEnabled(event: InlineCompletionEvent): Boolean {
return isEnabled()
}

fun isEnabled(event: DocumentEvent): Boolean {
return isEnabled()
}

private fun isEnabled(): Boolean {
val ideVersion = ApplicationInfo.getInstance().build.baselineVersion
val isRemoteDev = ClientSessionsManager.getAppSession()?.isRemote ?: false
return ideVersion >= 233 &&
isRemoteDev &&
ConfigUtil.isCodyEnabled() &&
ConfigUtil.isCodyAutocompleteEnabled()
}
}

This file was deleted.

0 comments on commit a2e8220

Please sign in to comment.