Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(spx-gui): fix huge of exits bugs #923

Merged
merged 3 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion spx-gui/src/components/editor/ProjectEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
/>
<SpriteEditor
v-else-if="editorCtx.project.selectedSprite != null"
ref="spriteCodeEditor"
:sprite="editorCtx.project.selectedSprite"
/>
<StageEditor
v-else-if="editorCtx.project.selected?.type === 'stage'"
ref="stageCodeEditor"
:stage="editorCtx.project.stage"
/>
<EditorPlaceholder v-else />
Expand All @@ -19,7 +21,7 @@
<DebugPreview v-else :project="editorCtx.project" />

<EditorPanels v-if="!editorCtx.debugProject" />
<DebugInfoPanels v-else :project="editorCtx.project" />
<DebugInfoPanels v-else :project="editorCtx.project" @jump-code="handleJumpCode" />
</div>
</template>

Expand All @@ -34,8 +36,33 @@ import EditorPlaceholder from './common/placeholder/EditorPlaceholder.vue'
import DebugInfoPanels from './panels/DebugInfoPanels.vue'
import DebugPreview from './preview/DebugPreview.vue'
import { useEditorCtx } from './EditorContextProvider.vue'
import type { Position } from '@/models/runtime'
import { ref } from 'vue'
import CodeEditor from '@/components/editor/code-editor/CodeEditor.vue'

const editorCtx = useEditorCtx()
const spriteCodeEditor = ref<InstanceType<typeof CodeEditor>>()
const stageCodeEditor = ref<InstanceType<typeof CodeEditor>>()

function handleJumpCode(target: 'stage' | 'sprite', name: string, position: Position) {
switch (target) {
case 'sprite': {
editorCtx.project.select({
name,
type: 'sprite'
})
spriteCodeEditor.value?.jump(position)
break
}
case 'stage': {
editorCtx.project.select({
type: 'stage'
})
stageCodeEditor.value?.jump(position)
break
}
}
}
</script>

<style scoped lang="scss">
Expand Down
7 changes: 5 additions & 2 deletions spx-gui/src/components/editor/code-editor/EditorUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,12 @@ export class EditorUI extends Disposable {
.filter((item): item is { type: 'audio'; layer: AudioPlayer } => item.type === 'audio')
.map((item) => item.layer)

// todo: consider if necessary to show trigger in accurate range when hovering, instead of whole line
const attentionHintDecorations = this.attentionHint?.attentionHintDecorations.filter(
(item) => item.range.startLineNumber === position.lineNumber
(item) =>
item.range.startLineNumber <= position.lineNumber &&
item.range.endLineNumber >= position.lineNumber &&
position.column <= item.range.endColumn &&
position.column >= item.range.startColumn
)

if (attentionHintDecorations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@
import type { Project } from '@/models/project'
import type { Sound } from '@/models/sound'
import { File } from '@/models/common/file'
import type { ChatBot } from '@/components/editor/code-editor/chat-bot'

export class HoverProvider {
private ui: EditorUI
private docAbility: DocAbility
private coordinatorState: CoordinatorState
private project: Project
private chatBot: ChatBot

constructor(
ui: EditorUI,
docAbility: DocAbility,
coordinatorState: CoordinatorState,
private project: Project
project: Project,
chatBot: ChatBot
) {
this.ui = ui
this.docAbility = docAbility
this.coordinatorState = coordinatorState
this.project = project
this.chatBot = chatBot
}

private get currentFilename() {
Expand Down Expand Up @@ -142,9 +148,9 @@
en: 'Please enter a new name'
}),
onSubmit: async (
newName: string,

Check warning on line 151 in spx-gui/src/components/editor/code-editor/coordinators/hoverProvider.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'newName' is defined but never used
ctx: { signal: AbortSignal },

Check warning on line 152 in spx-gui/src/components/editor/code-editor/coordinators/hoverProvider.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'ctx' is defined but never used
setError: (message: string) => void

Check warning on line 153 in spx-gui/src/components/editor/code-editor/coordinators/hoverProvider.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'setError' is defined but never used
) => {
// TODO: Add some logic code
}
Expand Down Expand Up @@ -211,7 +217,21 @@
}),
activeLabel: this.ui.i18n.t({ zh: '在线答疑', en: 'Online Q&A' }),
onActiveLabelClick: () => {
// TODO: add some logic code here
const usageId = usage.id
this.docAbility.getDetailDoc(doc.id).then((detailDoc) => {
const usageDetailDoc = detailDoc.usages.find(
(usage: UsageWithDoc) => usage.id === usageId
)?.doc
if (usageDetailDoc) {
const chat = this.chatBot.startExplainChat(
usage.declaration + '\n' + usageDetailDoc
)
this.ui.invokeAIChatModal(chat)
} else {
const chat = this.chatBot.startExplainChat(usage.declaration)
this.ui.invokeAIChatModal(chat)
}
})
}
},
moreActions: [...this.createDocDetailAction(doc, definition)]
Expand All @@ -230,13 +250,12 @@
' ' +
param.type
// if parma type is func() (func(mi *github.com/goplus/spx.MovingInfo))
// this line remove: "*"
.replace(/\*/g, '')
// this line remove: "github.com/goplus/spx."
.replace(/(?:[\w/]+\.)+/g, '')
)
.join(', ')
if (usage.type === 'func') usageDeclaration[usage.usageID] = `${name} (${params})`
else usageDeclaration[usage.usageID] = usage.declaration.replace(/(?:[\w/]+\.)+/g, '')
})
return usageDeclaration
}
Expand Down
92 changes: 64 additions & 28 deletions spx-gui/src/components/editor/code-editor/coordinators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type InputItem,
type InputItemCategory,
type InputItemGroup,
type LayerContent,
type SelectionMenuItem,
type TextModel
} from '@/components/editor/code-editor/EditorUI'
Expand Down Expand Up @@ -70,7 +71,7 @@ export class Coordinator {
this.docAbility = docAbility
this.chatBot = chatBot
this.compiler = compiler
this.hoverProvider = new HoverProvider(ui, docAbility, this.coordinatorState, project)
this.hoverProvider = new HoverProvider(ui, docAbility, this.coordinatorState, project, chatBot)
this.suggest = new Suggest(() => project)

ui.registerCompletionProvider({
Expand Down Expand Up @@ -111,18 +112,32 @@ export class Coordinator {
},
addItems: (items: CompletionItem[]) => void
) {
const transferUsageDeclaration = (declaration: string) =>
declaration
// if param type is func() (func(mi *github.com/goplus/spx.MovingInfo))
// this line remove: "github.com/goplus/spx."
.replace(/(?:[\w/]+\.)+/g, '')

// add project variables
const { sprites, sounds, stage, selectedSprite } = this.project

const createCompletionItem = (name: string) => ({
const createCompletionItem = (name: string, preview?: LayerContent) => ({
icon: Icon.Property,
insertText: `"${name}"`,
label: `"${name}"`
label: `"${name}"`,
preview
})

const items = [
...sprites.map((sprite) => createCompletionItem(sprite.name)),
...sounds.map((sound) => createCompletionItem(sound.name)),
...sounds.map((sound) =>
createCompletionItem(sound.name, {
type: 'audio',
layer: {
file: sound.file
}
})
),
...stage.backdrops.map((backdrop) => createCompletionItem(backdrop.name))
]

Expand Down Expand Up @@ -153,7 +168,6 @@ export class Coordinator {
name: completionItem.tokenName
}
const { usages } = await this.docAbility.getNormalDoc(tokenId)

usages.forEach((usage: UsageWithDoc) => completionItemDocMap.set(usage.insertText, usage))
}
addItems(
Expand All @@ -176,7 +190,7 @@ export class Coordinator {
content: completionItemDoc.doc,
header: {
icon: usageEffect2Icon(completionItemDoc.effect),
declaration: completionItemDoc.declaration
declaration: transferUsageDeclaration(completionItemDoc.declaration)
}
}
}
Expand Down Expand Up @@ -221,16 +235,8 @@ export class Coordinator {
items.map((item) => {
return {
icon: Icon.AIAbility,
insertText: ctx.unitWord + item.insertText,
label: ctx.unitWord + item.label,
desc: ctx.unitWord + item.label,
preview: {
type: 'doc',
layer: {
level: DocPreviewLevel.Normal,
content: ''
}
}
insertText: item.insertText,
label: ctx.unitWord + item.label
}
})
)
Expand Down Expand Up @@ -286,15 +292,17 @@ export class Coordinator {
this.coordinatorState.inlayHints = inlayHints
return inlayHints.flatMap((inlayHint): InlayHintDecoration[] => {
// from compiler has two type of inlay hint, so here use if else to distinguish
if (inlayHint.type === 'play') {

if (inlayHint.type === 'play') return []
if (inlayHint.name === 'mediaName') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里得记下 TODO,判断 name === 'mediaName' 应该只是临时手段?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的我会在后面的 PR 中标记这个 TODO

return [
{
content: Icon.Playlist,
style: 'icon',
behavior: 'triggerCompletion',
position: {
lineNumber: inlayHint.endPosition.line,
column: inlayHint.endPosition.column
lineNumber: inlayHint.startPosition.line,
column: inlayHint.startPosition.column
}
}
]
Expand Down Expand Up @@ -367,7 +375,8 @@ export class Coordinator {
}),
activeLabel: this.ui.i18n.t({ zh: '在线答疑', en: 'Online Q&A' }),
onActiveLabelClick: () => {
// TODO: Add some logic code
const chat = this.chatBot.startFixCodeChat(diagnostic.message)
this.ui.invokeAIChatModal(chat)
}
}
}
Expand Down Expand Up @@ -423,7 +432,8 @@ export class Coordinator {
this.ui,
this.docAbility,
tokenDetailsMap,
!this.project.selectedSprite
!this.project.selectedSprite,
this.chatBot
)
}

Expand All @@ -437,24 +447,34 @@ export class Coordinator {
)
}

public jump(position: JumpPosition): void {}
public jump(position: JumpPosition): void {
if (!position.ableToJump) return
// here temp using completion editor instance
// in fact all features in this ui have same editor instance
const editor = this.ui.completionMenu?.editor
editor?.setPosition({
column: position.column,
lineNumber: position.line
})
editor?.focus()
}
}

/* todo: this function params length need refactor to config object */
async function toolCategory2InputItemCategory(
category: TokenCategory,
icon: Icon,
color: string,
ui: EditorUI,
docAbility: DocAbility,
tokenDetailsMap: Record<string, TokenDetail>,
isInStageCode: boolean
isInStageCode: boolean,
chatBot: ChatBot
): Promise<InputItemCategory> {
const inputItemGroups: InputItemGroup[] = []
const transferUsageDeclaration = (declaration: string) =>
declaration
// if parma type is func() (func(mi *github.com/goplus/spx.MovingInfo))
// this line remove: "*"
.replace(/\*/g, '')
// if param type is func() (func(mi *github.com/goplus/spx.MovingInfo))
// this line remove: "github.com/goplus/spx."
.replace(/(?:[\w/]+\.)+/g, '')
for (const group of category.groups) {
Expand Down Expand Up @@ -503,7 +523,9 @@ async function toolCategory2InputItemCategory(
content: usage.doc,
header: {
icon: usageEffect2Icon(usage.effect),
declaration: usage.declaration
// if some usage is from wasm, also need to transform declaration
// you can remove `tokenUsages` related logic and only keep this line code
declaration: transferUsageDeclaration(usage.declaration)
},
recommendAction: {
label: ui.i18n.t({
Expand All @@ -512,7 +534,21 @@ async function toolCategory2InputItemCategory(
}),
activeLabel: ui.i18n.t({ zh: '在线答疑', en: 'Online Q&A' }),
onActiveLabelClick: () => {
// TODO: add some logic code here
const usageId = usage.id
docAbility.getDetailDoc(token.id).then((detailDoc) => {
const usageDetailDoc = detailDoc.usages.find(
(usage: UsageWithDoc) => usage.id === usageId
)?.doc
if (usageDetailDoc) {
const chat = chatBot.startExplainChat(
usage.declaration + '\n' + usageDetailDoc
)
ui.invokeAIChatModal(chat)
} else {
const chat = chatBot.startExplainChat(usage.declaration)
ui.invokeAIChatModal(chat)
}
})
}
},
moreActions: [
Expand Down
4 changes: 2 additions & 2 deletions spx-gui/src/components/editor/code-editor/tokens/spx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,15 @@ export const say: Token = {
effect: 'func',
target: 'Sprite',
declaration: 'func(msg interface{})',
sample: 'msg "Hello!"',
sample: '"Hello!"',
insertText: 'say ${1:msg}'
},
{
id: '0',
effect: 'func',
target: 'Sprite',
declaration: 'func(msg interface{}, secs ...float64)',
sample: 'msg "Hello!", 2',
sample: '"Hello!", 2',
insertText: 'say ${1:msg}, ${2:secs}'
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
const fence = md.renderer.rules.fence!
md.renderer.rules.fence = (tokens, currentTokenIndex, ...args) => {
const token = tokens[currentTokenIndex]
const [language, ...languageParams] = token.info.split(' ')

Check warning on line 7 in spx-gui/src/components/editor/code-editor/ui/MarkdownPreview.vue

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'language' is assigned a value but never used
if (languageParams.includes('pure')) {
// here only one token so index is 0
let renderedCode = fence([token], 0, ...args)
Expand Down Expand Up @@ -117,13 +117,15 @@
padding: initial;
border-radius: initial;
background-color: initial;
font-family: $markdown-code-font-family;
}
}

code {
padding: 0.1em 0.4em;
background-color: rgba(27, 31, 35, 0.05);
background-color: rgba(229, 229, 229, 0.4);
border-radius: 3px;
font-family: $markdown-code-font-family;
}

h1,
Expand Down Expand Up @@ -234,6 +236,10 @@
tr:nth-child(2n) {
background-color: #f6f8fa;
}

& > *:last-child {
margin-bottom: 0 !important;
}
}

.markdown-preview__wrapper {
Expand Down
Loading
Loading