enable find in md/output.

This commit is contained in:
rebornix 2022-01-12 12:20:46 -08:00
parent 7d6c9f1745
commit 347f954c29
No known key found for this signature in database
GPG key ID: 181FC90D15393C20
6 changed files with 133 additions and 90 deletions

View file

@ -100,6 +100,5 @@
"list",
"git",
"sash"
],
"notebook.find.experimental": true
]
}

View file

@ -53,23 +53,24 @@ export class FindInput extends Widget {
private fixFocusOnOptionClickEnabled = true;
private imeSessionInProgress = false;
private inputActiveOptionBorder?: Color;
private inputActiveOptionForeground?: Color;
private inputActiveOptionBackground?: Color;
private inputBackground?: Color;
private inputForeground?: Color;
private inputBorder?: Color;
protected inputActiveOptionBorder?: Color;
protected inputActiveOptionForeground?: Color;
protected inputActiveOptionBackground?: Color;
protected inputBackground?: Color;
protected inputForeground?: Color;
protected inputBorder?: Color;
private inputValidationInfoBorder?: Color;
private inputValidationInfoBackground?: Color;
private inputValidationInfoForeground?: Color;
private inputValidationWarningBorder?: Color;
private inputValidationWarningBackground?: Color;
private inputValidationWarningForeground?: Color;
private inputValidationErrorBorder?: Color;
private inputValidationErrorBackground?: Color;
private inputValidationErrorForeground?: Color;
protected inputValidationInfoBorder?: Color;
protected inputValidationInfoBackground?: Color;
protected inputValidationInfoForeground?: Color;
protected inputValidationWarningBorder?: Color;
protected inputValidationWarningBackground?: Color;
protected inputValidationWarningForeground?: Color;
protected inputValidationErrorBorder?: Color;
protected inputValidationErrorBackground?: Color;
protected inputValidationErrorForeground?: Color;
protected controls: HTMLDivElement;
private regex: RegexCheckbox;
private wholeWords: WholeWordsCheckbox;
private caseSensitive: CaseSensitiveCheckbox;
@ -242,14 +243,14 @@ export class FindInput extends Widget {
});
let controls = document.createElement('div');
controls.className = 'controls';
controls.style.display = this._showOptionButtons ? 'block' : 'none';
controls.appendChild(this.caseSensitive.domNode);
controls.appendChild(this.wholeWords.domNode);
controls.appendChild(this.regex.domNode);
this.controls = document.createElement('div');
this.controls.className = 'controls';
this.controls.style.display = this._showOptionButtons ? 'block' : 'none';
this.controls.appendChild(this.caseSensitive.domNode);
this.controls.appendChild(this.wholeWords.domNode);
this.controls.appendChild(this.regex.domNode);
this.domNode.appendChild(controls);
this.domNode.appendChild(this.controls);
if (parent) {
parent.appendChild(this.domNode);

View file

@ -33,7 +33,7 @@ interface IContextScopedWidget {
readonly target: IContextKeyServiceTarget;
}
interface IContextScopedHistoryNavigationWidget extends IContextScopedWidget {
export interface IContextScopedHistoryNavigationWidget extends IContextScopedWidget {
historyNavigator: IHistoryNavigationWidget;
}

View file

@ -50,7 +50,6 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget<INotebookFindFil
private _hideTimeout: number | null = null;
private _previousFocusElement?: HTMLElement;
private _findModel: FindModel;
private _styleElement!: HTMLStyleElement;
private _findInPreview: IContextKey<boolean>;
private _findInOutput: IContextKey<boolean>;
@ -64,7 +63,7 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget<INotebookFindFil
@IMenuService menuService: IMenuService,
@IInstantiationService instantiationService: IInstantiationService,
) {
super(contextViewService, contextKeyService, themeService, configurationService, menuService, contextMenuService, instantiationService, new FindReplaceState<INotebookFindFilter>(), true);
super(contextViewService, contextKeyService, themeService, configurationService, menuService, contextMenuService, instantiationService, new FindReplaceState<INotebookFindFilter>());
this._findModel = new FindModel(this._notebookEditor, this._state, this._configurationService);
DOM.append(this._notebookEditor.getDomNode(), this.getDomNode());
@ -97,22 +96,8 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget<INotebookFindFil
this._register(DOM.addDisposableListener(this.getDomNode(), DOM.EventType.FOCUS, e => {
this._previousFocusElement = e.relatedTarget instanceof HTMLElement ? e.relatedTarget : undefined;
}, true));
this._createLayoutStyles();
}
private _createLayoutStyles(): void {
this._styleElement = DOM.createStyleSheet(this.getDomNode());
const experimental = this._configurationService.getValue<boolean>('notebook.find.experimental');
const styleSheets: string[] = [];
if (experimental) {
styleSheets.push('.monaco-workbench .simple-fr-find-part-wrapper { width: 341px; }');
} else {
styleSheets.push('.monaco-workbench .simple-fr-find-part-wrapper { width: 318px; }');
}
this._styleElement.textContent = styleSheets.join('\n');
}
private _onFindInputKeyDown(e: IKeyboardEvent): void {
if (e.equals(KeyCode.Enter)) {
@ -273,15 +258,16 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget<INotebookFindFil
findInMarkdownPreview?: boolean,
findInOutput?: boolean
}) {
const currentFilters = this._state.filters;
const currentFilters = this._state.filters ?? { findInMarkdownPreview: false, findInOutput: false };
this._state.change({
filters: {
findInMarkdownPreview: filters.findInMarkdownPreview ?? currentFilters?.findInMarkdownPreview ?? false,
findInOutput: filters.findInOutput ?? currentFilters?.findInOutput ?? false
findInMarkdownPreview: filters.findInMarkdownPreview ? !currentFilters?.findInMarkdownPreview : currentFilters?.findInMarkdownPreview,
findInOutput: filters.findInOutput ? !currentFilters?.findInOutput : currentFilters?.findInOutput
}
}, false);
this._findInPreview.set(!!this._state.filters?.findInMarkdownPreview);
this._findInOutput.set(!!this._state.filters?.findInOutput);
this._findInput.updateFilterState((this._state.filters?.findInMarkdownPreview ?? false) || (this._state.filters?.findInOutput ?? false));
}
override hide() {

View file

@ -9,7 +9,7 @@
position: absolute;
top: -45px;
right: 18px;
width: 341px;
width: 318px;
max-width: calc(100% - 28px - 28px - 8px);
pointer-events: none;
transition: top 200ms linear;
@ -118,3 +118,11 @@
opacity: 0.3;
cursor: default;
}
.find-filter-button .monaco-action-bar:not(.vertical) .action-label:not(.disabled):hover {
background-color: inherit !important;
}
.find-filter-button .monaco-action-bar .action-label {
padding: 0;
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as dom from 'vs/base/browser/dom';
import { FindInput, IFindInputStyles } from 'vs/base/browser/ui/findinput/findInput';
import { FindInput, IFindInputOptions, IFindInputStyles } from 'vs/base/browser/ui/findinput/findInput';
import { IReplaceInputStyles, ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput';
import { IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
@ -15,7 +15,7 @@ import 'vs/css!./notebookFindReplaceWidget';
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState';
import { findNextMatchIcon, findPreviousMatchIcon, findReplaceAllIcon, findReplaceIcon, SimpleButton } from 'vs/editor/contrib/find/findWidget';
import * as nls from 'vs/nls';
import { ContextScopedFindInput, ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget';
import { ContextScopedReplaceInput, createAndBindHistoryNavigationWidgetScopedContextKeyService, IContextScopedHistoryNavigationWidget } from 'vs/platform/browser/contextScopedHistoryWidget';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { editorWidgetBackground, editorWidgetForeground, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
@ -30,6 +30,7 @@ import { IAction } from 'vs/base/common/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMenu, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { createActionViewItem, createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
const NLS_FIND_INPUT_LABEL = nls.localize('label.find', "Find");
const NLS_FIND_INPUT_PLACEHOLDER = nls.localize('placeholder.find', "Find");
@ -45,15 +46,77 @@ const NLS_REPLACE_ALL_BTN_LABEL = nls.localize('label.replaceAllButton', "Replac
export const findFilterButton = registerIcon('find-filter', Codicon.filter, nls.localize('findFilterIcon', 'Icon for Find Filter in find widget.'));
class NotebookFindInput extends FindInput {
protected readonly filterToolbar: ToolBar;
private _filterButtonContainer: HTMLElement;
private _filterChecked: boolean = false;
constructor(
contextKeyService: IContextKeyService,
themeService: IThemeService,
menuService: IMenuService,
contextMenuService: IContextMenuService,
instantiationService: IInstantiationService,
scopedContextKeyService: IContextKeyService,
parent: HTMLElement | null, contextViewProvider: IContextViewProvider, showOptionButtons: boolean, options: IFindInputOptions) {
super(parent, contextViewProvider, showOptionButtons, options);
this._register(createAndBindHistoryNavigationWidgetScopedContextKeyService(contextKeyService, <IContextScopedHistoryNavigationWidget>{ target: this.inputBox.element, historyNavigator: this.inputBox }).scopedContextKeyService);
this._filterButtonContainer = dom.$('.find-filter-button');
this._filterButtonContainer.classList.add('monaco-custom-checkbox');
const primaryMenu = menuService.createMenu(MenuId.NotebookFindToolbar, scopedContextKeyService);
this.filterToolbar = this._register(new ToolBar(this._filterButtonContainer, contextMenuService, {
actionViewItemProvider: action => {
return createActionViewItem(instantiationService, action);
}
}));
const actions = this.getCellToolbarActions(primaryMenu);
this.filterToolbar.setActions([...actions.primary, ...actions.secondary]);
this._register(primaryMenu.onDidChange(() => {
const actions = this.getCellToolbarActions(primaryMenu);
this.filterToolbar.setActions([...actions.primary, ...actions.secondary]);
}));
this.controls.appendChild(this._filterButtonContainer);
}
updateFilterState(changed: boolean) {
this._filterChecked = changed;
this.applyStyles();
}
override applyStyles(): void {
super.applyStyles();
this._filterButtonContainer.style.borderColor = this._filterChecked && this.inputActiveOptionBorder ? this.inputActiveOptionBorder.toString() : '';
this._filterButtonContainer.style.color = this._filterChecked && this.inputActiveOptionForeground ? this.inputActiveOptionForeground.toString() : 'inherit';
this._filterButtonContainer.style.backgroundColor = this._filterChecked && this.inputActiveOptionBackground ? this.inputActiveOptionBackground.toString() : '';
}
getCellToolbarActions(menu: IMenu): { primary: IAction[], secondary: IAction[]; } {
const primary: IAction[] = [];
const secondary: IAction[] = [];
const result = { primary, secondary };
createAndFillInActionBarActions(menu, { shouldForwardArgs: true }, result, g => /^inline/.test(g));
return result;
}
}
export abstract class SimpleFindReplaceWidget<T> extends Widget {
protected readonly _findInput: FindInput;
protected readonly _findInput: NotebookFindInput;
private readonly _domNode: HTMLElement;
private readonly _innerFindDomNode: HTMLElement;
private readonly _focusTracker: dom.IFocusTracker;
private readonly _findInputFocusTracker: dom.IFocusTracker;
private readonly _updateHistoryDelayer: Delayer<void>;
protected readonly _matchesCount!: HTMLElement;
protected readonly filterToolbar?: ToolBar;
private readonly prevBtn: SimpleButton;
private readonly nextBtn: SimpleButton;
@ -81,8 +144,7 @@ export abstract class SimpleFindReplaceWidget<T> extends Widget {
@IMenuService readonly menuService: IMenuService,
@IContextMenuService readonly contextMenuService: IContextMenuService,
@IInstantiationService readonly instantiationService: IInstantiationService,
protected readonly _state: FindReplaceState<T> = new FindReplaceState<T>(),
showOptionButtons?: boolean
protected readonly _state: FindReplaceState<T> = new FindReplaceState<T>()
) {
super();
@ -117,23 +179,34 @@ export abstract class SimpleFindReplaceWidget<T> extends Widget {
this._innerFindDomNode = document.createElement('div');
this._innerFindDomNode.classList.add('simple-fr-find-part');
this._findInput = this._register(new ContextScopedFindInput(null, this._contextViewService, {
label: NLS_FIND_INPUT_LABEL,
placeholder: NLS_FIND_INPUT_PLACEHOLDER,
validation: (value: string): InputBoxMessage | null => {
if (value.length === 0 || !this._findInput.getRegex()) {
return null;
}
try {
new RegExp(value);
return null;
} catch (e) {
this.foundMatch = false;
this.updateButtons(this.foundMatch);
return { content: e.message };
this._findInput = this._register(new NotebookFindInput(
this._scopedContextKeyService,
this._themeService,
this.menuService,
this.contextMenuService,
this.instantiationService,
this._scopedContextKeyService,
null,
this._contextViewService,
true,
{
label: NLS_FIND_INPUT_LABEL,
placeholder: NLS_FIND_INPUT_PLACEHOLDER,
validation: (value: string): InputBoxMessage | null => {
if (value.length === 0 || !this._findInput.getRegex()) {
return null;
}
try {
new RegExp(value);
return null;
} catch (e) {
this.foundMatch = false;
this.updateButtons(this.foundMatch);
return { content: e.message };
}
}
}
}, contextKeyService, showOptionButtons));
));
// Find History with update delayer
this._updateHistoryDelayer = new Delayer<void>(500);
@ -194,29 +267,6 @@ export abstract class SimpleFindReplaceWidget<T> extends Widget {
this._innerFindDomNode.appendChild(this._findInput.domNode);
this._innerFindDomNode.appendChild(this._matchesCount);
// Toggle filter button
const experimental = this._configurationService.getValue<boolean>('notebook.find.experimental');
if (experimental) {
let filterButtonContainer = dom.$('.find-filter-button');
this._innerFindDomNode.appendChild(filterButtonContainer);
const primaryMenu = this.menuService.createMenu(MenuId.NotebookFindToolbar, this._scopedContextKeyService);
this.filterToolbar = this._register(new ToolBar(filterButtonContainer, this.contextMenuService, {
actionViewItemProvider: action => {
return createActionViewItem(this.instantiationService, action);
}
}));
const actions = this.getCellToolbarActions(primaryMenu);
this.filterToolbar.setActions([...actions.primary, ...actions.secondary]);
this._register(primaryMenu.onDidChange(() => {
const actions = this.getCellToolbarActions(primaryMenu);
this.filterToolbar?.setActions([...actions.primary, ...actions.secondary]);
}));
}
this._innerFindDomNode.appendChild(this.prevBtn.domNode);
this._innerFindDomNode.appendChild(this.nextBtn.domNode);
this._innerFindDomNode.appendChild(closeBtn.domNode);
@ -365,7 +415,6 @@ export abstract class SimpleFindReplaceWidget<T> extends Widget {
inputValidationErrorBorder: theme.getColor(inputValidationErrorBorder),
};
this._replaceInput.style(replaceStyles);
// this.filterBtn?.style(inputStyles);
}
private _onStateChanged(e: FindReplaceStateChangedEvent): void {