@@ -5,10 +5,14 @@ import {
55 IAICompletionOption ,
66 IDisposable ,
77 IntelligentCompletionsRegistryToken ,
8+ isDefined ,
89 runWhenIdle ,
910} from '@opensumi/ide-core-common' ;
1011import { ICodeEditor , ICursorPositionChangedEvent , IRange , ITextModel , Range } from '@opensumi/ide-monaco' ;
1112import { empty } from '@opensumi/ide-utils/lib/strings' ;
13+ import { IObservable , autorun } from '@opensumi/monaco-editor-core/esm/vs/base/common/observable' ;
14+ import { GhostTextWidget } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget' ;
15+ import { InlineCompletionsController } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController' ;
1216
1317import { AINativeContextKey } from '../../contextkey/ai-native.contextkey.service' ;
1418import { REWRITE_DECORATION_INLINE_ADD , RewriteWidget } from '../../widget/rewrite/rewrite-widget' ;
@@ -25,6 +29,7 @@ import { IIntelligentCompletionsResult } from './intelligent-completions';
2529import { IntelligentCompletionsRegistry } from './intelligent-completions.feature.registry' ;
2630import { MultiLineDecorationModel } from './multi-line.decoration' ;
2731
32+
2833export class IntelligentCompletionsController extends BaseAIMonacoEditorController {
2934 public static readonly ID = 'editor.contrib.ai.intelligent.completions' ;
3035
@@ -36,20 +41,22 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
3641 return this . injector . get ( IntelligentCompletionsRegistryToken ) ;
3742 }
3843
39- private multiLineDecorationModel : MultiLineDecorationModel ;
40- private additionsDeletionsDecorationModel : AdditionsDeletionsDecorationModel ;
41-
42- private aiNativeContextKey : AINativeContextKey ;
43-
4444 private get model ( ) : ITextModel {
4545 return this . monacoEditor . getModel ( ) ! ;
4646 }
4747
48+ private multiLineDecorationModel : MultiLineDecorationModel ;
49+ private additionsDeletionsDecorationModel : AdditionsDeletionsDecorationModel ;
50+ private aiNativeContextKey : AINativeContextKey ;
4851 private rewriteWidget : RewriteWidget | null ;
4952 private whenMultiLineEditsVisibleDisposable : Disposable ;
5053
5154 public mount ( ) : IDisposable {
5255 this . whenMultiLineEditsVisibleDisposable = new Disposable ( ) ;
56+ this . multiLineDecorationModel = new MultiLineDecorationModel ( this . monacoEditor ) ;
57+ this . additionsDeletionsDecorationModel = new AdditionsDeletionsDecorationModel ( this . monacoEditor ) ;
58+ this . aiNativeContextKey = this . injector . get ( AINativeContextKey , [ this . monacoEditor . contextKeyService ] ) ;
59+
5360 return this . registerFeature ( this . monacoEditor ) ;
5461 }
5562
@@ -66,6 +73,12 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
6673 return ;
6774 }
6875
76+ // 如果上一次补全结果还在,则不重复请求
77+ const isVisible = this . aiNativeContextKey . multiLineEditsIsVisible . get ( ) ;
78+ if ( isVisible ) {
79+ return ;
80+ }
81+
6982 const position = this . monacoEditor . getPosition ( ) ! ;
7083 const intelligentCompletionModel = await provider ( this . monacoEditor , position , bean , this . token ) ;
7184
@@ -81,7 +94,7 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
8194 }
8295
8396 private applyInlineDecorations ( completionModel : IIntelligentCompletionsResult ) {
84- const { items } = completionModel ;
97+ const { items, alwaysVisible } = completionModel ;
8598
8699 const position = this . monacoEditor . getPosition ( ) ! ;
87100 const model = this . monacoEditor . getModel ( ) ;
@@ -160,6 +173,27 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
160173 }
161174 } ) ,
162175 ) ;
176+
177+ if ( isDefined ( alwaysVisible ) && alwaysVisible ) {
178+ const inlineCompletionsController = InlineCompletionsController . get ( this . monacoEditor ) ;
179+ if ( inlineCompletionsController ) {
180+ /**
181+ * https://github.com/microsoft/vscode/blob/1.88.1/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts#L67
182+ * 当 _ghostTextWidgets 发生变化时,说明是由下拉补全引起的 “内联补全” 字符出现,此时需要将其销毁
183+ */
184+ this . whenMultiLineEditsVisibleDisposable . addDispose (
185+ autorun ( ( reader ) => {
186+ const ghostTextWidgetsObservable = inlineCompletionsController [ '_ghostTextWidgets' ] as IObservable <
187+ readonly GhostTextWidget [ ]
188+ > ;
189+ ghostTextWidgetsObservable . read ( reader ) ;
190+
191+ const ghostTextWidget = ghostTextWidgetsObservable . get ( ) [ 0 ] ;
192+ ghostTextWidget ?. dispose ( ) ;
193+ } ) ,
194+ ) ;
195+ }
196+ }
163197 }
164198
165199 private async renderRewriteWidget (
@@ -241,10 +275,6 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
241275 }
242276
243277 public registerFeature ( monacoEditor : ICodeEditor ) : IDisposable {
244- this . multiLineDecorationModel = new MultiLineDecorationModel ( monacoEditor ) ;
245- this . additionsDeletionsDecorationModel = new AdditionsDeletionsDecorationModel ( monacoEditor ) ;
246- this . aiNativeContextKey = this . injector . get ( AINativeContextKey , [ monacoEditor . contextKeyService ] ) ;
247-
248278 this . addDispose (
249279 Event . any < any > (
250280 monacoEditor . onDidChangeCursorPosition ,
0 commit comments