@@ -7,8 +7,8 @@ import * as CodeMirror from 'codemirror';
7
7
import { CodeMirrorIntegration } from '../../editor_integration/codemirror' ;
8
8
import { JupyterFrontEnd } from '@jupyterlab/application' ;
9
9
import { IEditorChangedData , WidgetAdapter } from '../../adapters/adapter' ;
10
- import { LSPConnector } from './completion_handler' ;
11
- import { ICompletionManager } from '@jupyterlab/completer' ;
10
+ import { LazyCompletionItem , LSPConnector } from './completion_handler' ;
11
+ import { CompletionHandler , ICompletionManager } from '@jupyterlab/completer' ;
12
12
import { CodeEditor } from '@jupyterlab/codeeditor' ;
13
13
import { IDocumentWidget } from '@jupyterlab/docregistry' ;
14
14
import { NotebookPanel } from '@jupyterlab/notebook' ;
@@ -19,6 +19,8 @@ import { IDocumentConnectionData } from '../../connection_manager';
19
19
import { ILSPAdapterManager , ILSPLogConsole } from '../../tokens' ;
20
20
import { NotebookAdapter } from '../../adapters/notebook/notebook' ;
21
21
import { ILSPCompletionThemeManager } from '@krassowski/completion-theme/lib/types' ;
22
+ import { LSPCompletionRenderer } from './renderer' ;
23
+ import { IRenderMime , IRenderMimeRegistry } from '@jupyterlab/rendermime' ;
22
24
23
25
export class CompletionCM extends CodeMirrorIntegration {
24
26
private _completionCharacters : string [ ] ;
@@ -75,21 +77,44 @@ export class CompletionCM extends CodeMirrorIntegration {
75
77
export class CompletionLabIntegration implements IFeatureLabIntegration {
76
78
// TODO: maybe instead of creating it each time, keep a hash map instead?
77
79
protected current_completion_connector : LSPConnector ;
78
- protected current_completion_handler : ICompletionManager . ICompletableAttributes ;
80
+ protected current_completion_handler : CompletionHandler ;
79
81
protected current_adapter : WidgetAdapter < IDocumentWidget > = null ;
82
+ protected renderer : LSPCompletionRenderer ;
83
+ private markdown_renderer : IRenderMime . IRenderer ;
80
84
81
85
constructor (
82
86
private app : JupyterFrontEnd ,
83
87
private completionManager : ICompletionManager ,
84
88
public settings : FeatureSettings < LSPCompletionSettings > ,
85
89
private adapterManager : ILSPAdapterManager ,
86
90
private completionThemeManager : ILSPCompletionThemeManager ,
87
- private console : ILSPLogConsole
91
+ private console : ILSPLogConsole ,
92
+ private renderMimeRegistry : IRenderMimeRegistry
88
93
) {
94
+ this . renderer = new LSPCompletionRenderer ( { integrator : this } ) ;
95
+ this . renderer . activeChanged . connect ( this . active_completion_changed , this ) ;
89
96
adapterManager . adapterChanged . connect ( this . swap_adapter , this ) ;
90
97
settings . changed . connect ( ( ) => {
91
98
completionThemeManager . set_theme ( this . settings . composite . theme ) ;
99
+ completionThemeManager . set_icons_overrides (
100
+ this . settings . composite . typesMap
101
+ ) ;
92
102
} ) ;
103
+
104
+ this . markdown_renderer = this . renderMimeRegistry . createRenderer (
105
+ 'text/markdown'
106
+ ) ;
107
+ }
108
+
109
+ active_completion_changed (
110
+ renderer : LSPCompletionRenderer ,
111
+ item : LazyCompletionItem
112
+ ) {
113
+ if ( item . needsResolution ( ) ) {
114
+ item . fetchDocumentation ( ) ;
115
+ } else if ( item . isResolved ( ) ) {
116
+ this . refresh_doc_panel ( item ) ;
117
+ }
93
118
}
94
119
95
120
private swap_adapter (
@@ -130,11 +155,14 @@ export class CompletionLabIntegration implements IFeatureLabIntegration {
130
155
return ;
131
156
}
132
157
this . set_completion_connector ( adapter , editor ) ;
133
- this . current_completion_handler = this . completionManager . register ( {
134
- connector : this . current_completion_connector ,
135
- editor : editor ,
136
- parent : adapter . widget
137
- } ) ;
158
+ this . current_completion_handler = this . completionManager . register (
159
+ {
160
+ connector : this . current_completion_connector ,
161
+ editor : editor ,
162
+ parent : adapter . widget
163
+ } ,
164
+ this . renderer
165
+ ) as CompletionHandler ;
138
166
}
139
167
140
168
invoke_completer ( kind : ExtendedCompletionTriggerKind ) {
@@ -162,9 +190,53 @@ export class CompletionLabIntegration implements IFeatureLabIntegration {
162
190
}
163
191
this . set_completion_connector ( adapter , editor_changed . editor ) ;
164
192
this . current_completion_handler . editor = editor_changed . editor ;
193
+ // @ts -ignore
165
194
this . current_completion_handler . connector = this . current_completion_connector ;
166
195
}
167
196
197
+ refresh_doc_panel ( item : LazyCompletionItem ) {
198
+ // TODO upstream: make completer public?
199
+ let completer = this . current_completion_handler . completer ;
200
+
201
+ // TODO upstream: allow to get completionItems() without markup
202
+ // (note: not trivial as _markup() does filtering too)
203
+ const items = completer . model . completionItems ( ) ;
204
+
205
+ // TODO upstream: Completer will have getActiveItem()
206
+ // @ts -ignore
207
+ const index = completer . _activeIndex ;
208
+ const active : CompletionHandler . ICompletionItem = items [ index ] ;
209
+
210
+ if ( active . insertText != item . insertText ) {
211
+ return ;
212
+ }
213
+
214
+ if ( item . documentation ) {
215
+ let docPanel = completer . node . querySelector ( '.jp-Completer-docpanel' ) ;
216
+
217
+ // TODO upstream: renderer should take care of the documentation rendering
218
+ // sent PR: https://github.com/jupyterlab/jupyterlab/pull/9663
219
+ if ( item . isDocumentationMarkdown ) {
220
+ this . markdown_renderer
221
+ . renderModel ( {
222
+ data : {
223
+ 'text/markdown' : item . documentation
224
+ } ,
225
+ trusted : false ,
226
+ metadata : { } ,
227
+ setData ( options : IRenderMime . IMimeModel . ISetDataOptions ) { }
228
+ } )
229
+ . catch ( this . console . warn ) ;
230
+ // remove all children
231
+ docPanel . textContent = '' ;
232
+ docPanel . appendChild ( this . markdown_renderer . node ) ;
233
+ } else {
234
+ docPanel . textContent = item . documentation ;
235
+ }
236
+ docPanel . setAttribute ( 'style' , '' ) ;
237
+ }
238
+ }
239
+
168
240
private set_completion_connector (
169
241
adapter : WidgetAdapter < IDocumentWidget > ,
170
242
editor : CodeEditor . IEditor
@@ -178,6 +250,7 @@ export class CompletionLabIntegration implements IFeatureLabIntegration {
178
250
connections : this . current_adapter . connection_manager . connections ,
179
251
virtual_editor : this . current_adapter . virtual_editor ,
180
252
settings : this . settings ,
253
+ labIntegration : this ,
181
254
// it might or might not be a notebook panel (if it is not, the sessionContext and session will just be undefined)
182
255
session : ( this . current_adapter . widget as NotebookPanel ) ?. sessionContext
183
256
?. session ,
0 commit comments