@opensumi/ide-ai-native 3.2.5 → 3.2.6-next-1724809247.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.contribution.d.ts +1 -0
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +12 -23
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/ai-editor.contribution.d.ts +1 -0
- package/lib/browser/ai-editor.contribution.d.ts.map +1 -1
- package/lib/browser/ai-editor.contribution.js +8 -0
- package/lib/browser/ai-editor.contribution.js.map +1 -1
- package/lib/browser/chat/chat-agent.service.d.ts +1 -0
- package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-agent.service.js +1 -3
- package/lib/browser/chat/chat-agent.service.js.map +1 -1
- package/lib/browser/chat/chat.module.less +1 -0
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +21 -3
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatEditor.d.ts.map +1 -1
- package/lib/browser/components/ChatEditor.js +2 -2
- package/lib/browser/components/ChatEditor.js.map +1 -1
- package/lib/browser/components/ChatMarkdown.js +1 -1
- package/lib/browser/components/ChatMarkdown.js.map +1 -1
- package/lib/browser/components/ChatThinking.d.ts.map +1 -1
- package/lib/browser/components/ChatThinking.js +2 -2
- package/lib/browser/components/ChatThinking.js.map +1 -1
- package/lib/browser/contextkey/ai-native.contextkey.service.d.ts +1 -0
- package/lib/browser/contextkey/ai-native.contextkey.service.d.ts.map +1 -1
- package/lib/browser/contextkey/ai-native.contextkey.service.js +1 -0
- package/lib/browser/contextkey/ai-native.contextkey.service.js.map +1 -1
- package/lib/browser/contrib/inline-completions/completeProvider.d.ts +4 -31
- package/lib/browser/contrib/inline-completions/completeProvider.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/completeProvider.js +3 -224
- package/lib/browser/contrib/inline-completions/completeProvider.js.map +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts +1 -3
- package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.handler.js +8 -20
- package/lib/browser/contrib/inline-completions/inline-completions.handler.js.map +1 -1
- package/lib/browser/contrib/inline-completions/model/competionModel.d.ts +2 -2
- package/lib/browser/contrib/inline-completions/model/competionModel.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts +28 -0
- package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts.map +1 -0
- package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js +209 -0
- package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js.map +1 -0
- package/lib/browser/contrib/inline-completions/promptCache.d.ts +3 -2
- package/lib/browser/contrib/inline-completions/promptCache.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/promptCache.js.map +1 -1
- package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts +5 -6
- package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/service/ai-completions.service.js +33 -23
- package/lib/browser/contrib/inline-completions/service/ai-completions.service.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts +18 -0
- package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/diff-computer.js +144 -0
- package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +8 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +47 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts +15 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts +8 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js +19 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts +20 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js +94 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.js +3 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts +33 -0
- package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js +258 -0
- package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js.map +1 -0
- package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts +0 -1
- package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts.map +1 -1
- package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js +0 -3
- package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +7 -0
- 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 +4 -4
- package/lib/browser/layout/ai-layout.js.map +1 -1
- package/lib/browser/layout/layout.module.less +0 -9
- package/lib/browser/model/enhanceDecorationsCollection.d.ts +38 -4
- package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
- package/lib/browser/model/enhanceDecorationsCollection.js +44 -23
- package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
- package/lib/browser/types.d.ts +20 -13
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/types.js +0 -4
- package/lib/browser/types.js.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat.handler.js +18 -10
- package/lib/browser/widget/inline-chat/inline-chat.handler.js.map +1 -1
- package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +5 -2
- package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-content-widget.js +45 -53
- package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +16 -14
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js +98 -46
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts +5 -2
- package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-widget.js +11 -2
- package/lib/browser/widget/inline-diff/inline-diff-widget.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts +12 -13
- package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.handler.js +69 -77
- package/lib/browser/widget/inline-diff/inline-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-input/inline-input-widget.d.ts +1 -0
- package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
- package/lib/browser/widget/inline-input/inline-input-widget.js +1 -0
- package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
- package/lib/browser/widget/inline-input/inline-input.handler.js +2 -2
- package/lib/browser/widget/inline-input/inline-input.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +28 -15
- 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 +56 -31
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
- package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts +21 -0
- package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts.map +1 -0
- package/lib/browser/widget/inline-stream-diff/live-preview-stack.js +41 -0
- package/lib/browser/widget/inline-stream-diff/live-preview-stack.js.map +1 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +105 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js +237 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +27 -103
- 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 +186 -370
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/lib/common/index.d.ts +1 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js.map +1 -1
- package/package.json +19 -19
- package/src/browser/ai-core.contribution.ts +12 -26
- package/src/browser/ai-editor.contribution.ts +9 -0
- package/src/browser/chat/chat-agent.service.ts +1 -3
- package/src/browser/chat/chat.module.less +1 -0
- package/src/browser/chat/chat.view.tsx +48 -3
- package/src/browser/components/ChatEditor.tsx +14 -2
- package/src/browser/components/ChatMarkdown.tsx +1 -1
- package/src/browser/components/ChatThinking.tsx +3 -1
- package/src/browser/contextkey/ai-native.contextkey.service.ts +3 -0
- package/src/browser/contrib/inline-completions/completeProvider.ts +7 -289
- package/src/browser/contrib/inline-completions/inline-completions.handler.ts +15 -22
- package/src/browser/contrib/inline-completions/model/competionModel.ts +3 -2
- package/src/browser/contrib/inline-completions/model/inlineCompletionRequestTask.ts +270 -0
- package/src/browser/contrib/inline-completions/promptCache.ts +3 -2
- package/src/browser/contrib/inline-completions/service/ai-completions.service.ts +37 -36
- package/src/browser/contrib/intelligent-completions/diff-computer.ts +185 -0
- package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +54 -0
- package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts +17 -0
- package/src/browser/contrib/intelligent-completions/intelligent-completions.handler.ts +130 -0
- package/src/browser/contrib/intelligent-completions/intelligent-completions.ts +15 -0
- package/src/browser/contrib/intelligent-completions/multi-line.decoration.ts +325 -0
- package/src/browser/contrib/merge-conflict/merge-conflict.feature.registry.ts +0 -4
- package/src/browser/index.ts +8 -1
- package/src/browser/layout/ai-layout.tsx +7 -1
- package/src/browser/layout/layout.module.less +0 -9
- package/src/browser/model/enhanceDecorationsCollection.ts +71 -34
- package/src/browser/types.ts +27 -14
- package/src/browser/widget/inline-chat/inline-chat.handler.ts +20 -16
- package/src/browser/widget/inline-chat/inline-content-widget.tsx +58 -61
- package/src/browser/widget/inline-diff/inline-diff-previewer.ts +102 -62
- package/src/browser/widget/inline-diff/inline-diff-widget.tsx +36 -5
- package/src/browser/widget/inline-diff/inline-diff.handler.ts +82 -94
- package/src/browser/widget/inline-input/inline-input-widget.tsx +1 -0
- package/src/browser/widget/inline-input/inline-input.handler.ts +2 -2
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +108 -45
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
- package/src/browser/widget/inline-stream-diff/live-preview-stack.ts +52 -0
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +388 -0
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +244 -544
- 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 {
|
|
7
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
|
|
501
|
-
this.
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
-
|
|
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,21 +255,15 @@ export class LivePreviewDiffDecorationModel extends Disposable {
|
|
|
538
255
|
|
|
539
256
|
this.activeLineDec.set([
|
|
540
257
|
{
|
|
541
|
-
range: Range.fromPositions(
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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,
|
|
554
265
|
className: styles.inline_diff_current,
|
|
555
|
-
zIndex: StackingLevel.
|
|
266
|
+
zIndex: StackingLevel.Workbench,
|
|
556
267
|
}),
|
|
557
268
|
},
|
|
558
269
|
]);
|
|
@@ -584,7 +295,7 @@ export class LivePreviewDiffDecorationModel extends Disposable {
|
|
|
584
295
|
}
|
|
585
296
|
|
|
586
297
|
if (removedWidget) {
|
|
587
|
-
const position = removedWidget.
|
|
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.
|
|
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
|
-
|
|
622
|
-
|
|
623
|
-
|
|
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
|
|
628
|
-
const
|
|
363
|
+
const accpet = (decorationModel: LivePreviewDiffDecorationModel) => {
|
|
364
|
+
const partialEditWidget = findPartialWidgetByGroup(decorationModel);
|
|
365
|
+
partialEditWidget?.accept(addedLinesCount, deletedLinesCount);
|
|
629
366
|
|
|
630
|
-
|
|
367
|
+
const removedWidget = findRemovedWidgetByGroup(decorationModel);
|
|
631
368
|
removedWidget?.hide();
|
|
632
369
|
|
|
633
|
-
|
|
370
|
+
const addedDec = findAddedRangeDecByGroup(decorationModel);
|
|
371
|
+
addedDec?.hide();
|
|
634
372
|
};
|
|
635
373
|
|
|
636
|
-
const resume = () => {
|
|
637
|
-
|
|
638
|
-
|
|
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
|
-
|
|
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.
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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.
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
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
|
-
|
|
739
|
-
const
|
|
740
|
-
|
|
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
|
-
|
|
743
|
-
|
|
744
|
-
|
|
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
|
-
|
|
502
|
+
disposable.dispose();
|
|
789
503
|
});
|
|
790
504
|
|
|
791
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
617
|
+
if (pos) {
|
|
618
|
+
this.monacoEditor.revealLineInCenterIfOutsideViewport(pos.lineNumber);
|
|
619
|
+
}
|
|
920
620
|
}
|
|
921
621
|
}
|
|
922
622
|
}
|