import * as vscode from 'vscode' ; import { HoverRequest , LanguageClient } from 'vscode-languageclient' ; export class SignatureHelpProvider implements vscode . SignatureHelpProvider { private languageClient : LanguageClient ; private previousFunctionPosition ? : vscode . Position ; constructor ( lc ) { this . languageClient = lc ; } public provideSignatureHelp ( document , position , token , context ) { if ( context . triggerCharacter === '(' ) { this . previousFunctionPosition = position ; return this . provideHover ( this . languageClient , document , position , token ) . then ( hover => this . hoverToSignatureHelp ( hover , position , document ) ) ; } else if ( context . triggerCharacter === ',' ) { if ( this . previousFunctionPosition && position . line === this . previousFunctionPosition . line ) { return this . provideHover ( this . languageClient , document , this . previousFunctionPosition , token ) . then ( hover => this . hoverToSignatureHelp ( hover , position , document ) ) ; } else { return null ; } } else { if ( context . isRetrigger === false ) { this . previousFunctionPosition = undefined ; } return null ; } } private provideHover ( lc , document , position , token ) { return new Promise ( ( resolve , reject ) => { lc . sendRequest ( HoverRequest . type , lc . code2ProtocolConverter . asTextDocumentPositionParams ( document , position . translate ( 0 , - 1 ) ) , token ) . then ( data => resolve ( lc . protocol2CodeConverter . asHover ( data ) ) , error => reject ( error ) ) ; } ) ; } private hoverToSignatureHelp ( hover , position , document ) { const label = ( hover . contents [ 0 ] as vscode . MarkdownString ) . value . replace ( '```rust' , '' ) . replace ( '```' , '' ) ; if ( ! label . includes ( 'fn' ) || document . lineAt ( position . line ) . text . includes ( 'fn ' ) ) { return undefined ; } const doc = hover . contents . length > 1 ? ( hover . contents . slice ( - 1 ) [ 0 ] as vscode . MarkdownString ) : undefined ; const si = new vscode . SignatureInformation ( label , doc ) ; si . parameters = [ ] ; const sh = new vscode . SignatureHelp ( ) ; sh . signatures [ 0 ] = si ; sh . activeSignature = 0 ; return sh ; } }