Reworks command structure with context

This commit is contained in:
Eric Amodio
2017-06-26 23:55:39 -04:00
parent ceb9c5e126
commit f9275a8e1a
2 changed files with 110 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
'use strict';
import { commands, Disposable, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { Logger } from '../logger';
import { Telemetry } from '../telemetry';
@@ -86,6 +86,51 @@ export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined {
return editor.document.uri;
}
export interface ScmGroupsCommandContext {
type: 'scm-groups';
scmResourceGroups: SourceControlResourceGroup[];
}
export interface ScmStatesCommandContext {
type: 'scm-states';
scmResourceStates: SourceControlResourceState[];
}
export interface UnknownCommandContext {
type: 'unknown';
editor?: TextEditor;
}
export interface UriCommandContext {
type: 'uri';
editor?: TextEditor;
uri: Uri;
}
export type CommandContext = ScmGroupsCommandContext | ScmStatesCommandContext | UnknownCommandContext | UriCommandContext;
function isScmResourceGroup(group: any): group is SourceControlResourceGroup {
if (group === undefined) return false;
return (group as SourceControlResourceGroup).id !== undefined && (group.handle !== undefined || (group as SourceControlResourceGroup).label !== undefined || (group as SourceControlResourceGroup).resourceStates !== undefined);
}
function isScmResourceState(state: any): state is SourceControlResourceState {
if (state === undefined) return false;
return (state as SourceControlResourceState).resourceUri !== undefined;
}
function isTextEditor(editor: any): editor is TextEditor {
if (editor === undefined) return false;
return editor.id !== undefined && ((editor as TextEditor).edit !== undefined || (editor as TextEditor).document !== undefined);
}
export interface Command {
run?(context: CommandContext, ...args: any[]): any;
}
export abstract class Command extends Disposable {
private _disposable: Disposable;
@@ -101,6 +146,51 @@ export abstract class Command extends Disposable {
protected _execute(...args: any[]): any {
Telemetry.trackEvent(this.command);
if (typeof this.run === 'function') {
let editor: TextEditor | undefined = undefined;
let firstArg = args[0];
if (firstArg === undefined || isTextEditor(firstArg)) {
editor = firstArg;
args = args.slice(1);
firstArg = args[0];
}
if (firstArg instanceof Uri) {
const [uri, ...rest] = args;
return this.run({ type: 'uri', editor: editor, uri: uri }, ...rest);
}
if (isScmResourceState(firstArg)) {
const states = [];
let count = 0;
for (const arg of args) {
if (!isScmResourceState(arg)) break;
count++;
states.push(arg);
}
return this.run({ type: 'scm-states', scmResourceStates: states }, ...args.slice(count));
}
if (isScmResourceGroup(firstArg)) {
const groups = [];
let count = 0;
for (const arg of args) {
if (!isScmResourceGroup(arg)) break;
count++;
groups.push(arg);
}
return this.run({ type: 'scm-groups', scmResourceGroups: groups }, ...args.slice(count));
}
return this.run({ type: 'unknown', editor: editor }, ...args);
}
return this.execute(...args);
}