@@ -10,7 +10,7 @@ import * as nls from 'vs/nls';
1010import { IDisposable , dispose , Disposable } from 'vs/base/common/lifecycle' ;
1111import * as dom from 'vs/base/browser/dom' ;
1212import * as aria from 'vs/base/browser/ui/aria/aria' ;
13- import { SignatureHelp , SignatureInformation , SignatureHelpProviderRegistry } from 'vs/editor/common/modes' ;
13+ import * as modes from 'vs/editor/common/modes' ;
1414import { ContentWidgetPositionPreference , ICodeEditor , IContentWidget , IContentWidgetPosition } from 'vs/editor/browser/editorBrowser' ;
1515import { RunOnceScheduler , createCancelablePromise , CancelablePromise } from 'vs/base/common/async' ;
1616import { onUnexpectedError } from 'vs/base/common/errors' ;
@@ -31,12 +31,12 @@ import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer';
3131const $ = dom . $ ;
3232
3333export interface IHintEvent {
34- hints : SignatureHelp ;
34+ hints : modes . SignatureHelp ;
3535}
3636
3737export class ParameterHintsModel extends Disposable {
3838
39- static DELAY = 120 ; // ms
39+ private static readonly DEFAULT_DELAY = 120 ; // ms
4040
4141 private readonly _onHint = this . _register ( new Emitter < IHintEvent > ( ) ) ;
4242 public readonly onHint : Event < IHintEvent > = this . _onHint . event ;
@@ -47,34 +47,42 @@ export class ParameterHintsModel extends Disposable {
4747 private editor : ICodeEditor ;
4848 private enabled : boolean ;
4949 private triggerCharactersListeners : IDisposable [ ] ;
50- private active : boolean ;
50+ private active : boolean = false ;
51+ private pending : boolean = false ;
52+ private triggerChars = new CharacterSet ( ) ;
53+
54+ private triggerContext : modes . SignatureHelpContext | undefined ;
5155 private throttledDelayer : RunOnceScheduler ;
52- private provideSignatureHelpRequest ?: CancelablePromise < SignatureHelp > ;
56+ private provideSignatureHelpRequest ?: CancelablePromise < modes . SignatureHelp > ;
5357
54- constructor ( editor : ICodeEditor ) {
58+ constructor (
59+ editor : ICodeEditor ,
60+ delay : number = ParameterHintsModel . DEFAULT_DELAY
61+ ) {
5562 super ( ) ;
5663
5764 this . editor = editor ;
5865 this . enabled = false ;
5966 this . triggerCharactersListeners = [ ] ;
6067
61- this . throttledDelayer = new RunOnceScheduler ( ( ) => this . doTrigger ( ) , ParameterHintsModel . DELAY ) ;
62-
63- this . active = false ;
68+ this . throttledDelayer = new RunOnceScheduler ( ( ) => this . doTrigger ( ) , delay ) ;
6469
6570 this . _register ( this . editor . onDidChangeConfiguration ( ( ) => this . onEditorConfigurationChange ( ) ) ) ;
6671 this . _register ( this . editor . onDidChangeModel ( e => this . onModelChanged ( ) ) ) ;
6772 this . _register ( this . editor . onDidChangeModelLanguage ( _ => this . onModelChanged ( ) ) ) ;
6873 this . _register ( this . editor . onDidChangeCursorSelection ( e => this . onCursorChange ( e ) ) ) ;
6974 this . _register ( this . editor . onDidChangeModelContent ( e => this . onModelContentChange ( ) ) ) ;
70- this . _register ( SignatureHelpProviderRegistry . onDidChange ( this . onModelChanged , this ) ) ;
75+ this . _register ( modes . SignatureHelpProviderRegistry . onDidChange ( this . onModelChanged , this ) ) ;
76+ this . _register ( this . editor . onDidType ( text => this . onDidType ( text ) ) ) ;
7177
7278 this . onEditorConfigurationChange ( ) ;
7379 this . onModelChanged ( ) ;
7480 }
7581
7682 cancel ( silent : boolean = false ) : void {
7783 this . active = false ;
84+ this . pending = false ;
85+ this . triggerContext = undefined ;
7886
7987 this . throttledDelayer . cancel ( ) ;
8088
@@ -88,12 +96,13 @@ export class ParameterHintsModel extends Disposable {
8896 }
8997 }
9098
91- trigger ( delay = ParameterHintsModel . DELAY ) : void {
92- if ( ! SignatureHelpProviderRegistry . has ( this . editor . getModel ( ) ) ) {
99+ trigger ( context : modes . SignatureHelpContext , delay ?: number ) : void {
100+ if ( ! modes . SignatureHelpProviderRegistry . has ( this . editor . getModel ( ) ) ) {
93101 return ;
94102 }
95103
96104 this . cancel ( true ) ;
105+ this . triggerContext = context ;
97106 return this . throttledDelayer . schedule ( delay ) ;
98107 }
99108
@@ -102,9 +111,17 @@ export class ParameterHintsModel extends Disposable {
102111 this . provideSignatureHelpRequest . cancel ( ) ;
103112 }
104113
105- this . provideSignatureHelpRequest = createCancelablePromise ( token => provideSignatureHelp ( this . editor . getModel ( ) , this . editor . getPosition ( ) , token ) ) ;
114+ this . pending = true ;
115+
116+ const triggerContext = this . triggerContext || { triggerReason : modes . SignatureHelpTriggerReason . Invoke } ;
117+ this . triggerContext = undefined ;
118+
119+ this . provideSignatureHelpRequest = createCancelablePromise ( token =>
120+ provideSignatureHelp ( this . editor . getModel ( ) , this . editor . getPosition ( ) , triggerContext , token ) ) ;
106121
107122 this . provideSignatureHelpRequest . then ( result => {
123+ this . pending = false ;
124+
108125 if ( ! result || ! result . signatures || result . signatures . length === 0 ) {
109126 this . cancel ( ) ;
110127 this . _onCancel . fire ( void 0 ) ;
@@ -116,54 +133,63 @@ export class ParameterHintsModel extends Disposable {
116133 this . _onHint . fire ( event ) ;
117134 return true ;
118135
119- } ) . catch ( onUnexpectedError ) ;
136+ } ) . catch ( error => {
137+ this . pending = false ;
138+ onUnexpectedError ( error ) ;
139+ } ) ;
120140 }
121141
122- isTriggered ( ) : boolean {
123- return this . active || this . throttledDelayer . isScheduled ( ) ;
142+ private get isTriggered ( ) : boolean {
143+ return this . active || this . pending || this . throttledDelayer . isScheduled ( ) ;
124144 }
125145
126146 private onModelChanged ( ) : void {
127147 this . cancel ( ) ;
128148
129- this . triggerCharactersListeners = dispose ( this . triggerCharactersListeners ) ;
149+ // Update trigger characters
150+ this . triggerChars = new CharacterSet ( ) ;
130151
131152 const model = this . editor . getModel ( ) ;
132153 if ( ! model ) {
133154 return ;
134155 }
135156
136- const triggerChars = new CharacterSet ( ) ;
137- for ( const support of SignatureHelpProviderRegistry . ordered ( model ) ) {
157+ for ( const support of modes . SignatureHelpProviderRegistry . ordered ( model ) ) {
138158 if ( Array . isArray ( support . signatureHelpTriggerCharacters ) ) {
139159 for ( const ch of support . signatureHelpTriggerCharacters ) {
140- triggerChars . add ( ch . charCodeAt ( 0 ) ) ;
160+ this . triggerChars . add ( ch . charCodeAt ( 0 ) ) ;
141161 }
142162 }
143163 }
164+ }
144165
145- this . triggerCharactersListeners . push ( this . editor . onDidType ( ( text : string ) => {
146- if ( ! this . enabled ) {
147- return ;
148- }
166+ private onDidType ( text : string ) {
167+ if ( ! this . enabled ) {
168+ return ;
169+ }
149170
150- if ( triggerChars . has ( text . charCodeAt ( text . length - 1 ) ) ) {
151- this . trigger ( ) ;
152- }
153- } ) ) ;
171+ const lastCharIndex = text . length - 1 ;
172+ if ( this . triggerChars . has ( text . charCodeAt ( lastCharIndex ) ) ) {
173+ this . trigger ( {
174+ triggerReason : this . isTriggered
175+ ? modes . SignatureHelpTriggerReason . Retrigger
176+ : modes . SignatureHelpTriggerReason . TriggerCharacter ,
177+ triggerCharacter : text . charAt ( lastCharIndex )
178+ } ) ;
179+ }
154180 }
155181
156182 private onCursorChange ( e : ICursorSelectionChangedEvent ) : void {
157183 if ( e . source === 'mouse' ) {
158184 this . cancel ( ) ;
159- } else if ( this . isTriggered ( ) ) {
160- this . trigger ( ) ;
185+ } else if ( this . isTriggered ) {
186+ this . trigger ( { triggerReason : modes . SignatureHelpTriggerReason . Retrigger } ) ;
161187 }
162188 }
163189
164190 private onModelContentChange ( ) : void {
165- if ( this . isTriggered ( ) ) {
166- this . trigger ( ) ;
191+ if ( this . isTriggered ) {
192+ this . trigger ( { triggerReason : modes . SignatureHelpTriggerReason . Retrigger } ) ;
167193 }
168194 }
169195
@@ -198,7 +224,7 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable {
198224 private overloads : HTMLElement ;
199225 private currentSignature : number ;
200226 private visible : boolean ;
201- private hints : SignatureHelp ;
227+ private hints : modes . SignatureHelp ;
202228 private announcedLabel : string ;
203229 private scrollbar : DomScrollableElement ;
204230 private disposables : IDisposable [ ] ;
@@ -405,7 +431,7 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable {
405431 this . scrollbar . scanDomNode ( ) ;
406432 }
407433
408- private renderParameters ( parent : HTMLElement , signature : SignatureInformation , currentParameter : number ) : void {
434+ private renderParameters ( parent : HTMLElement , signature : modes . SignatureInformation , currentParameter : number ) : void {
409435 let end = signature . label . length ;
410436 let idx = 0 ;
411437 let element : HTMLSpanElement ;
@@ -526,8 +552,8 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable {
526552 return ParameterHintsWidget . ID ;
527553 }
528554
529- trigger ( ) : void {
530- this . model . trigger ( 0 ) ;
555+ trigger ( context : modes . SignatureHelpContext ) : void {
556+ this . model . trigger ( context , 0 ) ;
531557 }
532558
533559 private updateMaxHeight ( ) : void {
0 commit comments