-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
889 additions
and
45 deletions.
There are no files selected for viewing
114 changes: 114 additions & 0 deletions
114
spx-gui/src/components/editor/code-editor/CodeEditor.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<script setup lang="ts"> | ||
import { computed } from 'vue' | ||
import Emitter from '@/utils/emitter' | ||
import { useEditorCtx } from '../EditorContextProvider.vue' | ||
import { Copilot } from './copilot' | ||
import { DocumentBase } from './document-base' | ||
import { Spxlc } from './lsp' | ||
import { Runtime } from './runtime' | ||
import { | ||
CodeEditorUIComp, | ||
type ICodeEditorUI, | ||
type Diagnostic, | ||
type DiagnosticsContext, | ||
type IDiagnosticsProvider, | ||
type IResourceReferencesProvider, | ||
type ResourceReference, | ||
type ResourceReferencesContext | ||
} from './ui' | ||
const editorCtx = useEditorCtx() | ||
function initialize(ui: ICodeEditorUI) { | ||
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, documentBase, spxlc) | ||
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) | ||
class DiagnosticsProvider | ||
extends Emitter<{ | ||
didChangeDiagnostics: [] | ||
}> | ||
implements IDiagnosticsProvider | ||
{ | ||
async provideDiagnostics(ctx: DiagnosticsContext): Promise<Diagnostic[]> { | ||
console.warn('TODO', ctx, runtime) | ||
return [] | ||
} | ||
} | ||
ui.registerDiagnosticsProvider(new DiagnosticsProvider()) | ||
ui.registerFormattingEditProvider({ | ||
async provideDocumentFormattingEdits(ctx) { | ||
console.warn('TODO', ctx) | ||
return [] | ||
} | ||
}) | ||
ui.registerHoverProvider({ | ||
async provideHover(ctx, position) { | ||
console.warn('TODO', ctx, position) | ||
return null | ||
} | ||
}) | ||
class ResourceReferencesProvider | ||
extends Emitter<{ | ||
didChangeResourceReferences: [] | ||
}> | ||
implements IResourceReferencesProvider | ||
{ | ||
async provideResourceReferences(ctx: ResourceReferencesContext): Promise<ResourceReference[]> { | ||
console.warn('TODO', ctx) | ||
return [] | ||
} | ||
} | ||
ui.registerResourceReferencesProvider(new ResourceReferencesProvider()) | ||
} | ||
const editorKey = computed(() => { | ||
const selected = editorCtx.project.selected | ||
if (selected?.type === 'stage') return 'stage' | ||
if (selected?.type === 'sprite') return `sprite:${selected.id}` | ||
return '' | ||
}) | ||
defineExpose({ | ||
async format() { | ||
console.warn('TODO') | ||
} | ||
}) | ||
</script> | ||
|
||
<template> | ||
<CodeEditorUIComp :key="editorKey" :project="editorCtx.project" @initialize="initialize" /> | ||
</template> |
20 changes: 20 additions & 0 deletions
20
spx-gui/src/components/editor/code-editor/FormatButton.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<template> | ||
<UIButton type="boring" :loading="handleFormat.isLoading.value" @click="handleFormat.fn"> | ||
{{ $t({ en: 'Format', zh: '格式化' }) }} | ||
</UIButton> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { UIButton } from '@/components/ui' | ||
import { useMessageHandle } from '@/utils/exception' | ||
import type CodeEditor from './CodeEditor.vue' | ||
const props = defineProps<{ | ||
codeEditor: InstanceType<typeof CodeEditor> | ||
}>() | ||
const handleFormat = useMessageHandle(() => props.codeEditor.format(), { | ||
en: 'Failed to format', | ||
zh: '格式化失败' | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
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 | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
interface CommandConstraint<A, R> {} | ||
|
||
export type Command<A extends any[], R> = string & CommandConstraint<A, R> | ||
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 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 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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 [] | ||
} | ||
} |
Oops, something went wrong.