diff --git a/extensions/git/package.json b/extensions/git/package.json index 7b08ec75ad3..0922af5df9d 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -20,7 +20,25 @@ "watch": "gulp watch-extension:git" }, "contributes": { - "commands": [], + "commands": [ + { + "command": "git.refresh", + "title": "Git: Refresh", + "category": "Git", + "icon": { + "light": "resources/icons/light/refresh.svg", + "dark": "resources/icons/dark/refresh.svg" + } + } + ], + "menus": { + "scm/title": [ + { + "command": "git.refresh", + "group": "navigation" + } + ] + }, "languages": [ { "id": "git-commit", diff --git a/extensions/git/resources/icons/dark/refresh.svg b/extensions/git/resources/icons/dark/refresh.svg new file mode 100644 index 00000000000..d79fdaa4e8e --- /dev/null +++ b/extensions/git/resources/icons/dark/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/git/resources/icons/light/refresh.svg b/extensions/git/resources/icons/light/refresh.svg new file mode 100644 index 00000000000..e0345748192 --- /dev/null +++ b/extensions/git/resources/icons/light/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts new file mode 100644 index 00000000000..a0ea6698c24 --- /dev/null +++ b/extensions/git/src/commands.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { commands, Disposable } from 'vscode'; + +export function registerCommands(): Disposable { + return commands.registerCommand('git.refresh', () => console.log('REFRESH')); +} \ No newline at end of file diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index b252decbe5a..5bdf56e8899 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -8,6 +8,7 @@ import { scm, ExtensionContext, workspace, Uri } from 'vscode'; import * as path from 'path'; import { findGit, Git } from './git'; +import { registerCommands } from './commands'; export function log(...args: any[]): void { console.log.apply(console, ['git:', ...args]); @@ -55,6 +56,8 @@ export function activate(context: ExtensionContext): any { } }); - context.subscriptions.push(providerDisposable, contentProvider); + const commands = registerCommands(); + + context.subscriptions.push(providerDisposable, contentProvider, commands); }); } \ No newline at end of file diff --git a/src/vs/platform/actions/browser/menusExtensionPoint.ts b/src/vs/platform/actions/browser/menusExtensionPoint.ts index 9bfc70e8d83..ef19434b858 100644 --- a/src/vs/platform/actions/browser/menusExtensionPoint.ts +++ b/src/vs/platform/actions/browser/menusExtensionPoint.ts @@ -32,6 +32,7 @@ namespace schema { case 'editor/context': return MenuId.EditorContext; case 'explorer/context': return MenuId.ExplorerContext; case 'editor/title/context': return MenuId.EditorTitleContext; + case 'scm/title': return MenuId.SCMTitle; } } diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 09f505bcd15..17b9e876071 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -42,6 +42,7 @@ export class MenuId { static readonly EditorContext = new MenuId('3'); static readonly ExplorerContext = new MenuId('4'); static readonly ProblemsPanelContext = new MenuId('5'); + static readonly SCMTitle = new MenuId('scm/title'); constructor(private _id: string) { diff --git a/src/vs/workbench/parts/scm/browser/scmViewlet.ts b/src/vs/workbench/parts/scm/browser/scmViewlet.ts index 5dacd0792f1..e1608d65cfa 100644 --- a/src/vs/workbench/parts/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/browser/scmViewlet.ts @@ -24,9 +24,15 @@ import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { ISCMService, ISCMResourceGroup, ISCMResource } from 'vs/workbench/services/scm/common/scm'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IMessageService } from 'vs/platform/message/common/message'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions'; +import { IAction, IActionItem } from 'vs/base/common/actions'; +import { createActionItem, fillInActions } from 'vs/platform/actions/browser/menuItemActionItem'; // TODO@Joao remove import { GitSCMProvider } from 'vs/workbench/parts/git/browser/gitSCMProvider'; @@ -108,23 +114,43 @@ export class SCMViewlet extends Viewlet { private static ACCEPT_KEYBINDING = platform.isMacintosh ? 'Cmd+Enter' : 'Ctrl+Enter'; - private currentDimension: Dimension; + private cachedDimension: Dimension; private inputBoxContainer: HTMLElement; private inputBox: InputBox; private listContainer: HTMLElement; private list: List; + + private titleMenu: IMenu; + private _titleMenuActions: { primary: IAction[]; secondary: IAction[] }; + private get titleMenuActions() { + if (!this._titleMenuActions) { + this._titleMenuActions = { primary: [], secondary: [] }; + fillInActions(this.titleMenu, this._titleMenuActions); + } + return this._titleMenuActions; + } + private disposables: IDisposable[] = []; constructor( @ITelemetryService telemetryService: ITelemetryService, @ISCMService private scmService: ISCMService, @IInstantiationService private instantiationService: IInstantiationService, - @IContextViewService private contextViewService: IContextViewService + @IContextViewService private contextViewService: IContextViewService, + @IContextKeyService private contextKeyService: IContextKeyService, + @IKeybindingService protected keybindingService: IKeybindingService, + @IMessageService protected messageService: IMessageService, + @IMenuService private menuService: IMenuService ) { super(VIEWLET_ID, telemetryService); // TODO@Joao scmService.activeProvider = instantiationService.createInstance(GitSCMProvider); + + this.titleMenu = menuService.createMenu(MenuId.SCMTitle, contextKeyService); + + this.disposables.push(this.titleMenu); + this.titleMenu.onDidChange(this.onTitleMenuChange, this, this.disposables); } create(parent: Builder): TPromise { @@ -146,7 +172,7 @@ export class SCMViewlet extends Viewlet { .on(this.accept, this, this.disposables); chain(this.inputBox.onDidHeightChange) - .map(() => this.currentDimension) + .map(() => this.cachedDimension) .on(this.layout, this, this.disposables); this.listContainer = append(root, $('.scm-status.show-file-icons')); @@ -163,7 +189,8 @@ export class SCMViewlet extends Viewlet { .on(this.open, this, this.disposables); this.update(); - this.scmService.activeProvider.onChange(() => this.update()); + this.scmService.activeProvider.onChange(this.update, this, this.disposables); + this.disposables.push(this.inputBox, this.list); return TPromise.as(null); } @@ -184,12 +211,12 @@ export class SCMViewlet extends Viewlet { this.list.splice(0, this.list.length, ...elements); } - layout(dimension: Dimension = this.currentDimension): void { + layout(dimension: Dimension = this.cachedDimension): void { if (!dimension) { return; } - this.currentDimension = dimension; + this.cachedDimension = dimension; this.inputBox.layout(); const listHeight = dimension.height - (this.inputBox.height + 12 /* margin */); @@ -211,6 +238,23 @@ export class SCMViewlet extends Viewlet { this.scmService.activeProvider.open(e); } + private onTitleMenuChange(): void { + this._titleMenuActions = void 0; + this.updateTitleArea(); + } + + getActions(): IAction[] { + return this.titleMenuActions.primary; + } + + getSecondaryActions(): IAction[] { + return this.titleMenuActions.secondary; + } + + getActionItem(action: IAction): IActionItem { + return createActionItem(action, this.keybindingService, this.messageService); + } + dispose(): void { this.disposables = dispose(this.disposables); super.dispose();