@@ -27,6 +27,7 @@ import {
27
27
} from '@opensumi/ide-core-browser' ;
28
28
import {
29
29
AI_CHAT_VISIBLE ,
30
+ AI_INLINE_CHAT_INTERACTIVE_INPUT_CANCEL ,
30
31
AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE ,
31
32
AI_INLINE_CHAT_VISIBLE ,
32
33
AI_INLINE_COMPLETION_REPORTER ,
@@ -37,6 +38,7 @@ import {
37
38
InlineChatIsVisible ,
38
39
InlineDiffPartialEditsIsVisible ,
39
40
InlineHintWidgetIsVisible ,
41
+ InlineInputWidgetIsStreaming ,
40
42
InlineInputWidgetIsVisible ,
41
43
} from '@opensumi/ide-core-browser/lib/contextkey/ai-native' ;
42
44
import { DesignLayoutConfig } from '@opensumi/ide-core-browser/lib/layout/constants' ;
@@ -56,8 +58,9 @@ import {
56
58
runWhenIdle ,
57
59
} from '@opensumi/ide-core-common' ;
58
60
import { DESIGN_MENU_BAR_RIGHT } from '@opensumi/ide-design' ;
59
- import { IEditor } from '@opensumi/ide-editor' ;
61
+ import { IEditor , WorkbenchEditorService } from '@opensumi/ide-editor' ;
60
62
import { BrowserEditorContribution , IEditorFeatureRegistry } from '@opensumi/ide-editor/lib/browser' ;
63
+ import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service' ;
61
64
import { IMainLayoutService } from '@opensumi/ide-main-layout' ;
62
65
import { ISettingRegistry , SettingContribution } from '@opensumi/ide-preferences' ;
63
66
import { EditorContributionInstantiation } from '@opensumi/monaco-editor-core/esm/vs/editor/browser/editorExtensions' ;
@@ -101,11 +104,11 @@ import {
101
104
} from './types' ;
102
105
import { InlineChatEditorController } from './widget/inline-chat/inline-chat-editor.controller' ;
103
106
import { 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' ;
105
108
import { InlineDiffController } from './widget/inline-diff/inline-diff.controller' ;
106
109
import { InlineHintController } from './widget/inline-hint/inline-hint.controller' ;
107
110
import { 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' ;
109
112
import { InlineStreamDiffService } from './widget/inline-stream-diff/inline-stream-diff.service' ;
110
113
import { SumiLightBulbWidget } from './widget/light-bulb' ;
111
114
@@ -191,10 +194,10 @@ export class AINativeBrowserContribution
191
194
private readonly chatProxyService : ChatProxyService ;
192
195
193
196
@Autowired ( IAIInlineChatService )
194
- private readonly aiInlineChatService : AIInlineChatService ;
197
+ private readonly aiInlineChatService : InlineChatService ;
195
198
196
- @Autowired ( InlineInputChatService )
197
- private readonly inlineInputChatService : InlineInputChatService ;
199
+ @Autowired ( InlineInputService )
200
+ private readonly inlineInputService : InlineInputService ;
198
201
199
202
@Autowired ( InlineStreamDiffService )
200
203
private readonly inlineStreamDiffService : InlineStreamDiffService ;
@@ -205,6 +208,9 @@ export class AINativeBrowserContribution
205
208
@Autowired ( CodeActionSingleHandler )
206
209
private readonly codeActionSingleHandler : CodeActionSingleHandler ;
207
210
211
+ @Autowired ( WorkbenchEditorService )
212
+ private readonly workbenchEditorService : WorkbenchEditorServiceImpl ;
213
+
208
214
constructor ( ) {
209
215
this . registerFeature ( ) ;
210
216
}
@@ -237,7 +243,7 @@ export class AINativeBrowserContribution
237
243
EditorContributionInstantiation . BeforeFirstInteraction ,
238
244
) ;
239
245
240
- if ( this . inlineChatFeatureRegistry . getInteractiveInputHandler ( ) ) {
246
+ if ( this . inlineInputService . getInteractiveInputHandler ( ) ) {
241
247
register (
242
248
InlineHintController . ID ,
243
249
new SyncDescriptor ( InlineHintController , [ this . injector ] ) ,
@@ -418,14 +424,48 @@ export class AINativeBrowserContribution
418
424
} ) ;
419
425
420
426
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 ;
426
452
}
427
453
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
+ }
429
469
} ,
430
470
} ) ;
431
471
@@ -516,12 +556,12 @@ export class AINativeBrowserContribution
516
556
when : `editorFocus && ${ InlineChatIsVisible . raw } ` ,
517
557
} ) ;
518
558
519
- if ( this . inlineChatFeatureRegistry . getInteractiveInputHandler ( ) ) {
559
+ if ( this . inlineInputService . getInteractiveInputHandler ( ) ) {
520
560
// 当 Inline Chat (浮动组件)展示时,通过 CMD K 唤起 Inline Input
521
561
keybindings . registerKeybinding (
522
562
{
523
563
command : AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE . id ,
524
- keybinding : 'ctrlcmd+k' ,
564
+ keybinding : this . aiNativeConfigService . inlineChat . inputKeybinding ,
525
565
args : true ,
526
566
priority : 0 ,
527
567
when : `editorFocus && (${ InlineChatIsVisible . raw } || inlineSuggestionVisible)` ,
@@ -536,11 +576,18 @@ export class AINativeBrowserContribution
536
576
priority : 0 ,
537
577
when : `editorFocus && ${ InlineInputWidgetIsVisible . raw } ` ,
538
578
} ) ;
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
+ } ) ;
539
586
// 当出现 CMD K 展示信息时,通过快捷键快速唤起 Inline Input
540
587
keybindings . registerKeybinding (
541
588
{
542
589
command : AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE . id ,
543
- keybinding : 'ctrlcmd+k' ,
590
+ keybinding : this . aiNativeConfigService . inlineChat . inputKeybinding ,
544
591
args : true ,
545
592
priority : 0 ,
546
593
when : `editorFocus && ${ InlineHintWidgetIsVisible . raw } && ${ InlineChatIsVisible . not } ` ,
0 commit comments