From ca0e4c251b9d41bf4015bea7b31e92cef8e16ebb Mon Sep 17 00:00:00 2001 From: rebornix Date: Mon, 11 Sep 2023 21:47:13 -0700 Subject: [PATCH 1/2] Enable editor hint for notebook cell editor. --- .../emptyTextEditorHint.ts | 19 ++--- .../contrib/editorHint/emptyCellEditorHint.ts | 85 +++++++++++++++++++ .../browser/media/notebookCellEditorHint.css | 8 ++ .../notebook/browser/notebookEditorWidget.ts | 11 ++- 4 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts create mode 100644 src/vs/workbench/contrib/notebook/browser/media/notebookCellEditorHint.css diff --git a/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts b/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts index 5b715e5385e..987bcadb81f 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts @@ -53,22 +53,22 @@ Registry.as(Extensions.ConfigurationMigration) ]) }]); -const emptyTextEditorHintSetting = 'workbench.editor.empty.hint'; +export const emptyTextEditorHintSetting = 'workbench.editor.empty.hint'; export class EmptyTextEditorHintContribution implements IEditorContribution { public static readonly ID = 'editor.contrib.emptyTextEditorHint'; - private toDispose: IDisposable[]; + protected toDispose: IDisposable[]; private textHintContentWidget: EmptyTextEditorHintContentWidget | undefined; constructor( - private readonly editor: ICodeEditor, + protected readonly editor: ICodeEditor, @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService, @ICommandService private readonly commandService: ICommandService, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IConfigurationService protected readonly configurationService: IConfigurationService, @IKeybindingService private readonly keybindingService: IKeybindingService, @IInlineChatSessionService inlineChatSessionService: IInlineChatSessionService, - @IInlineChatService private readonly inlineChatService: IInlineChatService, + @IInlineChatService protected readonly inlineChatService: IInlineChatService, @ITelemetryService private readonly telemetryService: ITelemetryService, @IProductService private readonly productService: IProductService, ) { @@ -92,7 +92,7 @@ export class EmptyTextEditorHintContribution implements IEditorContribution { })); } - private _shouldRenderHint() { + protected _shouldRenderHint() { const configValue = this.configurationService.getValue(emptyTextEditorHintSetting); if (configValue === 'hidden') { return false; @@ -113,17 +113,12 @@ export class EmptyTextEditorHintContribution implements IEditorContribution { return false; } - const isNotebookCell = model?.uri.scheme === Schemas.vscodeNotebookCell; - if (isNotebookCell) { - return false; - } - const inlineChatProviders = [...this.inlineChatService.getAllProvider()]; const shouldRenderDefaultHint = model?.uri.scheme === Schemas.untitled && languageId === PLAINTEXT_LANGUAGE_ID && !inlineChatProviders.length; return inlineChatProviders.length > 0 || shouldRenderDefaultHint; } - private update(): void { + protected update(): void { this.textHintContentWidget?.dispose(); if (this._shouldRenderHint()) { diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts b/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts new file mode 100644 index 00000000000..7611d8b7e53 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { EditorContributionCtor, EditorContributionInstantiation } from 'vs/editor/browser/editorExtensions'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { EmptyTextEditorHintContribution } from 'vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint'; +import { IInlineChatSessionService } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession'; +import { IInlineChatService } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { getNotebookEditorFromEditorPane } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; + +export class EmptyCellEditorHintContribution extends EmptyTextEditorHintContribution { + public static readonly CONTRIB_ID = 'notebook.editor.contrib.emptyCellEditorHint'; + constructor( + editor: ICodeEditor, + @IEditorService private readonly _editorService: IEditorService, + @IEditorGroupsService editorGroupsService: IEditorGroupsService, + @ICommandService commandService: ICommandService, + @IConfigurationService configurationService: IConfigurationService, + @IKeybindingService keybindingService: IKeybindingService, + @IInlineChatSessionService inlineChatSessionService: IInlineChatSessionService, + @IInlineChatService inlineChatService: IInlineChatService, + @ITelemetryService telemetryService: ITelemetryService, + @IProductService productService: IProductService + ) { + super( + editor, + editorGroupsService, + commandService, + configurationService, + keybindingService, + inlineChatSessionService, + inlineChatService, + telemetryService, + productService + ); + + const activeEditor = getNotebookEditorFromEditorPane(this._editorService.activeEditorPane); + + if (!activeEditor) { + return; + } + + this.toDispose.push(activeEditor.onDidChangeActiveCell(() => this.update())); + } + + protected override _shouldRenderHint(): boolean { + const shouldRenderHint = super._shouldRenderHint(); + if (!shouldRenderHint) { + return false; + } + + const model = this.editor.getModel(); + if (!model) { + return false; + } + + const activeEditor = getNotebookEditorFromEditorPane(this._editorService.activeEditorPane); + if (!activeEditor) { + return false; + } + + const activeCell = activeEditor.getActiveCell(); + + if (activeCell?.uri.fragment !== model.uri.fragment) { + return false; + } + + return true; + } +} + +export const EmptyCellEditorHintContributionReg = { + id: EmptyCellEditorHintContribution.CONTRIB_ID, + ctor: EmptyCellEditorHintContribution, + instantiation: EditorContributionInstantiation.Eager +}; diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebookCellEditorHint.css b/src/vs/workbench/contrib/notebook/browser/media/notebookCellEditorHint.css new file mode 100644 index 00000000000..b9ce49783e8 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/browser/media/notebookCellEditorHint.css @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-workbench .notebookOverlay .monaco-editor .contentWidgets .empty-editor-hint { + cursor: auto; +} diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 3830664287b..4e94f404c5b 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/notebook'; +import 'vs/css!./media/notebookCellEditorHint'; import 'vs/css!./media/notebookCellInsertToolbar'; import 'vs/css!./media/notebookCellStatusBar'; import 'vs/css!./media/notebookCellTitleToolbar'; @@ -100,6 +101,8 @@ import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibil import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline'; import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; +import { EmptyCellEditorHintContributionReg } from 'vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint'; +import { EmptyTextEditorHintContribution } from 'vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint'; const $ = DOM.$; @@ -112,9 +115,13 @@ export function getDefaultNotebookCreationOptions(): INotebookEditorCreationOpti 'editor.contrib.testingOutputPeek', 'editor.contrib.testingDecorations', 'store.contrib.stickyScrollController', - 'editor.contrib.findController' + 'editor.contrib.findController', + EmptyTextEditorHintContribution.ID + ]; + const contributions = [ + ...EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1), + EmptyCellEditorHintContributionReg ]; - const contributions = EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1); return { menuIds: { From 52b5f9eae115b500e4511f79bc44332af86b60f4 Mon Sep 17 00:00:00 2001 From: rebornix Date: Tue, 12 Sep 2023 10:29:36 -0700 Subject: [PATCH 2/2] Fix leaks of editor contribs objects in tests. --- .../contrib/editorHint/emptyCellEditorHint.ts | 14 ++++++++------ .../notebook/browser/notebook.contribution.ts | 1 + .../notebook/browser/notebookEditorWidget.ts | 9 ++------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts b/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts index 7611d8b7e53..3948fef3117 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Schemas } from 'vs/base/common/network'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { EditorContributionCtor, EditorContributionInstantiation } from 'vs/editor/browser/editorExtensions'; +import { EditorContributionInstantiation, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -63,6 +64,11 @@ export class EmptyCellEditorHintContribution extends EmptyTextEditorHintContribu return false; } + const isNotebookCell = model?.uri.scheme === Schemas.vscodeNotebookCell; + if (!isNotebookCell) { + return false; + } + const activeEditor = getNotebookEditorFromEditorPane(this._editorService.activeEditorPane); if (!activeEditor) { return false; @@ -78,8 +84,4 @@ export class EmptyCellEditorHintContribution extends EmptyTextEditorHintContribu } } -export const EmptyCellEditorHintContributionReg = { - id: EmptyCellEditorHintContribution.CONTRIB_ID, - ctor: EmptyCellEditorHintContribution, - instantiation: EditorContributionInstantiation.Eager -}; +registerEditorContribution(EmptyCellEditorHintContribution.CONTRIB_ID, EmptyCellEditorHintContribution, EditorContributionInstantiation.Eager); // eager because it needs to render a help message diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 2ef3dfb4e8e..a02c7062c59 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -69,6 +69,7 @@ import 'vs/workbench/contrib/notebook/browser/controller/apiActions'; import 'vs/workbench/contrib/notebook/browser/controller/foldingController'; // Editor Contribution +import 'vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint'; import 'vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard'; import 'vs/workbench/contrib/notebook/browser/contrib/find/notebookFind'; import 'vs/workbench/contrib/notebook/browser/contrib/format/formatting'; diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 4e94f404c5b..9269abcf748 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -101,8 +101,6 @@ import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibil import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline'; import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; -import { EmptyCellEditorHintContributionReg } from 'vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint'; -import { EmptyTextEditorHintContribution } from 'vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint'; const $ = DOM.$; @@ -116,12 +114,9 @@ export function getDefaultNotebookCreationOptions(): INotebookEditorCreationOpti 'editor.contrib.testingDecorations', 'store.contrib.stickyScrollController', 'editor.contrib.findController', - EmptyTextEditorHintContribution.ID - ]; - const contributions = [ - ...EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1), - EmptyCellEditorHintContributionReg + 'editor.contrib.emptyTextEditorHint' ]; + const contributions = EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1); return { menuIds: {