Skip to content

Commit

Permalink
Use ScmTreeWidget in both commit details and in the diff widget
Browse files Browse the repository at this point in the history
Signed-off-by: Nigel Westbury <nigelipse@miegel.org>
  • Loading branch information
westbury committed Sep 30, 2020
1 parent 7e7d0cd commit 809e10c
Show file tree
Hide file tree
Showing 22 changed files with 1,266 additions and 743 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## v1.7.0

- [git] the changes in the commit details (opened from the history view) and in the diff view (opened with 'Compare With...' on a folder's context menu) are now switchable between 'list' and 'tree' modes [#8084](https://github.com/eclipse-theia/theia/pull/8084)
- [scm] show in the commit textbox the branch to which the commit will go [#6156](https://github.com/eclipse-theia/theia/pull/6156)


Expand Down
155 changes: 130 additions & 25 deletions packages/git/src/browser/diff/git-diff-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import { CommandRegistry, Command, MenuModelRegistry, SelectionService, MessageService } from '@theia/core/lib/common';
import { FrontendApplication, AbstractViewContribution } from '@theia/core/lib/browser';
import { WidgetManager } from '@theia/core/lib/browser/widget-manager';
import { EditorManager } from '@theia/editor/lib/browser';
import { injectable, inject } from 'inversify';
import { GitDiffWidget, GIT_DIFF } from './git-diff-widget';
import { GitCommitDetailWidget } from '../history/git-commit-detail-widget';
import { GitDiffTreeModel } from './git-diff-tree-model';
import { ScmService } from '@theia/scm/lib/browser/scm-service';
import { open, OpenerService } from '@theia/core/lib/browser';
import { NavigatorContextMenu, FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
Expand All @@ -30,7 +33,8 @@ import { GIT_RESOURCE_SCHEME } from '../git-resource';
import { Git, Repository } from '../../common';
import { WorkspaceRootUriAwareCommandHandler } from '@theia/workspace/lib/browser/workspace-commands';
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { TabBarToolbarContribution, TabBarToolbarRegistry, TabBarToolbarItem } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { Emitter } from '@theia/core/lib/common/event';
import { FileService } from '@theia/filesystem/lib/browser/file-service';

export namespace GitDiffCommands {
Expand All @@ -39,6 +43,30 @@ export namespace GitDiffCommands {
category: 'Git Diff',
label: 'Compare With...'
};
export const TREE_VIEW_MODE = {
id: 'git.viewmode.tree',
tooltip: 'Toggle to Tree View',
iconClass: 'codicon codicon-list-tree',
label: 'Toggle to Tree View',
};
export const LIST_VIEW_MODE = {
id: 'git.viewmode.list',
tooltip: 'Toggle to List View',
iconClass: 'codicon codicon-list-flat',
label: 'Toggle to List View',
};
export const PREVIOUS_CHANGE = {
id: 'git.navigate-changes.previous',
tooltip: 'Toggle to List View',
iconClass: 'fa fa-arrow-left',
label: 'Previous Change',
};
export const NEXT_CHANGE = {
id: 'git.navigate-changes.next',
tooltip: 'Toggle to List View',
iconClass: 'fa fa-arrow-right',
label: 'Next Change',
};
}

export namespace ScmNavigatorMoreToolbarGroups {
Expand All @@ -48,6 +76,9 @@ export namespace ScmNavigatorMoreToolbarGroups {
@injectable()
export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget> implements TabBarToolbarContribution {

@inject(EditorManager)
protected readonly editorManager: EditorManager;

@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;

Expand Down Expand Up @@ -88,31 +119,50 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>
isVisible: uri => !!this.findGitRepository(uri),
isEnabled: uri => !!this.findGitRepository(uri),
execute: async fileUri => {
await this.quickOpenService.chooseTagsAndBranches(
async (fromRevision, toRevision) => {
const uri = fileUri.toString();
const fileStat = await this.fileService.resolve(fileUri);
const options: Git.Options.Diff = {
uri,
range: {
fromRevision
}
};
if (fileStat.isDirectory) {
this.showWidget(options);
} else {
const fromURI = fileUri.withScheme(GIT_RESOURCE_SCHEME).withQuery(fromRevision);
const toURI = fileUri;
const diffUri = DiffUris.encode(fromURI, toURI);
if (diffUri) {
open(this.openerService, diffUri).catch(e => {
this.notifications.error(e.message);
});
const repository = this.findGitRepository(fileUri);
if (repository) {
await this.quickOpenService.chooseTagsAndBranches(
async (fromRevision, toRevision) => {
const uri = fileUri.toString();
const fileStat = await this.fileService.resolve(fileUri);
const diffOptions: Git.Options.Diff = {
uri,
range: {
fromRevision
}
};
if (fileStat.isDirectory) {
this.showWidget({ rootUri: repository.localUri, diffOptions });
} else {
const fromURI = fileUri.withScheme(GIT_RESOURCE_SCHEME).withQuery(fromRevision);
const toURI = fileUri;
const diffUri = DiffUris.encode(fromURI, toURI);
if (diffUri) {
open(this.openerService, diffUri).catch(e => {
this.notifications.error(e.message);
});
}
}
}
}, this.findGitRepository(fileUri));
}, repository);
}
}
}));
commands.registerCommand(GitDiffCommands.PREVIOUS_CHANGE, {
execute: widget => {
if (widget instanceof GitDiffWidget) {
widget.goToPreviousChange();
}
},
isVisible: widget => widget instanceof GitDiffWidget,
});
commands.registerCommand(GitDiffCommands.NEXT_CHANGE, {
execute: widget => {
if (widget instanceof GitDiffWidget) {
widget.goToNextChange();
}
},
isVisible: widget => widget instanceof GitDiffWidget,
});
}

registerToolbarItems(registry: TabBarToolbarRegistry): void {
Expand All @@ -122,7 +172,62 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>
tooltip: GitDiffCommands.OPEN_FILE_DIFF.label,
group: ScmNavigatorMoreToolbarGroups.SCM,
});
}

const viewModeEmitter = new Emitter<void>();
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
const extractDiffWidget = (widget: any) => {
if (widget instanceof GitDiffWidget) {
return widget;
}
};
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
const extractCommitDetailWidget = (widget: any) => {
const ref = widget ? widget : this.editorManager.currentEditor;
if (ref instanceof GitCommitDetailWidget) {
return ref;
}
return undefined;
};
const registerToggleViewItem = (command: Command, mode: 'tree' | 'list') => {
const id = command.id;
const item: TabBarToolbarItem = {
id,
command: id,
tooltip: command.label,
onDidChange: viewModeEmitter.event
};
this.commandRegistry.registerCommand({ id, iconClass: command && command.iconClass }, {
execute: widget => {
const widgetWithChanges = extractDiffWidget(widget) || extractCommitDetailWidget(widget);
if (widgetWithChanges) {
widgetWithChanges.viewMode = mode;
viewModeEmitter.fire();
}
},
isVisible: widget => {
const widgetWithChanges = extractDiffWidget(widget) || extractCommitDetailWidget(widget);
if (widgetWithChanges) {
return widgetWithChanges.viewMode !== mode;
}
return false;
},
});
registry.registerItem(item);
};
registerToggleViewItem(GitDiffCommands.TREE_VIEW_MODE, 'tree');
registerToggleViewItem(GitDiffCommands.LIST_VIEW_MODE, 'list');

registry.registerItem({
id: GitDiffCommands.PREVIOUS_CHANGE.id,
command: GitDiffCommands.PREVIOUS_CHANGE.id,
tooltip: GitDiffCommands.PREVIOUS_CHANGE.label,
});
registry.registerItem({
id: GitDiffCommands.NEXT_CHANGE.id,
command: GitDiffCommands.NEXT_CHANGE.id,
tooltip: GitDiffCommands.NEXT_CHANGE.label,
});
}

protected findGitRepository(uri: URI): Repository | undefined {
const repo = this.scmService.findRepository(uri);
Expand All @@ -132,7 +237,7 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>
return undefined;
}

async showWidget(options: Git.Options.Diff): Promise<GitDiffWidget> {
async showWidget(options: GitDiffTreeModel.Options): Promise<GitDiffWidget> {
const widget = await this.widget;
await widget.setContent(options);
return this.openView({
Expand Down
27 changes: 22 additions & 5 deletions packages/git/src/browser/diff/git-diff-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,40 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { interfaces } from 'inversify';
import { interfaces, Container } from 'inversify';
import { GitDiffContribution } from './git-diff-contribution';
import { WidgetFactory, bindViewContribution } from '@theia/core/lib/browser';
import { WidgetFactory, bindViewContribution, TreeModel } from '@theia/core/lib/browser';
import { GitDiffWidget, GIT_DIFF } from './git-diff-widget';
import { GitDiffHeaderWidget } from './git-diff-header-widget';
import { GitDiffTreeModel } from './git-diff-tree-model';
import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';

import { createScmTreeContainer } from '@theia/scm/lib/browser/scm-frontend-module';
import { GitResourceOpener } from './git-resource-opener';
import { GitOpenerInPrimaryArea } from './git-opener-in-primary-area';
import '../../../src/browser/style/diff.css';

export function bindGitDiffModule(bind: interfaces.Bind): void {

bind(GitDiffWidget).toSelf();
bind(WidgetFactory).toDynamicValue(ctx => ({
id: GIT_DIFF,
createWidget: () => ctx.container.get<GitDiffWidget>(GitDiffWidget)
}));
createWidget: () => {
const child = createGitDiffWidgetContainer(ctx.container);
return child.get(GitDiffWidget);
}
})).inSingletonScope();

bindViewContribution(bind, GitDiffContribution);
bind(TabBarToolbarContribution).toService(GitDiffContribution);

}

export function createGitDiffWidgetContainer(parent: interfaces.Container): Container {
const child = createScmTreeContainer(parent);

child.bind(GitDiffHeaderWidget).toSelf();
child.bind(GitDiffTreeModel).toSelf();
child.bind(TreeModel).toService(GitDiffTreeModel);
child.bind(GitResourceOpener).to(GitOpenerInPrimaryArea);
return child;
}
Loading

0 comments on commit 809e10c

Please sign in to comment.