Description
openedon Jul 25, 2022
With Find Widget introduced in File Explorer and Notebook Editor, we now have multiple implementations for input box with multiple filter/toggles. We reused FindInput
which has 3 built-in filters (caseSensitivity
, wholeWord
and regex
) and had to add additional filters in our own ways. File Explorer and Notebook handles this differently and there isn't a clear path of how they can be unified and how other input box users can adopt this in the future.
In addition, Problems panel and Terminal recent commands have their own input box with a single filter, which are not inherited from find input.
Variations
Text Editor
- 3 built-in filters
- Additional filter (Find in Selection) as a separate button
Terminal
- 3 built-in filters only
Webview
- Built-in filters all disabled/hidden
File Explorer
- Built-in filters disabled/hidden
- Additional filter shown as a toggle inside the input box
Notebook
- 3 built-in filters only
- Additional filters shown in a dropdown/context menu
Problems
- Multiple filters which are specific to Problems only
Proposal
The input boxes from find widgets shown above all derive from the original FindWidget
in Monaco, which only has 3 builtin filters and they are no longer universal as not all embedders have the capability of implementing all of them. Embedders also have the need to the extend the filters which is not well supported, leading to the fragmentation of the find widgets.
The proposal here is experimenting if we can introduce a generic input
box with dynamic filters support at the base/platform
level (not from editor
or workbench
). The common features are:
- Support filters as Toggle button
- Support filters as Dropdown/Context menu
- Broadcast events when filter state changes
The UI for it can be a mix of the input boxes from File Explorer and Notebook, and embedders can contribute dynamic filters and declare how they should be rendered (as Toggle or Dropdown) statically.
A draft for the interfaces of the new input box and its filters:
interface InputFilter {
value: boolean;
icon: Codicon;
isPrimary: boolean;
}
interface InputFilters {
[key: string]: InputFilter;
}
type FilterUpdateEvent<T> = { [K in keyof T]?: string };
interface InputWithFilters<T = InputFilters> {
filters: T;
onDidChangeFilter: Event<FilterUpdateEvent<T>>;
}
The input box in the Notebook Find Widget can then be declared as
interface NotebookEditorFindInputFilters extends InputFilters {
caseSensitive: InputFilter;
wholeWord: InputFilter;
regex: InputFilter;
searchInMarkdown: InputFilter;
searchInOutput: InputFilter;
}
type NotebookEditorFindInput = InputWithFilters<NotebookEditorFindInputFilters>;
// notebook editor find input filter object
{
caseSensitive: { value: false, icon: Codicon.caseSensitive, isPrimary: true },
wholeWord: { value: false, icon: Codicon.wholeWord, isPrimary: true },
regex: { value: false, icon: Codicon.regex, isPrimary: true },
searchInMarkdown: { value: false, icon: Codicon.markdown, isPrimary: false },
searchInOutput: { value: false, icon: Codicon.output, isPrimary: false }
}
cc @joaomoreno @Tyriar @andreamah @mjbvz feedbacks welcome!