@@ -7,8 +7,8 @@ import { inject, injectable } from 'inversify';
77import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api' ;
88import * as path from 'path' ;
99import * as uuid from 'uuid/v4' ;
10- import { CancellationToken , CancellationTokenSource , Event , EventEmitter , SignatureHelpContext , TextDocumentContentChangeEvent , Uri } from 'vscode' ;
11-
10+ import { CancellationToken , CancellationTokenSource , CompletionItem , Event , EventEmitter , SignatureHelpContext , TextDocumentContentChangeEvent , Uri } from 'vscode' ;
11+ import * as vscodeLanguageClient from 'vscode-languageclient' ;
1212import { concatMultilineStringInput } from '../../../../datascience-ui/common' ;
1313import { ILanguageServer , ILanguageServerCache } from '../../../activation/types' ;
1414import { IWorkspaceService } from '../../../common/application/types' ;
@@ -34,9 +34,17 @@ import {
3434 IProvideHoverRequest ,
3535 IProvideSignatureHelpRequest ,
3636 IRemoveCell ,
37+ IResolveCompletionItemRequest ,
3738 ISwapCells
3839} from '../interactiveWindowTypes' ;
39- import { convertStringsToSuggestions , convertToMonacoCompletionList , convertToMonacoHover , convertToMonacoSignatureHelp } from './conversion' ;
40+ import {
41+ convertStringsToSuggestions ,
42+ convertToMonacoCompletionItem ,
43+ convertToMonacoCompletionList ,
44+ convertToMonacoHover ,
45+ convertToMonacoSignatureHelp ,
46+ convertToVSCodeCompletionItem
47+ } from './conversion' ;
4048import { IntellisenseDocument } from './intellisenseDocument' ;
4149
4250// tslint:disable:no-any
@@ -95,6 +103,10 @@ export class IntellisenseProvider implements IInteractiveWindowListener {
95103 this . dispatchMessage ( message , payload , this . handleSignatureHelpRequest ) ;
96104 break ;
97105
106+ case InteractiveWindowMessages . ResolveCompletionItemRequest :
107+ this . dispatchMessage ( message , payload , this . handleResolveCompletionItemRequest ) ;
108+ break ;
109+
98110 case InteractiveWindowMessages . EditCell :
99111 this . dispatchMessage ( message , payload , this . editCell ) ;
100112 break ;
@@ -211,8 +223,7 @@ export class IntellisenseProvider implements IInteractiveWindowListener {
211223 cellId : string ,
212224 token : CancellationToken
213225 ) : Promise < monacoEditor . languages . CompletionList > {
214- const languageServer = await this . getLanguageServer ( ) ;
215- const document = await this . getDocument ( ) ;
226+ const [ languageServer , document ] = await Promise . all ( [ this . getLanguageServer ( ) , this . getDocument ( ) ] ) ;
216227 if ( languageServer && document ) {
217228 const docPos = document . convertToDocumentPosition ( cellId , position . lineNumber , position . column ) ;
218229 const result = await languageServer . provideCompletionItems ( document , docPos , token , context ) ;
@@ -227,8 +238,7 @@ export class IntellisenseProvider implements IInteractiveWindowListener {
227238 } ;
228239 }
229240 protected async provideHover ( position : monacoEditor . Position , cellId : string , token : CancellationToken ) : Promise < monacoEditor . languages . Hover > {
230- const languageServer = await this . getLanguageServer ( ) ;
231- const document = await this . getDocument ( ) ;
241+ const [ languageServer , document ] = await Promise . all ( [ this . getLanguageServer ( ) , this . getDocument ( ) ] ) ;
232242 if ( languageServer && document ) {
233243 const docPos = document . convertToDocumentPosition ( cellId , position . lineNumber , position . column ) ;
234244 const result = await languageServer . provideHover ( document , docPos , token ) ;
@@ -247,8 +257,7 @@ export class IntellisenseProvider implements IInteractiveWindowListener {
247257 cellId : string ,
248258 token : CancellationToken
249259 ) : Promise < monacoEditor . languages . SignatureHelp > {
250- const languageServer = await this . getLanguageServer ( ) ;
251- const document = await this . getDocument ( ) ;
260+ const [ languageServer , document ] = await Promise . all ( [ this . getLanguageServer ( ) , this . getDocument ( ) ] ) ;
252261 if ( languageServer && document ) {
253262 const docPos = document . convertToDocumentPosition ( cellId , position . lineNumber , position . column ) ;
254263 const result = await languageServer . provideSignatureHelp ( document , docPos , token , context as SignatureHelpContext ) ;
@@ -264,6 +273,31 @@ export class IntellisenseProvider implements IInteractiveWindowListener {
264273 } ;
265274 }
266275
276+ protected async resolveCompletionItem (
277+ position : monacoEditor . Position ,
278+ item : monacoEditor . languages . CompletionItem ,
279+ cellId : string ,
280+ token : CancellationToken
281+ ) : Promise < monacoEditor . languages . CompletionItem > {
282+ const [ languageServer , document ] = await Promise . all ( [ this . getLanguageServer ( ) , this . getDocument ( ) ] ) ;
283+ if ( languageServer && languageServer . resolveCompletionItem && document ) {
284+ const vscodeCompItem : CompletionItem = convertToVSCodeCompletionItem ( item ) ;
285+
286+ // Needed by Jedi in completionSource.ts to resolve the item
287+ const docPos = document . convertToDocumentPosition ( cellId , position . lineNumber , position . column ) ;
288+ ( vscodeCompItem as any ) . _documentPosition = { document, position : docPos } ;
289+
290+ const result = await languageServer . resolveCompletionItem ( vscodeCompItem , token ) ;
291+ if ( result ) {
292+ // Convert expects vclc completion item, but takes both vclc and vscode items so just cast here
293+ return convertToMonacoCompletionItem ( result as vscodeLanguageClient . CompletionItem , true ) ;
294+ }
295+ }
296+
297+ // If we can't fill in the extra info, just return the item
298+ return item ;
299+ }
300+
267301 protected async handleChanges ( document : IntellisenseDocument , changes : TextDocumentContentChangeEvent [ ] ) : Promise < void > {
268302 // For the dot net language server, we have to send extra data to the language server
269303 if ( document ) {
@@ -325,6 +359,25 @@ export class IntellisenseProvider implements IInteractiveWindowListener {
325359 ) ;
326360 }
327361
362+ private handleResolveCompletionItemRequest ( request : IResolveCompletionItemRequest ) {
363+ // Create a cancellation source. We'll use this for our sub class request and a jupyter one
364+ const cancelSource = new CancellationTokenSource ( ) ;
365+ this . cancellationSources . set ( request . requestId , cancelSource ) ;
366+
367+ // Combine all of the results together.
368+ this . postTimedResponse (
369+ [ this . resolveCompletionItem ( request . position , request . item , request . cellId , cancelSource . token ) ] ,
370+ InteractiveWindowMessages . ResolveCompletionItemResponse ,
371+ c => {
372+ if ( c && c [ 0 ] ) {
373+ return { item : c [ 0 ] , requestId : request . requestId } ;
374+ } else {
375+ return { item : request . item , requestId : request . requestId } ;
376+ }
377+ }
378+ ) ;
379+ }
380+
328381 private handleHoverRequest ( request : IProvideHoverRequest ) {
329382 const cancelSource = new CancellationTokenSource ( ) ;
330383 this . cancellationSources . set ( request . requestId , cancelSource ) ;
0 commit comments