diff --git a/spx-backend/internal/copilot/spx_defs.md b/spx-backend/internal/copilot/spx_defs.md index 299b364f6..0320e08ee 100644 --- a/spx-backend/internal/copilot/spx_defs.md +++ b/spx-backend/internal/copilot/spx_defs.md @@ -7,8 +7,8 @@ Name,Sample,Description backdropIndex,,Get the index of the current backdrop backdropName,,Get the name of the current backdrop broadcast,broadcast msg,"Broadcast a message, e.g., `broadcast ""msg""`" -broadcast,"broadcast msg, wait","Broadcast a message with waiting, e.g., `broadcast ""msg"", true`" -broadcast,"broadcast msg, data, wait","Broadcast a message with data and waiting, e.g., `broadcast ""msg"", data, true`" +broadcast,"broadcast msg, true","Broadcast a message with waiting for related (`onMsg`) works to complete, e.g., `broadcast ""msg"", true`" +broadcast,"broadcast msg, data, true","Broadcast a message with data and waiting for related (`onMsg`) works to complete, e.g., `broadcast ""msg"", data, true`" changeVolume,changeVolume dVolume,"Change the volume for sounds with given volume change, e.g., `changeVolume 10`" onClick,onClick => {},Listen to stage clicked onKey,"onKey key, => {}","Listen to given key pressed, e.g., `onKey KeyA, => {}`" @@ -23,6 +23,7 @@ mousePressed,,Check if the mouse is currently pressed mouseX,,Get X position of the mouse mouseY,,Get Y position of the mouse nextBackdrop,,Switch to the next backdrop +nextBackdrop,nextBackdrop true,"Switch to the next backdrop, with waiting for related (`onBackdrop`) works to complete" onAnyKey,onAnyKey key => {},Listen to any key pressed onBackdrop,onBackdrop backdrop => {},Listen to backdrop switching onBackdrop,"onBackdrop backdrop, => {}",Listen to switching to specific backdrop @@ -33,9 +34,10 @@ play,play name,"Play sound with given name, e.g., `play ""explosion""`" play,"play name, wait","Play sound with given name and waiting, e.g., `play ""explosion"", true`" play,"play name, options","Play sound with given name and options, e.g., `play ""explosion"", { Loop: true }`" prevBackdrop,,Switch to the previous backdrop +prevBackdrop,prevBackdrop true,"Switch to the previous backdrop, with waiting for related (`onBackdrop`) works to complete" setVolume,setVolume volume,"Set the volume for sounds, e.g., `setVolume 100`" startBackdrop,startBackdrop name,"Set the current backdrop by specifying name, e.g., `startBackdrop ""backdrop1""`" -startBackdrop,"startBackdrop name, wait","Set the current backdrop by specifying name, with waiting, e.g., `startBackdrop ""backdrop1"", true`" +startBackdrop,"startBackdrop name, true","Set the current backdrop by specifying name, with waiting for related (`onBackdrop`) works to complete, e.g., `startBackdrop ""backdrop1"", true`" stopAllSounds,,Stop all playing sounds volume,,Get the volume for sounds wait,wait seconds,"Block current execution (coroutine) for given seconds, e.g., `wait 0.5`" diff --git a/spx-gui/src/components/editor/code-editor/code-editor.ts b/spx-gui/src/components/editor/code-editor/code-editor.ts index 454d9bdd1..21da74729 100644 --- a/spx-gui/src/components/editor/code-editor/code-editor.ts +++ b/spx-gui/src/components/editor/code-editor/code-editor.ts @@ -62,15 +62,8 @@ import { import { TextDocument, createTextDocument } from './text-document' import { type Monaco } from './monaco' -class ResourceReferencesProvider - extends Emitter<{ - didChangeResourceReferences: [] // TODO - }> - implements IResourceReferencesProvider -{ - constructor(private lspClient: SpxLSPClient) { - super() - } +class ResourceReferencesProvider implements IResourceReferencesProvider { + constructor(private lspClient: SpxLSPClient) {} async provideResourceReferences(ctx: ResourceReferencesContext): Promise { return this.lspClient.getResourceReferences(ctx.textDocument.id) } @@ -117,7 +110,7 @@ class DiagnosticsProvider return { start, end } } async provideDiagnostics(ctx: DiagnosticsContext): Promise { - // TODO: get diagnostics from runtime + // TODO: get diagnostics from runtime. https://github.com/goplus/builder/issues/1256 const diagnostics: Diagnostic[] = [] const report = await this.lspClient.textDocumentDiagnostic({ textDocument: ctx.textDocument.id @@ -511,7 +504,6 @@ export class CodeEditor extends Disposable { async provideAPIReference(ctx, position) { const definitions = await lspClient .workspaceExecuteCommandSpxGetDefinitions({ - // TODO: support signal textDocument: ctx.textDocument.id, position: toLSPPosition(position) }) diff --git a/spx-gui/src/components/editor/code-editor/common.ts b/spx-gui/src/components/editor/code-editor/common.ts index eed8b3d56..2cccac17c 100644 --- a/spx-gui/src/components/editor/code-editor/common.ts +++ b/spx-gui/src/components/editor/code-editor/common.ts @@ -236,7 +236,7 @@ export function makeAdvancedMarkdownString(value: string | LocaleMessage): Advan return { value, flag: 'advanced' } } -export type CommandIconType = 'explain' | 'fix' | 'goto' | 'modify' | 'rename' +export type CommandIconType = 'explain' | 'fix' | 'goto' | 'modify' | 'rename' | 'copy' | 'copilot' /** * Documentation string for a definition. Typically: diff --git a/spx-gui/src/components/editor/code-editor/document-base/gop.ts b/spx-gui/src/components/editor/code-editor/document-base/gop.ts index 2a115e6f8..48e7d80f0 100644 --- a/spx-gui/src/components/editor/code-editor/document-base/gop.ts +++ b/spx-gui/src/components/editor/code-editor/document-base/gop.ts @@ -1,11 +1,13 @@ import { DefinitionKind, type DefinitionDocumentationItem, makeBasicMarkdownString, categories } from '../common' -// TODO: more frequently-used tools for gop +// TODO: https://github.com/goplus/builder/issues/1257 +// * Add more frequently-used statements for gop +// * Review naming for these definitions export const forIterate: DefinitionDocumentationItem = { categories: [categories.control.flowControl], kind: DefinitionKind.Statement, - definition: { name: 'for_iterate' }, // TODO + definition: { name: 'for_iterate' }, insertText: 'for ${1:i}, ${2:v} <- ${3:set} {\n\t${4:}\n}', overview: 'for i, v <- set {}', detail: makeBasicMarkdownString({ @@ -17,7 +19,7 @@ export const forIterate: DefinitionDocumentationItem = { export const forLoopWithCondition: DefinitionDocumentationItem = { categories: [categories.control.flowControl], kind: DefinitionKind.Statement, - definition: { name: 'for_loop_with_condition' }, // TODO + definition: { name: 'for_loop_with_condition' }, insertText: 'for ${1:condition} {\n\t${2:}\n}', overview: 'for condition {}', detail: makeBasicMarkdownString({ @@ -29,7 +31,7 @@ export const forLoopWithCondition: DefinitionDocumentationItem = { export const forLoopWithRange: DefinitionDocumentationItem = { categories: [categories.control.flowControl], kind: DefinitionKind.Statement, - definition: { name: 'for_loop_with_range' }, // TODO + definition: { name: 'for_loop_with_range' }, insertText: 'for ${1:i} <- ${2:start}:${3:end} {\n\t${4:}\n}', overview: 'for i <- start:end {}', detail: makeBasicMarkdownString({ @@ -41,7 +43,7 @@ export const forLoopWithRange: DefinitionDocumentationItem = { export const ifStatement: DefinitionDocumentationItem = { categories: [categories.control.flowControl], kind: DefinitionKind.Statement, - definition: { name: 'if_statement' }, // TODO + definition: { name: 'if_statement' }, insertText: 'if ${1:condition} {\n\t${2:}\n}', overview: 'if condition {}', detail: makeBasicMarkdownString({ @@ -53,7 +55,7 @@ export const ifStatement: DefinitionDocumentationItem = { export const ifElseStatement: DefinitionDocumentationItem = { categories: [categories.control.flowControl], kind: DefinitionKind.Statement, - definition: { name: 'if_else_statement' }, // TODO + definition: { name: 'if_else_statement' }, insertText: 'if ${1:condition} {\n\t${2:}\n} else {\n\t${3:}\n}', overview: 'if condition {} else {}', detail: makeBasicMarkdownString({ @@ -65,7 +67,7 @@ export const ifElseStatement: DefinitionDocumentationItem = { export const varDeclaration: DefinitionDocumentationItem = { categories: [categories.control.declaration], kind: DefinitionKind.Statement, - definition: { name: 'var_declaration' }, // TODO + definition: { name: 'var_declaration' }, insertText: 'var ${1:name} ${2:type}', overview: 'var name type', detail: makeBasicMarkdownString({ @@ -77,7 +79,7 @@ export const varDeclaration: DefinitionDocumentationItem = { export const importStatement: DefinitionDocumentationItem = { categories: [categories.control.declaration], kind: DefinitionKind.Statement, - definition: { name: 'import_declaration' }, // TODO + definition: { name: 'import_declaration' }, insertText: 'import "${1:package}"', overview: 'import "package"', detail: makeBasicMarkdownString({ @@ -89,7 +91,7 @@ export const importStatement: DefinitionDocumentationItem = { export const functionDeclaration: DefinitionDocumentationItem = { categories: [categories.control.declaration], kind: DefinitionKind.Statement, - definition: { name: 'func_declaration' }, // TODO + definition: { name: 'func_declaration' }, insertText: 'func ${1:name}(${2:params}) ${3:returnType} {\n\t${4}\n}', overview: 'func name(params) {}', detail: makeBasicMarkdownString({ diff --git a/spx-gui/src/components/editor/code-editor/document-base/spx/index.ts b/spx-gui/src/components/editor/code-editor/document-base/spx/index.ts index 10bb1d690..3074ee34a 100644 --- a/spx-gui/src/components/editor/code-editor/document-base/spx/index.ts +++ b/spx-gui/src/components/editor/code-editor/document-base/spx/index.ts @@ -1086,15 +1086,15 @@ export const startBackdrop1: DefinitionDocumentationItem = { name: 'Game.startBackdrop', overloadId: '1' }, - insertText: 'startBackdrop ${1:name}, ${2:wait}', - overview: 'startBackdrop name, wait', + insertText: 'startBackdrop ${1:name}, ${2:true}', + overview: 'startBackdrop name, true', detail: makeBasicMarkdownString({ - en: 'Set the current backdrop by specifying name, with waiting, e.g., `startBackdrop "backdrop1", true`', - zh: '通过指定名称切换背景,并等待切换完成,如:`startBackdrop "backdrop1", true`' + en: 'Set the current backdrop by specifying name, with waiting for related (`onBackdrop`) works to complete, e.g., `startBackdrop "backdrop1", true`', + zh: '通过指定名称切换背景,并等待关联的(`onBackdrop`)行为结束,如:`startBackdrop "backdrop1", true`' }) } -export const nextBackdrop: DefinitionDocumentationItem = { +export const nextBackdrop0: DefinitionDocumentationItem = { categories: [categories.look.backdrop], kind: DefinitionKind.Command, definition: { @@ -1110,7 +1110,23 @@ export const nextBackdrop: DefinitionDocumentationItem = { }) } -export const prevBackdrop: DefinitionDocumentationItem = { +export const nextBackdrop1: DefinitionDocumentationItem = { + categories: [categories.look.backdrop], + kind: DefinitionKind.Command, + definition: { + package: packageSpx, + name: 'Game.nextBackdrop', + overloadId: '1' + }, + insertText: 'nextBackdrop ${2:true}', + overview: 'nextBackdrop true', + detail: makeBasicMarkdownString({ + en: 'Switch to the next backdrop, with waiting for related (`onBackdrop`) works to complete', + zh: '切换到下一个背景,并等待关联的(`onBackdrop`)行为结束' + }) +} + +export const prevBackdrop0: DefinitionDocumentationItem = { categories: [categories.look.backdrop], kind: DefinitionKind.Command, definition: { @@ -1119,13 +1135,30 @@ export const prevBackdrop: DefinitionDocumentationItem = { overloadId: '0' }, insertText: 'prevBackdrop', - overview: 'prevBackdrop', // TODO: optional argument `wait` + overview: 'prevBackdrop', detail: makeBasicMarkdownString({ en: 'Switch to the previous backdrop', zh: '切换到上一个背景' }) } +export const prevBackdrop1: DefinitionDocumentationItem = { + categories: [categories.look.backdrop], + kind: DefinitionKind.Command, + definition: { + package: packageSpx, + name: 'Game.prevBackdrop', + overloadId: '1' + }, + insertText: 'prevBackdrop ${1:true}', + overview: 'prevBackdrop true', + detail: makeBasicMarkdownString({ + en: 'Switch to the previous backdrop, with waiting for related (`onBackdrop`) works to complete', + zh: '切换到上一个背景,并等待关联的(`onBackdrop`)行为结束' + }) +} + + export const keyPressed: DefinitionDocumentationItem = { categories: [categories.sensing.keyboard], kind: DefinitionKind.Read, @@ -1381,11 +1414,11 @@ export const broadcast1: DefinitionDocumentationItem = { name: 'Game.broadcast', overloadId: '1' }, - insertText: 'broadcast ${1:"msg"}, ${2:wait}', - overview: 'broadcast msg, wait', + insertText: 'broadcast ${1:"msg"}, ${2:true}', + overview: 'broadcast msg, true', detail: makeBasicMarkdownString({ - en: 'Broadcast a message with waiting, e.g., `broadcast "msg", true`', - zh: '广播一条消息并等待,如:`broadcast "msg", true`' + en: 'Broadcast a message with waiting for related (`onMsg`) works to complete, e.g., `broadcast "msg", true`', + zh: '广播一条消息并等待关联的(`onMsg`)行为结束,如:`broadcast "msg", true`' }) } @@ -1397,11 +1430,11 @@ export const broadcast2: DefinitionDocumentationItem = { name: 'Game.broadcast', overloadId: '2' }, - insertText: 'broadcast ${1:"msg"}, ${2:data}, ${3:wait}', - overview: 'broadcast msg, data, wait', + insertText: 'broadcast ${1:"msg"}, ${2:data}, ${3:true}', + overview: 'broadcast msg, data, true', detail: makeBasicMarkdownString({ - en: 'Broadcast a message with data and waiting, e.g., `broadcast "msg", data, true`', - zh: '广播一条消息(带有数据)并等待,如:`broadcast "msg", data, true`' + en: 'Broadcast a message with data and waiting for related (`onMsg`) works to complete, e.g., `broadcast "msg", data, true`', + zh: '广播一条带数据的消息并等待关联的(`onMsg`)行为结束,如:`broadcast "msg", data, true`' }) } diff --git a/spx-gui/src/components/editor/code-editor/monaco.ts b/spx-gui/src/components/editor/code-editor/monaco.ts index fcadf19be..8cd385901 100644 --- a/spx-gui/src/components/editor/code-editor/monaco.ts +++ b/spx-gui/src/components/editor/code-editor/monaco.ts @@ -50,8 +50,5 @@ export async function getMonaco(lang: Lang) { if (monacoPromise != null) return monacoPromise // now refreshing page required if lang changed loader.config(getLoaderConfig(lang)) - return (monacoPromise = loader.init().then((monaco) => { - // TODO: do general configuration for monaco here - return monaco - })) + return (monacoPromise = loader.init()) } diff --git a/spx-gui/src/components/editor/code-editor/text-document.ts b/spx-gui/src/components/editor/code-editor/text-document.ts index 15f249f40..8e893e34c 100644 --- a/spx-gui/src/components/editor/code-editor/text-document.ts +++ b/spx-gui/src/components/editor/code-editor/text-document.ts @@ -189,12 +189,12 @@ export class TextDocument pushEdits(edits: TextEdit[]): void { this.withChangeKindProgram(() => { this.monacoTextModel.pushEditOperations( - null, // TODO + null, edits.map((edit) => ({ range: toMonacoRange(edit.range), text: edit.newText })), - () => null // TODO + () => null ) }) } diff --git a/spx-gui/src/components/editor/code-editor/ui/CodeEditorUI.vue b/spx-gui/src/components/editor/code-editor/ui/CodeEditorUI.vue index 45f6f13f7..9275e60c5 100644 --- a/spx-gui/src/components/editor/code-editor/ui/CodeEditorUI.vue +++ b/spx-gui/src/components/editor/code-editor/ui/CodeEditorUI.vue @@ -23,7 +23,7 @@ import { onDeactivated, onActivated } from 'vue' -import { computedShallowReactive, untilNotNull, useLocalStorage } from '@/utils/utils' +import { computedShallowReactive, untilNotNull, localStorageRef } from '@/utils/utils' import { getCleanupSignal } from '@/utils/disposable' import { theme, tabSize, insertSpaces } from '@/utils/spx/highlighter' import { useI18n } from '@/utils/i18n' @@ -128,7 +128,7 @@ const uiRef = computed(() => { }) const initialFontSize = 12 -const fontSize = useLocalStorage('spx-gui-code-font-size', initialFontSize) +const fontSize = localStorageRef('spx-gui-code-font-size', initialFontSize) const monacoEditorOptions = computed(() => ({ language: 'spx', @@ -193,7 +193,7 @@ const minSidebarWidth = 160 // px const minMonacoEditorWidth = 200 // px const codeEditorEl = ref() const resizeHandleEl = ref() -const sidebarWidth = useLocalStorage('spx-code-editor-sidebar-width', defaultSidebarWidth) +const sidebarWidth = localStorageRef('spx-code-editor-sidebar-width', defaultSidebarWidth) const isResizing = ref(false) watchEffect((onCleanup) => { @@ -253,7 +253,7 @@ function zoomReset() { -
+
{ - codeEditorCtx.ui.insertSnippet(props.item.insertText) - codeEditorCtx.ui.editor.focus() - }, + () => codeEditorCtx.ui.insertSnippet(props.item.insertText), { en: 'Failed to insert', zh: '插入失败' } ).fn diff --git a/spx-gui/src/components/editor/code-editor/ui/api-reference/APIReferenceUI.vue b/spx-gui/src/components/editor/code-editor/ui/api-reference/APIReferenceUI.vue index 901444809..e1bd6b1b4 100644 --- a/spx-gui/src/components/editor/code-editor/ui/api-reference/APIReferenceUI.vue +++ b/spx-gui/src/components/editor/code-editor/ui/api-reference/APIReferenceUI.vue @@ -226,7 +226,7 @@ function handleCategoryClick(id: string) { if (categoryWrapper == null) return itemsWrapper.scrollTo({ top: (categoryWrapper as HTMLElement).offsetTop, - behavior: 'smooth' // TODO: scroll faster? + behavior: 'smooth' }) } diff --git a/spx-gui/src/components/editor/code-editor/ui/code-editor-ui.ts b/spx-gui/src/components/editor/code-editor/ui/code-editor-ui.ts index fe5365143..f82e036ae 100644 --- a/spx-gui/src/components/editor/code-editor/ui/code-editor-ui.ts +++ b/spx-gui/src/components/editor/code-editor/ui/code-editor-ui.ts @@ -251,9 +251,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { return range } - // TODO: Optimize inserting logic with inline context. For example: - // * If no space before cursor, insert a space before inserting snippet. - // * If current line isn't empty, insert a new line before inserting snippet for kind Command or Listen. + // TODO: Optimize inserting logic with inline context. https://github.com/goplus/builder/issues/1258 async insertText(text: string, range: Range = this.getSelectionRange()) { this.activeTextDocument?.pushEdits([ @@ -262,6 +260,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { newText: text } ]) + this.editor.focus() } async insertSnippet(snippet: string, range: Range = this.getSelectionRange()) { @@ -280,6 +279,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { const contribution = editor.getContribution('snippetController2') if (contribution == null) throw new Error('Snippet contribution not found') ;(contribution as any).insert(snippet) + this.editor.focus() } private cursorPositionRef = shallowRef(null) @@ -326,7 +326,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { ) this.registerCommand(builtInCommandCopilotInspire, { - icon: 'explain', // TODO + icon: 'copilot', title: { en: 'Ask copilot', zh: '向 Copilot 提问' }, handler: (problem) => { this.copilotController.startChat({ @@ -348,7 +348,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { }) this.registerCommand(builtInCommandCopilotReview, { - icon: 'explain', // TODO + icon: 'explain', // TODO: Add specific icon for review when it is needed title: { en: 'Review', zh: '审查' }, handler: (target) => { this.copilotController.startChat({ @@ -373,7 +373,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { // while these actions are missing in the `editor.getSupportedActions()`, see details in https://github.com/microsoft/monaco-editor/issues/2598. // As a workaround, we use `document.execCommand` to implement these actions. this.registerCommand(builtInCommandCopy, { - icon: 'explain', // TODO + icon: 'copy', title: { en: 'Copy', zh: '复制' }, handler: () => { editor.focus() @@ -381,7 +381,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { } }) this.registerCommand(builtInCommandCut, { - icon: 'explain', // TODO + icon: 'copy', // TODO: Add specific icon for cut when it is needed title: { en: 'Cut', zh: '剪切' }, handler: () => { editor.focus() @@ -389,7 +389,7 @@ export class CodeEditorUI extends Disposable implements ICodeEditorUI { } }) this.registerCommand(builtInCommandPaste, { - icon: 'explain', // TODO + icon: 'copy', // TODO: Add specific icon for paste when it is needed title: { en: 'Paste', zh: '粘贴' }, handler: async () => { try { diff --git a/spx-gui/src/components/editor/code-editor/ui/command/CommandIcon.vue b/spx-gui/src/components/editor/code-editor/ui/command/CommandIcon.vue index 3f0478a26..a1a705d0b 100644 --- a/spx-gui/src/components/editor/code-editor/ui/command/CommandIcon.vue +++ b/spx-gui/src/components/editor/code-editor/ui/command/CommandIcon.vue @@ -5,6 +5,8 @@ import iconFix from './fix.svg?raw' import iconGoto from './goto.svg?raw' import iconModify from './modify.svg?raw' import iconRename from './rename.svg?raw' +import iconCopy from './copy.svg?raw' +import iconCopilot from '../copilot/logo-simple.svg?raw' defineProps<{ type: CommandIconType @@ -15,7 +17,9 @@ const typeIconMap = { fix: iconFix, goto: iconGoto, modify: iconModify, - rename: iconRename + rename: iconRename, + copy: iconCopy, + copilot: iconCopilot } diff --git a/spx-gui/src/components/editor/code-editor/ui/command/copy.svg b/spx-gui/src/components/editor/code-editor/ui/command/copy.svg new file mode 100644 index 000000000..517c5762b --- /dev/null +++ b/spx-gui/src/components/editor/code-editor/ui/command/copy.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/spx-gui/src/components/editor/code-editor/ui/common.ts b/spx-gui/src/components/editor/code-editor/ui/common.ts index fa3174616..c0591e10d 100644 --- a/spx-gui/src/components/editor/code-editor/ui/common.ts +++ b/spx-gui/src/components/editor/code-editor/ui/common.ts @@ -61,7 +61,6 @@ export function toMonacoSelection(selection: Selection): monaco.ISelection { } export function fromMonacoUri(uri: monaco.Uri): TextDocumentIdentifier { - // TODO: check if this is correct return { uri: uri.toString() } } diff --git a/spx-gui/src/components/editor/code-editor/ui/completion/CompletionItem.vue b/spx-gui/src/components/editor/code-editor/ui/completion/CompletionItem.vue index d4757fc3f..500ae2c33 100644 --- a/spx-gui/src/components/editor/code-editor/ui/completion/CompletionItem.vue +++ b/spx-gui/src/components/editor/code-editor/ui/completion/CompletionItem.vue @@ -76,7 +76,6 @@ watchEffect(() => { } .matched { - // TODO: reconfirm color here color: var(--ui-color-primary-main); } diff --git a/spx-gui/src/components/editor/code-editor/ui/completion/index.ts b/spx-gui/src/components/editor/code-editor/ui/completion/index.ts index 511b548bf..832bbd5f0 100644 --- a/spx-gui/src/components/editor/code-editor/ui/completion/index.ts +++ b/spx-gui/src/components/editor/code-editor/ui/completion/index.ts @@ -139,7 +139,7 @@ export class CompletionController extends Emitter<{ } async applyCompletionItem(item: InternalCompletionItem) { - const { editor, cursorPosition } = this.ui + const { cursorPosition } = this.ui if (this.completion == null) return const { wordStart, position } = this.completion if (!positionEq(cursorPosition, position)) return @@ -152,7 +152,6 @@ export class CompletionController extends Emitter<{ await this.ui.insertSnippet(item.insertText, range) } this.stopCompletion() - editor.focus() } init() { diff --git a/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotInput.vue b/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotInput.vue index f73e20c7b..6d7d78eb4 100644 --- a/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotInput.vue +++ b/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotInput.vue @@ -24,7 +24,7 @@ const placeholder = computed(() => { function handleSubmit() { const problem = inputStr.value.trim() - if (problem === '') return // TODO: show hint? + if (problem === '') return inputStr.value = '' if (props.controller.currentChat == null) { props.controller.startChat({ diff --git a/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotTrigger.vue b/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotTrigger.vue index fa185231e..2e4e93393 100644 --- a/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotTrigger.vue +++ b/spx-gui/src/components/editor/code-editor/ui/copilot/CopilotTrigger.vue @@ -1,13 +1,11 @@ - +