Skip to content

Commit 811d994

Browse files
committed
Try to restore prefixing
1 parent 444e337 commit 811d994

File tree

1 file changed

+48
-16
lines changed
  • packages/jupyterlab-lsp/src/adapters/jupyterlab/components

1 file changed

+48
-16
lines changed

packages/jupyterlab-lsp/src/adapters/jupyterlab/components/completion.ts

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { LSPConnection } from '../../../connection';
2121
import { Session } from '@jupyterlab/services';
2222
import ICompletionItemsResponseType = CompletionHandler.ICompletionItemsResponseType;
23-
23+
import { kernelIcon } from '@jupyterlab/ui-components';
2424

2525
/**
2626
* A LSP connector for completion handlers.
@@ -268,23 +268,29 @@ export class LSPConnector
268268
reply: CompletionHandler.IReply
269269
): CompletionHandler.ICompletionItemsReply {
270270
console.log('[LSP][Completer] Transforming kernel reply:', reply);
271-
const items = new Array<CompletionHandler.ICompletionItem>();
271+
let items: CompletionHandler.ICompletionItem[];
272272
const metadata = reply.metadata || {};
273273
const types = metadata._jupyter_types_experimental as JSONArray;
274274

275275
if (types) {
276-
types.forEach((item: JSONObject) => {
277-
const text = item.text as string;
278-
const type = item.type as string;
279-
items.push({ label: text, type });
276+
items = types.map((item: JSONObject) => {
277+
return {
278+
label: item.text as string,
279+
insertText: item.text as string,
280+
type: item.type as string,
281+
icon: typeof item.type === 'undefined' ? kernelIcon : undefined
282+
};
280283
});
281284
} else {
282-
const matches = reply.matches;
283-
matches.forEach(match => {
284-
items.push({ label: match });
285+
items = reply.matches.map(match => {
286+
return {
287+
label: match,
288+
insertText: match,
289+
icon: kernelIcon
290+
};
285291
});
286292
}
287-
return { ...reply, items };
293+
return { start: reply.start, end: reply.end, items };
288294
}
289295

290296
private merge_replies(
@@ -293,34 +299,60 @@ export class LSPConnector
293299
editor: CodeEditor.IEditor
294300
): CompletionHandler.ICompletionItemsReply {
295301
console.log('[LSP][Completer] Merging completions:', lsp, kernel);
302+
296303
if (!kernel.items.length) {
297304
return lsp;
298305
}
299306
if (!lsp.items.length) {
300307
return kernel;
301308
}
302309

303-
// combine completions, de-duping by label; LSP completions will show up first, kernel second.
304-
const aggregatedItems = lsp.items.concat(kernel.items);
305-
const labelSet = new Set<string>();
310+
let prefix = '';
311+
312+
// if the kernel used a wider range, get the previous characters to strip the prefix off,
313+
// so that both use the same range
314+
if (lsp.start > kernel.start) {
315+
const cursor = editor.getCursorPosition();
316+
const line = editor.getLine(cursor.line);
317+
prefix = line.substring(kernel.start, lsp.start);
318+
console.log('[LSP][Completer] Removing kernel prefix: ', prefix);
319+
} else if (lsp.start < kernel.start) {
320+
console.warn('[LSP][Completer] Kernel start > LSP start');
321+
}
322+
323+
// combine completions, de-duping by insertText; LSP completions will show up first, kernel second.
324+
const aggregatedItems = lsp.items.concat(
325+
kernel.items.map(item => {
326+
return {
327+
...item,
328+
label: item.label.startsWith(prefix)
329+
? item.label.substr(prefix.length)
330+
: item.label,
331+
insertText: item.insertText.startsWith(prefix)
332+
? item.insertText.substr(prefix.length)
333+
: item.insertText
334+
};
335+
})
336+
);
337+
const insertTextSet = new Set<string>();
306338
const processedItems = new Array<CompletionHandler.ICompletionItem>();
307339

308-
// TODO: Integrate prefix stripping?
309340
aggregatedItems.forEach(item => {
310341
if (
311342
// For some reason the _jupyter_types_experimental list has two entries
312343
// for each match, with one having a type of "<unknown>". Discard those
313344
// and use undefined to indicate an unknown type.
314-
labelSet.has(item.label) ||
345+
insertTextSet.has(item.insertText) ||
315346
(item.type && item.type === '<unknown>')
316347
) {
317348
return;
318349
}
319-
labelSet.add(item.label);
350+
insertTextSet.add(item.insertText);
320351
processedItems.push(item);
321352
});
322353
// TODO: Sort items
323354
// Return reply with processed items.
355+
console.log('[LSP][Completer] Merged: ', { ...lsp, items: processedItems });
324356
return { ...lsp, items: processedItems };
325357
}
326358

0 commit comments

Comments
 (0)