mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-14 01:25:43 -05:00
Reworks command structure with context
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user