package com.plexworlds.l3 import com.intellij.codeInsight.inline.completion.* import com.intellij.codeInsight.inline.completion.elements.InlineCompletionElement import com.intellij.codeInsight.inline.completion.elements.InlineCompletionGrayTextElement import com.plexworlds.l3.config.L3PersistentState import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.launch class L3InlineCompletionProvider : InlineCompletionProvider { override val id = InlineCompletionProviderID("L3InlineCompletionProvider") override suspend fun getSuggestion(request: InlineCompletionRequest): InlineCompletionSuggestion { val startTime = System.nanoTime() request.editor.project?.basePath return InlineCompletionSuggestion.Default( channelFlow { val (prefix, suffix) = request.document.text.splitUsingOffset(request.startOffset) val lastPrefixLine = prefix.lines().last() val pState = L3PersistentState.getInstance() val suggestion = pState.provider.call( pState.url, pState.model, prefix, suffix ) launch { try { trySend(InlineCompletionGrayTextElement(suggestion)) } catch (e: Exception) { println("Inline completion suggestion dispatch failed") } } }.onCompletion { val endTime = System.nanoTime() val duration = (endTime - startTime) / 1_000_000 // Convert to milliseconds } ) } override val insertHandler: InlineCompletionInsertHandler get() = object : InlineCompletionInsertHandler { override fun afterInsertion( environment: InlineCompletionInsertEnvironment, elements: List ) { } } override fun isEnabled(event: InlineCompletionEvent): Boolean { return event is InlineCompletionEvent.DocumentChange && with(event.editor) { !document.text.shouldBeSkippedOnPosition(caretModel.offset) } } private fun String.splitUsingOffset(offset: Int): Pair { return substring(0, offset + 1) to substring(offset + 1) } }