🐛 any resource can come in via command arguments

This commit is contained in:
Joao Moreno 2017-03-30 14:40:46 +02:00
parent d1d5b8009c
commit 8738327b29
5 changed files with 89 additions and 54 deletions

View file

@ -5,9 +5,9 @@
'use strict';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange } from 'vscode';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState } from 'vscode';
import { Ref, RefType, Git } from './git';
import { Model, Resource, Status, CommitOptions } from './model';
import { Model, Resource, Status, CommitOptions, WorkingTreeGroup, IndexGroup, MergeGroup } from './model';
import * as staging from './staging';
import * as path from 'path';
import * as os from 'os';
@ -270,7 +270,10 @@ export class CommandCenter {
}
@command('git.stage')
async stage(...resources: Resource[]): Promise<void> {
async stage(...resourceStates: SourceControlResourceState[]): Promise<void> {
const resources = resourceStates
.filter(s => s instanceof Resource && (s.resourceGroup instanceof WorkingTreeGroup || s.resourceGroup instanceof MergeGroup)) as Resource[];
if (!resources.length) {
return;
}
@ -363,7 +366,10 @@ export class CommandCenter {
}
@command('git.unstage')
async unstage(...resources: Resource[]): Promise<void> {
async unstage(...resourceStates: SourceControlResourceState[]): Promise<void> {
const resources = resourceStates
.filter(s => s instanceof Resource && s.resourceGroup instanceof IndexGroup) as Resource[];
if (!resources.length) {
return;
}
@ -418,7 +424,10 @@ export class CommandCenter {
}
@command('git.clean')
async clean(...resources: Resource[]): Promise<void> {
async clean(...resourceStates: SourceControlResourceState[]): Promise<void> {
const resources = resourceStates
.filter(s => s instanceof Resource && s.resourceGroup instanceof WorkingTreeGroup) as Resource[];
if (!resources.length) {
return;
}

View file

@ -71,6 +71,7 @@ export class Resource implements SourceControlResourceState {
};
}
get resourceGroup(): ResourceGroup { return this._resourceGroup; }
get type(): Status { return this._type; }
get original(): Uri { return this._resourceUri; }
get renameResourceUri(): Uri | undefined { return this._renameResourceUri; }
@ -139,10 +140,15 @@ export class Resource implements SourceControlResourceState {
return { strikeThrough: this.strikeThrough, light, dark };
}
constructor(private resourceGroupId: string, private _resourceUri: Uri, private _type: Status, private _renameResourceUri?: Uri) { }
constructor(
private _resourceGroup: ResourceGroup,
private _resourceUri: Uri,
private _type: Status,
private _renameResourceUri?: Uri
) { }
}
export class ResourceGroup {
export abstract class ResourceGroup {
get id(): string { return this._id; }
get contextKey(): string { return this._id; }
@ -619,30 +625,30 @@ export class Model implements Disposable {
const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined;
switch (raw.x + raw.y) {
case '??': return workingTree.push(new Resource(WorkingTreeGroup.ID, uri, Status.UNTRACKED));
case '!!': return workingTree.push(new Resource(WorkingTreeGroup.ID, uri, Status.IGNORED));
case 'DD': return merge.push(new Resource(MergeGroup.ID, uri, Status.BOTH_DELETED));
case 'AU': return merge.push(new Resource(MergeGroup.ID, uri, Status.ADDED_BY_US));
case 'UD': return merge.push(new Resource(MergeGroup.ID, uri, Status.DELETED_BY_THEM));
case 'UA': return merge.push(new Resource(MergeGroup.ID, uri, Status.ADDED_BY_THEM));
case 'DU': return merge.push(new Resource(MergeGroup.ID, uri, Status.DELETED_BY_US));
case 'AA': return merge.push(new Resource(MergeGroup.ID, uri, Status.BOTH_ADDED));
case 'UU': return merge.push(new Resource(MergeGroup.ID, uri, Status.BOTH_MODIFIED));
case '??': return workingTree.push(new Resource(this.workingTreeGroup, uri, Status.UNTRACKED));
case '!!': return workingTree.push(new Resource(this.workingTreeGroup, uri, Status.IGNORED));
case 'DD': return merge.push(new Resource(this.mergeGroup, uri, Status.BOTH_DELETED));
case 'AU': return merge.push(new Resource(this.mergeGroup, uri, Status.ADDED_BY_US));
case 'UD': return merge.push(new Resource(this.mergeGroup, uri, Status.DELETED_BY_THEM));
case 'UA': return merge.push(new Resource(this.mergeGroup, uri, Status.ADDED_BY_THEM));
case 'DU': return merge.push(new Resource(this.mergeGroup, uri, Status.DELETED_BY_US));
case 'AA': return merge.push(new Resource(this.mergeGroup, uri, Status.BOTH_ADDED));
case 'UU': return merge.push(new Resource(this.mergeGroup, uri, Status.BOTH_MODIFIED));
}
let isModifiedInIndex = false;
switch (raw.x) {
case 'M': index.push(new Resource(IndexGroup.ID, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break;
case 'A': index.push(new Resource(IndexGroup.ID, uri, Status.INDEX_ADDED)); break;
case 'D': index.push(new Resource(IndexGroup.ID, uri, Status.INDEX_DELETED)); break;
case 'R': index.push(new Resource(IndexGroup.ID, uri, Status.INDEX_RENAMED, renameUri)); break;
case 'C': index.push(new Resource(IndexGroup.ID, uri, Status.INDEX_COPIED)); break;
case 'M': index.push(new Resource(this.indexGroup, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break;
case 'A': index.push(new Resource(this.indexGroup, uri, Status.INDEX_ADDED)); break;
case 'D': index.push(new Resource(this.indexGroup, uri, Status.INDEX_DELETED)); break;
case 'R': index.push(new Resource(this.indexGroup, uri, Status.INDEX_RENAMED, renameUri)); break;
case 'C': index.push(new Resource(this.indexGroup, uri, Status.INDEX_COPIED)); break;
}
switch (raw.y) {
case 'M': workingTree.push(new Resource(WorkingTreeGroup.ID, uri, Status.MODIFIED, renameUri)); break;
case 'D': workingTree.push(new Resource(WorkingTreeGroup.ID, uri, Status.DELETED, renameUri)); break;
case 'M': workingTree.push(new Resource(this.workingTreeGroup, uri, Status.MODIFIED, renameUri)); break;
case 'D': workingTree.push(new Resource(this.workingTreeGroup, uri, Status.DELETED, renameUri)); break;
}
});

View file

@ -198,14 +198,8 @@ class ExtHostSourceControl implements vscode.SourceControl {
return group;
}
getResourceState(groupHandle: GroupHandle, handle: number): vscode.SourceControlResourceState | undefined {
const group = this._groups.get(groupHandle);
if (!group) {
return undefined;
}
return group.getResourceState(handle);
getResourceGroup(handle: GroupHandle): ExtHostSourceControlResourceGroup | undefined {
return this._groups.get(handle);
}
dispose(): void {
@ -249,7 +243,21 @@ export class ExtHostSCM {
return arg;
}
return sourceControl.getResourceState(arg.groupHandle, arg.handle);
const group = sourceControl.getResourceGroup(arg.groupHandle);
if (!group) {
return arg;
}
return group.getResourceState(arg.handle);
} else if (arg && arg.$mid === 4) {
const sourceControl = this._sourceControls.get(arg.sourceControlHandle);
if (!sourceControl) {
return arg;
}
return sourceControl.getResourceGroup(arg.groupHandle);
}
return arg;

View file

@ -16,14 +16,25 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResource, SCMGroupFeatures } from './extHost.protocol';
import { Command } from 'vs/editor/common/modes';
interface IMainThreadSCMResourceGroup {
handle: number;
provider: ISCMProvider;
uri: URI;
features: SCMGroupFeatures;
label: string;
contextKey?: string;
resources: ISCMResource[];
class MainThreadSCMResourceGroup implements ISCMResourceGroup {
constructor(
private sourceControlHandle: number,
private handle: number,
public provider: ISCMProvider,
public features: SCMGroupFeatures,
public label: string,
public contextKey: string,
public resources: ISCMResource[]
) { }
toJSON(): any {
return {
$mid: 4,
sourceControlHandle: this.sourceControlHandle,
groupHandle: this.handle
};
}
}
class MainThreadSCMResource implements ISCMResource {
@ -50,8 +61,8 @@ class MainThreadSCMResource implements ISCMResource {
class MainThreadSCMProvider implements ISCMProvider {
private _groups: IMainThreadSCMResourceGroup[] = [];
private _groupsByHandle: { [handle: number]: IMainThreadSCMResourceGroup; } = Object.create(null);
private _groups: MainThreadSCMResourceGroup[] = [];
private _groupsByHandle: { [handle: number]: MainThreadSCMResourceGroup; } = Object.create(null);
get resources(): ISCMResourceGroup[] {
return this._groups
@ -85,15 +96,15 @@ class MainThreadSCMProvider implements ISCMProvider {
}
$registerGroup(handle: number, id: string, label: string): void {
const group: IMainThreadSCMResourceGroup = {
const group = new MainThreadSCMResourceGroup(
this.handle,
handle,
provider: this,
contextKey: id,
this,
{},
label,
uri: null,
resources: [],
features: {}
};
id,
[]
);
this._groups.push(group);
this._groupsByHandle[handle] = group;
@ -110,8 +121,8 @@ class MainThreadSCMProvider implements ISCMProvider {
this._onDidChange.fire();
}
$updateGroupResourceStates(handle: number, resources: SCMRawResource[]): void {
const group = this._groupsByHandle[handle];
$updateGroupResourceStates(groupHandle: number, resources: SCMRawResource[]): void {
const group = this._groupsByHandle[groupHandle];
if (!group) {
return;
@ -129,7 +140,7 @@ class MainThreadSCMProvider implements ISCMProvider {
return new MainThreadSCMResource(
this.handle,
group.handle,
groupHandle,
handle,
URI.parse(sourceUri),
command,

View file

@ -109,6 +109,7 @@ class ResourceGroupRenderer implements IRenderer<ISCMResourceGroup, ResourceGrou
template.name.textContent = group.label;
template.count.setCount(group.resources.length);
template.actionBar.clear();
template.actionBar.context = group;
template.actionBar.push(this.scmMenus.getResourceGroupActions(group));
}
@ -126,11 +127,11 @@ interface ResourceTemplate {
class MultipleSelectionActionRunner extends ActionRunner {
constructor(private getSelectedResources: () => (ISCMResource | ISCMResourceGroup)[]) {
constructor(private getSelectedResources: () => ISCMResource[]) {
super();
}
runAction(action: IAction, context: ISCMResource | ISCMResourceGroup): TPromise<any> {
runAction(action: IAction, context: ISCMResource): TPromise<any> {
if (action instanceof MenuItemAction) {
const selection = this.getSelectedResources();
const filteredSelection = selection.filter(s => s !== context);