@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
|
@@ -226,6 +226,18 @@ export class InlineChatHandler extends Disposable {
|
|
|
226
226
|
return;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
const previewer = () => {
|
|
230
|
+
// 兼容 providerDiffPreviewStrategy api
|
|
231
|
+
const strategy = handler.providerDiffPreviewStrategy
|
|
232
|
+
? handler.providerDiffPreviewStrategy
|
|
233
|
+
: handler.providePreviewStrategy;
|
|
234
|
+
if (!strategy) {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return strategy.bind(this, monacoEditor, this.cancelIndicator.token);
|
|
239
|
+
};
|
|
240
|
+
|
|
229
241
|
this.runInlineChatAction(
|
|
230
242
|
monacoEditor,
|
|
231
243
|
() => {
|
|
@@ -238,9 +250,7 @@ export class InlineChatHandler extends Disposable {
|
|
|
238
250
|
return relationId;
|
|
239
251
|
},
|
|
240
252
|
handler.execute ? handler.execute!.bind(this, monacoEditor, this.cancelIndicator.token) : undefined,
|
|
241
|
-
|
|
242
|
-
? handler.providerDiffPreviewStrategy.bind(this, monacoEditor, this.cancelIndicator.token)
|
|
243
|
-
: undefined,
|
|
253
|
+
previewer(),
|
|
244
254
|
);
|
|
245
255
|
}),
|
|
246
256
|
);
|
|
@@ -268,8 +278,8 @@ export class InlineChatHandler extends Disposable {
|
|
|
268
278
|
handler.execute && strategy === ERunStrategy.EXECUTE
|
|
269
279
|
? handler.execute!.bind(this, monacoEditor, value, this.cancelIndicator.token)
|
|
270
280
|
: undefined,
|
|
271
|
-
handler.
|
|
272
|
-
? handler.
|
|
281
|
+
handler.providePreviewStrategy && strategy === ERunStrategy.PREVIEW
|
|
282
|
+
? handler.providePreviewStrategy.bind(this, monacoEditor, value, this.cancelIndicator.token)
|
|
273
283
|
: undefined,
|
|
274
284
|
);
|
|
275
285
|
}),
|
|
@@ -400,7 +410,7 @@ export class InlineChatHandler extends Disposable {
|
|
|
400
410
|
|
|
401
411
|
const model = monacoEditor.getModel();
|
|
402
412
|
|
|
403
|
-
this.inlineDiffHandler.
|
|
413
|
+
this.inlineDiffHandler.destroyPreviewer(model!.uri.toString());
|
|
404
414
|
this.aiInlineChatOperationDisposable.dispose();
|
|
405
415
|
|
|
406
416
|
this.ensureInlineChatVisible(monacoEditor, crossSelection);
|
|
@@ -442,7 +452,7 @@ export class InlineChatHandler extends Disposable {
|
|
|
442
452
|
|
|
443
453
|
this.aiInlineChatOperationDisposable.addDispose([
|
|
444
454
|
this.aiInlineContentWidget.onResultClick((kind: EResultKind) => {
|
|
445
|
-
this.inlineDiffHandler.handleAction(
|
|
455
|
+
this.inlineDiffHandler.handleAction(kind);
|
|
446
456
|
|
|
447
457
|
if (kind === EResultKind.ACCEPT) {
|
|
448
458
|
this.aiReporter.end(relationId, { message: 'accept', success: true, isReceive: true });
|
|
@@ -477,7 +487,7 @@ export class InlineChatHandler extends Disposable {
|
|
|
477
487
|
monacoEditor: monaco.ICodeEditor,
|
|
478
488
|
reporterFn: () => string,
|
|
479
489
|
execute?: () => MaybePromise<void>,
|
|
480
|
-
|
|
490
|
+
providerPreview?: () => MaybePromise<ChatResponse | InlineChatController>,
|
|
481
491
|
) {
|
|
482
492
|
const selection = monacoEditor.getSelection();
|
|
483
493
|
if (!selection) {
|
|
@@ -490,20 +500,14 @@ export class InlineChatHandler extends Disposable {
|
|
|
490
500
|
this.disposeAllWidget();
|
|
491
501
|
}
|
|
492
502
|
|
|
493
|
-
if (
|
|
503
|
+
if (providerPreview) {
|
|
494
504
|
const crossSelection = selection
|
|
495
505
|
.setStartPosition(selection.startLineNumber, 1)
|
|
496
506
|
.setEndPosition(selection.endLineNumber, Number.MAX_SAFE_INTEGER);
|
|
497
507
|
|
|
498
508
|
const relationId = reporterFn();
|
|
499
509
|
|
|
500
|
-
await this.handleDiffPreviewStrategy(
|
|
501
|
-
monacoEditor,
|
|
502
|
-
providerDiffPreviewStrategy,
|
|
503
|
-
crossSelection,
|
|
504
|
-
relationId,
|
|
505
|
-
false,
|
|
506
|
-
);
|
|
510
|
+
await this.handleDiffPreviewStrategy(monacoEditor, providerPreview, crossSelection, relationId, false);
|
|
507
511
|
}
|
|
508
512
|
}
|
|
509
513
|
}
|
|
@@ -351,39 +351,42 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
|
|
|
351
351
|
};
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
354
|
+
/**
|
|
355
|
+
* 以当前 selection 为中心取上下各 1 行重新计算
|
|
356
|
+
*/
|
|
357
|
+
private recheckSelection(selection: monaco.Selection): monaco.editor.IContentWidgetPosition {
|
|
358
|
+
const preStartPosition = selection.getStartPosition();
|
|
359
|
+
const preEndPosition = selection.getEndPosition();
|
|
360
|
+
|
|
361
|
+
const model = this.editor.getModel()!;
|
|
362
|
+
const maxCount = model.getLineCount();
|
|
363
|
+
|
|
364
|
+
const safeAboveStartLine = Math.max(1, preEndPosition.lineNumber - 1);
|
|
365
|
+
const safeBelowEndLine = Math.min(maxCount, preEndPosition.lineNumber + 1);
|
|
366
|
+
|
|
367
|
+
const newStartPosition = preStartPosition.with(safeAboveStartLine, 1);
|
|
368
|
+
const newEndPosition = preEndPosition.with(
|
|
369
|
+
safeBelowEndLine,
|
|
370
|
+
this.safeGetLineLastNonWhitespaceColumn(safeBelowEndLine),
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
// 如果整个文档只有 1 行,则直接显示在右下角
|
|
374
|
+
if (maxCount === 1) {
|
|
375
|
+
return this.toBelowPosition(safeBelowEndLine, this.safeGetLineLastNonWhitespaceColumn(safeBelowEndLine));
|
|
377
376
|
}
|
|
378
377
|
|
|
379
|
-
if (lineNumber === 1
|
|
380
|
-
|
|
378
|
+
if (newEndPosition.lineNumber === 1 && preEndPosition.lineNumber !== preStartPosition.lineNumber) {
|
|
379
|
+
return this.computePosition(monaco.Selection.fromPositions(newStartPosition, newEndPosition));
|
|
381
380
|
}
|
|
382
381
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
382
|
+
const aboveMaxColumn = this.safeGetLineLastNonWhitespaceColumn(safeAboveStartLine);
|
|
383
|
+
const belowMaxColumn = this.safeGetLineLastNonWhitespaceColumn(safeBelowEndLine);
|
|
384
|
+
const currentMaxColumn = this.safeGetLineLastNonWhitespaceColumn(preEndPosition.lineNumber);
|
|
385
|
+
if (belowMaxColumn > currentMaxColumn && belowMaxColumn > aboveMaxColumn) {
|
|
386
|
+
return this.computePosition(monaco.Selection.fromPositions(newEndPosition, newStartPosition));
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return this.computePosition(monaco.Selection.fromPositions(newStartPosition, newEndPosition));
|
|
387
390
|
}
|
|
388
391
|
|
|
389
392
|
private isProtrudeAbove(line: number) {
|
|
@@ -408,25 +411,27 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
|
|
|
408
411
|
* 2. 靠近光标处周围没有字符的空白区域作为要显示的区域
|
|
409
412
|
* 3. 显示的区域方向在右侧,左侧不考虑
|
|
410
413
|
*/
|
|
411
|
-
protected computePosition(selection: monaco.Selection): monaco.editor.IContentWidgetPosition
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
414
|
+
protected computePosition(selection: monaco.Selection): monaco.editor.IContentWidgetPosition {
|
|
415
|
+
let startPosition = selection.getStartPosition();
|
|
416
|
+
let endPosition = selection.getEndPosition();
|
|
417
|
+
let cursorPosition = selection.getPosition();
|
|
415
418
|
|
|
416
|
-
|
|
417
|
-
|
|
419
|
+
const model = this.editor.getModel()!;
|
|
420
|
+
const maxCount = model.getLineCount();
|
|
421
|
+
|
|
422
|
+
// 只选中了一行
|
|
423
|
+
if (startPosition.lineNumber === endPosition.lineNumber) {
|
|
424
|
+
return this.recheckSelection(selection);
|
|
418
425
|
}
|
|
419
426
|
|
|
420
|
-
|
|
421
|
-
|
|
427
|
+
if (endPosition.lineNumber - startPosition.lineNumber === 1) {
|
|
428
|
+
cursorPosition = endPosition;
|
|
429
|
+
}
|
|
422
430
|
|
|
423
|
-
|
|
424
|
-
let direction: 'above' | 'below' | null = null;
|
|
431
|
+
const getCursorLastNonWhitespaceColumn = this.safeGetLineLastNonWhitespaceColumn(cursorPosition.lineNumber);
|
|
425
432
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return this.recheckPosition(cursorPosition.lineNumber, cursorPosition.column);
|
|
429
|
-
}
|
|
433
|
+
let targetLine: number = cursorPosition.lineNumber;
|
|
434
|
+
let direction: 'above' | 'below' = 'below';
|
|
430
435
|
|
|
431
436
|
// 用户选中了多行,光标在选中的开始位置
|
|
432
437
|
if (cursorPosition.equals(startPosition)) {
|
|
@@ -435,10 +440,9 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
|
|
|
435
440
|
this.safeGetLineLastNonWhitespaceColumn(cursorPosition.lineNumber - 2),
|
|
436
441
|
);
|
|
437
442
|
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return this.toAbovePosition(cursorPosition.lineNumber, getMaxLastWhitespaceColumn + 1);
|
|
443
|
+
// 如果上面两行的最后一个非空白字符的列数小于当前行的最后一个非空白字符的列数, 则直接显示在上面
|
|
444
|
+
if (getMaxLastWhitespaceColumn <= getCursorLastNonWhitespaceColumn) {
|
|
445
|
+
return this.toAbovePosition(cursorPosition.lineNumber, getCursorLastNonWhitespaceColumn);
|
|
442
446
|
}
|
|
443
447
|
|
|
444
448
|
for (let i = startPosition.lineNumber; i <= endPosition.lineNumber; i++) {
|
|
@@ -459,11 +463,11 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
|
|
|
459
463
|
this.safeGetLineLastNonWhitespaceColumn(cursorPosition.lineNumber + 2),
|
|
460
464
|
);
|
|
461
465
|
|
|
462
|
-
if (getMaxLastWhitespaceColumn
|
|
463
|
-
return this.toBelowPosition(cursorPosition.lineNumber,
|
|
466
|
+
if (getMaxLastWhitespaceColumn <= getCursorLastNonWhitespaceColumn) {
|
|
467
|
+
return this.toBelowPosition(cursorPosition.lineNumber, getCursorLastNonWhitespaceColumn);
|
|
464
468
|
}
|
|
465
469
|
|
|
466
|
-
for (let i = endPosition.lineNumber; i >= startPosition.lineNumber; i--) {
|
|
470
|
+
for (let i = Math.min(maxCount, endPosition.lineNumber + 1); i >= startPosition.lineNumber; i--) {
|
|
467
471
|
if (this.isProtrudeBelow(i)) {
|
|
468
472
|
targetLine = i;
|
|
469
473
|
direction = 'below';
|
|
@@ -477,18 +481,11 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
|
|
|
477
481
|
}
|
|
478
482
|
}
|
|
479
483
|
|
|
480
|
-
|
|
481
|
-
const column = this.safeGetLineLastNonWhitespaceColumn(targetLine) + 1;
|
|
484
|
+
const column = this.safeGetLineLastNonWhitespaceColumn(targetLine) + 1;
|
|
482
485
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
486
|
-
return this.toAbovePosition(targetLine, column);
|
|
486
|
+
if (direction === 'below') {
|
|
487
|
+
return this.toBelowPosition(targetLine, column);
|
|
487
488
|
}
|
|
488
|
-
|
|
489
|
-
return this.recheckPosition(
|
|
490
|
-
cursorPosition.lineNumber,
|
|
491
|
-
this.safeGetLineLastNonWhitespaceColumn(cursorPosition.lineNumber),
|
|
492
|
-
);
|
|
489
|
+
return this.toAbovePosition(targetLine, column);
|
|
493
490
|
}
|
|
494
491
|
}
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
import { EResultKind } from '../inline-chat/inline-chat.service';
|
|
15
15
|
import { AIInlineContentWidget } from '../inline-chat/inline-content-widget';
|
|
16
16
|
import { EComputerMode, InlineStreamDiffHandler } from '../inline-stream-diff/inline-stream-diff.handler';
|
|
17
|
-
import { SerializableState } from '../inline-stream-diff/live-preview.decoration';
|
|
18
17
|
|
|
19
18
|
import { InlineDiffWidget } from './inline-diff-widget';
|
|
20
19
|
|
|
@@ -22,41 +21,30 @@ export interface IDiffPreviewerOptions {
|
|
|
22
21
|
disposeWhenEditorClosed: boolean;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
export interface
|
|
26
|
-
|
|
24
|
+
export interface IInlineDiffPreviewerNode extends IDisposable {
|
|
25
|
+
previewerOptions: IDiffPreviewerOptions;
|
|
26
|
+
setPreviewerOptions(options: IDiffPreviewerOptions): void;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
@Injectable({ multiple: true })
|
|
30
|
-
export abstract class BaseInlineDiffPreviewer<N extends
|
|
30
|
+
export abstract class BaseInlineDiffPreviewer<N extends IInlineDiffPreviewerNode> extends Disposable {
|
|
31
31
|
@Autowired(INJECTOR_TOKEN)
|
|
32
32
|
protected readonly injector: Injector;
|
|
33
33
|
|
|
34
34
|
protected inlineContentWidget: AIInlineContentWidget | null = null;
|
|
35
|
-
|
|
35
|
+
protected selection: Selection;
|
|
36
36
|
protected model: ITextModel;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
return this.options.disposeWhenEditorClosed;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
constructor(
|
|
43
|
-
protected readonly monacoEditor: ICodeEditor,
|
|
44
|
-
protected readonly selection: Selection,
|
|
45
|
-
public options: IDiffPreviewerOptions = {
|
|
46
|
-
disposeWhenEditorClosed: true,
|
|
47
|
-
},
|
|
48
|
-
) {
|
|
38
|
+
constructor(protected readonly monacoEditor: ICodeEditor) {
|
|
49
39
|
super();
|
|
50
|
-
this.node = this.createNode();
|
|
51
40
|
this.model = this.monacoEditor.getModel()!;
|
|
52
41
|
this.addDispose(
|
|
53
42
|
Disposable.create(() => {
|
|
54
43
|
if (this.inlineContentWidget) {
|
|
55
44
|
this.inlineContentWidget.dispose();
|
|
56
45
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
46
|
+
|
|
47
|
+
this.attachNode(undefined);
|
|
60
48
|
}),
|
|
61
49
|
);
|
|
62
50
|
}
|
|
@@ -104,8 +92,12 @@ export abstract class BaseInlineDiffPreviewer<N extends IDisposable> extends Dis
|
|
|
104
92
|
return newTextLines.join(eol);
|
|
105
93
|
}
|
|
106
94
|
|
|
107
|
-
protected node: N;
|
|
108
|
-
public getNode(): N {
|
|
95
|
+
protected node: N | undefined;
|
|
96
|
+
public getNode(): N | undefined {
|
|
97
|
+
return this.node;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public createNodeSnapshot(): N | undefined {
|
|
109
101
|
return this.node;
|
|
110
102
|
}
|
|
111
103
|
|
|
@@ -123,11 +115,26 @@ export abstract class BaseInlineDiffPreviewer<N extends IDisposable> extends Dis
|
|
|
123
115
|
return Disposable.NULL;
|
|
124
116
|
}
|
|
125
117
|
|
|
126
|
-
abstract createNode(): N;
|
|
118
|
+
protected abstract createNode(): N;
|
|
127
119
|
abstract onData(data: ReplyResponse): void;
|
|
128
120
|
abstract handleAction(action: EResultKind): void;
|
|
129
121
|
abstract getPosition(): IPosition;
|
|
130
122
|
|
|
123
|
+
create(
|
|
124
|
+
selection: Selection,
|
|
125
|
+
options: IDiffPreviewerOptions = {
|
|
126
|
+
disposeWhenEditorClosed: true,
|
|
127
|
+
},
|
|
128
|
+
): void {
|
|
129
|
+
this.selection = selection;
|
|
130
|
+
this.node = this.createNode();
|
|
131
|
+
this.node.setPreviewerOptions(options);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
attachNode(node: N | undefined): void {
|
|
135
|
+
this.node = node;
|
|
136
|
+
}
|
|
137
|
+
|
|
131
138
|
show(line: number, heightInLines: number): void {
|
|
132
139
|
// do nothing
|
|
133
140
|
}
|
|
@@ -191,17 +198,20 @@ export class SideBySideInlineDiffWidget extends BaseInlineDiffPreviewer<InlineDi
|
|
|
191
198
|
super.layout();
|
|
192
199
|
}
|
|
193
200
|
onReady(exec: () => void): IDisposable {
|
|
194
|
-
|
|
201
|
+
if (this.node) {
|
|
202
|
+
return this.node!.onReady(exec.bind(this));
|
|
203
|
+
}
|
|
204
|
+
return Disposable.NULL;
|
|
195
205
|
}
|
|
196
206
|
show(line: number, heightInLines: number): void {
|
|
197
|
-
this.node
|
|
207
|
+
this.node?.showByLine(line, heightInLines);
|
|
198
208
|
}
|
|
199
209
|
setValue(content: string): void {
|
|
200
|
-
const modifiedModel = this.node
|
|
210
|
+
const modifiedModel = this.node?.getModifiedModel();
|
|
201
211
|
modifiedModel?.setValue(this.formatIndentation(content));
|
|
202
212
|
}
|
|
203
213
|
getValue(): string {
|
|
204
|
-
const model = this.node
|
|
214
|
+
const model = this.node?.getModifiedModel();
|
|
205
215
|
return model!.getValue();
|
|
206
216
|
}
|
|
207
217
|
handleAction(action: EResultKind): void {
|
|
@@ -212,14 +222,14 @@ export class SideBySideInlineDiffWidget extends BaseInlineDiffPreviewer<InlineDi
|
|
|
212
222
|
}
|
|
213
223
|
}
|
|
214
224
|
onLineCount(event: (count: number) => void): Disposable {
|
|
215
|
-
this.node
|
|
225
|
+
this.node?.onMaxLineCount(event.bind(this));
|
|
216
226
|
return this;
|
|
217
227
|
}
|
|
218
228
|
onData(data: ReplyResponse): void {
|
|
219
229
|
const { message } = data;
|
|
220
230
|
|
|
221
231
|
const indentMessage = this.formatIndentation(message);
|
|
222
|
-
const modifiedModel = this.node
|
|
232
|
+
const modifiedModel = this.node?.getModifiedModel()!;
|
|
223
233
|
|
|
224
234
|
const defaultEOL = modifiedModel.getEOL() === EOL.CRLF ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF;
|
|
225
235
|
const { textBuffer, disposable } = createTextBuffer(indentMessage, defaultEOL);
|
|
@@ -227,29 +237,24 @@ export class SideBySideInlineDiffWidget extends BaseInlineDiffPreviewer<InlineDi
|
|
|
227
237
|
modifiedModel.pushEditOperations([], singleEditOperation, () => []);
|
|
228
238
|
|
|
229
239
|
disposable.dispose();
|
|
230
|
-
this.node
|
|
240
|
+
this.node?.layout();
|
|
231
241
|
}
|
|
232
242
|
onError(error: ErrorResponse): void {
|
|
233
|
-
this.node
|
|
243
|
+
this.node?.layout();
|
|
234
244
|
}
|
|
235
245
|
onAbort(): void {
|
|
236
|
-
this.node
|
|
246
|
+
this.node?.layout();
|
|
237
247
|
}
|
|
238
248
|
onEnd(): void {
|
|
239
|
-
this.node
|
|
249
|
+
this.node?.layout();
|
|
240
250
|
}
|
|
241
251
|
}
|
|
242
252
|
|
|
243
253
|
@Injectable({ multiple: true })
|
|
244
254
|
export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStreamDiffHandler> {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this.addDispose(node.onDidEditChange(() => this.layout()));
|
|
249
|
-
this.addDispose(node.onDispose(() => this.dispose()));
|
|
250
|
-
this.addDispose(node);
|
|
251
|
-
|
|
252
|
-
this.addDispose(
|
|
255
|
+
private listenNode(node: InlineStreamDiffHandler): void {
|
|
256
|
+
node.addDispose(node.onDidEditChange(() => this.layout()));
|
|
257
|
+
node.addDispose(
|
|
253
258
|
node.onPartialEditWidgetListChange((widgets) => {
|
|
254
259
|
if (widgets.every((widget) => widget.isHidden)) {
|
|
255
260
|
this.dispose();
|
|
@@ -257,22 +262,62 @@ export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStrea
|
|
|
257
262
|
}
|
|
258
263
|
}),
|
|
259
264
|
);
|
|
265
|
+
|
|
266
|
+
const dispose = node.onDispose(() => {
|
|
267
|
+
this.dispose();
|
|
268
|
+
dispose.dispose();
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
this.addDispose(node);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
createNode(): InlineStreamDiffHandler {
|
|
275
|
+
const node = this.injector.get(InlineStreamDiffHandler, [this.monacoEditor]);
|
|
276
|
+
node.initialize(this.selection);
|
|
277
|
+
this.listenNode(node);
|
|
260
278
|
return node;
|
|
261
279
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
280
|
+
attachNode(node: InlineStreamDiffHandler): void {
|
|
281
|
+
this.node?.dispose();
|
|
282
|
+
this.node = node;
|
|
283
|
+
|
|
284
|
+
if (node) {
|
|
285
|
+
const snapshot = node.currentSnapshotStore;
|
|
286
|
+
if (snapshot) {
|
|
287
|
+
this.node.restoreDecorationSnapshot(snapshot.decorationSnapshotData);
|
|
288
|
+
this.listenNode(node);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
public createNodeSnapshot(): InlineStreamDiffHandler | undefined {
|
|
293
|
+
if (!this.node) {
|
|
294
|
+
return this.createNode();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// 拿前一个 node 的快照信息
|
|
298
|
+
const snapshot = this.node.createSnapshot();
|
|
299
|
+
// 创建新的实例
|
|
300
|
+
const node = this.injector.get(InlineStreamDiffHandler, [this.monacoEditor]);
|
|
301
|
+
node.restoreSnapshot(snapshot);
|
|
302
|
+
return node;
|
|
265
303
|
}
|
|
266
304
|
|
|
305
|
+
getPosition(): IPosition {
|
|
306
|
+
const zone = this.node?.getZone();
|
|
307
|
+
if (zone) {
|
|
308
|
+
return Position.lift({ lineNumber: Math.max(0, zone.startLineNumber - 1), column: 1 });
|
|
309
|
+
}
|
|
310
|
+
return Position.lift({ lineNumber: 1, column: 1 });
|
|
311
|
+
}
|
|
267
312
|
handleAction(action: EResultKind): void {
|
|
268
313
|
switch (action) {
|
|
269
314
|
case EResultKind.ACCEPT:
|
|
270
|
-
this.node
|
|
315
|
+
this.node?.acceptAll();
|
|
271
316
|
break;
|
|
272
317
|
|
|
273
318
|
case EResultKind.DISCARD:
|
|
274
319
|
case EResultKind.REGENERATE:
|
|
275
|
-
this.node
|
|
320
|
+
this.node?.rejectAll();
|
|
276
321
|
break;
|
|
277
322
|
|
|
278
323
|
default:
|
|
@@ -288,29 +333,24 @@ export class LiveInlineDiffPreviewer extends BaseInlineDiffPreviewer<InlineStrea
|
|
|
288
333
|
}
|
|
289
334
|
onData(data: ReplyResponse): void {
|
|
290
335
|
const { message } = data;
|
|
291
|
-
this.node
|
|
336
|
+
this.node?.addLinesToDiff(this.formatIndentation(message));
|
|
292
337
|
}
|
|
293
338
|
onEnd(): void {
|
|
294
|
-
const diffModel = this.node
|
|
295
|
-
|
|
339
|
+
const diffModel = this.node?.recompute(EComputerMode.legacy);
|
|
340
|
+
if (diffModel) {
|
|
341
|
+
this.node?.pushRateFinallyDiffStack(diffModel);
|
|
342
|
+
}
|
|
296
343
|
}
|
|
297
344
|
setValue(content: string): void {
|
|
298
|
-
const diffModel = this.node
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return {
|
|
303
|
-
...this.node.serializeState(),
|
|
304
|
-
options: this.options,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
restoreState(state: IExtendedSerializedState): void {
|
|
308
|
-
this.node.restoreState(state);
|
|
345
|
+
const diffModel = this.node?.recompute(EComputerMode.legacy, this.formatIndentation(content));
|
|
346
|
+
if (diffModel) {
|
|
347
|
+
this.node?.finallyRender(diffModel);
|
|
348
|
+
}
|
|
309
349
|
}
|
|
310
350
|
get onPartialEditEvent() {
|
|
311
|
-
return this.node
|
|
351
|
+
return this.node?.onPartialEditEvent;
|
|
312
352
|
}
|
|
313
353
|
revealFirstDiff(): void {
|
|
314
|
-
this.node
|
|
354
|
+
this.node?.revealFirstDiff();
|
|
315
355
|
}
|
|
316
356
|
}
|
|
@@ -3,7 +3,16 @@ import { createPortal } from 'react-dom';
|
|
|
3
3
|
import ReactDOMClient from 'react-dom/client';
|
|
4
4
|
|
|
5
5
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
AppConfig,
|
|
8
|
+
ConfigProvider,
|
|
9
|
+
Emitter,
|
|
10
|
+
Event,
|
|
11
|
+
MonacoService,
|
|
12
|
+
Schemes,
|
|
13
|
+
randomString,
|
|
14
|
+
useInjectable,
|
|
15
|
+
} from '@opensumi/ide-core-browser';
|
|
7
16
|
import * as monaco from '@opensumi/ide-monaco';
|
|
8
17
|
import { ICodeEditor } from '@opensumi/ide-monaco';
|
|
9
18
|
import { IDiffEditorOptions } from '@opensumi/ide-monaco/lib/browser/monaco-api/editor';
|
|
@@ -13,6 +22,7 @@ import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common
|
|
|
13
22
|
import { ZoneWidget } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/zoneWidget/browser/zoneWidget';
|
|
14
23
|
import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
15
24
|
|
|
25
|
+
import { IDiffPreviewerOptions, IInlineDiffPreviewerNode } from './inline-diff-previewer';
|
|
16
26
|
import styles from './inline-diff-widget.module.less';
|
|
17
27
|
|
|
18
28
|
const diffEditorOptions: IDiffEditorOptions = {
|
|
@@ -84,8 +94,24 @@ const DiffContentProvider = React.memo((props: IDiffContentProviderProps) => {
|
|
|
84
94
|
const modelService = StandaloneServices.get(IModelService);
|
|
85
95
|
const languageSelection: ILanguageSelection = { languageId: model.getLanguageId(), onDidChange: Event.None };
|
|
86
96
|
|
|
87
|
-
const originalModel = modelService.createModel(
|
|
88
|
-
|
|
97
|
+
const originalModel = modelService.createModel(
|
|
98
|
+
codeValueInRange,
|
|
99
|
+
languageSelection,
|
|
100
|
+
monaco.Uri.from({
|
|
101
|
+
scheme: Schemes.inMemory,
|
|
102
|
+
path: 'inline-diff-widget/' + randomString(8),
|
|
103
|
+
}),
|
|
104
|
+
true,
|
|
105
|
+
);
|
|
106
|
+
const modifiedModel = modelService.createModel(
|
|
107
|
+
'',
|
|
108
|
+
languageSelection,
|
|
109
|
+
monaco.Uri.from({
|
|
110
|
+
scheme: Schemes.inMemory,
|
|
111
|
+
path: 'inline-diff-widget/' + randomString(8),
|
|
112
|
+
}),
|
|
113
|
+
true,
|
|
114
|
+
);
|
|
89
115
|
|
|
90
116
|
diffEditor.setModel({
|
|
91
117
|
original: originalModel,
|
|
@@ -123,7 +149,7 @@ const DiffContentProvider = React.memo((props: IDiffContentProviderProps) => {
|
|
|
123
149
|
});
|
|
124
150
|
|
|
125
151
|
@Injectable({ multiple: true })
|
|
126
|
-
export class InlineDiffWidget extends ZoneWidget {
|
|
152
|
+
export class InlineDiffWidget extends ZoneWidget implements IInlineDiffPreviewerNode {
|
|
127
153
|
@Autowired(AppConfig)
|
|
128
154
|
private configContext: AppConfig;
|
|
129
155
|
|
|
@@ -137,7 +163,12 @@ export class InlineDiffWidget extends ZoneWidget {
|
|
|
137
163
|
private root: ReactDOMClient.Root | null;
|
|
138
164
|
private diffWidgetHandler: IDiffWidgetHandler | null = null;
|
|
139
165
|
private resultContainer: HTMLDivElement | null = null;
|
|
140
|
-
hiddenArea: monaco.languages.IRange;
|
|
166
|
+
private hiddenArea: monaco.languages.IRange;
|
|
167
|
+
|
|
168
|
+
previewerOptions: IDiffPreviewerOptions;
|
|
169
|
+
setPreviewerOptions(options: IDiffPreviewerOptions): void {
|
|
170
|
+
this.previewerOptions = options;
|
|
171
|
+
}
|
|
141
172
|
|
|
142
173
|
protected _fillContainer(container: HTMLElement): void {
|
|
143
174
|
this.setCssClass('inline-diff-widget');
|