diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/notebookFindWidget.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts similarity index 75% rename from src/vs/workbench/contrib/notebook/browser/contrib/notebookFindWidget.ts rename to src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts index 8a78e23134b438049ddfe0bfa3f35e99f7ab37c8..e1db68872192d0985cf9850db33d88c486c3f9ec 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/notebookFindWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED, INotebookEditor, CellFindMatch, CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { IContextKeyService, IContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED, INotebookEditor, CellFindMatch, CellEditState, INotebookEditorContribution, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { FindDecorations } from 'vs/editor/contrib/find/findDecorations'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; @@ -15,8 +15,17 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { SimpleFindReplaceWidget } from 'vs/workbench/contrib/codeEditor/browser/find/simpleFindReplaceWidget'; import { IThemeService } from 'vs/platform/theme/common/themeService'; - -export class NotebookFindWidget extends SimpleFindReplaceWidget { +import * as DOM from 'vs/base/browser/dom'; +import { registerNotebookContribution } from 'vs/workbench/contrib/notebook/browser/notebookEditorExtensions'; +import { registerAction2, Action2 } from 'vs/platform/actions/common/actions'; +import { localize } from 'vs/nls'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { getActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/contrib/notebookActions'; + +export class NotebookFindWidget extends SimpleFindReplaceWidget implements INotebookEditorContribution { + static id: string = 'workbench.notebook.find'; protected _findWidgetFocused: IContextKey; private _findMatches: CellFindMatch[] = []; protected _findMatchesStarts: PrefixSumComputer | null = null; @@ -32,8 +41,11 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget { ) { super(contextViewService, contextKeyService, themeService); + DOM.append(this._notebookEditor.getDomNode(), this.getDomNode()); + this._findWidgetFocused = KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED.bindTo(contextKeyService); this._register(this._findInput.onKeyDown((e) => this._onFindInputKeyDown(e))); + this.updateTheme(themeService.getColorTheme()); } private _onFindInputKeyDown(e: IKeyboardEvent): void { @@ -236,3 +248,58 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget { this._findMatches = []; } } + +registerNotebookContribution(NotebookFindWidget.id, NotebookFindWidget); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.action.notebook.hideFind', + title: localize('notebookActions.hideFind', "Hide Find in Notebook"), + keybinding: { + when: ContextKeyExpr.and(NOTEBOOK_EDITOR_FOCUSED, KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED), + primary: KeyCode.Escape, + weight: KeybindingWeight.WorkbenchContrib + } + }); + } + + async run(accessor: ServicesAccessor): Promise { + let editorService = accessor.get(IEditorService); + let editor = getActiveNotebookEditor(editorService); + + if (!editor) { + return; + } + + const controller = editor.getContribution(NotebookFindWidget.id); + controller.hide(); + editor.focus(); + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.action.notebook.find', + title: localize('notebookActions.findInNotebook', "Find in Notebook"), + keybinding: { + when: NOTEBOOK_EDITOR_FOCUSED, + primary: KeyCode.KEY_F | KeyMod.CtrlCmd, + weight: KeybindingWeight.WorkbenchContrib + } + }); + } + + async run(accessor: ServicesAccessor): Promise { + let editorService = accessor.get(IEditorService); + let editor = getActiveNotebookEditor(editorService); + + if (!editor) { + return; + } + + const controller = editor.getContribution(NotebookFindWidget.id); + controller.show(); + } +}); diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/notebookActions.ts b/src/vs/workbench/contrib/notebook/browser/contrib/notebookActions.ts index d505d096d93abb26b82a05cc54dfa45fc10c30d6..95d9f7145822713759e4ec78bf14482ff1ff3354 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/notebookActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/notebookActions.ts @@ -13,7 +13,7 @@ import { InputFocusedContext, InputFocusedContextKey } from 'vs/platform/context import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { NOTEBOOK_CELL_EDITABLE_CONTEXT_KEY, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE_CONTEXT_KEY, NOTEBOOK_CELL_TYPE_CONTEXT_KEY, NOTEBOOK_EDITABLE_CONTEXT_KEY, NOTEBOOK_EXECUTING_KEY } from 'vs/workbench/contrib/notebook/browser/constants'; -import { BaseCellRenderTemplate, CellEditState, CellRunState, ICellViewModel, INotebookEditor, KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { BaseCellRenderTemplate, CellEditState, CellRunState, ICellViewModel, INotebookEditor, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellKind, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -289,48 +289,6 @@ registerAction2(class extends Action2 { } }); -registerAction2(class extends Action2 { - constructor() { - super({ - id: 'workbench.action.notebook.hideFind', - title: localize('notebookActions.hideFind', "Hide Find in Notebook"), - keybinding: { - when: ContextKeyExpr.and(NOTEBOOK_EDITOR_FOCUSED, KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED), - primary: KeyCode.Escape, - weight: KeybindingWeight.WorkbenchContrib - } - }); - } - - async run(accessor: ServicesAccessor): Promise { - let editorService = accessor.get(IEditorService); - let editor = getActiveNotebookEditor(editorService); - - editor?.hideFind(); - } -}); - -registerAction2(class extends Action2 { - constructor() { - super({ - id: 'workbench.action.notebook.find', - title: localize('notebookActions.findInNotebook', "Find in Notebook"), - keybinding: { - when: NOTEBOOK_EDITOR_FOCUSED, - primary: KeyCode.KEY_F | KeyMod.CtrlCmd, - weight: KeybindingWeight.WorkbenchContrib - } - }); - } - - async run(accessor: ServicesAccessor): Promise { - let editorService = accessor.get(IEditorService); - let editor = getActiveNotebookEditor(editorService); - - editor?.showFind(); - } -}); - MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: EXECUTE_NOTEBOOK_COMMAND_ID, diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 7cb5da4727c47db6e1ca952670a7297bc35c1647..cb8acdd264e965a5c0c655e7835417edb3b80b65 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -33,6 +33,7 @@ import { ResourceMap } from 'vs/base/common/map'; // Editor Contribution import 'vs/workbench/contrib/notebook/browser/contrib/fold/folding'; +import 'vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget'; // Output renderers registration diff --git a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts index a1851c77e716406012952a4fbf315500f82857ca..e08f3555e1c2eceb4dbdcd98dd957d35ff3d2ec9 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts @@ -125,6 +125,7 @@ export interface INotebookEditor { readonly onDidChangeModel: Event; isNotebookEditor: boolean; + getDomNode(): HTMLElement; getInnerWebview(): Webview | undefined; /** @@ -297,18 +298,6 @@ export interface INotebookEditor { */ changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any; - /** - * Show Find Widget. - * - * Currently Find is still part of the NotebookEditor core - */ - showFind(): void; - - /** - * Hide Find Widget - */ - hideFind(): void; - /** * An event emitted on a "mouseup". * @event diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts index 75d5af497b83c6af10fac425d47ac4c8bac8ed99..9cc41720d92e29776e88519c26c6c25346c33569 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts @@ -29,7 +29,6 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor'; import { EditorOptions, IEditorCloseEvent, IEditorMemento } from 'vs/workbench/common/editor'; import { CELL_MARGIN, CELL_RUN_GUTTER, EDITOR_TOP_MARGIN, EDITOR_TOP_PADDING, EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; -import { NotebookFindWidget } from 'vs/workbench/contrib/notebook/browser/contrib/notebookFindWidget'; import { CellEditState, CellFocusMode, ICellRange, ICellViewModel, INotebookCellList, INotebookEditor, INotebookEditorMouseEvent, NotebookLayoutInfo, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, INotebookEditorContribution } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorInput, NotebookEditorModel } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput'; import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService'; @@ -91,7 +90,7 @@ export class NotebookCodeEditors implements ICompositeCodeEditor { export class NotebookEditor extends BaseEditor implements INotebookEditor { static readonly ID: string = 'workbench.editor.notebook'; - private rootElement!: HTMLElement; + private _rootElement!: HTMLElement; private body!: HTMLElement; private webview: BackLayerWebView | null = null; private webviewTransparentCover: HTMLElement | null = null; @@ -109,8 +108,6 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { private editorEditable: IContextKey | null = null; private editorExecutingNotebook: IContextKey | null = null; private outputRenderer: OutputRenderer; - private findWidget: NotebookFindWidget; - // private folding: FoldingController | null = null; protected readonly _contributions: { [key: string]: INotebookEditorContribution; }; constructor( @@ -121,27 +118,13 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { @INotebookService private notebookService: INotebookService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @IConfigurationService private readonly configurationService: IConfigurationService, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - // @IEditorProgressService private readonly progressService: IEditorProgressService, + @IContextKeyService private readonly contextKeyService: IContextKeyService ) { super(NotebookEditor.ID, telemetryService, themeService, storageService); this.editorMemento = this.getEditorMemento(editorGroupService, NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY); this.outputRenderer = new OutputRenderer(this, this.instantiationService); - this.findWidget = this.instantiationService.createInstance(NotebookFindWidget, this); - this.findWidget.updateTheme(this.themeService.getColorTheme()); - this._contributions = {}; - const contributions = NotebookEditorExtensionsRegistry.getEditorContributions(); - - for (const desc of contributions) { - try { - const contribution = this.instantiationService.createInstance(desc.ctor, this); - this._contributions[desc.id] = contribution; - } catch (err) { - onUnexpectedError(err); - } - } } private readonly _onDidChangeModel = new Emitter(); @@ -173,8 +156,8 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { } protected createEditor(parent: HTMLElement): void { - this.rootElement = DOM.append(parent, $('.notebook-editor')); - this.createBody(this.rootElement); + this._rootElement = DOM.append(parent, $('.notebook-editor')); + this.createBody(this._rootElement); this.generateFontInfo(); this.editorFocus = NOTEBOOK_EDITOR_FOCUSED.bindTo(this.contextKeyService); this.editorFocus.set(true); @@ -189,6 +172,17 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { this.editorEditable = NOTEBOOK_EDITOR_EDITABLE.bindTo(this.contextKeyService); this.editorEditable.set(true); this.editorExecutingNotebook = NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK.bindTo(this.contextKeyService); + + const contributions = NotebookEditorExtensionsRegistry.getEditorContributions(); + + for (const desc of contributions) { + try { + const contribution = this.instantiationService.createInstance(desc.ctor, this); + this._contributions[desc.id] = contribution; + } catch (err) { + onUnexpectedError(err); + } + } } private generateFontInfo(): void { @@ -201,7 +195,6 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { DOM.addClass(this.body, 'cell-list-container'); this.createCellList(); DOM.append(parent, this.body); - DOM.append(parent, this.findWidget.getDomNode()); } private createCellList(): void { @@ -269,13 +262,13 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { this.webviewTransparentCover = DOM.append(this.list.rowsContainer, $('.webview-cover')); this.webviewTransparentCover.style.display = 'none'; - this._register(DOM.addStandardDisposableGenericMouseDownListner(this.rootElement, (e: StandardMouseEvent) => { + this._register(DOM.addStandardDisposableGenericMouseDownListner(this._rootElement, (e: StandardMouseEvent) => { if (DOM.hasClass(e.target, 'slider') && this.webviewTransparentCover) { this.webviewTransparentCover.style.display = 'block'; } })); - this._register(DOM.addStandardDisposableGenericMouseUpListner(this.rootElement, (e: StandardMouseEvent) => { + this._register(DOM.addStandardDisposableGenericMouseUpListner(this._rootElement, (e: StandardMouseEvent) => { if (this.webviewTransparentCover) { // no matter when this.webviewTransparentCover.style.display = 'none'; @@ -296,6 +289,10 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { } + getDomNode() { + return this._rootElement; + } + getControl() { return this.control; } @@ -393,7 +390,6 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { this.notebookViewModel = undefined; this.webview?.clearInsets(); this.webview?.clearPreloadsCache(); - this.findWidget.clear(); this.list?.clear(); } @@ -567,8 +563,8 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { layout(dimension: DOM.Dimension): void { this.dimension = new DOM.Dimension(dimension.width, dimension.height); - DOM.toggleClass(this.rootElement, 'mid-width', dimension.width < 1000 && dimension.width >= 600); - DOM.toggleClass(this.rootElement, 'narrow-width', dimension.width < 600); + DOM.toggleClass(this._rootElement, 'mid-width', dimension.width < 1000 && dimension.width >= 600); + DOM.toggleClass(this._rootElement, 'narrow-width', dimension.width < 600); DOM.size(this.body, dimension.width, dimension.height); this.list?.updateOptions({ additionalScrollHeight: dimension.height }); this.list?.layout(dimension.height, dimension.width); @@ -647,19 +643,6 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { //#endregion - //#region Find Delegate - - public showFind() { - this.findWidget.reveal(); - } - - public hideFind() { - this.findWidget.hide(); - this.focus(); - } - - //#endregion - //#region Mouse Events private readonly _onMouseUp: Emitter = this._register(new Emitter()); public readonly onMouseUp: Event = this._onMouseUp.event; @@ -948,6 +931,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { } //#endregion + dispose() { const keys = Object.keys(this._contributions); for (let i = 0, len = keys.length; i < len; i++) { diff --git a/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts b/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts index 9d48784b6006cc627fd75e0726427e1823f85faa..0eaf05d2ec3169763c90d35e20e7c87cc5e831aa 100644 --- a/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts @@ -51,6 +51,9 @@ export class TestNotebookEditor implements INotebookEditor { constructor( ) { } + getDomNode(): HTMLElement { + throw new Error('Method not implemented.'); + } private _onDidChangeModel = new Emitter(); onDidChangeModel: Event = this._onDidChangeModel.event;