Skip to content

Commit

Permalink
Add Signal to proxy all Completer selected Signals (#16312)
Browse files Browse the repository at this point in the history
* Add Signal to proxy all Completer selected Signals

Completer currently emits a signal when a completion is selected.
This surfaces that signal to the CompletionProviderManager, which
then proxies all the Completer signals to the new signal.

This will allow extensions to know when a selection is made in a
Completer. Currently there are edge cases where a selection can be
made without calling a command that can be connected to.

Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>

* Emit ICompleterSelection instead of string

* change text to insertText

* add new test for selected

---------

Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
  • Loading branch information
ajbozarth committed May 16, 2024
1 parent 5a74e4f commit e34aad0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
16 changes: 16 additions & 0 deletions packages/completer/src/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { CompletionHandler } from './handler';
import { CompleterModel } from './model';
import { InlineCompleter } from './inline';
import {
ICompleterSelection,
ICompletionContext,
ICompletionProvider,
ICompletionProviderManager,
Expand All @@ -36,6 +37,10 @@ export class CompletionProviderManager implements ICompletionProviderManager {
this._activeProvidersChanged = new Signal<ICompletionProviderManager, void>(
this
);
this._selected = new Signal<
ICompletionProviderManager,
ICompleterSelection
>(this);
this._inlineCompleterFactory = null;
}

Expand All @@ -46,6 +51,13 @@ export class CompletionProviderManager implements ICompletionProviderManager {
return this._activeProvidersChanged;
}

/**
* Signal emitted when a selection is made from a completer menu.
*/
get selected(): ISignal<ICompletionProviderManager, ICompleterSelection> {
return this._selected;
}

/**
* Set provider timeout.
*
Expand Down Expand Up @@ -172,6 +184,9 @@ export class CompletionProviderManager implements ICompletionProviderManager {
// Create a new handler.
const handler = await this._generateHandler(newCompleterContext, options);
this._panelHandlers.set(widget.id, handler);
handler.completer.selected.connect((completer, insertText) =>
this._selected.emit({ insertText })
);
widget.disposed.connect(old => {
this.disposeHandler(old.id, handler);
this._mostRecentContext.delete(id);
Expand Down Expand Up @@ -410,6 +425,7 @@ export class CompletionProviderManager implements ICompletionProviderManager {
private _autoCompletion: boolean;

private _activeProvidersChanged: Signal<ICompletionProviderManager, void>;
private _selected: Signal<ICompletionProviderManager, ICompleterSelection>;
private _inlineCompleterFactory: IInlineCompleterFactory | null;
private _inlineCompleterSettings = InlineCompleter.defaultSettings;
}
12 changes: 12 additions & 0 deletions packages/completer/src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ export interface ICompletionProviderManager {
*/
activeProvidersChanged: ISignal<ICompletionProviderManager, void>;

/**
* Signal emitted when a selection is made from a completer menu.
*/
selected: ISignal<ICompletionProviderManager, ICompleterSelection>;

/**
* Inline completer actions.
*/
Expand All @@ -394,6 +399,13 @@ export interface ICompletionProviderManager {
inlineProviders?: IInlineCompletionProviderInfo[];
}

export interface ICompleterSelection {
/**
* The text selected by the completer.
*/
insertText: string;
}

export interface IInlineCompleterActions {
/**
* Invoke inline completer.
Expand Down
29 changes: 29 additions & 0 deletions packages/metapackage/test/completer/manager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { createStandaloneCell } from '@jupyter/ydoc';

import { createSessionContext } from '@jupyterlab/apputils/lib/testutils';
import { NBTestUtils } from '@jupyterlab/notebook/lib/testutils';
import { MessageLoop } from '@lumino/messaging';
import { Widget } from '@lumino/widgets';

const DEFAULT_PROVIDER_ID = 'CompletionProvider:context';
const SAMPLE_PROVIDER_ID = 'CompletionProvider:sample';
Expand Down Expand Up @@ -241,5 +243,32 @@ describe('completer/manager', () => {
expect(handler.completer.model).toBeInstanceOf(CustomCompleterModel);
});
});

describe('#selected', () => {
let completerContext: ICompletionContext;
let widget: NotebookPanel;

beforeEach(() => {
const context = contextFactory();
widget = NBTestUtils.createNotebookPanel(context);
completerContext = { widget };
});

it('should emit `selected` signal', async () => {
const callback = jest.fn();
await manager.updateCompleter(completerContext);
const handler = manager['_panelHandlers'].get(
widget.id
) as CompletionHandler;
handler.completer.model!.setCompletionItems([{ label: 'foo' }]);
MessageLoop.sendMessage(handler.completer, Widget.Msg.UpdateRequest);

manager.selected.connect(callback);
expect(callback).toHaveBeenCalledTimes(0);
manager.select(widget.id);
expect(callback).toHaveBeenCalledTimes(1);
manager.selected.disconnect(callback);
});
});
});
});

0 comments on commit e34aad0

Please sign in to comment.