@opensumi/ide-ai-native 3.7.1-next-1739430207.0 → 3.7.1-next-1739439717.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.
Files changed (122) hide show
  1. package/lib/browser/ai-core.contextkeys.d.ts +0 -1
  2. package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contextkeys.js +0 -1
  4. package/lib/browser/ai-core.contextkeys.js.map +1 -1
  5. package/lib/browser/ai-core.contribution.d.ts +1 -2
  6. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-core.contribution.js +14 -55
  8. package/lib/browser/ai-core.contribution.js.map +1 -1
  9. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +0 -1
  10. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -1
  11. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +4 -26
  12. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
  13. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts +1 -3
  14. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
  15. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +1 -9
  16. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
  17. package/lib/browser/contrib/intelligent-completions/source/base.d.ts +2 -1
  18. package/lib/browser/contrib/intelligent-completions/source/base.d.ts.map +1 -1
  19. package/lib/browser/contrib/intelligent-completions/source/base.js.map +1 -1
  20. package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts +3 -2
  21. package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts.map +1 -1
  22. package/lib/browser/contrib/intelligent-completions/source/line-change.source.js +21 -51
  23. package/lib/browser/contrib/intelligent-completions/source/line-change.source.js.map +1 -1
  24. package/lib/browser/contrib/terminal/component/terminal-command-suggest-controller.js +2 -2
  25. package/lib/browser/contrib/terminal/component/terminal-command-suggest-controller.js.map +1 -1
  26. package/lib/browser/index.js +1 -1
  27. package/lib/browser/index.js.map +1 -1
  28. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  29. package/lib/browser/layout/ai-layout.js +2 -2
  30. package/lib/browser/layout/ai-layout.js.map +1 -1
  31. package/lib/browser/model/enhanceDecorationsCollection.d.ts +10 -14
  32. package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
  33. package/lib/browser/model/enhanceDecorationsCollection.js +53 -42
  34. package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
  35. package/lib/browser/model/styles.module.less +7 -0
  36. package/lib/browser/types.d.ts +1 -2
  37. package/lib/browser/types.d.ts.map +1 -1
  38. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts +1 -2
  39. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts.map +1 -1
  40. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js +41 -13
  41. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js.map +1 -1
  42. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts +13 -3
  43. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts.map +1 -1
  44. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js +72 -24
  45. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js.map +1 -1
  46. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts +6 -1
  47. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts.map +1 -1
  48. package/lib/browser/widget/inline-chat/inline-chat.service.js +19 -5
  49. package/lib/browser/widget/inline-chat/inline-chat.service.js.map +1 -1
  50. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +5 -2
  51. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  52. package/lib/browser/widget/inline-chat/inline-content-widget.js +42 -17
  53. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  54. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +5 -22
  55. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  56. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +30 -61
  57. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  58. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +12 -8
  59. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
  60. package/lib/browser/widget/inline-diff/inline-diff.controller.js +96 -68
  61. package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
  62. package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts +1 -0
  63. package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts.map +1 -1
  64. package/lib/browser/widget/inline-hint/inline-hint.controller.js +5 -0
  65. package/lib/browser/widget/inline-hint/inline-hint.controller.js.map +1 -1
  66. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +2 -12
  67. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  68. package/lib/browser/widget/inline-input/inline-input-widget.js +18 -26
  69. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  70. package/lib/browser/widget/inline-input/inline-input.controller.d.ts +6 -14
  71. package/lib/browser/widget/inline-input/inline-input.controller.d.ts.map +1 -1
  72. package/lib/browser/widget/inline-input/inline-input.controller.js +169 -320
  73. package/lib/browser/widget/inline-input/inline-input.controller.js.map +1 -1
  74. package/lib/browser/widget/inline-input/inline-input.module.less +0 -4
  75. package/lib/browser/widget/inline-input/inline-input.service.d.ts +7 -19
  76. package/lib/browser/widget/inline-input/inline-input.service.d.ts.map +1 -1
  77. package/lib/browser/widget/inline-input/inline-input.service.js +12 -72
  78. package/lib/browser/widget/inline-input/inline-input.service.js.map +1 -1
  79. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +19 -8
  80. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  81. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +41 -48
  82. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  83. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +4 -17
  84. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  85. package/lib/browser/widget/inline-stream-diff/live-preview.component.js +5 -37
  86. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  87. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +11 -7
  88. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  89. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +77 -33
  90. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  91. package/package.json +21 -21
  92. package/src/browser/ai-core.contextkeys.ts +0 -3
  93. package/src/browser/ai-core.contribution.ts +16 -63
  94. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +8 -29
  95. package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +1 -13
  96. package/src/browser/contrib/intelligent-completions/source/base.ts +2 -0
  97. package/src/browser/contrib/intelligent-completions/source/line-change.source.ts +24 -79
  98. package/src/browser/contrib/terminal/component/terminal-command-suggest-controller.tsx +1 -1
  99. package/src/browser/index.ts +2 -2
  100. package/src/browser/layout/ai-layout.tsx +2 -5
  101. package/src/browser/model/enhanceDecorationsCollection.ts +77 -62
  102. package/src/browser/model/styles.module.less +7 -0
  103. package/src/browser/types.ts +2 -2
  104. package/src/browser/widget/inline-chat/inline-chat-editor.controller.ts +56 -21
  105. package/src/browser/widget/inline-chat/inline-chat.feature.registry.ts +90 -23
  106. package/src/browser/widget/inline-chat/inline-chat.service.ts +19 -2
  107. package/src/browser/widget/inline-chat/inline-content-widget.tsx +71 -14
  108. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +32 -87
  109. package/src/browser/widget/inline-diff/inline-diff.controller.ts +114 -90
  110. package/src/browser/widget/inline-hint/inline-hint.controller.ts +7 -1
  111. package/src/browser/widget/inline-input/inline-input-widget.tsx +12 -34
  112. package/src/browser/widget/inline-input/inline-input.controller.ts +247 -453
  113. package/src/browser/widget/inline-input/inline-input.module.less +0 -4
  114. package/src/browser/widget/inline-input/inline-input.service.ts +13 -92
  115. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +69 -58
  116. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +6 -45
  117. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +112 -40
  118. package/lib/browser/widget/inline-input/model.d.ts +0 -34
  119. package/lib/browser/widget/inline-input/model.d.ts.map +0 -1
  120. package/lib/browser/widget/inline-input/model.js +0 -63
  121. package/lib/browser/widget/inline-input/model.js.map +0 -1
  122. package/src/browser/widget/inline-input/model.ts +0 -74
@@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
4
4
  import { IAIInlineChatService, StackingLevel, useInjectable } from '@opensumi/ide-core-browser';
5
5
  import { AIAction } from '@opensumi/ide-core-browser/lib/components/ai-native';
6
+ import { InteractiveInput } from '@opensumi/ide-core-browser/lib/components/ai-native/interactive-input/index';
6
7
  import { MenuNode } from '@opensumi/ide-core-browser/lib/menu/next/base';
7
8
  import {
8
9
  AIInlineChatContentWidgetId,
@@ -10,6 +11,7 @@ import {
10
11
  Emitter,
11
12
  Event,
12
13
  InlineChatFeatureRegistryToken,
14
+ localize,
13
15
  runWhenIdle,
14
16
  } from '@opensumi/ide-core-common';
15
17
  import * as monaco from '@opensumi/ide-monaco';
@@ -21,32 +23,40 @@ import {
21
23
 
22
24
  import { AINativeContextKey } from '../../ai-core.contextkeys';
23
25
  import { InlineResultAction } from '../inline-actions/result-items/index';
24
- import { InlineInputService } from '../inline-input/inline-input.service';
25
- import { InteractiveInputModel } from '../inline-input/model';
26
26
 
27
27
  import { InlineChatFeatureRegistry } from './inline-chat.feature.registry';
28
28
  import styles from './inline-chat.module.less';
29
- import { EInlineChatStatus, EResultKind, InlineChatService } from './inline-chat.service';
29
+ import { AIInlineChatService, EInlineChatStatus, EResultKind } from './inline-chat.service';
30
30
 
31
31
  import type { ICodeEditor as IMonacoCodeEditor } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
32
32
 
33
33
  interface IAIInlineChatControllerProps {
34
34
  onClickActions: (id: string) => void;
35
+ onLayoutChange: (height: number) => void;
35
36
  onClose?: () => void;
37
+ onInteractiveInputSend?: (value: string) => void;
36
38
  onChatStatus: Event<EInlineChatStatus>;
37
39
  onResultClick: (k: EResultKind) => void;
38
40
  }
39
41
 
40
42
  const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
41
- const { onClickActions, onClose, onChatStatus, onResultClick } = props;
42
- const aiInlineChatService: InlineChatService = useInjectable(IAIInlineChatService);
43
+ const { onClickActions, onClose, onInteractiveInputSend, onLayoutChange, onChatStatus, onResultClick } = props;
44
+ const aiInlineChatService: AIInlineChatService = useInjectable(IAIInlineChatService);
43
45
  const inlineChatFeatureRegistry: InlineChatFeatureRegistry = useInjectable(InlineChatFeatureRegistryToken);
44
-
45
46
  const [status, setStatus] = useState<EInlineChatStatus>(EInlineChatStatus.READY);
47
+ const [interactiveInputVisible, setInteractiveInputVisible] = useState<boolean>(
48
+ aiInlineChatService.interactiveInputVisible,
49
+ );
46
50
  useEffect(() => {
47
51
  const dis = new Disposable();
48
52
  dis.addDispose(onChatStatus((s) => setStatus(s)));
49
53
 
54
+ dis.addDispose(
55
+ aiInlineChatService.onInteractiveInputVisible((v) => {
56
+ setInteractiveInputVisible(v);
57
+ }),
58
+ );
59
+
50
60
  return () => {
51
61
  dis.dispose();
52
62
  };
@@ -74,6 +84,13 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
74
84
  onClose?.();
75
85
  }, [onClose]);
76
86
 
87
+ const handleInteractiveInputSend = useCallback(
88
+ (value: string) => {
89
+ onInteractiveInputSend?.(value);
90
+ },
91
+ [onInteractiveInputSend],
92
+ );
93
+
77
94
  const moreOperation = useMemo(
78
95
  () =>
79
96
  inlineChatFeatureRegistry.getEditorActionMenus().map(
@@ -90,6 +107,24 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
90
107
  [inlineChatFeatureRegistry],
91
108
  );
92
109
 
110
+ const customOperationRender = useMemo(() => {
111
+ if (!interactiveInputVisible) {
112
+ return null;
113
+ }
114
+
115
+ return (
116
+ <InteractiveInput
117
+ autoFocus
118
+ onHeightChange={(height) => onLayoutChange(height)}
119
+ size='small'
120
+ placeholder={localize('aiNative.inline.chat.input.placeholder.default')}
121
+ width={320}
122
+ disabled={isLoading}
123
+ onSend={handleInteractiveInputSend}
124
+ />
125
+ );
126
+ }, [isLoading, interactiveInputVisible]);
127
+
93
128
  const renderContent = useCallback(() => {
94
129
  if (operationList.length === 0 && moreOperation.length === 0) {
95
130
  return null;
@@ -110,9 +145,11 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
110
145
  onClickItem={handleClickActions}
111
146
  onClose={handleClose}
112
147
  loading={isLoading}
148
+ loadingShowOperation={interactiveInputVisible}
149
+ customOperationRender={customOperationRender}
113
150
  />
114
151
  );
115
- }, [operationList, moreOperation, onResultClick, status]);
152
+ }, [operationList, moreOperation, customOperationRender, onResultClick, status, interactiveInputVisible]);
116
153
 
117
154
  return <div className={styles.inline_chat_controller_box}>{renderContent()}</div>;
118
155
  };
@@ -124,20 +161,28 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
124
161
  @Autowired(INJECTOR_TOKEN)
125
162
  private readonly injector: Injector;
126
163
 
127
- @Autowired(InlineInputService)
128
- protected readonly inlineInputService: InlineInputService;
164
+ @Autowired(InlineChatFeatureRegistryToken)
165
+ private readonly inlineChatFeatureRegistry: InlineChatFeatureRegistry;
129
166
 
130
167
  private readonly aiNativeContextKey: AINativeContextKey;
131
168
 
132
169
  private readonly _onActionClickEmitter = new Emitter<{ actionId: string; source: string }>();
133
170
  public readonly onActionClick = this._onActionClickEmitter.event;
134
171
 
172
+ protected readonly _onInteractiveInputValue = new Emitter<string>();
173
+ public readonly onInteractiveInputValue = this._onInteractiveInputValue.event;
174
+
135
175
  protected readonly _onStatusChange = new Emitter<EInlineChatStatus>();
136
176
  public readonly onStatusChange: Event<EInlineChatStatus> = this._onStatusChange.event;
137
177
 
138
178
  protected readonly _onResultClick = new Emitter<EResultKind>();
139
179
  public readonly onResultClick: Event<EResultKind> = this._onResultClick.event;
140
180
 
181
+ protected _interactiveInputValue: string;
182
+ public get interactiveInputValue(): string {
183
+ return this._interactiveInputValue;
184
+ }
185
+
141
186
  protected _status: EInlineChatStatus = EInlineChatStatus.READY;
142
187
  public get status(): EInlineChatStatus {
143
188
  return this._status;
@@ -151,6 +196,13 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
151
196
  super(editor);
152
197
 
153
198
  this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.editor.contextKeyService]);
199
+ this.addDispose(
200
+ this.editor.onDidLayoutChange(() => {
201
+ if (this.isOutOfArea()) {
202
+ this.dispose();
203
+ }
204
+ }),
205
+ );
154
206
  }
155
207
 
156
208
  public launchChatStatus(status: EInlineChatStatus) {
@@ -166,11 +218,8 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
166
218
  }
167
219
 
168
220
  public clickActionId(actionId: string, source: string): void {
169
- if (actionId === InteractiveInputModel.ID && this.options?.selection) {
170
- // 隐藏当前的 inline chat widget
171
- this.hide();
172
- // 显示 inline input widget
173
- this.inlineInputService.visibleBySelection(this.options.selection);
221
+ if (actionId === this.inlineChatFeatureRegistry.getInteractiveInputId()) {
222
+ this.inlineChatFeatureRegistry._onChatClick.fire();
174
223
  return;
175
224
  }
176
225
 
@@ -183,6 +232,14 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
183
232
  onClickActions={(id) => this.clickActionId(id, 'widget')}
184
233
  onClose={() => this.dispose()}
185
234
  onChatStatus={this.onStatusChange.bind(this)}
235
+ onLayoutChange={() => {
236
+ this.editor.layoutContentWidget(this);
237
+ }}
238
+ onInteractiveInputSend={(value) => {
239
+ this.launchChatStatus(EInlineChatStatus.THINKING);
240
+ this._interactiveInputValue = value;
241
+ this._onInteractiveInputValue.fire(value);
242
+ }}
186
243
  onResultClick={(kind: EResultKind) => {
187
244
  this._onResultClick.fire(kind);
188
245
  }}
@@ -3,7 +3,6 @@ import { Disposable, ErrorResponse, IDisposable, ReplyResponse } from '@opensumi
3
3
  import { EOL, ICodeEditor, IPosition, ITextModel, Position, Selection } from '@opensumi/ide-monaco';
4
4
  import { ContentWidgetPositionPreference } from '@opensumi/ide-monaco/lib/browser/monaco-exports/editor';
5
5
  import { empty, getLeadingWhitespace } from '@opensumi/ide-utils/lib/strings';
6
- import { LineRange } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/lineRange';
7
6
  import { DefaultEndOfLine } from '@opensumi/monaco-editor-core/esm/vs/editor/common/model';
8
7
  import { createTextBuffer } from '@opensumi/monaco-editor-core/esm/vs/editor/common/model/textModel';
9
8
  import { ModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/modelService';
@@ -44,13 +43,10 @@ export abstract class BaseInlineDiffPreviewer<N extends IInlineDiffPreviewerNode
44
43
  protected inlineContentWidget: AIInlineContentWidget | null = null;
45
44
  protected selection: Selection;
46
45
  protected model: ITextModel;
47
- public modelId: string;
48
46
 
49
47
  constructor(protected readonly monacoEditor: ICodeEditor) {
50
48
  super();
51
49
  this.model = this.monacoEditor.getModel()!;
52
- this.modelId = this.model.id;
53
-
54
50
  this.addDispose(
55
51
  Disposable.create(() => {
56
52
  if (this.inlineContentWidget) {
@@ -110,7 +106,11 @@ export abstract class BaseInlineDiffPreviewer<N extends IInlineDiffPreviewerNode
110
106
  return this.node;
111
107
  }
112
108
 
113
- public mountWidget(contentWidget: AIInlineContentWidget): void {
109
+ public createNodeSnapshot(): N | undefined {
110
+ return this.node;
111
+ }
112
+
113
+ public mount(contentWidget: AIInlineContentWidget): void {
114
114
  this.inlineContentWidget = contentWidget;
115
115
  }
116
116
 
@@ -156,25 +156,20 @@ export abstract class BaseInlineDiffPreviewer<N extends IInlineDiffPreviewerNode
156
156
  setValue(content: string): void {
157
157
  // do nothing
158
158
  }
159
-
160
159
  getValue(): string {
161
160
  // do nothing
162
161
  return '';
163
162
  }
164
-
165
163
  getOriginValue(): string {
166
164
  // do nothing
167
165
  return '';
168
166
  }
169
-
170
167
  onError(error: ErrorResponse): void {
171
168
  // do nothing
172
169
  }
173
-
174
170
  onAbort(): void {
175
171
  // do nothing
176
172
  }
177
-
178
173
  onEnd(): void {
179
174
  // do nothing
180
175
  }
@@ -183,30 +178,6 @@ export abstract class BaseInlineDiffPreviewer<N extends IInlineDiffPreviewerNode
183
178
  // do nothing
184
179
  }
185
180
 
186
- /**
187
- * 会新建一个渲染层的实例
188
- * 或重新赋值渲染层的数据
189
- * 适用于首次渲染
190
- */
191
- render(): void {
192
- // do nothing
193
- }
194
-
195
- /**
196
- * 仅隐藏渲染层,而不销毁实例
197
- */
198
- hide(): void {
199
- // do nothing
200
- }
201
-
202
- /**
203
- * 恢复渲染层
204
- * 适用于非首次渲染
205
- */
206
- resume(): void {
207
- // do nothing
208
- }
209
-
210
181
  isModel(uri: string): boolean {
211
182
  return this.model.uri.toString() === uri;
212
183
  }
@@ -228,37 +199,30 @@ export class SideBySideInlineDiffWidget extends BaseInlineDiffPreviewer<InlineDi
228
199
  this.addDispose(widget);
229
200
  return widget;
230
201
  }
231
-
232
- mountWidget(contentWidget: AIInlineContentWidget): void {
233
- super.mountWidget(contentWidget);
202
+ mount(contentWidget: AIInlineContentWidget): void {
203
+ super.mount(contentWidget);
234
204
  contentWidget.addDispose(this);
235
205
  }
236
-
237
206
  getPosition(): IPosition {
238
207
  return Position.lift({ lineNumber: this.selection.endLineNumber + 1, column: 1 });
239
208
  }
240
-
241
209
  layout(): void {
242
210
  this.inlineContentWidget?.setPositionPreference([ContentWidgetPositionPreference.BELOW]);
243
211
  super.layout();
244
212
  }
245
-
246
213
  onReady(exec: () => void): IDisposable {
247
214
  if (this.node) {
248
215
  return this.node!.onReady(exec.bind(this));
249
216
  }
250
217
  return Disposable.NULL;
251
218
  }
252
-
253
219
  show(line: number, heightInLines: number): void {
254
220
  this.node?.showByLine(line, heightInLines);
255
221
  }
256
-
257
222
  setValue(content: string): void {
258
223
  const modifiedModel = this.node?.getModifiedModel();
259
224
  modifiedModel?.setValue(this.formatIndentation(content));
260
225
  }
261
-
262
226
  getValue(): string {
263
227
  const model = this.node?.getModifiedModel();
264
228
  return model!.getValue();
@@ -276,12 +240,10 @@ export class SideBySideInlineDiffWidget extends BaseInlineDiffPreviewer<InlineDi
276
240
  this.model.pushStackElement();
277
241
  }
278
242
  }
279
-
280
243
  onLineCount(event: (count: number) => void): Disposable {
281
244
  this.node?.onMaxLineCount(event.bind(this));
282
245
  return this;
283
246
  }
284
-
285
247
  onData(data: ReplyResponse): void {
286
248
  const { message } = data;
287
249
 
@@ -296,15 +258,12 @@ export class SideBySideInlineDiffWidget extends BaseInlineDiffPreviewer<InlineDi
296
258
  disposable.dispose();
297
259
  this.node?.layout();
298
260
  }
299
-
300
261
  onError(error: ErrorResponse): void {
301
262
  this.node?.layout();
302
263
  }
303
-
304
264
  onAbort(): void {
305
265
  this.node?.layout();
306
266
  }
307
-
308
267
  onEnd(): void {
309
268
  this.node?.layout();
310
269
  }
@@ -337,6 +296,30 @@ export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStrea
337
296
  this.listenNode(node);
338
297
  return node;
339
298
  }
299
+ attachNode(node: InlineStreamDiffHandler): void {
300
+ this.node?.dispose();
301
+ this.node = node;
302
+
303
+ if (node) {
304
+ const snapshot = node.currentSnapshotStore;
305
+ if (snapshot) {
306
+ this.node.restoreDecorationSnapshot(snapshot.decorationSnapshotData);
307
+ this.listenNode(node);
308
+ }
309
+ }
310
+ }
311
+ public createNodeSnapshot(): InlineStreamDiffHandler | undefined {
312
+ if (!this.node) {
313
+ return this.createNode();
314
+ }
315
+
316
+ // 拿前一个 node 的快照信息
317
+ const snapshot = this.node.createSnapshot();
318
+ // 创建新的实例
319
+ const node = this.injector.get(InlineStreamDiffHandler, [this.monacoEditor]);
320
+ node.restoreSnapshot(snapshot);
321
+ return node;
322
+ }
340
323
 
341
324
  getPosition(): IPosition {
342
325
  const zone = this.node?.getZone();
@@ -345,7 +328,6 @@ export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStrea
345
328
  }
346
329
  return Position.lift({ lineNumber: 1, column: 1 });
347
330
  }
348
-
349
331
  handleAction(action: EResultKind): void {
350
332
  switch (action) {
351
333
  case EResultKind.ACCEPT:
@@ -361,11 +343,9 @@ export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStrea
361
343
  break;
362
344
  }
363
345
  }
364
-
365
346
  onLineCount() {
366
347
  return Disposable.NULL;
367
348
  }
368
-
369
349
  layout(): void {
370
350
  this.inlineContentWidget?.setPositionPreference([
371
351
  ContentWidgetPositionPreference.ABOVE,
@@ -385,52 +365,17 @@ export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStrea
385
365
  const firstRemovedWidgetLineNumber = firstRemovedWidget.getLastPosition()?.lineNumber;
386
366
  if (firstRemovedWidgetLineNumber <= lineNumber) {
387
367
  const lineHeight = this.inlineContentWidget.getLineHeight();
388
- const len = firstRemovedWidget.height + 1;
368
+ const len = firstRemovedWidget.height;
389
369
  this.inlineContentWidget.setOffsetTop(-lineHeight * len - 4);
390
- } else {
391
- this.inlineContentWidget.setOffsetTop(0);
392
370
  }
393
371
  }
394
- } else {
395
- this.inlineContentWidget.setOffsetTop(0);
396
372
  }
397
373
  }
398
374
  }
399
-
400
- render(): void {
401
- this.inlineContentWidget?.show();
402
- this.node?.rateRenderEditController();
403
- }
404
-
405
- hide(): void {
406
- this.inlineContentWidget?.hide();
407
- this.node?.hide();
408
- }
409
-
410
- resume(): void {
411
- this.inlineContentWidget?.show();
412
- this.node?.resume();
413
- }
414
-
415
375
  onData(data: ReplyResponse): void {
416
376
  const { message } = data;
417
377
  this.node?.addLinesToDiff(this.formatIndentation(message));
418
378
  }
419
-
420
- onAbort(): void {
421
- const diffModel = this.node?.recompute(EComputerMode.default);
422
- if (diffModel) {
423
- /**
424
- * abort 的时候,需要保留当前已经输出的内容
425
- * 同时需要去掉流式过程中的 pending 区域和 activeLine
426
- */
427
- diffModel.activeLine = 0;
428
- diffModel.pendingRange = new LineRange(0, 0);
429
-
430
- this.node?.finallyRender(diffModel);
431
- }
432
- }
433
-
434
379
  onEnd(): void {
435
380
  const diffModel = this.node?.recompute(EComputerMode.legacy);
436
381
  if (diffModel) {