Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Adding a 'onKeyDown' handler to the quick pick/inputbox #36690

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/vs/base/parts/quickopen/browser/quickOpenWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface IQuickOpenCallbacks {
onOk: () => void;
onCancel: () => void;
onType: (value: string) => void;
onKeyDown?: (e: KeyboardEvent, value: string) => string;
onShow?: () => void;
onHide?: (reason: HideReason) => void;
onFocusLost?: () => boolean /* veto close */;
Expand Down Expand Up @@ -217,6 +218,9 @@ export class QuickOpenWidget implements IModelProvider {
}
});

DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
this.onKeyDown(e);
});
DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.INPUT, (e: Event) => {
this.onType();
});
Expand Down Expand Up @@ -414,6 +418,12 @@ export class QuickOpenWidget implements IModelProvider {
return element.selectionEnd === this.inputBox.value.length && element.selectionStart === element.selectionEnd;
}

private onKeyDown(e: KeyboardEvent): void {
const value = this.inputBox.value;
if (this.callbacks.onKeyDown) {
this.inputBox.value = this.callbacks.onKeyDown(e, value);
}
}
private onType(): void {
const value = this.inputBox.value;

Expand Down
5 changes: 5 additions & 0 deletions src/vs/platform/quickOpen/common/quickOpen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ export interface IInputOptions {
* an optional function that is used to validate user input.
*/
validateInput?: (input: string) => TPromise<string>;

/**
* An optional function that can modify the input box in response to input.
*/
handleKeyDown?: (e: KeyboardEvent, value: string) => string;
}

export interface IShowOptions {
Expand Down
54 changes: 54 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,60 @@ declare module 'vscode' {
findFiles?(query: string, progress: Progress<Uri>, token: CancellationToken): Thenable<void>;
}

/**
* Options to configure the behavior of the input box UI.
*/
export interface InputBoxOptions {

/**
* The value to prefill in the input box.
*/
value?: string;

/**
* Selection of the prefilled [`value`](#InputBoxOptions.value). Defined as tuple of two number where the
* first is the inclusive start index and the second the exclusive end index. When `undefined` the whole
* word will be selected, when empty (start equals end) only the cursor will be set,
* otherwise the defined range will be selected.
*/
valueSelection?: [number, number];

/**
* The text to display underneath the input box.
*/
prompt?: string;

/**
* An optional string to show as place holder in the input box to guide the user what to type.
*/
placeHolder?: string;

/**
* Set to `true` to show a password prompt that will not show the typed value.
*/
password?: boolean;

/**
* Set to `true` to keep the input box open when focus moves to another part of the editor or to another window.
*/
ignoreFocusOut?: boolean;

/**
* An optional function that will be called to validate input and to give a hint
* to the user.
*
* @param value The current value of the input box.
* @return A human readable string which is presented as diagnostic message.
* Return `undefined`, `null`, or the empty string when 'value' is valid.
*/
validateInput?(value: string): string | undefined | null | Thenable<string | undefined | null>;

/**
* An optional function that can modify the input box in response to input.
*/
handleKeyDown?: (e: KeyboardEvent, value: string) => string;
}

export namespace workspace {
export function registerFileSystemProvider(authority: string, provider: FileSystemProvider): Disposable;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
inputOptions.prompt = options.prompt;
inputOptions.value = options.value;
inputOptions.ignoreFocusLost = options.ignoreFocusOut;
inputOptions.handleKeyDown = options.handleKeyDown;
}

if (validateInput) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ interface IInternalPickOptions {
ignoreFocusLost?: boolean;
quickNavigateConfiguration?: IQuickNavigateConfiguration;
onDidType?: (value: string) => any;
onKeyDown?: (e: KeyboardEvent, value: string) => string;
}

export class QuickOpenController extends Component implements IQuickOpenService {
Expand Down Expand Up @@ -167,7 +168,6 @@ export class QuickOpenController extends Component implements IQuickOpenService
if (this.pickOpenWidget && this.pickOpenWidget.isVisible()) {
this.pickOpenWidget.hide(HideReason.CANCELED);
}

const defaultMessage = options.prompt
? nls.localize('inputModeEntryDescription', "{0} (Press 'Enter' to confirm or 'Escape' to cancel)", options.prompt)
: nls.localize('inputModeEntry', "Press 'Enter' to confirm your input or 'Escape' to cancel");
Expand Down Expand Up @@ -217,7 +217,8 @@ export class QuickOpenController extends Component implements IQuickOpenService
});
}
}
}
},
onKeyDown: options.handleKeyDown
}, token).then(resolve, reject);
};

Expand Down Expand Up @@ -461,6 +462,7 @@ export class QuickOpenController extends Component implements IQuickOpenService

this.pickOpenWidget.refresh(model, value ? { autoFocusFirstEntry: true } : autoFocus);
},
onKeyDown: (e: KeyboardEvent, value: string) => options.onKeyDown(e, value),
onShow: () => this.handleOnShow(true),
onHide: (reason: HideReason) => this.handleOnHide(true, reason)
};
Expand Down