feat: implement ghost text and generalize inline elements
Refactors the InlayHint system into a generic InlineElement architecture to support inline code completion.
- Introduce
InlineElementinterface,InlineElementContainer, andInlineElementRenderer - Implement
GhostTextandGhostTextRendererfor displaying completion suggestions - Add
InlineCompletionProviderAPI andrequireInlineCompletioninLanguage - Update
CodeEditorto supportsetInlineCompletionProviderand handle Tab key to accept ghost text - Refactor
TextRow,LineBreakLayout, andWordwrapLayoutto useInlineElementinstead ofInlayHint - Add
GHOST_TEXT_FOREGROUNDtoEditorColorScheme
https://github.com/user-attachments/assets/2890550e-33d3-447e-93d9-42f2e3def2a4
Limitations
- currently it only supports single line completions
I have a few questions:
- Does the rendered text support multi-line display and word wrapping? (As shown in the image below)
-
Is the getInstance method in GhostTextRenderer necessary? Is there any risk of memory leaks?
-
Does InlineCompletionItem support multi-line content (i.e., setting different display lines and defining the cursor position after the completion is applied)?
Does the rendered text support multi-line display and word wrapping? (As shown in the image below)
No, currently it only supports single line completions. It can be extended to support multiline completions.
Is the getInstance method in GhostTextRenderer necessary? Is there any risk of memory leaks?
It is not necessary now, but when I created that function I was added all editor's event listeners in that function but later I used GhostTextRenderer's init { } block for registering event listeners. Sorry, I forgot to remove that function.
Does InlineCompletionItem support multi-line content (i.e., setting different display lines and defining the cursor position after the completion is applied)?
It is absolutely possible but I need to make some changes, currently editor only renders one GhostText even if there are many GhostTexts present.
Here are my thoughts about the changes to inlay hints and inline elements:
- use layout instead of renderer for inline elements, and inline element layout is capable of:
- break associated logic elements into row fragments, and fits editor viewport in wordwrap mode
- measure and draw the row fragments generated
- add
LineLayoutto layout a single line with logic inline elements to rows with their row fragments - inlay hint works with a subset of inline element funcitonalities (inlay hints can not be multi-line or fit wordwrap)
- editor layout takes care of line layouts
-
LineBreakLayoutcreates specific line layout if required (multi-line element detected) -
WordwrapLayoutalways layout all lines
-
-
TextRowcan draw according to a list of visually-reordered row fragments -
TextRowcan locate what row fragment is clicked by horizontal offset
I will keep the InlineElementRenderer interface as it is.
It will help user to add their own InlineElement such as Git Blame Annotation.