Skip to content

Commit

Permalink
sv
Browse files Browse the repository at this point in the history
  • Loading branch information
nighca committed Nov 19, 2024
1 parent 0e879bc commit 7640d0d
Show file tree
Hide file tree
Showing 16 changed files with 588 additions and 0 deletions.
55 changes: 55 additions & 0 deletions spx-gui/src/components/editor/code-editor/CodeEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script setup lang="ts">
import { type ICodeEditorUI, CodeEditorUI } from './ui'
import { Copilot } from './copilot'
import { DocumentBase } from './document-base'
import { Spxlc } from './lsp'
import { Runtime } from './runtime'
import { useEditorCtx } from '../EditorContextProvider.vue'
const editorCtx = useEditorCtx()
const ui: ICodeEditorUI = new CodeEditorUI()
const copilot = new Copilot()
const documentBase = new DocumentBase()
const spxlc = new Spxlc()
const runtime = new Runtime()
ui.registerAPIReferenceProvider({
async provideAPIReference(ctx, position) {
console.warn('TODO', ctx, position)
return []
}
})
ui.registerCompletionProvider({
async provideCompletion(ctx, position) {
console.warn('TODO', ctx, position)
return []
}
})
ui.registerContextMenuProvider({
async provideContextMenu(ctx, position) {
console.warn('TODO', ctx, position)
return []
},
async provideSelectionContextMenu(ctx, selection) {
console.warn('TODO', ctx, selection)
return []
},
})
ui.registerCopilot(copilot)
ui.registerProject(editorCtx.project)
ui.registerDiagnosticsProvider({
async provideDiagnostics(ctx) {
console.warn('TODO', ctx)
return []
}
})
</script>

<template>
<div>TODO</div>
</template>

<style lang="scss" scoped></style>
140 changes: 140 additions & 0 deletions spx-gui/src/components/editor/code-editor/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
export type Position = {
line: number
column: number
}

export type IRange = {
start: Position
end: Position
}

export type ResourceIdentifier = {
uri: string
}

export type TextDocumentIdentifier = {
uri: string
}

export type TextDocumentPosition = {
textDocument: TextDocumentIdentifier
position: Position
}

export type TextDocumentRange = {
textDocument: TextDocumentIdentifier
range: IRange
}

export type CodeSegment = {
range: IRange
content: string
}

export enum DefinitionKind {
/** General function or method */
Function,
/** Function or method for reading data */
Read,
/** Function or method for causing effect, e.g., writing data */
Effect,
/** Function or method for listening to event */
Listen,
/** Language defined statements, e.g., `for { ... }` */
Statement,
/** Variable or field definition */
Variable,
/** Constant definition */
Constant,
/** Package definition */
Package
}

export type DefinitionIdentifier = {
/**
* Full name of source package.
* If not provided, it's assumed to be kind-statement.
* If `main`, it's the current user package.
* Exmples:
* - `fmt`
* - `github.com/goplus/spx`
* - `main`
*/
package?: string
/**
* Exported name of the definition.
* If not provided, it's assumed to be kind-package.
* Examples:
* - `Println`
* - `Sprite`
* - `Sprite.turn`
* - `for_statement_with_single_condition`: kind-statement
*/
name?: string
/** Index in overloads. */
overloadIndex?: number
}

/**
* Model for text document
* Similar to https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.ITextModel.html
*/
interface TextDocument {
id: TextDocumentIdentifier
getOffsetAt(position: Position): number
getPositionAt(offset: number): Position
getValueInRange(range: IRange): string
}

export type MarkdownString = {
/** Markdown string with MDX support. */
value: string
}

export type Icon = string

/**
* Documentation for an identifier, keyword, etc. Typically:
* ```mdx
* <Overview>func turn(dDirection float64)</Overview>
* <Detail>
* Turn with given direction change.
* </Detail>
* ```
*/
export type Documentation = MarkdownString

export type Action<I extends any[] = any, R = any> = {
title: string
command: Command<I, R>
arguments: I
}

export type BaseContext = {
/** Current active text document */
textDocument: TextDocument
/** Signal to abort long running operations */
signal: AbortSignal
}

export type Command<A extends any[], R> = string
export type CommandHandler<A extends any[], R> = (...args: A) => Promise<R>
export type CommandInfo<A extends any[], R> = {
icon: Icon
title: string
handler: CommandHandler<A, R>
}

export type TextEdit = {
range: Range
newText: string
}

export type WorkspaceEdit = {
changes?: { [uri: string]: TextEdit[] }
}

// const builtInCommandCopilotChat: Command<[ChatTopic], void> = 'spx.copilot.chat'
// const builtInCommandGoToDefinition: Command<[TextDocumentPosition], void> = 'spx.goToDefinition'
// const builtInCommandRename: Command<[TextDocumentPosition], void> = 'spx.rename'
// const builtInCommandResourceReferenceModify: Command<[TextDocumentRange, ResourceIdentifier], void> = 'spx.resourceReference.modify'
8 changes: 8 additions & 0 deletions spx-gui/src/components/editor/code-editor/copilot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Chat, ChatContext, ChatMessage, ICopilot } from './ui/copilot'

export class Copilot implements ICopilot {
async getChatCompletion(ctx: ChatContext, chat: Chat): Promise<ChatMessage | null> {
console.warn('TODO', ctx, chat)
return null
}
}
9 changes: 9 additions & 0 deletions spx-gui/src/components/editor/code-editor/document-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { DefinitionIdentifier } from './common'
import type { APIReferenceItem } from './ui/api-reference'

export class DocumentBase {
async getDocumentaion(definition: DefinitionIdentifier): Promise<APIReferenceItem | null> {
console.warn('TODO', definition)
return null
}
}
41 changes: 41 additions & 0 deletions spx-gui/src/components/editor/code-editor/lsp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { Disposer } from '@/utils/disposable'

// TODO: use implementation from `/tools/spxls/client.ts`
export class Spxlc {
/**
* Sends a request to the language server and waits for response.
* @param method LSP method name.
* @param params Method parameters.
* @returns Promise that resolves with the response.
*/
request<T>(method: string, params?: any): Promise<T> {
console.warn('TODO', method, params)
return null as any
}

/**
* Sends a notification to the language server (no response expected).
* @param method LSP method name.
* @param params Method parameters.
*/
notify(method: string, params?: any): void {
console.warn('TODO', method, params)
}

/**
* Registers a handler for server notifications.
* @param method LSP method name.
* @param handler Function to handle the notification.
*/
onNotification(method: string, handler: (params: any) => void): Disposer {
console.warn('TODO', method, handler)
return () => {}
}

/**
* Cleans up client resources.
*/
dispose(): void {
console.warn('TODO')
}
}
23 changes: 23 additions & 0 deletions spx-gui/src/components/editor/code-editor/runtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Emitter from '@/utils/emitter'
import type { TextDocumentRange } from './common'

enum RuntimeOutputKind {
Error,
Log
}

interface RuntimeOutput {
kind: RuntimeOutputKind
time: number
message: string
source: TextDocumentRange
}

export class Runtime extends Emitter<{
didChangeOutput: []
}> {
async getOutput(): Promise<RuntimeOutput[]> {
console.warn('TODO')
return []
}
}
20 changes: 20 additions & 0 deletions spx-gui/src/components/editor/code-editor/ui/api-reference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
DefinitionKind,
type BaseContext,
type Documentation,
type Position,
type DefinitionIdentifier
} from '../common'

export type APIReferenceItem = {
kind: DefinitionKind
definition: DefinitionIdentifier
insertText: string
documentation: Documentation
}

export type APIReferenceContext = BaseContext

export interface IAPIReferenceProvider {
provideAPIReference(ctx: APIReferenceContext, position: Position): Promise<APIReferenceItem[]>
}
15 changes: 15 additions & 0 deletions spx-gui/src/components/editor/code-editor/ui/completion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DefinitionKind, type BaseContext, type Documentation, type Position } from '../common'

export type CompletionContext = BaseContext

export type CompletionItemKind = DefinitionKind

export type CompletionItem = {
label: string
kind: CompletionItemKind
documentation: Documentation
}

export interface ICompletionProvider {
provideCompletion(ctx: CompletionContext, position: Position): Promise<CompletionItem[]>
}
14 changes: 14 additions & 0 deletions spx-gui/src/components/editor/code-editor/ui/context-menu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type Action, type BaseContext, type IRange, type Position } from '../common'

export type ContextMenuContext = BaseContext

export type Selection = IRange

export type MenuItem = {
action: Action
}

export interface IContextMenuProvider {
provideContextMenu(ctx: ContextMenuContext, position: Position): Promise<MenuItem[]>
provideSelectionContextMenu(ctx: ContextMenuContext, selection: Selection): Promise<MenuItem[]>
}
Loading

0 comments on commit 7640d0d

Please sign in to comment.