diff --git a/extensions/git/package.json b/extensions/git/package.json
index fb84e21d6ed..7fd88a4d57c 100644
--- a/extensions/git/package.json
+++ b/extensions/git/package.json
@@ -38,22 +38,38 @@
{
"command": "git.stage",
"title": "Stage",
- "category": "Git"
+ "category": "Git",
+ "icon": {
+ "light": "resources/icons/light/stage.svg",
+ "dark": "resources/icons/dark/stage.svg"
+ }
},
{
"command": "git.stage-all",
"title": "Stage All",
- "category": "Git"
+ "category": "Git",
+ "icon": {
+ "light": "resources/icons/light/stage.svg",
+ "dark": "resources/icons/dark/stage.svg"
+ }
},
{
"command": "git.unstage",
"title": "Unstage",
- "category": "Git"
+ "category": "Git",
+ "icon": {
+ "light": "resources/icons/light/unstage.svg",
+ "dark": "resources/icons/dark/unstage.svg"
+ }
},
{
"command": "git.unstage-all",
"title": "Unstage All",
- "category": "Git"
+ "category": "Git",
+ "icon": {
+ "light": "resources/icons/light/unstage.svg",
+ "dark": "resources/icons/dark/unstage.svg"
+ }
}
],
"menus": {
@@ -63,24 +79,48 @@
"group": "navigation"
}
],
+ "scm/git/index/group": [
+ {
+ "command": "git.unstage-all",
+ "group": "navigation"
+ }
+ ],
"scm/git/index/group/context": [
{
"command": "git.unstage-all",
"group": "navigation"
}
],
+ "scm/git/index/resource": [
+ {
+ "command": "git.unstage",
+ "group": "navigation"
+ }
+ ],
"scm/git/index/resource/context": [
{
"command": "git.unstage",
"group": "navigation"
}
],
+ "scm/git/workingTree/group": [
+ {
+ "command": "git.stage-all",
+ "group": "navigation"
+ }
+ ],
"scm/git/workingTree/group/context": [
{
"command": "git.stage-all",
"group": "navigation"
}
],
+ "scm/git/workingTree/resource": [
+ {
+ "command": "git.stage",
+ "group": "navigation"
+ }
+ ],
"scm/git/workingTree/resource/context": [
{
"command": "git.stage",
diff --git a/extensions/git/resources/icons/dark/stage.svg b/extensions/git/resources/icons/dark/stage.svg
new file mode 100644
index 00000000000..3475c1e1963
--- /dev/null
+++ b/extensions/git/resources/icons/dark/stage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/git/resources/icons/dark/unstage.svg b/extensions/git/resources/icons/dark/unstage.svg
new file mode 100644
index 00000000000..2de46fcf5b5
--- /dev/null
+++ b/extensions/git/resources/icons/dark/unstage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/git/resources/icons/light/stage.svg b/extensions/git/resources/icons/light/stage.svg
new file mode 100644
index 00000000000..bdecdb0e45b
--- /dev/null
+++ b/extensions/git/resources/icons/light/stage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/git/resources/icons/light/unstage.svg b/extensions/git/resources/icons/light/unstage.svg
new file mode 100644
index 00000000000..f5d128b2df8
--- /dev/null
+++ b/extensions/git/resources/icons/light/unstage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts
index 96a8a9aba2b..c4cf4bded6b 100644
--- a/extensions/git/src/commands.ts
+++ b/extensions/git/src/commands.ts
@@ -5,7 +5,7 @@
'use strict';
-import { commands, Disposable } from 'vscode';
+import { commands, Disposable, SCMResourceGroup, SCMResource } from 'vscode';
import { Model } from './model';
import { log } from './util';
@@ -20,9 +20,29 @@ function openChange(...args: any[]): void {
console.log('openChange', args);
}
+function stage(resource: SCMResource): void {
+ log('stage', resource);
+}
+
+function stageAll(resourceGroup: SCMResourceGroup): void {
+ log('stage-all', resourceGroup);
+}
+
+function unstage(resource: SCMResource): void {
+ log('unstage', resource);
+}
+
+function unstageAll(resourceGroup: SCMResourceGroup): void {
+ log('unstage-all', resourceGroup);
+}
+
export function registerCommands(model: Model): Disposable {
const disposables = [
commands.registerCommand('git.refresh', refresh(model)),
+ commands.registerCommand('git.stage', stage),
+ commands.registerCommand('git.stage-all', stageAll),
+ commands.registerCommand('git.unstage', unstage),
+ commands.registerCommand('git.unstage-all', unstageAll),
commands.registerCommand('git.open-change', openChange)
];
diff --git a/src/vs/workbench/parts/scm/browser/media/scmViewlet.css b/src/vs/workbench/parts/scm/browser/media/scmViewlet.css
index 62bf3a862a2..398f2149b3b 100644
--- a/src/vs/workbench/parts/scm/browser/media/scmViewlet.css
+++ b/src/vs/workbench/parts/scm/browser/media/scmViewlet.css
@@ -29,12 +29,41 @@
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
-.scm-viewlet .monaco-list-row > .resource-group > .count-badge {
+.scm-viewlet .monaco-list-row > .resource-group:hover > .count {
+ display: none;
+}
+
+.scm-viewlet .monaco-list-row > .resource-group:not(:hover) > .actions {
+ display: none;
+}
+
+.scm-viewlet .monaco-list-row > .resource {
+ display: flex;
+}
+
+.scm-viewlet .monaco-list-row > .resource > .name {
flex: 1;
- font-size: 11px;
- font-weight: bold;
- text-transform: uppercase;
- cursor: default;
+ overflow: hidden;
+}
+
+.scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label {
+ width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.scm-viewlet .monaco-list-row > .resource > .actions .action-label,
+.scm-viewlet .monaco-list-row > .resource-group > .actions .action-label {
+ width: 16px;
+ height: 100%;
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+}
+
+.scm-viewlet .monaco-list-row > .resource:not(:hover) > .actions {
+ display: none;
}
\ No newline at end of file
diff --git a/src/vs/workbench/parts/scm/browser/scmMenus.ts b/src/vs/workbench/parts/scm/browser/scmMenus.ts
index 2214fda7c95..540eabce68f 100644
--- a/src/vs/workbench/parts/scm/browser/scmMenus.ts
+++ b/src/vs/workbench/parts/scm/browser/scmMenus.ts
@@ -63,23 +63,39 @@ export class SCMMenus implements IDisposable {
return this.titleSecondaryActions;
}
- getResourceGroupActions(providerId: string, resourceGroupId: string): IAction[] {
- const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.ResourceGroup, false);
+ getResourceGroupActions(resourceGroupId: string): IAction[] {
+ if (!this.scmService.activeProvider) {
+ return [];
+ }
+
+ const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.ResourceGroup, false);
return this.getActions(menuId);
}
- getResourceGroupContextActions(providerId: string, resourceGroupId: string): IAction[] {
- const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.ResourceGroup, true);
+ getResourceGroupContextActions(resourceGroupId: string): IAction[] {
+ if (!this.scmService.activeProvider) {
+ return [];
+ }
+
+ const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.ResourceGroup, true);
return this.getActions(menuId);
}
- getResourceActions(providerId: string, resourceGroupId: string): IAction[] {
- const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.Resource, false);
+ getResourceActions(resourceGroupId: string): IAction[] {
+ if (!this.scmService.activeProvider) {
+ return [];
+ }
+
+ const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.Resource, false);
return this.getActions(menuId);
}
- getResourceContextActions(providerId: string, resourceGroupId: string): IAction[] {
- const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.Resource, true);
+ getResourceContextActions(resourceGroupId: string): IAction[] {
+ if (!this.scmService.activeProvider) {
+ return [];
+ }
+
+ const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.Resource, true);
return this.getActions(menuId);
}
diff --git a/src/vs/workbench/parts/scm/browser/scmViewlet.ts b/src/vs/workbench/parts/scm/browser/scmViewlet.ts
index cc7216ca98e..bb02b070d7e 100644
--- a/src/vs/workbench/parts/scm/browser/scmViewlet.ts
+++ b/src/vs/workbench/parts/scm/browser/scmViewlet.ts
@@ -34,6 +34,7 @@ import { IMenuService } from 'vs/platform/actions/common/actions';
import { IAction, IActionItem } from 'vs/base/common/actions';
import { createActionItem } from 'vs/platform/actions/browser/menuItemActionItem';
import { SCMMenus } from './scmMenus';
+import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
interface SearchInputEvent extends Event {
target: HTMLInputElement;
@@ -43,6 +44,7 @@ interface SearchInputEvent extends Event {
interface ResourceGroupTemplate {
name: HTMLElement;
count: CountBadge;
+ actionBar: ActionBar;
}
class ResourceGroupRenderer implements IRenderer {
@@ -50,18 +52,27 @@ class ResourceGroupRenderer implements IRenderer {
@@ -79,19 +91,27 @@ class ResourceRenderer implements IRenderer {
get templateId(): string { return ResourceRenderer.TEMPLATE_ID; }
constructor(
+ private scmMenus: SCMMenus,
+ private actionItemProvider: IActionItemProvider,
@IInstantiationService private instantiationService: IInstantiationService
) {
}
renderTemplate(container: HTMLElement): ResourceTemplate {
- const fileLabel = this.instantiationService.createInstance(FileLabel, container, void 0);
+ const element = append(container, $('.resource'));
+ const name = append(element, $('.name'));
+ const fileLabel = this.instantiationService.createInstance(FileLabel, name, void 0);
+ const actionsContainer = append(element, $('.actions'));
+ const actionBar = new ActionBar(actionsContainer, { actionItemProvider: this.actionItemProvider });
- return { fileLabel };
+ return { fileLabel, actionBar };
}
renderElement(resource: ISCMResource, index: number, template: ResourceTemplate): void {
template.fileLabel.setFile(resource.uri);
+ template.actionBar.clear();
+ template.actionBar.push(this.scmMenus.getResourceActions(resource.resourceGroupId));
}
disposeTemplate(template: ResourceTemplate): void {
@@ -176,9 +196,11 @@ export class SCMViewlet extends Viewlet {
this.listContainer = append(root, $('.scm-status.show-file-icons'));
const delegate = new Delegate();
+ const actionItemProvider = action => this.getActionItem(action);
+
this.list = new List(this.listContainer, delegate, [
- new ResourceGroupRenderer(),
- this.instantiationService.createInstance(ResourceRenderer)
+ new ResourceGroupRenderer(this.menus, actionItemProvider),
+ this.instantiationService.createInstance(ResourceRenderer, this.menus, actionItemProvider)
]);
chain(this.list.onSelectionChange)
@@ -254,21 +276,15 @@ export class SCMViewlet extends Viewlet {
}
private onListContextMenu(e: IListMouseEvent): void {
- const provider = this.scmService.activeProvider;
-
- if (!provider) {
- return;
- }
-
const element = e.element;
let actions: IAction[];
if ((element as ISCMResource).uri) {
const resource = element as ISCMResource;
- actions = this.menus.getResourceContextActions(provider.id, resource.resourceGroupId);
+ actions = this.menus.getResourceContextActions(resource.resourceGroupId);
} else {
const resourceGroup = element as ISCMResourceGroup;
- actions = this.menus.getResourceGroupContextActions(provider.id, resourceGroup.id);
+ actions = this.menus.getResourceGroupContextActions(resourceGroup.id);
}
this.contextMenuService.showContextMenu({