mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 05:28:19 -05:00
scoped menus
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
"when": "scm.provider == git"
|
||||
}
|
||||
],
|
||||
"scm/context": [
|
||||
"scm/git/workingTree/context": [
|
||||
{
|
||||
"command": "git.open-change",
|
||||
"group": "navigation",
|
||||
|
||||
@@ -55,7 +55,7 @@ async function init(disposables: Disposable[]): Promise<void> {
|
||||
const model = new Model(repositoryRoot, repository);
|
||||
const provider = new GitSCMProvider(model);
|
||||
|
||||
provider.onDidChange(g => console.log(g));
|
||||
provider.onDidChange(g => log(g));
|
||||
|
||||
const outputChannel = window.createOutputChannel('git');
|
||||
outputChannel.appendLine(`Using git ${info.version} from ${info.path}`);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { MenuId, SCMMenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
|
||||
namespace schema {
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace schema {
|
||||
group?: string;
|
||||
}
|
||||
|
||||
const SCMMenuRegex = /^scm\/([^/]+)\/([^/]+)(\/context)?$/;
|
||||
|
||||
export function parseMenuId(value: string): MenuId {
|
||||
switch (value) {
|
||||
case 'editor/title': return MenuId.EditorTitle;
|
||||
@@ -33,7 +35,13 @@ namespace schema {
|
||||
case 'explorer/context': return MenuId.ExplorerContext;
|
||||
case 'editor/title/context': return MenuId.EditorTitleContext;
|
||||
case 'scm/title': return MenuId.SCMTitle;
|
||||
case 'scm/context': return MenuId.SCMContext;
|
||||
}
|
||||
|
||||
const match = SCMMenuRegex.exec(value);
|
||||
|
||||
if (match) {
|
||||
const [, providerId, resourceGroupId, isContext] = match;
|
||||
return new SCMMenuId(providerId, resourceGroupId, !!isContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ export class MenuId {
|
||||
static readonly ExplorerContext = new MenuId('4');
|
||||
static readonly ProblemsPanelContext = new MenuId('5');
|
||||
static readonly SCMTitle = new MenuId('scm/title');
|
||||
static readonly SCMContext = new MenuId('scm/context');
|
||||
|
||||
constructor(private _id: string) {
|
||||
|
||||
@@ -53,6 +52,17 @@ export class MenuId {
|
||||
}
|
||||
}
|
||||
|
||||
export class SCMMenuId extends MenuId {
|
||||
|
||||
get providerId(): string { return this._providerId; }
|
||||
get resourceGroupId(): string { return this._resourceGroupId; }
|
||||
get isContext(): boolean { return this._isContext; }
|
||||
|
||||
constructor(private _providerId: string, private _resourceGroupId: string, private _isContext: boolean) {
|
||||
super(`scm/${_providerId}/${_resourceGroupId}${_isContext ? '/context' : ''}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const IMenuService = createDecorator<IMenuService>('menuService');
|
||||
|
||||
export interface IMenuService {
|
||||
|
||||
@@ -89,7 +89,7 @@ class MainThreadSCMProvider implements ISCMProvider {
|
||||
const resources = rawResources.map(rawResource => {
|
||||
const [uri] = rawResource;
|
||||
|
||||
return { uri: URI.parse(uri) };
|
||||
return { uri: URI.parse(uri), resourceGroupId: id };
|
||||
});
|
||||
|
||||
return { id, label, resources };
|
||||
|
||||
@@ -10,14 +10,13 @@ import Event, { mapEvent } from 'vs/base/common/event';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
|
||||
import { IMenuService, MenuId, IMenu, SCMMenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
|
||||
|
||||
export class SCMMenus implements IDisposable {
|
||||
|
||||
private titleMenu: IMenu;
|
||||
private contextMenu: IMenu;
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
private _titleMenuActions: { primary: IAction[]; secondary: IAction[] };
|
||||
@@ -34,8 +33,7 @@ export class SCMMenus implements IDisposable {
|
||||
@IMenuService private menuService: IMenuService
|
||||
) {
|
||||
this.titleMenu = menuService.createMenu(MenuId.SCMTitle, contextKeyService);
|
||||
this.contextMenu = menuService.createMenu(MenuId.SCMContext, contextKeyService);
|
||||
this.disposables.push(this.titleMenu, this.contextMenu);
|
||||
this.disposables.push(this.titleMenu);
|
||||
}
|
||||
|
||||
@memoize
|
||||
@@ -51,9 +49,21 @@ export class SCMMenus implements IDisposable {
|
||||
return this.cachedTitleMenuActions.secondary;
|
||||
}
|
||||
|
||||
get context(): IAction[] {
|
||||
getResourceActions(providerId: string, resourceGroupId: string): IAction[] {
|
||||
const menuId = new SCMMenuId(providerId, resourceGroupId, false);
|
||||
const menu = this.menuService.createMenu(menuId, this.contextKeyService);
|
||||
const result = [];
|
||||
fillInActions(this.contextMenu, null, result);
|
||||
fillInActions(menu, null, result);
|
||||
menu.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
getResourceContextActions(providerId: string, resourceGroupId: string): IAction[] {
|
||||
const menuId = new SCMMenuId(providerId, resourceGroupId, true);
|
||||
const menu = this.menuService.createMenu(menuId, this.contextKeyService);
|
||||
const result = [];
|
||||
fillInActions(menu, null, result);
|
||||
menu.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,9 +255,28 @@ export class SCMViewlet extends Viewlet {
|
||||
}
|
||||
|
||||
private onListContextMenu(e: IListMouseEvent<ISCMResourceGroup | ISCMResource>): void {
|
||||
const provider = this.scmService.activeProvider;
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = e.element;
|
||||
let resourceGroupId: string;
|
||||
|
||||
if ((element as ISCMResource).uri) {
|
||||
const resource = element as ISCMResource;
|
||||
resourceGroupId = resource.resourceGroupId;
|
||||
} else {
|
||||
const resourceGroup = element as ISCMResourceGroup;
|
||||
resourceGroupId = resourceGroup.id;
|
||||
}
|
||||
|
||||
const actions = this.menus.getResourceContextActions(provider.id, resourceGroupId);
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => ({ x: e.clientX + 1, y: e.clientY }),
|
||||
getActions: () => TPromise.as(this.menus.context)
|
||||
getActions: () => TPromise.as(actions)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ export const ISCMService = createDecorator<ISCMService>('scm');
|
||||
|
||||
export interface ISCMResource {
|
||||
readonly uri: URI;
|
||||
readonly resourceGroupId: string;
|
||||
}
|
||||
|
||||
export interface ISCMResourceGroup {
|
||||
|
||||
Reference in New Issue
Block a user