Browse Source

Reworks command structure with context

main
Eric Amodio 7 years ago
parent
commit
f9275a8e1a
2 changed files with 110 additions and 8 deletions
  1. +91
    -1
      src/commands/common.ts
  2. +19
    -7
      src/commands/diffWithPrevious.ts

+ 91
- 1
src/commands/common.ts 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);
}

+ 19
- 7
src/commands/diffWithPrevious.ts View File

@ -1,7 +1,7 @@
'use strict';
import { Iterables } from '../system';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
import { GitCommit, GitService, GitUri } from '../gitService';
@ -22,15 +22,27 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
super(Commands.DiffWithPrevious);
}
async execute(editor: TextEditor, uri?: Uri, args: DiffWithPreviousCommandArgs = {}): Promise<any> {
async run(context: CommandContext, args: DiffWithPreviousCommandArgs = {}): Promise<any> {
// Since we can change the args and they could be cached -- make a copy
switch (context.type) {
case 'uri':
return this.execute(context.editor, context.uri, { ...args });
case 'scm-states':
const resource = context.scmResourceStates[0];
return this.execute(undefined, resource.resourceUri, { ...args });
case 'scm-groups':
return undefined;
default:
return this.execute(context.editor, undefined, { ...args });
}
}
async execute(editor: TextEditor | undefined, uri?: Uri, args: DiffWithPreviousCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
if (args.commit !== undefined && args.commit.type !== 'file') {
args.line = 0;
}
else {
args.line = args.line || (editor === undefined ? 0 : editor.selection.active.line);
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
if (args.commit === undefined || args.commit.type !== 'file' || args.range !== undefined) {

Loading…
Cancel
Save