[inline-completion] IDEA-333789, IDEA-341524: describe how rendering of inline completion works

GitOrigin-RevId: c0885952a023ec4674c8dbfd1bc4d3fad3562431
This commit is contained in:
Kirill.Karnaukhov
2024-03-27 15:41:02 +00:00
committed by intellij-monorepo-bot
parent bf6332ff9f
commit 586a5d0986
6 changed files with 48 additions and 14 deletions
@@ -7,7 +7,11 @@ import com.intellij.openapi.editor.markup.TextAttributes
import org.jetbrains.annotations.ApiStatus
import java.awt.Color
// TODO docs
/**
* Draws text using IntelliJ inlays with respect to provided [Color].
*
* It uses [InlineCompletionFontUtils.attributes] with changed [TextAttributes.getForegroundColor].
*/
@ApiStatus.Experimental
open class InlineCompletionColorTextElement(
override val text: String,
@@ -1,6 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.inline.completion.elements
import com.intellij.codeInsight.inline.completion.InlineCompletionFontUtils
import com.intellij.codeInsight.inline.completion.render.InlineCompletionTextRenderManager
import com.intellij.codeInsight.inline.completion.render.RenderedInlineCompletionElementDescriptor
import com.intellij.openapi.editor.Editor
@@ -8,6 +9,15 @@ import com.intellij.openapi.editor.markup.TextAttributes
import org.jetbrains.annotations.ApiStatus
import java.awt.Rectangle
/**
* Draws text using the IntelliJ inlays with respect to provided [TextAttributes].
*
* Consider using [InlineCompletionFontUtils.attributes] as a base for custom attributes.
*
* At this moment the following attributes are supported:
* * [TextAttributes.getForegroundColor]
* * [TextAttributes.getFontType]
*/
@ApiStatus.Experimental
open class InlineCompletionTextElement @ApiStatus.Experimental constructor(
override val text: String,
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.ApiStatus
import java.awt.Graphics
import java.awt.Rectangle
@Deprecated("All rendering uses InlineSuffixRenderer")
@Deprecated("All rendering uses InlineCompletionLineRenderer")
@ApiStatus.ScheduledForRemoval
@ApiStatus.Internal
class InlineBlockElementRenderer(private val editor: Editor, lines: List<String>) : EditorCustomElementRenderer {
@@ -11,10 +11,18 @@ import org.jetbrains.annotations.ApiStatus
import java.awt.Graphics
import java.awt.Rectangle
// TODO name
// TODO what attributes are supported
/**
* Should not be used outside rendering the default inline completion elements.
*
* For now, it supports:
* * [TextAttributes.getForegroundColor]
* * [TextAttributes.getFontType]
*/
@ApiStatus.Internal
class InlineSuffixRenderer(private val editor: Editor, blocks: List<InlineCompletionRenderTextBlock>) : EditorCustomElementRenderer {
class InlineCompletionLineRenderer(
private val editor: Editor,
blocks: List<InlineCompletionRenderTextBlock>
) : EditorCustomElementRenderer {
constructor(editor: Editor, text: String, attributes: TextAttributes = InlineCompletionFontUtils.attributes(editor)) : this(
editor,
@@ -78,6 +86,6 @@ class InlineSuffixRenderer(private val editor: Editor, blocks: List<InlineComple
}
companion object {
private val LOG = logger<InlineSuffixRenderer>()
private val LOG = logger<InlineCompletionLineRenderer>()
}
}
@@ -4,6 +4,9 @@ package com.intellij.codeInsight.inline.completion.render
import com.intellij.openapi.editor.markup.TextAttributes
import org.jetbrains.annotations.ApiStatus
/**
* Represents a block to be rendered **on one line**. Passing a multiline text results into an exception.
*/
@ApiStatus.Internal
class InlineCompletionRenderTextBlock(val text: String, val attributes: TextAttributes) {
init {
@@ -18,9 +18,18 @@ import com.intellij.util.concurrency.annotations.RequiresEdt
import org.jetbrains.annotations.ApiStatus
import java.awt.Rectangle
// TODO docs
// TODO describe disposing (all at once)
// TODO describe rectangle
/**
* Accumulates all the text to be rendered at one offset and renders them.
* To be able to render streaming text, all blocks are split line by line.
*
* When a new text part comes, the last line is changed, while the previous lines stay the same.
* Even if an element has multiline text, it's split into lines and they are rendered one by one.
*
* Rules:
* * Disposing of the whole text happens only when all the 'children' elements are disposed.
* It relies on the internal implementation of the inline completion: all elements are always disposed at once.
* * Each 'child' element returns [Rectangle] that represents the whole text. It may be fixed at some point.
*/
@ApiStatus.Experimental
internal class InlineCompletionTextRenderManager private constructor(
editor: Editor,
@@ -53,8 +62,8 @@ internal class InlineCompletionTextRenderManager private constructor(
private class Renderer(private val editor: Editor, private val offset: Int) : Disposable {
private var suffixInlay: Inlay<InlineSuffixRenderer>? = null
private val blockLineInlays = mutableListOf<Inlay<InlineSuffixRenderer>>()
private var suffixInlay: Inlay<InlineCompletionLineRenderer>? = null
private val blockLineInlays = mutableListOf<Inlay<InlineCompletionLineRenderer>>()
private var state = RenderState.RENDERING_SUFFIX
fun append(text: String, attributes: TextAttributes): RenderedInlineCompletionElementDescriptor? {
@@ -94,7 +103,7 @@ internal class InlineCompletionTextRenderManager private constructor(
suffixInlay = null
if (suffixBlocks.any { it.text.isNotEmpty() }) {
val element = editor.inlayModel.addInlineElement(offset, true, InlineSuffixRenderer(editor, suffixBlocks))
val element = editor.inlayModel.addInlineElement(offset, true, InlineCompletionLineRenderer(editor, suffixBlocks))
if (element != null) {
element.addActionAvailabilityHint(
EditorActionAvailabilityHint(
@@ -136,13 +145,13 @@ internal class InlineCompletionTextRenderManager private constructor(
editor: Editor,
offset: Int,
blocks: List<InlineCompletionRenderTextBlock>
): Inlay<InlineSuffixRenderer>? {
): Inlay<InlineCompletionLineRenderer>? {
return editor.inlayModel.addBlockElement(
offset,
true,
false,
1,
InlineSuffixRenderer(editor, blocks)
InlineCompletionLineRenderer(editor, blocks)
)
}