@@ -27,6 +27,7 @@ import {
2727} from '@opensumi/ide-core-browser' ;
2828import {
2929 AI_CHAT_VISIBLE ,
30+ AI_INLINE_CHAT_INTERACTIVE_INPUT_CANCEL ,
3031 AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE ,
3132 AI_INLINE_CHAT_VISIBLE ,
3233 AI_INLINE_COMPLETION_REPORTER ,
@@ -37,6 +38,7 @@ import {
3738 InlineChatIsVisible ,
3839 InlineDiffPartialEditsIsVisible ,
3940 InlineHintWidgetIsVisible ,
41+ InlineInputWidgetIsStreaming ,
4042 InlineInputWidgetIsVisible ,
4143} from '@opensumi/ide-core-browser/lib/contextkey/ai-native' ;
4244import { DesignLayoutConfig } from '@opensumi/ide-core-browser/lib/layout/constants' ;
@@ -56,8 +58,9 @@ import {
5658 runWhenIdle ,
5759} from '@opensumi/ide-core-common' ;
5860import { DESIGN_MENU_BAR_RIGHT } from '@opensumi/ide-design' ;
59- import { IEditor } from '@opensumi/ide-editor' ;
61+ import { IEditor , WorkbenchEditorService } from '@opensumi/ide-editor' ;
6062import { BrowserEditorContribution , IEditorFeatureRegistry } from '@opensumi/ide-editor/lib/browser' ;
63+ import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service' ;
6164import { IMainLayoutService } from '@opensumi/ide-main-layout' ;
6265import { ISettingRegistry , SettingContribution } from '@opensumi/ide-preferences' ;
6366import { EditorContributionInstantiation } from '@opensumi/monaco-editor-core/esm/vs/editor/browser/editorExtensions' ;
@@ -101,11 +104,11 @@ import {
101104} from './types' ;
102105import { InlineChatEditorController } from './widget/inline-chat/inline-chat-editor.controller' ;
103106import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry' ;
104- import { AIInlineChatService } from './widget/inline-chat/inline-chat.service' ;
107+ import { InlineChatService } from './widget/inline-chat/inline-chat.service' ;
105108import { InlineDiffController } from './widget/inline-diff/inline-diff.controller' ;
106109import { InlineHintController } from './widget/inline-hint/inline-hint.controller' ;
107110import { InlineInputController } from './widget/inline-input/inline-input.controller' ;
108- import { InlineInputChatService } from './widget/inline-input/inline-input.service' ;
111+ import { InlineInputService } from './widget/inline-input/inline-input.service' ;
109112import { InlineStreamDiffService } from './widget/inline-stream-diff/inline-stream-diff.service' ;
110113import { SumiLightBulbWidget } from './widget/light-bulb' ;
111114
@@ -191,10 +194,10 @@ export class AINativeBrowserContribution
191194 private readonly chatProxyService : ChatProxyService ;
192195
193196 @Autowired ( IAIInlineChatService )
194- private readonly aiInlineChatService : AIInlineChatService ;
197+ private readonly aiInlineChatService : InlineChatService ;
195198
196- @Autowired ( InlineInputChatService )
197- private readonly inlineInputChatService : InlineInputChatService ;
199+ @Autowired ( InlineInputService )
200+ private readonly inlineInputService : InlineInputService ;
198201
199202 @Autowired ( InlineStreamDiffService )
200203 private readonly inlineStreamDiffService : InlineStreamDiffService ;
@@ -205,6 +208,9 @@ export class AINativeBrowserContribution
205208 @Autowired ( CodeActionSingleHandler )
206209 private readonly codeActionSingleHandler : CodeActionSingleHandler ;
207210
211+ @Autowired ( WorkbenchEditorService )
212+ private readonly workbenchEditorService : WorkbenchEditorServiceImpl ;
213+
208214 constructor ( ) {
209215 this . registerFeature ( ) ;
210216 }
@@ -237,7 +243,7 @@ export class AINativeBrowserContribution
237243 EditorContributionInstantiation . BeforeFirstInteraction ,
238244 ) ;
239245
240- if ( this . inlineChatFeatureRegistry . getInteractiveInputHandler ( ) ) {
246+ if ( this . inlineInputService . getInteractiveInputHandler ( ) ) {
241247 register (
242248 InlineHintController . ID ,
243249 new SyncDescriptor ( InlineHintController , [ this . injector ] ) ,
@@ -418,14 +424,48 @@ export class AINativeBrowserContribution
418424 } ) ;
419425
420426 commands . registerCommand ( AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE , {
421- execute : ( isVisible : boolean ) => {
422- if ( isVisible ) {
423- this . inlineInputChatService . visible ( ) ;
424- } else {
425- this . inlineInputChatService . hide ( ) ;
427+ execute : async ( isVisible : boolean ) => {
428+ if ( ! isVisible ) {
429+ this . inlineInputService . hide ( ) ;
430+ return ;
431+ }
432+
433+ // 每次在展示 inline input 的时候,先隐藏 inline chat
434+ this . commandService . executeCommand ( AI_INLINE_CHAT_VISIBLE . id , false ) ;
435+
436+ const editor = this . workbenchEditorService . currentCodeEditor ;
437+ if ( ! editor ) {
438+ return ;
439+ }
440+
441+ const position = editor . monacoEditor . getPosition ( ) ;
442+ if ( ! position ) {
443+ return ;
444+ }
445+
446+ const selection = editor . monacoEditor . getSelection ( ) ;
447+ const isEmptyLine = position ? editor . monacoEditor . getModel ( ) ?. getLineLength ( position . lineNumber ) === 0 : false ;
448+
449+ if ( isEmptyLine ) {
450+ this . inlineInputService . visibleByPosition ( position ) ;
451+ return ;
426452 }
427453
428- this . aiInlineChatService . _onInteractiveInputVisible . fire ( isVisible ) ;
454+ if ( selection && ! selection . isEmpty ( ) ) {
455+ this . inlineInputService . visibleBySelection ( selection ) ;
456+ return ;
457+ }
458+
459+ this . inlineInputService . visibleByNearestCodeBlock ( position , editor . monacoEditor ) ;
460+ } ,
461+ } ) ;
462+
463+ commands . registerCommand ( AI_INLINE_CHAT_INTERACTIVE_INPUT_CANCEL , {
464+ execute : ( ) => {
465+ const editor = this . workbenchEditorService . currentCodeEditor ;
466+ if ( editor ) {
467+ InlineInputController . get ( editor . monacoEditor ) ?. cancelToken ( ) ;
468+ }
429469 } ,
430470 } ) ;
431471
@@ -516,12 +556,12 @@ export class AINativeBrowserContribution
516556 when : `editorFocus && ${ InlineChatIsVisible . raw } ` ,
517557 } ) ;
518558
519- if ( this . inlineChatFeatureRegistry . getInteractiveInputHandler ( ) ) {
559+ if ( this . inlineInputService . getInteractiveInputHandler ( ) ) {
520560 // 当 Inline Chat (浮动组件)展示时,通过 CMD K 唤起 Inline Input
521561 keybindings . registerKeybinding (
522562 {
523563 command : AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE . id ,
524- keybinding : 'ctrlcmd+k' ,
564+ keybinding : this . aiNativeConfigService . inlineChat . inputKeybinding ,
525565 args : true ,
526566 priority : 0 ,
527567 when : `editorFocus && (${ InlineChatIsVisible . raw } || inlineSuggestionVisible)` ,
@@ -536,11 +576,18 @@ export class AINativeBrowserContribution
536576 priority : 0 ,
537577 when : `editorFocus && ${ InlineInputWidgetIsVisible . raw } ` ,
538578 } ) ;
579+ // 当 Inline Input 流式编辑时,通过 ESC 退出
580+ keybindings . registerKeybinding ( {
581+ command : AI_INLINE_CHAT_INTERACTIVE_INPUT_CANCEL . id ,
582+ keybinding : 'esc' ,
583+ priority : 1 ,
584+ when : `editorFocus && ${ InlineInputWidgetIsStreaming . raw } ` ,
585+ } ) ;
539586 // 当出现 CMD K 展示信息时,通过快捷键快速唤起 Inline Input
540587 keybindings . registerKeybinding (
541588 {
542589 command : AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE . id ,
543- keybinding : 'ctrlcmd+k' ,
590+ keybinding : this . aiNativeConfigService . inlineChat . inputKeybinding ,
544591 args : true ,
545592 priority : 0 ,
546593 when : `editorFocus && ${ InlineHintWidgetIsVisible . raw } && ${ InlineChatIsVisible . not } ` ,
0 commit comments