builder
builder copied to clipboard
Intelligent Code Editor
UI
- sidebar
- completion menu
- inlay hint
- hover layer (content, action, ...)
- highlight
- code suggestion
- context menu?
Source
- compiler (syntax check, type check, AST manipulation)
- linter
- engine (runtime error)
- docs (APIs, keywords)
- project variables (sprite, sound, ...)
- AI
Features
1. Input Helper
Source:
- docs
- project variables
- compiler
- AI
UI Result:
- sidebar
- completion menu
- code suggestion
2. Explanation
Source:
- docs
- project variables?
- AI?
UI Result:
- inlay hint
- hover layer
3. Diagnostic
Source:
- compiler
- linter
- engine
- AI?
UI Result:
- hover layer
- highlight
4. Refactoring
Source:
- compiler
- project variables?
UI Result:
- hover layer
- context menu?
// --------------------- ui ---------------------
// <EditorUIComp ref="editorUI" />
// TODO: AbortSignal
type GopDefinition = {
module: string // "github.com/goplus/spx"
name: string // "Sprite.touching"
}
type GopKeyword = string // TODO
type Identifier = GopDefinition | GopKeyword
interface EditorUI {
registerCompletionProvider(provider: CompletionProvider): void
registerInlayHintsProvider(provider: InlayHintsProvider): void
registerDocumentProvider(provider: DocumentProvider): void
registerSelectionMenuProvider(provider: SelectionMenuProvider): void
registerHoverProvider(provider: HoverProvider): void
registerAttentionHintProvider(provider: AttentionHintProvider): void
invokeAIChatModal(options: AIChatModalOptions): void
}
interface TextModel {
// TODO
}
type Position = {
lineNumber: number
column: number
}
type Icon = string // TODO
type Markdown = string // TODO
type SoundPlayer = string // TODO
type LayerContent = DocPreview | SoundPlayer
type CompletionItem = {
icon: Icon
label: string
insertText: string
desc: string
preview: LayerContent
}
interface CompletionProvider {
provideCompletionItems(textModel: TextModel, position: Position, addItems: (items: CompletionItem[]) => void): void
}
type InlayHintStyle = 'default' | '...' // TODO
type InlayHintBehavior = 'none' | 'triggerCompletion' // TODO
type InlayHint = {
content: string | Icon
style: InlayHintStyle
behavior: InlayHintBehavior
position: Position
}
interface InlayHintsProvider {
provideInlayHints(textModel: TextModel): Promise<InlayHint[]>
}
type RecommendedAction = {
// TODO
label: string // TODO
fn: () => void
}
type Action = {
icon: Icon
label: string
}
type DocPreview = {
id: Identifier
content: Markdown
recommendedAction?: RecommendedAction
moreActions?: Action[]
}
type DocDetail = {
id: Identifier
content: Markdown
}
interface DocumentProvider {
provideDocumentDetail(id: Identifier): Promise<DocDetail>
}
type SelectionMenuItem = {
icon: Icon
label: string
action: () => void
}
type SelectedRange = {
// TODO: range?
// let user know the code selected
start: Position
end: Position
}
interface SelectionMenuProvider {
provideSelectionMenuItems(textModel: TextModel, selection: SelectedRange): Promise<SelectionMenuItem[]>
}
interface HoverProvider {
provideHover(textModel: TextModel, position: Position): Promise<LayerContent>
}
type ReplyAction = {
message: string
}
type Reply = {
message: Markdown
actions: ReplyAction[]
}
type AIChatModalOptions = {
// TODO
initialMessage: string
reply: (userMessage: Markdown) => Promise<Reply>
}
type AttentionHint = {
level: 'warning' | 'error' // TODO
range: SelectedRange
message: string
hovered: LayerContent // TODO: if we should integrate HoverLayer in AttentionHint
}
interface AttentionHintProvider {
provideAttentionHint(addHints: (hints: AttentionHint[]) => void): void
}
// --------------------- coordinator ---------------------
interface Editor {
jump(position: Position): void
}
// --------------------- ability ---------------------
type SuggestTaskInput = unknown // TODO
type SuggestTaskResult = unknown // TODO
type ExplainChatInput = unknown // TODO
type CommentChatInput = unknown // TODO
type FixCodeChatInput = unknown // TODO
interface AIAbility {
startSuggestTask(input: SuggestTaskInput): SuggestTaskResult
startExplainChat(input: ExplainChatInput): Chat
startCommentChat(input: CommentChatInput): Chat
startFixCodeChat(input: FixCodeChatInput): Chat
}
type Message = {
content: Markdown
actions: ReplyAction[]
}
interface Chat {
// TODO: ignore first message?
sendUserMessage(userMessage: Message): Promise<Message>
}
Follow up in #495.