From 7bc4dac9ac7c068a1be8b1efaa6fe8f209f674eb Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Thu, 23 Oct 2025 19:59:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20AI=E4=BB=A3=E7=A0=81=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inline-completions/inline-completions.ts | 53 +++++++++++++------ .../inline-completions/worker-manager.ts | 1 + packages/ai-code/src/module/interface.ts | 6 +++ .../src/monaco-editor/monaco-editor.tsx | 9 +++- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/packages/ai-code/src/module/inline-completions/inline-completions.ts b/packages/ai-code/src/module/inline-completions/inline-completions.ts index c22a2e74..0044f1ba 100644 --- a/packages/ai-code/src/module/inline-completions/inline-completions.ts +++ b/packages/ai-code/src/module/inline-completions/inline-completions.ts @@ -1,4 +1,5 @@ /* eslint-disable no-useless-escape */ +/* eslint-disable no-bitwise */ import { calcResPath } from '@ibiz-template/runtime'; import * as IMonaco from 'monaco-editor'; import { createUUID } from 'qx-util'; @@ -203,10 +204,10 @@ export class InlineCompletions { const disposable = this.monaco.languages.registerInlineCompletionsProvider( this.config.language, { - provideInlineCompletions: async (model, position) => { + provideInlineCompletions: async (model, position, context) => { this.visible = false; // 校验 - if (!this.validate(model, position)) return { items: [] }; + if (!this.validate(model, position, context)) return { items: [] }; // 清除之前的计时器 if (this.debounceTimer) { @@ -219,22 +220,22 @@ export class InlineCompletions { const completion = await this.getCompletion(model, position); if (!completion) { resolve({ items: [] }); - return; + } else { + this.visible = true; + resolve({ + items: [ + { + insertText: completion, + range: new this.monaco.Range( + position.lineNumber, + position.column, + position.lineNumber, + position.column, + ), + }, + ], + }); } - this.visible = true; - resolve({ - items: [ - { - insertText: completion, - range: new this.monaco.Range( - position.lineNumber, - position.column, - position.lineNumber, - position.column, - ), - }, - ], - }); }, 1000); }); }, @@ -252,6 +253,19 @@ export class InlineCompletions { this.editor.trigger(null, 'tab', {}); } }); + + // Alt + P 触发代码补全 + this.editor.addCommand( + this.monaco.KeyMod.Alt | this.monaco.KeyCode.KeyP, + () => { + this.editor.trigger('keyboard', 'editor.action.inlineSuggest.trigger', { + // 标记触发类型:手动 + triggerType: 'manual', + triggerKey: 'Alt+P', + }); + }, + ); + // 编辑器销毁时清理资源 this.editor.onDidDispose(() => { disposable.dispose(); @@ -268,6 +282,7 @@ export class InlineCompletions { private validate( model: IMonaco.editor.ITextModel, position: IMonaco.Position, + context: IMonaco.languages.InlineCompletionContext, ): boolean { const currentEditor = this.monaco.editor .getEditors() @@ -278,6 +293,8 @@ export class InlineCompletions { (currentEditor as IData).__inlineCompletionsId !== this.UUID ) return false; + // 手动触发的不需要校验 + if (context.triggerKind === 1) return true; const lineContent = model.getLineContent(position.lineNumber).trim(); const languageId = model.getLanguageId(); // 校验注释行 @@ -440,6 +457,7 @@ export class InlineCompletions { private buildMessages(context: ICompletionContext): IData { const { currentLine, aboveLines, belowLines, languageId, position } = context; + const { inlinecompletionmode } = this.config; const above = `\`\`\`${languageId} \n ${aboveLines} \n \`\`\``; const current = `\`\`\`${languageId} \n ${currentLine} \n \`\`\``; const below = `\`\`\`${languageId} \n ${belowLines} \n \`\`\``; @@ -453,6 +471,7 @@ export class InlineCompletions { },请基于以上上下文,在光标处提供最合适的代码补全建议。`, }, ], + inlinecompletionmode, }; } diff --git a/packages/ai-code/src/module/inline-completions/worker-manager.ts b/packages/ai-code/src/module/inline-completions/worker-manager.ts index 17ea994e..9755434d 100644 --- a/packages/ai-code/src/module/inline-completions/worker-manager.ts +++ b/packages/ai-code/src/module/inline-completions/worker-manager.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /** * @description worker 消息接口 * @export diff --git a/packages/ai-code/src/module/interface.ts b/packages/ai-code/src/module/interface.ts index e56da8b2..485ec968 100644 --- a/packages/ai-code/src/module/interface.ts +++ b/packages/ai-code/src/module/interface.ts @@ -70,6 +70,12 @@ export interface IConfig { * @memberof IConfig */ enableAICompletion: boolean; + /** + * @description 行内补全模式 + * @type {string} + * @memberof IConfig + */ + inlinecompletionmode?: string; /** * 全局变量映射 * diff --git a/packages/ai-code/src/monaco-editor/monaco-editor.tsx b/packages/ai-code/src/monaco-editor/monaco-editor.tsx index 3d10da06..672484ea 100644 --- a/packages/ai-code/src/monaco-editor/monaco-editor.tsx +++ b/packages/ai-code/src/monaco-editor/monaco-editor.tsx @@ -33,8 +33,8 @@ import { import { CodeEditorController } from '../code-editor.controller'; import { calcAiToolbarItemsByAc } from '../util'; import { CodeModuleCenter } from '../module'; -import './monaco-editor.scss'; import { Monaco } from '../module/interface'; +import './monaco-editor.scss'; export const IBizAICode = defineComponent({ name: 'IBizAICode', @@ -80,6 +80,8 @@ export const IBizAICode = defineComponent({ // 全局变量映射 let globalVariable = ''; + let envlanguag = ibiz.i18n.getLang().toLowerCase(); + const editorModel = c.model; if (editorModel.editorParams) { if (editorModel.editorParams.enableEdit) { @@ -104,6 +106,9 @@ export const IBizAICode = defineComponent({ ) { inlinecompletionmode = editorModel.editorParams.completionmode; } + if (editorModel.editorParams.envlanguag) { + envlanguag = editorModel.editorParams.envlanguag; + } if (editorModel.editorParams.GLOBALVARIABLE) { globalVariable = editorModel.editorParams.GLOBALVARIABLE; } @@ -535,6 +540,7 @@ export const IBizAICode = defineComponent({ paths: { vs: `${ibiz.env.pluginBaseUrl}/monaco-editor@0.52.2/min/vs`, }, + 'vs/nls': { availableLanguages: { '*': envlanguag } }, }); loader .init() @@ -550,6 +556,7 @@ export const IBizAICode = defineComponent({ params: c.params, context: c.context, deACMode: c.deACMode, + inlinecompletionmode, enableAICompletion: ['all', 'inline'].includes(completionmode), appDataEntityId: c.model.appDataEntityId, language: props.language || props.controller.language, -- Gitee