diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index afa4414c3c0..90dbcd2f771 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -53,6 +53,7 @@ import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/note import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { CellEditType, CellKind, CellUri, INTERACTIVE_WINDOW_EDITOR_ID, NotebookWorkingCopyTypeIdentifier } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { InteractiveWindowOpen } from 'vs/workbench/contrib/notebook/common/notebookContextKeys'; import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { columnToEditorGroup } from 'vs/workbench/services/editor/common/editorGroupColumn'; @@ -699,7 +700,11 @@ registerAction2(class extends Action2 { id: 'interactive.input.focus', title: { value: localize('interactive.input.focus', "Focus Input Editor"), original: 'Focus Input Editor' }, category: interactiveWindowCategory, - f1: true + menu: { + id: MenuId.CommandPalette, + when: InteractiveWindowOpen, + }, + precondition: InteractiveWindowOpen, }); } diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts index e61cfbe8181..e5baf7c6af3 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts @@ -12,9 +12,12 @@ import { isCompositeNotebookEditorInput, NotebookEditorInput } from 'vs/workbenc import { IBorrowValue, INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { INotebookEditor, INotebookEditorCreationOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { Emitter } from 'vs/base/common/event'; -import { GroupIdentifier } from 'vs/workbench/common/editor'; +import { GroupIdentifier, GroupModelChangeKind } from 'vs/workbench/common/editor'; import { Dimension } from 'vs/base/browser/dom'; import { URI } from 'vs/base/common/uri'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { InteractiveWindowOpen } from 'vs/workbench/contrib/notebook/common/notebookContextKeys'; export class NotebookEditorWidgetService implements INotebookEditorService { @@ -34,6 +37,8 @@ export class NotebookEditorWidgetService implements INotebookEditorService { constructor( @IEditorGroupsService editorGroupService: IEditorGroupsService, + @IEditorService editorService: IEditorService, + @IContextKeyService contextKeyService: IContextKeyService ) { const groupListener = new Map(); @@ -90,6 +95,19 @@ export class NotebookEditorWidgetService implements INotebookEditorService { } } })); + + const interactiveWindowOpen = InteractiveWindowOpen.bindTo(contextKeyService); + this._disposables.add(editorService.onDidEditorsChange(e => { + if (e.event.kind === GroupModelChangeKind.EDITOR_OPEN && !interactiveWindowOpen.get()) { + if (editorService.editors.find(editor => editor.editorId === 'interactive')) { + interactiveWindowOpen.set(true); + } + } else if (e.event.kind === GroupModelChangeKind.EDITOR_CLOSE && interactiveWindowOpen.get()) { + if (!editorService.editors.find(editor => editor.editorId === 'interactive')) { + interactiveWindowOpen.set(false); + } + } + })); } dispose() { diff --git a/src/vs/workbench/contrib/notebook/common/notebookContextKeys.ts b/src/vs/workbench/contrib/notebook/common/notebookContextKeys.ts index c226a32fe0f..42b5d294c13 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookContextKeys.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookContextKeys.ts @@ -11,6 +11,7 @@ import { INTERACTIVE_WINDOW_EDITOR_ID, NOTEBOOK_EDITOR_ID } from 'vs/workbench/c //#region Context Keys export const HAS_OPENED_NOTEBOOK = new RawContextKey('userHasOpenedNotebook', false); export const KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED = new RawContextKey('notebookFindWidgetFocused', false); +export const InteractiveWindowOpen = new RawContextKey('interactiveWindowOpen', false); // Is Notebook export const NOTEBOOK_IS_ACTIVE_EDITOR = ContextKeyExpr.equals('activeEditor', NOTEBOOK_EDITOR_ID); diff --git a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts index 6dc0a94bc80..715554ed96a 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts @@ -27,7 +27,7 @@ import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentitySe import { ILabelService } from 'vs/platform/label/common/label'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; import { NotebookEditorWidgetService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl'; import { createFileUriFromPathFromRoot, getRootName } from 'vs/workbench/contrib/search/test/browser/searchTestCommon'; import { ICellMatch, IFileMatchWithCells, contentMatchesToTextSearchMatches, webviewMatchesToTextSearchMatches } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; @@ -37,6 +37,9 @@ import { FindMatch, IReadonlyTextBuffer } from 'vs/editor/common/model'; import { ResourceMap, ResourceSet } from 'vs/base/common/map'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; const nullEvent = new class { id: number = -1; @@ -580,6 +583,8 @@ suite('SearchModel', () => { function stubNotebookEditorService(instantiationService: TestInstantiationService): INotebookEditorService { instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService()); + instantiationService.stub(IContextKeyService, new MockContextKeyService()); + instantiationService.stub(IEditorService, new TestEditorService()); return instantiationService.createInstance(NotebookEditorWidgetService); } }); diff --git a/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts b/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts index 50500494d9a..923d74b550d 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts @@ -26,12 +26,15 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { MockLabelService } from 'vs/workbench/services/label/test/common/mockLabelService'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; import { NotebookEditorWidgetService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl'; import { ICellMatch, IFileMatchWithCells } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { addToSearchResult, createFileUriFromPathFromRoot, getRootName } from 'vs/workbench/contrib/search/test/browser/searchTestCommon'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; const lineOneRange = new OneLineRange(1, 0, 1); @@ -553,6 +556,8 @@ suite('SearchResult', () => { function stubNotebookEditorService(instantiationService: TestInstantiationService): INotebookEditorService { instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService()); + instantiationService.stub(IContextKeyService, new MockContextKeyService()); + instantiationService.stub(IEditorService, new TestEditorService()); return instantiationService.createInstance(NotebookEditorWidgetService); } diff --git a/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts b/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts index 026df47ea9c..71e860b9f75 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts @@ -9,15 +9,18 @@ import { IModelService } from 'vs/editor/common/services/model'; import { ModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { NotebookEditorWidgetService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl'; import { SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IFileMatch } from 'vs/workbench/services/search/common/search'; -import { TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; export function createFileUriFromPathFromRoot(path?: string): URI { const rootName = getRootName(); @@ -50,6 +53,8 @@ export function stubModelService(instantiationService: TestInstantiationService) export function stubNotebookEditorService(instantiationService: TestInstantiationService): INotebookEditorService { instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService()); + instantiationService.stub(IContextKeyService, new MockContextKeyService()); + instantiationService.stub(IEditorService, new TestEditorService()); return instantiationService.createInstance(NotebookEditorWidgetService); } diff --git a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts index 279ee49e361..f73f00799f6 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts @@ -26,9 +26,12 @@ import { IFileMatch, ITextSearchMatch, OneLineRange, QueryType, SearchSortOrder import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; import { NotebookEditorWidgetService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl'; import { createFileUriFromPathFromRoot, getRootName } from 'vs/workbench/contrib/search/test/browser/searchTestCommon'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; suite('Search - Viewlet', () => { let instantiation: TestInstantiationService; @@ -215,6 +218,8 @@ suite('Search - Viewlet', () => { function stubNotebookEditorService(instantiationService: TestInstantiationService): INotebookEditorService { instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService()); + instantiationService.stub(IContextKeyService, new MockContextKeyService()); + instantiationService.stub(IEditorService, new TestEditorService()); return instantiationService.createInstance(NotebookEditorWidgetService); } });