@opensumi/ide-ai-native 3.7.1-next-1739439717.0 → 3.7.1-next-1739448958.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/ai-core.contextkeys.d.ts +1 -0
- package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
- package/lib/browser/ai-core.contextkeys.js +1 -0
- package/lib/browser/ai-core.contextkeys.js.map +1 -1
- package/lib/browser/ai-core.contribution.d.ts +2 -1
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +55 -14
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +26 -4
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts +3 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +9 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/base.d.ts +1 -2
- package/lib/browser/contrib/intelligent-completions/source/base.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/base.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts +2 -3
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.js +51 -21
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.js.map +1 -1
- package/lib/browser/index.js +1 -1
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/layout/ai-layout.d.ts.map +1 -1
- package/lib/browser/layout/ai-layout.js +2 -2
- package/lib/browser/layout/ai-layout.js.map +1 -1
- package/lib/browser/model/enhanceDecorationsCollection.d.ts +14 -10
- package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
- package/lib/browser/model/enhanceDecorationsCollection.js +42 -53
- package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
- package/lib/browser/types.d.ts +2 -1
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts +2 -1
- package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js +13 -41
- package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts +3 -13
- package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js +24 -72
- package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat.service.d.ts +1 -6
- package/lib/browser/widget/inline-chat/inline-chat.service.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat.service.js +5 -19
- package/lib/browser/widget/inline-chat/inline-chat.service.js.map +1 -1
- package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +2 -5
- package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-content-widget.js +17 -42
- package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +22 -5
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js +61 -30
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +8 -12
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.js +68 -96
- package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
- package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts +0 -1
- package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-hint/inline-hint.controller.js +0 -5
- package/lib/browser/widget/inline-hint/inline-hint.controller.js.map +1 -1
- package/lib/browser/widget/inline-input/inline-input-widget.d.ts +12 -2
- package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
- package/lib/browser/widget/inline-input/inline-input-widget.js +26 -18
- package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
- package/lib/browser/widget/inline-input/inline-input.controller.d.ts +14 -6
- package/lib/browser/widget/inline-input/inline-input.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-input/inline-input.controller.js +320 -169
- package/lib/browser/widget/inline-input/inline-input.controller.js.map +1 -1
- package/lib/browser/widget/inline-input/inline-input.module.less +4 -0
- package/lib/browser/widget/inline-input/inline-input.service.d.ts +19 -7
- package/lib/browser/widget/inline-input/inline-input.service.d.ts.map +1 -1
- package/lib/browser/widget/inline-input/inline-input.service.js +72 -12
- package/lib/browser/widget/inline-input/inline-input.service.js.map +1 -1
- package/lib/browser/widget/inline-input/model.d.ts +34 -0
- package/lib/browser/widget/inline-input/model.d.ts.map +1 -0
- package/lib/browser/widget/inline-input/model.js +63 -0
- package/lib/browser/widget/inline-input/model.js.map +1 -0
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +8 -19
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +48 -41
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +17 -4
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js +37 -5
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +7 -11
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +33 -77
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/package.json +21 -21
- package/src/browser/ai-core.contextkeys.ts +3 -0
- package/src/browser/ai-core.contribution.ts +63 -16
- package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +29 -8
- package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +13 -1
- package/src/browser/contrib/intelligent-completions/source/base.ts +0 -2
- package/src/browser/contrib/intelligent-completions/source/line-change.source.ts +79 -24
- package/src/browser/index.ts +2 -2
- package/src/browser/layout/ai-layout.tsx +5 -2
- package/src/browser/model/enhanceDecorationsCollection.ts +62 -77
- package/src/browser/types.ts +2 -2
- package/src/browser/widget/inline-chat/inline-chat-editor.controller.ts +21 -56
- package/src/browser/widget/inline-chat/inline-chat.feature.registry.ts +23 -90
- package/src/browser/widget/inline-chat/inline-chat.service.ts +2 -19
- package/src/browser/widget/inline-chat/inline-content-widget.tsx +14 -71
- package/src/browser/widget/inline-diff/inline-diff-previewer.ts +87 -32
- package/src/browser/widget/inline-diff/inline-diff.controller.ts +90 -114
- package/src/browser/widget/inline-hint/inline-hint.controller.ts +1 -7
- package/src/browser/widget/inline-input/inline-input-widget.tsx +34 -12
- package/src/browser/widget/inline-input/inline-input.controller.ts +453 -247
- package/src/browser/widget/inline-input/inline-input.module.less +4 -0
- package/src/browser/widget/inline-input/inline-input.service.ts +92 -13
- package/src/browser/widget/inline-input/model.ts +74 -0
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +58 -69
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +45 -6
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +40 -112
- package/lib/browser/model/styles.module.less +0 -7
- package/src/browser/model/styles.module.less +0 -7
|
@@ -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 {
|
|
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 {
|
|
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:
|
|
197
|
+
private readonly aiInlineChatService: InlineChatService;
|
|
195
198
|
|
|
196
|
-
@Autowired(
|
|
197
|
-
private readonly
|
|
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.
|
|
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.
|
|
424
|
-
|
|
425
|
-
|
|
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
|
-
|
|
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.
|
|
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:
|
|
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:
|
|
590
|
+
keybinding: this.aiNativeConfigService.inlineChat.inputKeybinding,
|
|
544
591
|
args: true,
|
|
545
592
|
priority: 0,
|
|
546
593
|
when: `editorFocus && ${InlineHintWidgetIsVisible.raw} && ${InlineChatIsVisible.not}`,
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { Autowired } from '@opensumi/di';
|
|
2
2
|
import {
|
|
3
|
+
AINativeConfigService,
|
|
3
4
|
ClientAppContribution,
|
|
4
5
|
Key,
|
|
5
6
|
KeybindingContribution,
|
|
6
7
|
KeybindingRegistry,
|
|
7
8
|
KeybindingScope,
|
|
8
9
|
} from '@opensumi/ide-core-browser';
|
|
9
|
-
import {
|
|
10
|
-
AI_MULTI_LINE_COMPLETION_ACCEPT,
|
|
11
|
-
AI_MULTI_LINE_COMPLETION_DISCARD,
|
|
12
|
-
} from '@opensumi/ide-core-browser/lib/ai-native/command';
|
|
10
|
+
import { AI_CODE_EDITS_COMMANDS } from '@opensumi/ide-core-browser/lib/ai-native/command';
|
|
13
11
|
import { MultiLineEditsIsVisible } from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
|
|
14
12
|
import { CommandContribution, CommandRegistry, Domain } from '@opensumi/ide-core-common';
|
|
15
13
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
16
14
|
import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service';
|
|
15
|
+
import { transaction } from '@opensumi/ide-monaco/lib/common/observable';
|
|
17
16
|
|
|
18
17
|
import { IntelligentCompletionsController } from './intelligent-completions.controller';
|
|
19
18
|
|
|
@@ -22,8 +21,11 @@ export class IntelligentCompletionsContribution implements KeybindingContributio
|
|
|
22
21
|
@Autowired(WorkbenchEditorService)
|
|
23
22
|
private readonly workbenchEditorService: WorkbenchEditorServiceImpl;
|
|
24
23
|
|
|
24
|
+
@Autowired(AINativeConfigService)
|
|
25
|
+
private readonly aiNativeConfigService: AINativeConfigService;
|
|
26
|
+
|
|
25
27
|
registerCommands(commands: CommandRegistry): void {
|
|
26
|
-
commands.registerCommand(
|
|
28
|
+
commands.registerCommand(AI_CODE_EDITS_COMMANDS.DISCARD, {
|
|
27
29
|
execute: () => {
|
|
28
30
|
const editor = this.workbenchEditorService.currentCodeEditor;
|
|
29
31
|
if (editor) {
|
|
@@ -32,7 +34,7 @@ export class IntelligentCompletionsContribution implements KeybindingContributio
|
|
|
32
34
|
},
|
|
33
35
|
});
|
|
34
36
|
|
|
35
|
-
commands.registerCommand(
|
|
37
|
+
commands.registerCommand(AI_CODE_EDITS_COMMANDS.ACCEPT, {
|
|
36
38
|
execute: () => {
|
|
37
39
|
const editor = this.workbenchEditorService.currentCodeEditor;
|
|
38
40
|
if (editor) {
|
|
@@ -40,11 +42,24 @@ export class IntelligentCompletionsContribution implements KeybindingContributio
|
|
|
40
42
|
}
|
|
41
43
|
},
|
|
42
44
|
});
|
|
45
|
+
|
|
46
|
+
commands.registerCommand(AI_CODE_EDITS_COMMANDS.TRIGGER, {
|
|
47
|
+
execute: () => {
|
|
48
|
+
const editor = this.workbenchEditorService.currentCodeEditor;
|
|
49
|
+
if (editor) {
|
|
50
|
+
transaction((tx) => {
|
|
51
|
+
IntelligentCompletionsController.get(editor.monacoEditor)?.trigger(tx);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
registerKeybindings(keybindings: KeybindingRegistry): void {
|
|
59
|
+
const { codeEdits } = this.aiNativeConfigService;
|
|
60
|
+
|
|
46
61
|
keybindings.registerKeybinding({
|
|
47
|
-
command:
|
|
62
|
+
command: AI_CODE_EDITS_COMMANDS.DISCARD.id,
|
|
48
63
|
keybinding: Key.ESCAPE.code,
|
|
49
64
|
when: MultiLineEditsIsVisible.raw,
|
|
50
65
|
priority: 100,
|
|
@@ -52,11 +67,17 @@ export class IntelligentCompletionsContribution implements KeybindingContributio
|
|
|
52
67
|
|
|
53
68
|
keybindings.registerKeybinding(
|
|
54
69
|
{
|
|
55
|
-
command:
|
|
70
|
+
command: AI_CODE_EDITS_COMMANDS.ACCEPT.id,
|
|
56
71
|
keybinding: Key.TAB.code,
|
|
57
72
|
when: MultiLineEditsIsVisible.raw,
|
|
58
73
|
},
|
|
59
74
|
KeybindingScope.USER,
|
|
60
75
|
);
|
|
76
|
+
|
|
77
|
+
keybindings.registerKeybinding({
|
|
78
|
+
command: AI_CODE_EDITS_COMMANDS.TRIGGER.id,
|
|
79
|
+
keybinding: codeEdits.triggerKeybinding,
|
|
80
|
+
when: 'editorFocus',
|
|
81
|
+
});
|
|
61
82
|
}
|
|
62
83
|
}
|
|
@@ -13,10 +13,13 @@ import {
|
|
|
13
13
|
import { Emitter, ICodeEditor, ICursorPositionChangedEvent, IRange, ITextModel, Range } from '@opensumi/ide-monaco';
|
|
14
14
|
import {
|
|
15
15
|
IObservable,
|
|
16
|
+
IObservableSignal,
|
|
16
17
|
ISettableObservable,
|
|
18
|
+
ITransaction,
|
|
17
19
|
autorun,
|
|
18
20
|
autorunWithStoreHandleChanges,
|
|
19
21
|
derived,
|
|
22
|
+
observableSignal,
|
|
20
23
|
observableValue,
|
|
21
24
|
transaction,
|
|
22
25
|
} from '@opensumi/ide-monaco/lib/common/observable';
|
|
@@ -85,11 +88,13 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
85
88
|
private aiNativeContextKey: AINativeContextKey;
|
|
86
89
|
private rewriteWidget: RewriteWidget | null;
|
|
87
90
|
private whenMultiLineEditsVisibleDisposable: Disposable;
|
|
91
|
+
private codeEditsTriggerSignal: IObservableSignal<void>;
|
|
88
92
|
|
|
89
93
|
public mount(): IDisposable {
|
|
90
94
|
this.handlerAlwaysVisiblePreference();
|
|
91
95
|
|
|
92
96
|
this.codeEditsResult = observableValue<CodeEditsResultValue | undefined>(this, undefined);
|
|
97
|
+
this.codeEditsTriggerSignal = observableSignal(this);
|
|
93
98
|
|
|
94
99
|
this.whenMultiLineEditsVisibleDisposable = new Disposable();
|
|
95
100
|
this.multiLineDecorationModel = new MultiLineDecorationModel(this.monacoEditor);
|
|
@@ -393,6 +398,10 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
393
398
|
this.hide();
|
|
394
399
|
});
|
|
395
400
|
|
|
401
|
+
public trigger(tx: ITransaction): void {
|
|
402
|
+
this.codeEditsTriggerSignal.trigger(tx);
|
|
403
|
+
}
|
|
404
|
+
|
|
396
405
|
private registerFeature(monacoEditor: ICodeEditor): void {
|
|
397
406
|
this.featureDisposable.addDispose(
|
|
398
407
|
Event.any<any>(
|
|
@@ -432,16 +441,19 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
432
441
|
autorunWithStoreHandleChanges(
|
|
433
442
|
{
|
|
434
443
|
createEmptyChangeSummary: () => ({}),
|
|
435
|
-
handleChange: (context
|
|
444
|
+
handleChange: (context) => {
|
|
436
445
|
if (context.didChange(this.codeEditsSourceCollection.codeEditsContextBean)) {
|
|
437
446
|
// 如果上一次补全结果还在,则不重复请求
|
|
438
447
|
const isVisible = this.aiNativeContextKey.multiLineEditsIsVisible.get();
|
|
439
448
|
return !isVisible;
|
|
449
|
+
} else if (context.didChange(this.codeEditsTriggerSignal)) {
|
|
450
|
+
return true;
|
|
440
451
|
}
|
|
441
452
|
return false;
|
|
442
453
|
},
|
|
443
454
|
},
|
|
444
455
|
async (reader, _, store) => {
|
|
456
|
+
this.codeEditsTriggerSignal.read(reader);
|
|
445
457
|
const context = this.codeEditsSourceCollection.codeEditsContextBean.read(reader);
|
|
446
458
|
|
|
447
459
|
const provider = this.intelligentCompletionsRegistry.getCodeEditsProvider();
|
|
@@ -69,8 +69,6 @@ export abstract class BaseCodeEditsSource extends Disposable {
|
|
|
69
69
|
private cancellationTokenSource = new CancellationTokenSource();
|
|
70
70
|
private readonly relationID = observableValue<string | undefined>(this, undefined);
|
|
71
71
|
|
|
72
|
-
protected abstract doTrigger(...args: any[]): MaybePromise<void>;
|
|
73
|
-
|
|
74
72
|
public readonly codeEditsContextBean = disposableObservableValue<CodeEditsContextBean | undefined>(this, undefined);
|
|
75
73
|
public abstract priority: number;
|
|
76
74
|
public abstract mount(): IDisposable;
|
|
@@ -1,47 +1,102 @@
|
|
|
1
1
|
import { Injectable } from '@opensumi/di';
|
|
2
2
|
import { AINativeSettingSectionsId, ECodeEditsSourceTyping, IDisposable } from '@opensumi/ide-core-common';
|
|
3
|
-
import { ICursorPositionChangedEvent,
|
|
3
|
+
import { ICursorPositionChangedEvent, IModelContentChangedEvent } from '@opensumi/ide-monaco';
|
|
4
|
+
import {
|
|
5
|
+
autorunDelta,
|
|
6
|
+
derivedHandleChanges,
|
|
7
|
+
observableFromEvent,
|
|
8
|
+
recomputeInitiallyAndOnChange,
|
|
9
|
+
} from '@opensumi/ide-monaco/lib/common/observable';
|
|
4
10
|
|
|
5
11
|
import { BaseCodeEditsSource } from './base';
|
|
6
12
|
|
|
7
13
|
export interface ILineChangeData {
|
|
8
14
|
currentLineNumber: number;
|
|
9
15
|
preLineNumber?: number;
|
|
16
|
+
change?: IModelContentChangedEvent;
|
|
10
17
|
}
|
|
11
18
|
|
|
12
19
|
@Injectable({ multiple: true })
|
|
13
20
|
export class LineChangeCodeEditsSource extends BaseCodeEditsSource {
|
|
14
21
|
public priority = 2;
|
|
15
22
|
|
|
16
|
-
private prePosition = this.monacoEditor.getPosition();
|
|
17
|
-
|
|
18
23
|
public mount(): IDisposable {
|
|
24
|
+
const modelContentChangeObs = observableFromEvent<IModelContentChangedEvent>(
|
|
25
|
+
this,
|
|
26
|
+
this.monacoEditor.onDidChangeModelContent,
|
|
27
|
+
(event: IModelContentChangedEvent) => event,
|
|
28
|
+
);
|
|
29
|
+
const positionChangeObs = observableFromEvent<ICursorPositionChangedEvent>(
|
|
30
|
+
this,
|
|
31
|
+
this.monacoEditor.onDidChangeCursorPosition,
|
|
32
|
+
(event: ICursorPositionChangedEvent) => event,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const latestModelContentChangeObs = derivedHandleChanges(
|
|
36
|
+
{
|
|
37
|
+
owner: this,
|
|
38
|
+
createEmptyChangeSummary: () => ({ change: undefined }),
|
|
39
|
+
handleChange: (ctx, changeSummary: { change: IModelContentChangedEvent | undefined }) => {
|
|
40
|
+
// 如果只是改了光标则设置 change 为空,避免获取到缓存的 change
|
|
41
|
+
if (ctx.didChange(positionChangeObs)) {
|
|
42
|
+
changeSummary.change = undefined;
|
|
43
|
+
} else {
|
|
44
|
+
changeSummary.change = modelContentChangeObs.get();
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
(reader, changeSummary) => {
|
|
50
|
+
positionChangeObs.read(reader);
|
|
51
|
+
modelContentChangeObs.read(reader);
|
|
52
|
+
return changeSummary.change;
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
this.addDispose(recomputeInitiallyAndOnChange(latestModelContentChangeObs));
|
|
57
|
+
|
|
58
|
+
let lastModelContent: IModelContentChangedEvent | undefined;
|
|
19
59
|
this.addDispose(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
60
|
+
/**
|
|
61
|
+
* 由于 monaco 的 changeModelContent 事件比 changeCursorPosition 事件先触发,所以这里需要拿上一次的值进行消费
|
|
62
|
+
* 否则永远返回 undefined
|
|
63
|
+
*/
|
|
64
|
+
autorunDelta(latestModelContentChangeObs, ({ lastValue }) => {
|
|
65
|
+
lastModelContent = lastValue;
|
|
26
66
|
}),
|
|
27
67
|
);
|
|
28
|
-
return this;
|
|
29
|
-
}
|
|
30
68
|
|
|
31
|
-
|
|
32
|
-
|
|
69
|
+
this.addDispose(
|
|
70
|
+
autorunDelta(positionChangeObs, ({ lastValue, newValue }) => {
|
|
71
|
+
const contentChange = lastModelContent;
|
|
33
72
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
73
|
+
const isLineChangeEnabled = this.preferenceService.getValid(
|
|
74
|
+
AINativeSettingSectionsId.CodeEditsLineChange,
|
|
75
|
+
false,
|
|
76
|
+
);
|
|
77
|
+
if (!isLineChangeEnabled) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
37
80
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
81
|
+
const prePosition = lastValue?.position;
|
|
82
|
+
const currentPosition = newValue?.position;
|
|
83
|
+
if (prePosition && prePosition.lineNumber !== currentPosition?.lineNumber) {
|
|
84
|
+
this.setBean({
|
|
85
|
+
typing: ECodeEditsSourceTyping.LineChange,
|
|
86
|
+
position: currentPosition,
|
|
87
|
+
data: {
|
|
88
|
+
preLineNumber: prePosition.lineNumber,
|
|
89
|
+
currentLineNumber: currentPosition.lineNumber,
|
|
90
|
+
change: contentChange,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 消费完之后设置为 undefined,避免下次获取到缓存的值
|
|
96
|
+
lastModelContent = undefined;
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return this;
|
|
46
101
|
}
|
|
47
102
|
}
|
package/src/browser/index.ts
CHANGED
|
@@ -46,7 +46,7 @@ import { LanguageParserService } from './languages/service';
|
|
|
46
46
|
import { AINativePreferencesContribution } from './preferences';
|
|
47
47
|
import { AINativeCoreContribution } from './types';
|
|
48
48
|
import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry';
|
|
49
|
-
import {
|
|
49
|
+
import { InlineChatService } from './widget/inline-chat/inline-chat.service';
|
|
50
50
|
import { InlineDiffService } from './widget/inline-diff';
|
|
51
51
|
|
|
52
52
|
@Injectable()
|
|
@@ -90,7 +90,7 @@ export class AINativeModule extends BrowserModule {
|
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
token: IAIInlineChatService,
|
|
93
|
-
useClass:
|
|
93
|
+
useClass: InlineChatService,
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
token: IChatManagerService,
|
|
@@ -10,11 +10,14 @@ export const AILayout = () => {
|
|
|
10
10
|
const { layout } = getStorageValue();
|
|
11
11
|
const designLayoutConfig = useInjectable(DesignLayoutConfig);
|
|
12
12
|
|
|
13
|
-
const defaultRightSize = useMemo(
|
|
13
|
+
const defaultRightSize = useMemo(
|
|
14
|
+
() => (designLayoutConfig.useMergeRightWithLeftPanel ? 0 : 49),
|
|
15
|
+
[designLayoutConfig.useMergeRightWithLeftPanel],
|
|
16
|
+
);
|
|
14
17
|
|
|
15
18
|
return (
|
|
16
19
|
<BoxPanel direction='top-to-bottom'>
|
|
17
|
-
<SlotRenderer id='top' defaultSize={layout.top?.currentId ? layout.top?.size ||
|
|
20
|
+
<SlotRenderer id='top' defaultSize={layout.top?.currentId ? layout.top?.size || 32 : 32} slot='top' />
|
|
18
21
|
<SplitPanel
|
|
19
22
|
id='main-horizontal-ai'
|
|
20
23
|
flex={1}
|