@opensumi/ide-ai-native 3.2.4 → 3.2.5-next-1724062137.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 (181) hide show
  1. package/lib/browser/ai-core.contribution.d.ts +1 -0
  2. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contribution.js +14 -25
  4. package/lib/browser/ai-core.contribution.js.map +1 -1
  5. package/lib/browser/ai-editor.contribution.d.ts +1 -0
  6. package/lib/browser/ai-editor.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-editor.contribution.js +8 -0
  8. package/lib/browser/ai-editor.contribution.js.map +1 -1
  9. package/lib/browser/chat/chat-agent.service.d.ts +1 -0
  10. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-agent.service.js +1 -3
  12. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  13. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  14. package/lib/browser/chat/chat.view.js +22 -4
  15. package/lib/browser/chat/chat.view.js.map +1 -1
  16. package/lib/browser/components/ChatEditor.d.ts +2 -1
  17. package/lib/browser/components/ChatEditor.d.ts.map +1 -1
  18. package/lib/browser/components/ChatEditor.js +8 -8
  19. package/lib/browser/components/ChatEditor.js.map +1 -1
  20. package/lib/browser/components/ChatMarkdown.d.ts +1 -0
  21. package/lib/browser/components/ChatMarkdown.d.ts.map +1 -1
  22. package/lib/browser/components/ChatMarkdown.js +2 -2
  23. package/lib/browser/components/ChatMarkdown.js.map +1 -1
  24. package/lib/browser/components/ChatThinking.d.ts.map +1 -1
  25. package/lib/browser/components/ChatThinking.js +2 -2
  26. package/lib/browser/components/ChatThinking.js.map +1 -1
  27. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts +1 -0
  28. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts.map +1 -1
  29. package/lib/browser/contextkey/ai-native.contextkey.service.js +1 -0
  30. package/lib/browser/contextkey/ai-native.contextkey.service.js.map +1 -1
  31. package/lib/browser/contrib/inline-completions/completeProvider.d.ts +4 -31
  32. package/lib/browser/contrib/inline-completions/completeProvider.d.ts.map +1 -1
  33. package/lib/browser/contrib/inline-completions/completeProvider.js +3 -224
  34. package/lib/browser/contrib/inline-completions/completeProvider.js.map +1 -1
  35. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts +1 -3
  36. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts.map +1 -1
  37. package/lib/browser/contrib/inline-completions/inline-completions.handler.js +8 -20
  38. package/lib/browser/contrib/inline-completions/inline-completions.handler.js.map +1 -1
  39. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts +2 -2
  40. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts.map +1 -1
  41. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts +28 -0
  42. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts.map +1 -0
  43. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js +210 -0
  44. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js.map +1 -0
  45. package/lib/browser/contrib/inline-completions/promptCache.d.ts +3 -2
  46. package/lib/browser/contrib/inline-completions/promptCache.d.ts.map +1 -1
  47. package/lib/browser/contrib/inline-completions/promptCache.js.map +1 -1
  48. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts +7 -6
  49. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts.map +1 -1
  50. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js +48 -25
  51. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js.map +1 -1
  52. package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts +18 -0
  53. package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts.map +1 -0
  54. package/lib/browser/contrib/intelligent-completions/diff-computer.js +144 -0
  55. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -0
  56. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +8 -0
  57. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -0
  58. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +47 -0
  59. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -0
  60. package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts +15 -0
  61. package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts.map +1 -0
  62. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts +8 -0
  63. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts.map +1 -0
  64. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js +19 -0
  65. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js.map +1 -0
  66. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts +20 -0
  67. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts.map +1 -0
  68. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js +94 -0
  69. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js.map +1 -0
  70. package/lib/browser/contrib/intelligent-completions/intelligent-completions.js +3 -0
  71. package/lib/browser/contrib/intelligent-completions/intelligent-completions.js.map +1 -0
  72. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts +33 -0
  73. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts.map +1 -0
  74. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js +258 -0
  75. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js.map +1 -0
  76. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts +0 -1
  77. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts.map +1 -1
  78. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js +0 -3
  79. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js.map +1 -1
  80. package/lib/browser/contrib/rename/rename.handler.d.ts.map +1 -1
  81. package/lib/browser/contrib/rename/rename.handler.js +1 -0
  82. package/lib/browser/contrib/rename/rename.handler.js.map +1 -1
  83. package/lib/browser/index.d.ts.map +1 -1
  84. package/lib/browser/index.js +7 -0
  85. package/lib/browser/index.js.map +1 -1
  86. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  87. package/lib/browser/layout/ai-layout.js +4 -4
  88. package/lib/browser/layout/ai-layout.js.map +1 -1
  89. package/lib/browser/model/enhanceDecorationsCollection.d.ts +38 -4
  90. package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
  91. package/lib/browser/model/enhanceDecorationsCollection.js +44 -23
  92. package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
  93. package/lib/browser/types.d.ts +20 -13
  94. package/lib/browser/types.d.ts.map +1 -1
  95. package/lib/browser/types.js +0 -4
  96. package/lib/browser/types.js.map +1 -1
  97. package/lib/browser/widget/inline-chat/inline-chat.handler.d.ts.map +1 -1
  98. package/lib/browser/widget/inline-chat/inline-chat.handler.js +31 -12
  99. package/lib/browser/widget/inline-chat/inline-chat.handler.js.map +1 -1
  100. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +5 -2
  101. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  102. package/lib/browser/widget/inline-chat/inline-content-widget.js +45 -53
  103. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  104. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +20 -14
  105. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  106. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +114 -46
  107. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  108. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts +5 -2
  109. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts.map +1 -1
  110. package/lib/browser/widget/inline-diff/inline-diff-widget.js +3 -0
  111. package/lib/browser/widget/inline-diff/inline-diff-widget.js.map +1 -1
  112. package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts +13 -13
  113. package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts.map +1 -1
  114. package/lib/browser/widget/inline-diff/inline-diff.handler.js +71 -76
  115. package/lib/browser/widget/inline-diff/inline-diff.handler.js.map +1 -1
  116. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +1 -0
  117. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  118. package/lib/browser/widget/inline-input/inline-input-widget.js +1 -0
  119. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  120. package/lib/browser/widget/inline-input/inline-input.handler.js +2 -2
  121. package/lib/browser/widget/inline-input/inline-input.handler.js.map +1 -1
  122. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +28 -15
  123. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  124. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +52 -31
  125. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  126. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
  127. package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts +21 -0
  128. package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts.map +1 -0
  129. package/lib/browser/widget/inline-stream-diff/live-preview-stack.js +41 -0
  130. package/lib/browser/widget/inline-stream-diff/live-preview-stack.js.map +1 -0
  131. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +105 -0
  132. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -0
  133. package/lib/browser/widget/inline-stream-diff/live-preview.component.js +237 -0
  134. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -0
  135. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +27 -103
  136. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  137. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +185 -369
  138. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  139. package/lib/common/index.d.ts +1 -0
  140. package/lib/common/index.d.ts.map +1 -1
  141. package/lib/common/index.js.map +1 -1
  142. package/package.json +19 -19
  143. package/src/browser/ai-core.contribution.ts +14 -28
  144. package/src/browser/ai-editor.contribution.ts +9 -0
  145. package/src/browser/chat/chat-agent.service.ts +1 -3
  146. package/src/browser/chat/chat.view.tsx +49 -4
  147. package/src/browser/components/ChatEditor.tsx +21 -7
  148. package/src/browser/components/ChatMarkdown.tsx +8 -2
  149. package/src/browser/components/ChatThinking.tsx +3 -1
  150. package/src/browser/contextkey/ai-native.contextkey.service.ts +3 -0
  151. package/src/browser/contrib/inline-completions/completeProvider.ts +7 -289
  152. package/src/browser/contrib/inline-completions/inline-completions.handler.ts +15 -22
  153. package/src/browser/contrib/inline-completions/model/competionModel.ts +3 -2
  154. package/src/browser/contrib/inline-completions/model/inlineCompletionRequestTask.ts +272 -0
  155. package/src/browser/contrib/inline-completions/promptCache.ts +3 -2
  156. package/src/browser/contrib/inline-completions/service/ai-completions.service.ts +55 -38
  157. package/src/browser/contrib/intelligent-completions/diff-computer.ts +185 -0
  158. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +54 -0
  159. package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts +17 -0
  160. package/src/browser/contrib/intelligent-completions/intelligent-completions.handler.ts +130 -0
  161. package/src/browser/contrib/intelligent-completions/intelligent-completions.ts +15 -0
  162. package/src/browser/contrib/intelligent-completions/multi-line.decoration.ts +325 -0
  163. package/src/browser/contrib/merge-conflict/merge-conflict.feature.registry.ts +0 -4
  164. package/src/browser/contrib/rename/rename.handler.ts +1 -0
  165. package/src/browser/index.ts +8 -1
  166. package/src/browser/layout/ai-layout.tsx +7 -1
  167. package/src/browser/model/enhanceDecorationsCollection.ts +71 -34
  168. package/src/browser/types.ts +27 -14
  169. package/src/browser/widget/inline-chat/inline-chat.handler.ts +34 -19
  170. package/src/browser/widget/inline-chat/inline-content-widget.tsx +58 -61
  171. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +118 -61
  172. package/src/browser/widget/inline-diff/inline-diff-widget.tsx +8 -2
  173. package/src/browser/widget/inline-diff/inline-diff.handler.ts +83 -92
  174. package/src/browser/widget/inline-input/inline-input-widget.tsx +1 -0
  175. package/src/browser/widget/inline-input/inline-input.handler.ts +2 -2
  176. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +98 -44
  177. package/src/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
  178. package/src/browser/widget/inline-stream-diff/live-preview-stack.ts +52 -0
  179. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +388 -0
  180. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +243 -543
  181. package/src/common/index.ts +2 -0
@@ -1,35 +1,15 @@
1
- import cls from 'classnames';
2
- import React, { useCallback, useEffect, useMemo } from 'react';
3
- import ReactDOMClient from 'react-dom/client';
4
-
5
1
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
6
- import { KeybindingRegistry, StackingLevel, useDisposable } from '@opensumi/ide-core-browser';
7
- import { AI_INLINE_DIFF_PARTIAL_EDIT } from '@opensumi/ide-core-browser/lib/ai-native/command';
8
- import { Disposable, Emitter, Event, IPosition, isUndefined, uuid } from '@opensumi/ide-core-common';
2
+ import { StackingLevel } from '@opensumi/ide-core-browser';
3
+ import { Disposable, Emitter, Event } from '@opensumi/ide-core-common';
9
4
  import { ISingleEditOperation } from '@opensumi/ide-editor';
10
- import {
11
- ICodeEditor,
12
- IEditorDecorationsCollection,
13
- ITextModel,
14
- Position,
15
- Range,
16
- Selection,
17
- } from '@opensumi/ide-monaco';
18
- import { ReactInlineContentWidget } from '@opensumi/ide-monaco/lib/browser/ai-native/BaseInlineContentWidget';
19
- import { URI } from '@opensumi/ide-monaco/lib/browser/monaco-api';
5
+ import { ICodeEditor, IEditorDecorationsCollection, ITextModel, Position, Range } from '@opensumi/ide-monaco';
20
6
  import { StandaloneServices } from '@opensumi/ide-monaco/lib/browser/monaco-api/services';
21
- import { ContentWidgetPositionPreference } from '@opensumi/ide-monaco/lib/browser/monaco-exports/editor';
22
- import { EditorOption } from '@opensumi/monaco-editor-core/esm/vs/editor/common/config/editorOptions';
23
7
  import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
24
8
  import { LineRange } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/lineRange';
25
- import { IScrollEvent } from '@opensumi/monaco-editor-core/esm/vs/editor/common/editorCommon';
26
9
  import { ModelDecorationOptions } from '@opensumi/monaco-editor-core/esm/vs/editor/common/model/textModel';
27
- import { LineTokens } from '@opensumi/monaco-editor-core/esm/vs/editor/common/tokens/lineTokens';
28
- import { IOptions, ZoneWidget } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/zoneWidget/browser/zoneWidget';
29
10
  import {
30
- IResourceUndoRedoElement,
31
11
  IUndoRedoService,
32
- UndoRedoElementType,
12
+ ResourceEditStackSnapshot,
33
13
  UndoRedoGroup,
34
14
  } from '@opensumi/monaco-editor-core/esm/vs/platform/undoRedo/common/undoRedo';
35
15
 
@@ -39,360 +19,29 @@ import {
39
19
  IDecorationSerializableState,
40
20
  IEnhanceModelDeltaDecoration,
41
21
  } from '../../model/enhanceDecorationsCollection';
42
- import { renderLines } from '../ghost-text-widget/index';
43
22
 
44
23
  import styles from './inline-stream-diff.module.less';
45
24
  import { InlineStreamDiffService } from './inline-stream-diff.service';
46
-
47
- const ActiveLineDecoration = 'activeLine-decoration';
48
- const AddedRangeDecoration = 'added-range-decoration';
49
- const PendingRangeDecoration = 'pending-range-decoration';
50
-
51
- interface IPartialEditWidgetComponent {
52
- acceptSequence: string;
53
- discardSequence: string;
54
- }
55
-
56
- export enum EPartialEdit {
57
- accept = 'accept',
58
- discard = 'discard',
59
- }
60
-
61
- export interface IPartialEditEvent {
62
- uri: URI;
63
- /**
64
- * 总 diff 数
65
- */
66
- totalPartialEditCount: number;
67
- /**
68
- * 已处理的个数
69
- */
70
- resolvedPartialEditCount: number;
71
- /**
72
- * 已添加行数
73
- */
74
- totalAddedLinesCount: number;
75
- /**
76
- * 已删除行数
77
- */
78
- totalDeletedLinesCount: number;
79
- currentPartialEdit: {
80
- type: EPartialEdit;
81
- addedLinesCount: number;
82
- deletedLinesCount: number;
83
- };
84
- }
85
-
86
- export interface ITextLinesTokens {
87
- text: string;
88
- lineTokens: LineTokens;
89
- }
90
-
91
- type IWidgetStatus = 'accept' | 'discard' | 'pending';
92
-
93
- export interface IWidgetSerializedState {
94
- addedLinesCount: number;
95
- deletedLinesCount: number;
96
- status: IWidgetStatus;
97
- lineNumber: number;
98
- }
99
-
100
- export interface SerializableState {
101
- addedState: IDecorationSerializableState[];
102
- removedTextLines: IRemovedWidgetSerializedState[];
103
- widgets: IWidgetSerializedState[];
104
- selection: Selection;
105
- }
106
-
107
- const PartialEditComponent = (props: {
108
- keyStrings: IPartialEditWidgetComponent;
109
- onAccept: () => void;
110
- onDiscard: () => void;
111
- editor: ICodeEditor;
112
- }) => {
113
- const { keyStrings, onAccept, onDiscard, editor } = props;
114
- const [scrollLeft, setScrollLeft] = React.useState(0);
115
-
116
- const handleAccept = useCallback(() => {
117
- onAccept?.();
118
- }, [onAccept]);
119
-
120
- const handleDiscard = useCallback(() => {
121
- onDiscard?.();
122
- }, [onDiscard]);
123
-
124
- useDisposable(
125
- () =>
126
- editor.onDidScrollChange((event: IScrollEvent) => {
127
- const { scrollLeftChanged, scrollLeft } = event;
128
- if (scrollLeftChanged) {
129
- setScrollLeft(scrollLeft);
130
- }
131
- }),
132
- [editor],
133
- );
134
-
135
- return (
136
- <div className={styles.inline_diff_accept_partial_widget_container} style={{ marginLeft: scrollLeft + 'px' }}>
137
- <div className={styles.content}>
138
- <span className={cls(styles.accept_btn, styles.btn)} onClick={handleAccept}>
139
- {keyStrings.acceptSequence}
140
- </span>
141
- <span className={cls(styles.discard_btn, styles.btn)} onClick={handleDiscard}>
142
- {keyStrings.discardSequence}
143
- </span>
144
- </div>
145
- </div>
146
- );
147
- };
148
-
149
- @Injectable({ multiple: true })
150
- export class AcceptPartialEditWidget extends ReactInlineContentWidget {
151
- static ID = 'AcceptPartialEditWidgetID';
152
-
153
- @Autowired(KeybindingRegistry)
154
- private readonly keybindingRegistry: KeybindingRegistry;
155
-
156
- private _id: string;
157
- private _decorationId: string;
158
-
159
- private readonly _onAccept = this.registerDispose(new Emitter<void>());
160
- public readonly onAccept: Event<void> = this._onAccept.event;
161
-
162
- private readonly _onDiscard = this.registerDispose(new Emitter<void>());
163
- public readonly onDiscard: Event<void> = this._onDiscard.event;
164
-
165
- positionPreference = [ContentWidgetPositionPreference.EXACT];
166
-
167
- public addedLinesCount: number = 0;
168
- public deletedLinesCount: number = 0;
169
- public status: IWidgetStatus = 'pending';
170
-
171
- private getSequenceKeyStrings(): IPartialEditWidgetComponent | undefined {
172
- let keybindings = this.keybindingRegistry.getKeybindingsForCommand(AI_INLINE_DIFF_PARTIAL_EDIT.id);
173
- keybindings = keybindings.sort((a, b) => b.args - a.args);
174
-
175
- if (!keybindings || (keybindings.length !== 2 && keybindings.some((k) => isUndefined(k.resolved)))) {
176
- return;
177
- }
178
-
179
- return {
180
- acceptSequence: this.keybindingRegistry.acceleratorForSequence(keybindings[0].resolved!, '')[0],
181
- discardSequence: this.keybindingRegistry.acceleratorForSequence(keybindings[1].resolved!, '')[0],
182
- };
183
- }
184
-
185
- public renderView(): React.ReactNode {
186
- const keyStrings = this.getSequenceKeyStrings();
187
- if (!keyStrings) {
188
- return;
189
- }
190
-
191
- return (
192
- <PartialEditComponent
193
- keyStrings={keyStrings}
194
- onAccept={() => this._onAccept.fire()}
195
- onDiscard={() => this._onDiscard.fire()}
196
- editor={this.editor}
197
- />
198
- );
199
- }
200
-
201
- public id(): string {
202
- if (!this._id) {
203
- this._id = `${AcceptPartialEditWidget.ID}_${uuid(4)}`;
204
- }
205
- return this._id;
206
- }
207
-
208
- public getClassName(): string {
209
- return styles.accept_partial_edit_widget_id;
210
- }
211
-
212
- public recordDecorationId(id: string): void {
213
- this._decorationId = id;
214
- }
215
-
216
- public getDecorationId(): string {
217
- return this._decorationId;
218
- }
219
-
220
- public resume(): void {
221
- this.status = 'pending';
222
- this.addedLinesCount = 0;
223
- this.deletedLinesCount = 0;
224
-
225
- super.resume();
226
- }
227
-
228
- public accept(addedLinesCount: number, deletedLinesCount: number): void {
229
- this.status = 'accept';
230
- this.addedLinesCount = addedLinesCount;
231
- this.deletedLinesCount = deletedLinesCount;
232
- super.hide();
233
- }
234
-
235
- get isAccepted(): boolean {
236
- return this.status === 'accept';
237
- }
238
-
239
- public discard(addedLinesCount: number, deletedLinesCount: number): void {
240
- this.status = 'discard';
241
- this.addedLinesCount = addedLinesCount;
242
- this.deletedLinesCount = deletedLinesCount;
243
- super.hide();
244
- }
245
-
246
- get isRejected(): boolean {
247
- return this.status === 'discard';
248
- }
249
-
250
- public serializeState(): IWidgetSerializedState {
251
- return {
252
- addedLinesCount: this.addedLinesCount,
253
- deletedLinesCount: this.deletedLinesCount,
254
- status: this.status,
255
- lineNumber: this.getPosition()!.position!.lineNumber,
256
- };
257
- }
258
-
259
- public restoreSerializedState(state: IWidgetSerializedState) {
260
- if (state.status === 'accept') {
261
- this.accept(state.addedLinesCount, state.deletedLinesCount);
262
- } else if (state.status === 'discard') {
263
- this.discard(state.addedLinesCount, state.deletedLinesCount);
264
- } else {
265
- this.resume();
266
- }
267
- }
268
- }
269
-
270
- export interface IRemovedWidgetSerializedState {
271
- textLines: ITextLinesTokens[];
272
- position: IPosition;
273
- }
274
-
275
- const RemovedWidgetComponent = ({ dom, editor }) => {
276
- const ref = React.useRef<HTMLDivElement>(null);
277
- const [scrollLeft, setScrollLeft] = React.useState(0);
278
- const [marginWidth, setMarginWidth] = React.useState(0);
279
-
280
- useEffect(() => {
281
- if (dom && ref && ref.current) {
282
- ref.current.appendChild(dom);
283
- }
284
- }, [dom, ref]);
285
-
286
- useDisposable(
287
- () =>
288
- editor.onDidScrollChange((event: IScrollEvent) => {
289
- const { scrollLeftChanged, scrollLeft } = event;
290
- if (scrollLeftChanged) {
291
- setScrollLeft(scrollLeft);
292
- }
293
- }),
294
- [editor],
295
- );
296
-
297
- useDisposable(() => {
298
- setMarginWidth(editor.getOption(EditorOption.layoutInfo).contentLeft);
299
- return editor.onDidChangeConfiguration((event) => {
300
- if (event.hasChanged(EditorOption.layoutInfo)) {
301
- setMarginWidth(editor.getOption(EditorOption.layoutInfo).contentLeft);
302
- }
303
- });
304
- }, [editor]);
305
-
306
- return (
307
- <div className={styles.inline_diff_remove_zone_fixed_box} style={{ marginLeft: marginWidth + 'px' }}>
308
- <div className={styles.inline_diff_remove_zone} ref={ref} style={{ marginLeft: -scrollLeft + 'px' }}></div>
309
- </div>
310
- );
311
- };
312
-
313
- class RemovedZoneWidget extends ZoneWidget {
314
- private root: ReactDOMClient.Root;
315
- private recordPositionData: { position: IPosition; heightInLines: number };
316
-
317
- private _hidden: boolean = false;
318
- get isHidden(): boolean {
319
- return this._hidden;
320
- }
321
-
322
- constructor(editor: ICodeEditor, private readonly textLines: ITextLinesTokens[], options: IOptions) {
323
- super(editor, options);
324
- }
325
-
326
- _fillContainer(container: HTMLElement): void {
327
- container.classList.add(styles.inline_diff_remove_zone_widget_container);
328
- this.root = ReactDOMClient.createRoot(container);
329
- }
330
-
331
- getRemovedTextLines(): string[] {
332
- return this.textLines.map((v) => v.text);
333
- }
334
-
335
- get height() {
336
- return this.textLines.length;
337
- }
338
-
339
- getLastPosition(): IPosition {
340
- return this.recordPositionData.position;
341
- }
342
-
343
- serializeState(): IRemovedWidgetSerializedState {
344
- return {
345
- textLines: this.textLines,
346
- position: this.getLastPosition(),
347
- };
348
- }
349
-
350
- hide(): void {
351
- if (this._viewZone && this.position) {
352
- this.recordPositionData = {
353
- position: this.position,
354
- heightInLines: this._viewZone?.heightInLines,
355
- };
356
- }
357
- this._hidden = true;
358
- super.hide();
359
- }
360
-
361
- resume(): void {
362
- if (this.recordPositionData) {
363
- this.show(this.recordPositionData.position, this.recordPositionData.heightInLines);
364
- }
365
- }
366
-
367
- override show(pos: IPosition, heightInLines: number): void {
368
- this.recordPositionData = { position: pos, heightInLines };
369
- this._hidden = false;
370
- super.show(pos, heightInLines);
371
- }
372
-
373
- override revealRange(): void {}
374
-
375
- override create(): void {
376
- super.create();
377
- const dom = document.createElement('div');
378
- renderLines(
379
- dom,
380
- this.editor.getOption(EditorOption.tabIndex),
381
- this.textLines.map(({ text: content, lineTokens }) => ({
382
- content,
383
- decorations: [],
384
- lineTokens,
385
- })),
386
- this.editor.getOptions(),
387
- );
388
-
389
- this.root.render(<RemovedWidgetComponent dom={dom} editor={this.editor} />);
390
- }
391
-
392
- dispose(): void {
393
- this.root.unmount();
394
- super.dispose();
395
- }
25
+ import { LivePreviewUndoRedoStackElement } from './live-preview-stack';
26
+ import {
27
+ AcceptPartialEditWidget,
28
+ ActiveLineDecoration,
29
+ AddedRangeDecoration,
30
+ EPartialEdit,
31
+ IPartialEditEvent,
32
+ IRemovedWidgetState,
33
+ IRemovedZoneWidgetOptions,
34
+ ITextLinesTokens,
35
+ PendingRangeDecoration,
36
+ RemovedZoneWidget,
37
+ } from './live-preview.component';
38
+
39
+ export interface ILivePreviewDiffDecorationSnapshotData {
40
+ addedDecList: IEnhanceModelDeltaDecoration[];
41
+ partialEditWidgetList: AcceptPartialEditWidget[];
42
+ removedWidgetList: RemovedZoneWidget[];
43
+ editStackSnapshot: ResourceEditStackSnapshot;
44
+ zone: LineRange;
396
45
  }
397
46
 
398
47
  @Injectable({ multiple: true })
@@ -408,15 +57,8 @@ export class LivePreviewDiffDecorationModel extends Disposable {
408
57
 
409
58
  private activeLineDec: IEditorDecorationsCollection;
410
59
  private pendingRangeDec: IEditorDecorationsCollection;
411
-
412
- private addedRangeDec: EnhanceDecorationsCollection;
413
- private partialEditWidgetList: AcceptPartialEditWidget[] = [];
414
- private removedZoneWidgets: Array<RemovedZoneWidget> = [];
415
-
416
- private undoRedoService: IUndoRedoService;
417
-
418
- private zone: LineRange;
419
60
  private aiNativeContextKey: AINativeContextKey;
61
+ private undoRedoService: IUndoRedoService;
420
62
 
421
63
  protected readonly _onPartialEditWidgetListChange = this.registerDispose(new Emitter<AcceptPartialEditWidget[]>());
422
64
  public readonly onPartialEditWidgetListChange: Event<AcceptPartialEditWidget[]> =
@@ -424,39 +66,23 @@ export class LivePreviewDiffDecorationModel extends Disposable {
424
66
 
425
67
  protected model: ITextModel;
426
68
 
427
- constructor(private readonly monacoEditor: ICodeEditor, private selection: Selection) {
69
+ // Parts that require snapshots
70
+ private addedRangeDec: EnhanceDecorationsCollection;
71
+ private partialEditWidgetList: AcceptPartialEditWidget[] = [];
72
+ private removedZoneWidgets: Array<RemovedZoneWidget> = [];
73
+ private zone: LineRange;
74
+
75
+ constructor(private readonly monacoEditor: ICodeEditor) {
428
76
  super();
429
77
  this.model = this.monacoEditor.getModel()!;
430
78
 
79
+ this.undoRedoService = StandaloneServices.get(IUndoRedoService);
80
+
431
81
  this.activeLineDec = this.monacoEditor.createDecorationsCollection();
432
82
  this.pendingRangeDec = this.monacoEditor.createDecorationsCollection();
433
83
 
434
- this.addedRangeDec = new EnhanceDecorationsCollection(this.monacoEditor);
435
84
  this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.monacoEditor.contextKeyService]);
436
85
 
437
- this.undoRedoService = StandaloneServices.get(IUndoRedoService);
438
-
439
- this.updateSelection(selection);
440
-
441
- this.addDispose(
442
- this.addedRangeDec.onDidDecorationsChange((newAddedRangeDec) => {
443
- const inlineDiffPartialEditsIsVisible = this.aiNativeContextKey.inlineDiffPartialEditsIsVisible.get();
444
- if (inlineDiffPartialEditsIsVisible) {
445
- this.partialEditWidgetList.forEach((widget) => {
446
- const addedWidget = newAddedRangeDec.find((a) => widget.getDecorationId() === a.id);
447
- if (addedWidget) {
448
- const range = addedWidget.getRange();
449
- /**
450
- * 重新定位 added decoration 与 partial edit widget 的位置
451
- */
452
- widget.setOptions({ position: { lineNumber: range.startLineNumber, column: 1 } });
453
- widget.layoutContentWidget();
454
- }
455
- });
456
- }
457
- }),
458
- );
459
-
460
86
  this.addDispose(
461
87
  this.inlineStreamDiffService.onAcceptDiscardPartialEdit((isAccept) => {
462
88
  const currentPosition = this.monacoEditor.getPosition()!;
@@ -482,6 +108,26 @@ export class LivePreviewDiffDecorationModel extends Disposable {
482
108
  }),
483
109
  );
484
110
 
111
+ this.addedRangeDec = new EnhanceDecorationsCollection(this.monacoEditor);
112
+ this.addDispose(
113
+ this.addedRangeDec.onDidDecorationsChange((newAddedRangeDec) => {
114
+ const inlineDiffPartialEditsIsVisible = this.aiNativeContextKey.inlineDiffPartialEditsIsVisible.get();
115
+ if (inlineDiffPartialEditsIsVisible) {
116
+ this.partialEditWidgetList.forEach((widget) => {
117
+ const addedWidget = newAddedRangeDec.find((a) => widget.getDecorationId() === a.id);
118
+ if (addedWidget) {
119
+ const range = addedWidget.getRange();
120
+ /**
121
+ * 重新定位 added decoration 与 partial edit widget 的位置
122
+ */
123
+ widget.setOptions({ position: { lineNumber: range.startLineNumber, column: 1 } });
124
+ widget.layoutContentWidget();
125
+ }
126
+ });
127
+ }
128
+ }),
129
+ );
130
+
485
131
  this.addDispose(
486
132
  Disposable.create(() => {
487
133
  this.clear();
@@ -497,32 +143,103 @@ export class LivePreviewDiffDecorationModel extends Disposable {
497
143
  this.clearPartialEditWidgetList();
498
144
  }
499
145
 
500
- public updateSelection(selection: Selection) {
501
- this.selection = selection;
502
- this.updateZone(
503
- LineRange.fromRangeInclusive(
504
- Range.fromPositions(
505
- { lineNumber: this.selection.startLineNumber, column: 1 },
506
- { lineNumber: this.selection.endLineNumber, column: Number.MAX_SAFE_INTEGER },
507
- ),
508
- ),
509
- );
146
+ initialize(zone: LineRange): void {
147
+ this.updateZone(zone);
148
+ }
149
+
150
+ restoreSnapshot(snapshot: ILivePreviewDiffDecorationSnapshotData): void {
151
+ const {
152
+ addedDecList,
153
+ removedWidgetList,
154
+ zone,
155
+ editStackSnapshot,
156
+ partialEditWidgetList: snapshotPartialEditWidgetList,
157
+ } = snapshot;
158
+
159
+ // restore zone
160
+ this.updateZone(zone);
161
+
162
+ // restore added
163
+ this.addedRangeDec.set(addedDecList);
164
+
165
+ // restore removed
166
+ this.clearRemovedWidgets();
167
+ removedWidgetList.forEach((widget) => {
168
+ const position = widget.getLastPosition();
169
+ if (position) {
170
+ this.showRemovedWidgetByLineNumber(position.lineNumber, widget.textLines, {
171
+ isHidden: widget.isHidden,
172
+ recordPosition: widget.getLastPosition(),
173
+ undoRedoGroup: widget.group,
174
+ });
175
+ }
176
+ });
177
+
178
+ // restore partial edit widget
179
+ this.clearPartialEditWidgetList();
180
+ snapshotPartialEditWidgetList.forEach((snapshotWidget) => {
181
+ const lineNumber = snapshotWidget.getPosition()?.position?.lineNumber;
182
+ if (lineNumber) {
183
+ const newPartialEditWidget = this.createPartialEditWidget(lineNumber);
184
+
185
+ if (snapshotWidget.status === 'accept') {
186
+ newPartialEditWidget.accept(snapshotWidget.addedLinesCount, snapshotWidget.deletedLinesCount);
187
+ } else if (snapshotWidget.status === 'discard') {
188
+ newPartialEditWidget.discard(snapshotWidget.addedLinesCount, snapshotWidget.deletedLinesCount);
189
+ }
190
+
191
+ newPartialEditWidget.setGroup(snapshotWidget.group);
192
+ this.partialEditWidgetList.push(newPartialEditWidget);
193
+ }
194
+ });
195
+ this.firePartialEditWidgetList();
196
+ this.recordPartialEditWidgetWithAddedDec();
197
+
198
+ // restore undo/redo stack
199
+ const uri = this.model.uri;
200
+ this.undoRedoService.restoreSnapshot(editStackSnapshot);
201
+ const elements = this.undoRedoService.getElements(uri);
202
+ elements.future.concat(elements.past).forEach((node) => {
203
+ if (node instanceof LivePreviewUndoRedoStackElement) {
204
+ // 在每次 restore 的时候需要将当前的类重新指向到 undo/redo 的 stack 中
205
+ node.attachModel(this);
206
+ }
207
+ });
510
208
  }
511
209
 
512
- public showRemovedWidgetByLineNumber(lineNumber: number, texts: ITextLinesTokens[]): void {
210
+ createSnapshot(): ILivePreviewDiffDecorationSnapshotData {
211
+ return {
212
+ addedDecList: this.addedRangeDec.getDecorations(),
213
+ partialEditWidgetList: this.partialEditWidgetList,
214
+ removedWidgetList: this.removedZoneWidgets,
215
+ editStackSnapshot: this.undoRedoService.createSnapshot(this.model.uri),
216
+ zone: this.zone,
217
+ };
218
+ }
219
+
220
+ public showRemovedWidgetByLineNumber(
221
+ lineNumber: number,
222
+ texts: ITextLinesTokens[],
223
+ options: IRemovedZoneWidgetOptions,
224
+ ): void {
513
225
  const position = new Position(lineNumber, 1);
514
226
  const heightInLines = texts.length;
515
227
 
516
228
  const widget = new RemovedZoneWidget(this.monacoEditor, texts, {
229
+ ...options,
517
230
  showInHiddenAreas: true,
518
231
  showFrame: false,
519
232
  showArrow: false,
520
233
  });
521
234
 
522
235
  widget.create();
523
- widget.show(position, heightInLines);
524
-
525
236
  this.removedZoneWidgets.push(widget);
237
+
238
+ if (options.isHidden) {
239
+ widget.hide();
240
+ } else {
241
+ widget.show(position, heightInLines);
242
+ }
526
243
  }
527
244
 
528
245
  public updateZone(newZone: LineRange): void {
@@ -538,16 +255,10 @@ export class LivePreviewDiffDecorationModel extends Disposable {
538
255
 
539
256
  this.activeLineDec.set([
540
257
  {
541
- range: Range.fromPositions(
542
- {
543
- lineNumber: zone.startLineNumber + lineNumber - 1,
544
- column: 0,
545
- },
546
- {
547
- lineNumber: zone.startLineNumber + lineNumber - 1,
548
- column: Number.MAX_SAFE_INTEGER,
549
- },
550
- ),
258
+ range: Range.fromPositions({
259
+ lineNumber: zone.startLineNumber + lineNumber - 1,
260
+ column: 0,
261
+ }),
551
262
  options: ModelDecorationOptions.register({
552
263
  description: ActiveLineDecoration,
553
264
  isWholeLine: true,
@@ -584,7 +295,7 @@ export class LivePreviewDiffDecorationModel extends Disposable {
584
295
  }
585
296
 
586
297
  if (removedWidget) {
587
- const position = removedWidget.position!;
298
+ const position = removedWidget.getLastPosition();
588
299
  const eol = this.model.getEOL();
589
300
 
590
301
  const lines = removedWidget.getRemovedTextLines();
@@ -611,60 +322,93 @@ export class LivePreviewDiffDecorationModel extends Disposable {
611
322
  * added widget 通常是在 removed widget 的下面一行的位置
612
323
  */
613
324
  const removedWidget = this.removedZoneWidgets.find(
614
- (w) => w.position?.lineNumber === Math.max(1, position.lineNumber - 1),
325
+ (w) => w.getLastPosition().lineNumber === Math.max(1, position.lineNumber - 1),
615
326
  );
616
- const addedDec = this.addedRangeDec.getDecorationByLineNumber(position.lineNumber);
617
327
 
328
+ const addedDec = this.addedRangeDec.getDecorationByLineNumber(position.lineNumber);
618
329
  const addedLinesCount = addedDec?.length || 0;
619
330
  const deletedLinesCount = removedWidget?.height || 0;
620
331
 
621
- const accpet = () => {
622
- widget.accept(addedLinesCount, deletedLinesCount);
623
- addedDec?.hide();
332
+ // partial widget 的所有操作和代码变更放在单独的 undo/redo 堆栈组里面
333
+ const group = new UndoRedoGroup();
334
+ // 并将此刻的 group 信息记录到每个 widget/decoration 中
335
+ widget.setGroup(group);
336
+ removedWidget?.setGroup(group);
337
+ addedDec?.setGroup(group);
338
+
339
+ /**
340
+ * 在 undo/redo 的 stack 中,原本的 widget 和 decoration 信息已经是旧的数据了,所以不能直接拿旧的数据进行 resume 或 accept
341
+ * 需要根据 group 信息和当前实例的 LivePreviewDiffDecorationModel 对象重新找到 widget 和 decoration
342
+ */
343
+ const findPartialWidgetByGroup = (model: LivePreviewDiffDecorationModel) =>
344
+ model.partialEditWidgetList.find((widget) => widget.group === group);
345
+ const findRemovedWidgetByGroup = (model: LivePreviewDiffDecorationModel) =>
346
+ model.removedZoneWidgets.find((widget) => widget.group === group);
347
+ const findAddedRangeDecByGroup = (model: LivePreviewDiffDecorationModel) =>
348
+ model.addedRangeDec.getDecorationByGroup(group);
349
+
350
+ const discard = (decorationModel: LivePreviewDiffDecorationModel) => {
351
+ const removedWidget = findRemovedWidgetByGroup(decorationModel);
624
352
  removedWidget?.hide();
353
+
354
+ const addedDec = findAddedRangeDecByGroup(decorationModel);
355
+ addedDec?.hide();
356
+
357
+ const partialEditWidget = findPartialWidgetByGroup(decorationModel);
358
+ const operation = this.doDiscardPartialWidget(partialEditWidget!, addedDec, removedWidget);
359
+
360
+ return operation;
625
361
  };
626
362
 
627
- const discard = () => {
628
- const operation = this.doDiscardPartialWidget(widget, addedDec, removedWidget);
363
+ const accpet = (decorationModel: LivePreviewDiffDecorationModel) => {
364
+ const partialEditWidget = findPartialWidgetByGroup(decorationModel);
365
+ partialEditWidget?.accept(addedLinesCount, deletedLinesCount);
629
366
 
630
- addedDec?.hide();
367
+ const removedWidget = findRemovedWidgetByGroup(decorationModel);
631
368
  removedWidget?.hide();
632
369
 
633
- return operation;
370
+ const addedDec = findAddedRangeDecByGroup(decorationModel);
371
+ addedDec?.hide();
634
372
  };
635
373
 
636
- const resume = () => {
637
- widget.resume();
638
- addedDec?.resume();
374
+ const resume = (decorationModel: LivePreviewDiffDecorationModel) => {
375
+ const partialEditWidget = findPartialWidgetByGroup(decorationModel);
376
+ partialEditWidget?.resume();
377
+
378
+ const removedWidget = findRemovedWidgetByGroup(decorationModel);
639
379
  removedWidget?.resume();
640
- };
641
380
 
642
- /**
643
- * 将 partial widget 的所有操作和代码变更放在单独的 undo/redo 堆栈组里面
644
- */
645
- const group = new UndoRedoGroup();
381
+ const addedDec = findAddedRangeDecByGroup(decorationModel);
382
+ addedDec?.resume();
383
+ };
646
384
 
647
385
  switch (type) {
648
386
  case EPartialEdit.accept:
649
- accpet();
387
+ accpet(this);
650
388
  if (isPushStack) {
651
- this.pushUndoElement({
652
- undo: () => resume(),
653
- redo: () => accpet(),
654
- group,
389
+ const stack = this.createEditStackElement(group);
390
+ stack.attachModel(this);
391
+ stack.registerUndo((model: LivePreviewDiffDecorationModel) => {
392
+ resume(model);
393
+ });
394
+ stack.registerRedo((model: LivePreviewDiffDecorationModel) => {
395
+ accpet(model);
655
396
  });
656
397
  }
657
398
  break;
658
399
 
659
400
  case EPartialEdit.discard:
660
401
  {
661
- const op = discard();
402
+ const op = discard(this);
662
403
  if (op) {
663
404
  if (isPushStack) {
664
- this.pushUndoElement({
665
- undo: () => resume(),
666
- redo: () => discard(),
667
- group,
405
+ const stack = this.createEditStackElement(group);
406
+ stack.attachModel(this);
407
+ stack.registerUndo((model: LivePreviewDiffDecorationModel) => {
408
+ resume(model);
409
+ });
410
+ stack.registerRedo((model: LivePreviewDiffDecorationModel) => {
411
+ discard(model);
668
412
  });
669
413
  }
670
414
  model.pushStackElement();
@@ -692,7 +436,19 @@ export class LivePreviewDiffDecorationModel extends Disposable {
692
436
  this.monacoEditor.focus();
693
437
 
694
438
  this._onPartialEditEvent.fire(event);
439
+ this.firePartialEditWidgetList();
440
+ }
441
+
442
+ private firePartialEditWidgetList(): void {
695
443
  this._onPartialEditWidgetListChange.fire(this.partialEditWidgetList);
444
+ const visiableLists = this.partialEditWidgetList.filter((widget) => !widget.isHidden);
445
+ this.aiNativeContextKey.inlineDiffPartialEditsIsVisible.set(visiableLists.length !== 0);
446
+ }
447
+
448
+ public createEditStackElement(group: UndoRedoGroup): LivePreviewUndoRedoStackElement {
449
+ const newElement = new LivePreviewUndoRedoStackElement(this.model);
450
+ this.undoRedoService.pushElement(newElement, group);
451
+ return newElement;
696
452
  }
697
453
 
698
454
  protected getTotalCodeCount(): {
@@ -735,62 +491,33 @@ export class LivePreviewDiffDecorationModel extends Disposable {
735
491
  });
736
492
  }
737
493
 
738
- public pushUndoElement(data: { undo: () => void; redo: () => void; group?: UndoRedoGroup }): void {
739
- const resource = this.model.uri;
740
- const group = data.group ?? new UndoRedoGroup();
494
+ private createPartialEditWidget(lineNumber: number): AcceptPartialEditWidget {
495
+ const acceptPartialEditWidget = this.injector.get(AcceptPartialEditWidget, [this.monacoEditor]);
496
+ acceptPartialEditWidget.show({ position: { lineNumber, column: 1 } });
741
497
 
742
- this.undoRedoService.pushElement(
743
- {
744
- type: UndoRedoElementType.Resource,
745
- resource,
746
- label: 'Live.Preview.UndoRedo',
747
- undo: () => {
748
- if (!this.disposed) {
749
- data.undo();
750
- }
751
- },
752
- redo: () => {
753
- if (!this.disposed) {
754
- data.redo();
755
- }
756
- },
757
- } as IResourceUndoRedoElement,
758
- group,
759
- );
760
- }
761
-
762
- public touchPartialEditWidgets(startLineNumbers: number[]) {
763
- this.clearPartialEditWidgetList();
764
-
765
- startLineNumbers.forEach((lineNumber) => {
766
- const dispoable = new Disposable();
767
- const acceptPartialEditWidget = this.injector.get(AcceptPartialEditWidget, [this.monacoEditor]);
768
- acceptPartialEditWidget.show({ position: { lineNumber, column: 1 } });
769
-
770
- dispoable.addDispose(
771
- acceptPartialEditWidget.onDispose(() => {
772
- const id = acceptPartialEditWidget.getId();
773
- this.partialEditWidgetList = this.partialEditWidgetList.filter((p) => p.getId() !== id);
774
-
775
- dispoable.dispose();
776
- }),
777
- );
778
-
779
- acceptPartialEditWidget.addDispose([
780
- acceptPartialEditWidget.onAccept(() => {
781
- this.handlePartialEditAction(EPartialEdit.accept, acceptPartialEditWidget);
782
- }),
783
- acceptPartialEditWidget.onDiscard(() => {
784
- this.handlePartialEditAction(EPartialEdit.discard, acceptPartialEditWidget);
785
- }),
786
- ]);
498
+ const disposable = acceptPartialEditWidget.onDispose(() => {
499
+ const id = acceptPartialEditWidget.getId();
500
+ this.partialEditWidgetList = this.partialEditWidgetList.filter((p) => p.getId() !== id);
787
501
 
788
- this.partialEditWidgetList.push(acceptPartialEditWidget);
502
+ disposable.dispose();
789
503
  });
790
504
 
791
- this._onPartialEditWidgetListChange.fire(this.partialEditWidgetList);
505
+ acceptPartialEditWidget.addDispose([
506
+ acceptPartialEditWidget.onAccept(() => {
507
+ this.handlePartialEditAction(EPartialEdit.accept, acceptPartialEditWidget);
508
+ }),
509
+ acceptPartialEditWidget.onDiscard(() => {
510
+ this.handlePartialEditAction(EPartialEdit.discard, acceptPartialEditWidget);
511
+ }),
512
+ ]);
792
513
 
793
- this.aiNativeContextKey.inlineDiffPartialEditsIsVisible.set(true);
514
+ return acceptPartialEditWidget;
515
+ }
516
+
517
+ public touchPartialEditWidgets(lineNumbers: number[]) {
518
+ this.clearPartialEditWidgetList();
519
+ this.partialEditWidgetList = lineNumbers.map((lineNumber) => this.createPartialEditWidget(lineNumber));
520
+ this.firePartialEditWidgetList();
794
521
  }
795
522
 
796
523
  public touchAddedRange(ranges: IDecorationSerializableState[]) {
@@ -811,11 +538,11 @@ export class LivePreviewDiffDecorationModel extends Disposable {
811
538
  return {
812
539
  length,
813
540
  range,
541
+ isHidden: length === 0,
814
542
  options: ModelDecorationOptions.register({
815
543
  description: AddedRangeDecoration,
816
544
  isWholeLine: true,
817
545
  className,
818
- // stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
819
546
  }),
820
547
  };
821
548
  }),
@@ -824,11 +551,11 @@ export class LivePreviewDiffDecorationModel extends Disposable {
824
551
  this.recordPartialEditWidgetWithAddedDec();
825
552
  }
826
553
 
827
- public touchRemovedWidget(states: IRemovedWidgetSerializedState[]) {
554
+ public touchRemovedWidget(states: IRemovedWidgetState[]) {
828
555
  this.clearRemovedWidgets();
829
556
 
830
557
  states.forEach(({ textLines, position }) => {
831
- this.showRemovedWidgetByLineNumber(position.lineNumber, textLines);
558
+ this.showRemovedWidgetByLineNumber(position.lineNumber, textLines, {});
832
559
  });
833
560
  }
834
561
 
@@ -883,40 +610,13 @@ export class LivePreviewDiffDecorationModel extends Disposable {
883
610
  this.removedZoneWidgets = [];
884
611
  }
885
612
 
886
- serializeState(): SerializableState {
887
- const addedState = this.addedRangeDec.serializeState();
888
- const removedTextLines = this.removedZoneWidgets.filter((v) => !v.isHidden).map((w) => w.serializeState());
889
- const widgets = this.partialEditWidgetList.map((w) => w.serializeState());
890
-
891
- const state = {
892
- addedState,
893
- removedTextLines,
894
- widgets,
895
- selection: this.selection,
896
- };
897
- return state;
898
- }
899
-
900
- restoreSerializedState(state: SerializableState): void {
901
- this.clear();
902
-
903
- this.touchAddedRange(state.addedState);
904
- const widgetLineNumber = state.widgets.map((w) => w.lineNumber);
905
- this.touchPartialEditWidgets(widgetLineNumber);
906
- widgetLineNumber.forEach((range, index) => {
907
- const widget = this.partialEditWidgetList[index];
908
- if (widget) {
909
- widget.restoreSerializedState(state.widgets[index]);
910
- }
911
- });
912
- this.touchRemovedWidget(state.removedTextLines);
913
- }
914
-
915
613
  revealFirstDiff(): void {
916
614
  const first = this.removedZoneWidgets[0];
917
615
  if (first) {
918
616
  const pos = first.getLastPosition();
919
- this.monacoEditor.revealLineInCenterIfOutsideViewport(pos.lineNumber);
617
+ if (pos) {
618
+ this.monacoEditor.revealLineInCenterIfOutsideViewport(pos.lineNumber);
619
+ }
920
620
  }
921
621
  }
922
622
  }