@@ -8,14 +8,25 @@ import {
88 CompletionHandler ,
99 ICompletionContext
1010} from '@jupyterlab/completer' ;
11+ import { IDocumentWidget } from '@jupyterlab/docregistry' ;
12+ import {
13+ ILSPDocumentConnectionManager ,
14+ IEditorPosition
15+ } from '@jupyterlab/lsp' ;
1116import { LabIcon } from '@jupyterlab/ui-components' ;
1217
1318import { CodeCompletion as LSPCompletionSettings } from '../../_completion' ;
19+ import {
20+ editorPositionToRootPosition ,
21+ PositionConverter ,
22+ documentAtRootPosition
23+ } from '../../converter' ;
1424import { FeatureSettings } from '../../feature' ;
1525
1626interface IOptions {
1727 settings : FeatureSettings < LSPCompletionSettings > ;
1828 iconsThemeManager : ILSPCompletionThemeManager ;
29+ connectionManager : ILSPDocumentConnectionManager ;
1930}
2031
2132export class EnhancedContextCompleterProvider extends ContextCompleterProvider {
@@ -75,6 +86,56 @@ export class EnhancedKernelCompleterProvider extends KernelCompleterProvider {
7586 return result ;
7687 }
7788
89+ async isApplicable ( context : ICompletionContext ) : Promise < boolean > {
90+ // Note: this method logs errors instead of throwing to ensure we do not ever
91+ // break the upstream kernel completer, even if there is an error elsehwere.
92+ const upstream = await super . isApplicable ( context ) ;
93+
94+ if ( upstream === false ) {
95+ return false ;
96+ }
97+
98+ const manager = this . options . connectionManager ;
99+ const widget = context . widget as IDocumentWidget ;
100+ const adapter = manager . adapters . get ( widget . context . path ) ;
101+
102+ if ( ! adapter ) {
103+ return upstream ;
104+ }
105+
106+ if ( ! context . editor ) {
107+ // TODO: why is editor optional in the first place?
108+ console . error ( 'No editor' ) ;
109+ return upstream ;
110+ }
111+ const editor = context . editor ;
112+
113+ const editorPosition = PositionConverter . ce_to_cm (
114+ editor . getCursorPosition ( )
115+ ) as IEditorPosition ;
116+
117+ const block = adapter . editors . find (
118+ value => value . ceEditor . getEditor ( ) == editor
119+ ) ;
120+
121+ if ( ! block ) {
122+ console . error ( 'Could not get block with editor' ) ;
123+ return upstream ;
124+ }
125+ const rootPosition = editorPositionToRootPosition (
126+ adapter ,
127+ block . ceEditor ,
128+ editorPosition
129+ ) ;
130+
131+ if ( ! rootPosition ) {
132+ console . error ( 'Could not get root position' ) ;
133+ return upstream ;
134+ }
135+ const virtualDocument = documentAtRootPosition ( adapter , rootPosition ) ;
136+ return virtualDocument === adapter . virtualDocument ;
137+ }
138+
78139 protected iconFor ( type : string ) : LabIcon | undefined {
79140 const icon = this . options . iconsThemeManager . getIcon ( type ) as LabIcon | null ;
80141 return icon ? icon : undefined ;
0 commit comments