Skip to content

Commit

Permalink
fix #4529: compute resource context keys based on global selection
Browse files Browse the repository at this point in the history
and clean up global selection when owning widgets are disposed

Signed-off-by: Anton Kosyakov <[email protected]>
  • Loading branch information
akosyakov committed Mar 12, 2019
1 parent 15a3b34 commit 21245a4
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 18 deletions.
16 changes: 16 additions & 0 deletions packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import * as browser from './browser';
import URI from '../common/uri';
import { ContextKeyService } from './context-key-service';
import { OS } from '../common/os';
import { ResourceContextKey } from './resource-context-key';
import { UriSelection } from '../common/selection';

export namespace CommonMenus {

Expand Down Expand Up @@ -203,11 +205,25 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
@inject(ContextKeyService)
protected readonly contextKeyService: ContextKeyService;

@inject(ResourceContextKey)
protected readonly resourceContextKey: ResourceContextKey;

@postConstruct()
protected init(): void {
this.contextKeyService.createKey<boolean>('isLinux', OS.type() === OS.Type.Linux);
this.contextKeyService.createKey<boolean>('isMac', OS.type() === OS.Type.OSX);
this.contextKeyService.createKey<boolean>('isWindows', OS.type() === OS.Type.Windows);

this.initResourceContextKeys();
}

protected initResourceContextKeys(): void {
const updateContextKeys = () => {
const resourceUri = UriSelection.getUri(this.selectionService.selection);
this.resourceContextKey.set(resourceUri);
};
updateContextKeys();
this.selectionService.onSelectionChanged(updateContextKeys);
}

registerMenus(registry: MenuModelRegistry): void {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/browser/frontend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { bindCorePreferences } from './core-preferences';
import { QuickPickServiceImpl } from './quick-open/quick-pick-service-impl';
import { QuickPickService, quickPickServicePath } from '../common/quick-pick-service';
import { ContextKeyService } from './context-key-service';
import { ResourceContextKey } from './resource-context-key';

export const frontendApplicationModule = new ContainerModule((bind, unbind, isBound, rebind) => {
const themeService = ThemeService.get();
Expand Down Expand Up @@ -152,6 +153,7 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
return messages;
});

bind(ResourceContextKey).toSelf().inSingletonScope();
bind(CommonFrontendContribution).toSelf().inSingletonScope();
[FrontendApplicationContribution, CommandContribution, KeybindingContribution, MenuContribution].forEach(serviceIdentifier =>
bind(serviceIdentifier).toService(CommonFrontendContribution)
Expand Down
52 changes: 52 additions & 0 deletions packages/core/src/browser/resource-context-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable, inject, postConstruct } from 'inversify';
import URI from '../common/uri';
import { ContextKeyService, ContextKey } from './context-key-service';

@injectable()
export class ResourceContextKey {

@inject(ContextKeyService)
protected readonly contextKeyService: ContextKeyService;

protected resourceSchemeKey: ContextKey<string>;
protected resourceFileName: ContextKey<string>;
protected resourceExtname: ContextKey<string>;
protected resourceLangId: ContextKey<string>;

@postConstruct()
protected init(): void {
this.resourceSchemeKey = this.contextKeyService.createKey<string>('resourceScheme', undefined);
this.resourceFileName = this.contextKeyService.createKey<string>('resourceFilename', undefined);
this.resourceExtname = this.contextKeyService.createKey<string>('resourceExtname', undefined);
this.resourceLangId = this.contextKeyService.createKey<string>('resourceLangId', undefined);
}

set(resourceUri: URI | undefined): void {
this.resourceSchemeKey.set(resourceUri && resourceUri.scheme);
this.resourceFileName.set(resourceUri && resourceUri.path.base);
this.resourceExtname.set(resourceUri && resourceUri.path.ext);
this.resourceLangId.set(resourceUri && this.getLanguageId(resourceUri));
}

/** should be implemented by subclasses */
protected getLanguageId(uri: URI | undefined): string | undefined {
return undefined;
}

}
17 changes: 2 additions & 15 deletions packages/editor/src/browser/editor-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,16 @@ export class EditorContribution implements FrontendApplicationContribution {
protected readonly contextKeyService: ContextKeyService;

onStart(): void {
this.initResourceContextKeys();
this.initEditorContextKeys();

this.updateStatusBar();
this.editorManager.onCurrentEditorChanged(() => this.updateStatusBar());
}

/** @default since 0.5.0 - will be removed in farther releases */
protected initResourceContextKeys(): void {
const resourceSchemeKey = this.contextKeyService.createKey<string>('resourceScheme', undefined);
const resourceFileName = this.contextKeyService.createKey<string>('resourceFilename', undefined);
const resourceExtname = this.contextKeyService.createKey<string>('resourceExtname', undefined);
const resourceLangId = this.contextKeyService.createKey<string>('resourceLangId', undefined);
const updateContextKeys = () => {
const editor = this.editorManager.currentEditor;
const resourceUri = editor && editor.getResourceUri();
resourceSchemeKey.set(resourceUri && resourceUri.scheme);
resourceFileName.set(resourceUri && resourceUri.path.base);
resourceExtname.set(resourceUri && resourceUri.path.ext);
resourceLangId.set(this.getLanguageId(resourceUri));
};
updateContextKeys();
this.editorManager.onCurrentEditorChanged(updateContextKeys);
}
/** @default since 0.5.0 - will be removed in farther releases */
protected getLanguageId(uri: URI | undefined): string | undefined {
const { languages } = this.languages;
if (uri && languages) {
Expand Down
7 changes: 6 additions & 1 deletion packages/editor/src/browser/editor-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { SelectionService } from '@theia/core/lib/common';
import { Disposable, SelectionService } from '@theia/core/lib/common';
import { Widget, BaseWidget, Message, Saveable, SaveableSource, Navigatable, StatefulWidget, DiffUris } from '@theia/core/lib/browser';
import URI from '@theia/core/lib/common/uri';
import { TextEditor } from './editor';
Expand All @@ -32,6 +32,11 @@ export class EditorWidget extends BaseWidget implements SaveableSource, Navigata
this.selectionService.selection = this.editor;
}
}));
this.toDispose.push(Disposable.create(() => {
if (this.selectionService.selection === this.editor) {
this.selectionService.selection = undefined;
}
}));
}

get saveable(): Saveable {
Expand Down
40 changes: 40 additions & 0 deletions packages/languages/src/browser/language-resource-context-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable, inject } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { ResourceContextKey } from '@theia/core/lib/browser/resource-context-key';
import { Languages } from './language-client-services';

@injectable()
export class LanguageResourceContextKey extends ResourceContextKey {

@inject(Languages)
protected readonly languages: Languages;

protected getLanguageId(uri: URI | undefined): string | undefined {
const { languages } = this.languages;
if (uri && languages) {
for (const language of languages) {
if (language.extensions.has(uri.path.ext)) {
return language.id;
}
}
}
return undefined;
}

}
7 changes: 6 additions & 1 deletion packages/languages/src/browser/languages-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import { ContainerModule } from 'inversify';
import { bindContributionProvider, CommandContribution } from '@theia/core/lib/common';
import { ResourceContextKey } from '@theia/core/lib/browser/resource-context-key';
import { FrontendApplicationContribution, KeybindingContribution, QuickOpenContribution, WebSocketConnectionProvider } from '@theia/core/lib/browser';
import { Window } from './language-client-services';
import { WindowImpl } from './window-impl';
Expand All @@ -26,8 +27,9 @@ import { WorkspaceSymbolCommand } from './workspace-symbols';
import { LanguageClientProvider } from './language-client-provider';
import { LanguageClientProviderImpl } from './language-client-provider-impl';
import { LanguageContribution } from '../common';
import { LanguageResourceContextKey } from './language-resource-context-key';

export default new ContainerModule(bind => {
export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(Window).to(WindowImpl).inSingletonScope();

bind(LanguageClientFactory).toSelf().inSingletonScope();
Expand All @@ -47,4 +49,7 @@ export default new ContainerModule(bind => {

bind(LanguageClientProviderImpl).toSelf().inSingletonScope();
bind(LanguageClientProvider).toService(LanguageClientProviderImpl);

bind(LanguageResourceContextKey).toSelf().inSingletonScope();
rebind(ResourceContextKey).to(LanguageResourceContextKey).inSingletonScope();
});
7 changes: 6 additions & 1 deletion packages/navigator/src/browser/navigator-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { injectable, inject, postConstruct } from 'inversify';
import { Message } from '@phosphor/messaging';
import URI from '@theia/core/lib/common/uri';
import { CommandService, SelectionService } from '@theia/core/lib/common';
import { CommandService, SelectionService, Disposable } from '@theia/core/lib/common';
import { CommonCommands, CorePreferences } from '@theia/core/lib/browser';
import {
ContextMenuRenderer, ExpandableTreeNode,
Expand Down Expand Up @@ -83,6 +83,11 @@ export class FileNavigatorWidget extends FileTreeWidget {
this.model.expandNode(child);
}
}
}),
Disposable.create(() => {
if (this.selectionService.selection === this) {
this.selectionService.selection = undefined;
}
})
]);
}
Expand Down

0 comments on commit 21245a4

Please sign in to comment.