From fc0f2188e9b00faf2ed43078cb0385a0af79dabb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 12 Jan 2017 11:20:56 +0100 Subject: [PATCH] git: open change/file --- extensions/git/src/commands.ts | 92 ++++++++++++++++++++++++++++--- extensions/git/src/main.ts | 2 +- extensions/git/src/scmProvider.ts | 73 ++---------------------- 3 files changed, 90 insertions(+), 77 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index ebed2e329d4..cee7d2468ea 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -7,13 +7,10 @@ import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window, workspace, QuickPickItem, OutputChannel } from 'vscode'; import { IRef, RefType } from './git'; -import { Model, Resource } from './model'; -import { log } from './util'; +import { Model, Resource, Status } from './model'; import { decorate } from 'core-decorators'; import * as path from 'path'; -type Command = (...args: any[]) => any; - function catchErrors(fn: (...args) => Promise): (...args) => void { return (...args) => fn.call(this, ...args).catch(async err => { if (err.gitErrorCode) { @@ -124,14 +121,93 @@ export class CommandCenter { return await this.model.update(); } - openChange(uri: Uri): void { + @decorate(catchErrors) + async openChange(uri: Uri): Promise { const resource = resolveGitResource(uri); - log('open change', resource); + + if (!resource) { + return; + } + + return this.open(resource); } - openFile(uri: Uri): void { + async open(resource: Resource): Promise { + const left = this.getLeftResource(resource); + const right = this.getRightResource(resource); + const title = this.getTitle(resource); + + if (!left) { + if (!right) { + // TODO + console.error('oh no'); + return; + } + + return commands.executeCommand('vscode.open', right); + } + + return commands.executeCommand('vscode.diff', left, right, title); + } + + private getLeftResource(resource: Resource): Uri | undefined { + switch (resource.type) { + case Status.INDEX_MODIFIED: + case Status.INDEX_RENAMED: + return resource.uri.with({ scheme: 'git', query: 'HEAD' }); + + case Status.MODIFIED: + const uriString = resource.uri.toString(); + const [indexStatus] = this.model.indexGroup.resources.filter(r => r.uri.toString() === uriString); + const query = indexStatus ? '~' : 'HEAD'; + return resource.uri.with({ scheme: 'git', query }); + } + } + + private getRightResource(resource: Resource): Uri | undefined { + switch (resource.type) { + case Status.INDEX_MODIFIED: + case Status.INDEX_ADDED: + case Status.INDEX_COPIED: + case Status.INDEX_RENAMED: + return resource.uri.with({ scheme: 'git' }); + + case Status.INDEX_DELETED: + case Status.DELETED: + return resource.uri.with({ scheme: 'git', query: 'HEAD' }); + + case Status.MODIFIED: + case Status.UNTRACKED: + case Status.IGNORED: + case Status.BOTH_MODIFIED: + return resource.uri; + } + } + + private getTitle(resource: Resource): string { + const basename = path.basename(resource.uri.fsPath); + + switch (resource.type) { + case Status.INDEX_MODIFIED: + case Status.INDEX_RENAMED: + return `${basename} (Index)`; + + case Status.MODIFIED: + return `${basename} (Working Tree)`; + } + + return ''; + } + + @decorate(catchErrors) + async openFile(uri: Uri): Promise { const resource = resolveGitResource(uri); - log('open file', resource); + + if (!resource) { + return; + } + + return commands.executeCommand('vscode.open', resource.uri); } @decorate(catchErrors) diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 8be1124b583..22b6b2292fb 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -55,13 +55,13 @@ async function init(disposables: Disposable[]): Promise { const repository = git.open(rootPath); const repositoryRoot = await repository.getRoot(); const model = new Model(repositoryRoot, repository); - const provider = new GitSCMProvider(model); const outputChannel = window.createOutputChannel('git'); outputChannel.appendLine(`Using git ${info.version} from ${info.path}`); git.onOutput(str => outputChannel.append(str), null, disposables); const commandCenter = new CommandCenter(model, outputChannel); + const provider = new GitSCMProvider(model, commandCenter); const fsWatcher = workspace.createFileSystemWatcher('**'); const onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete); diff --git a/extensions/git/src/scmProvider.ts b/extensions/git/src/scmProvider.ts index 148495d03ec..776f8ca97bd 100644 --- a/extensions/git/src/scmProvider.ts +++ b/extensions/git/src/scmProvider.ts @@ -5,9 +5,9 @@ 'use strict'; -import { scm, Uri, Disposable, SCMProvider, SCMResourceGroup, Event, commands, ProviderResult } from 'vscode'; -import { Model, Status, Resource, ResourceGroup } from './model'; -import * as path from 'path'; +import { scm, Uri, Disposable, SCMProvider, SCMResourceGroup, Event, ProviderResult } from 'vscode'; +import { Model, Resource, ResourceGroup } from './model'; +import { CommandCenter } from './commands'; export class GitSCMProvider implements SCMProvider { @@ -17,7 +17,7 @@ export class GitSCMProvider implements SCMProvider { get onDidChange(): Event { return this.model.onDidChange; } get label(): string { return 'Git'; } - constructor(private model: Model) { + constructor(private model: Model, private commandCenter: CommandCenter) { model.update(); scm.registerSCMProvider('git', this); } @@ -29,70 +29,7 @@ export class GitSCMProvider implements SCMProvider { } open(resource: Resource): ProviderResult { - const left = this.getLeftResource(resource); - const right = this.getRightResource(resource); - const title = this.getTitle(resource); - - if (!left) { - if (!right) { - // TODO - console.error('oh no'); - return; - } - - return commands.executeCommand('vscode.open', right); - } - - return commands.executeCommand('vscode.diff', left, right, title); - } - - private getLeftResource(resource: Resource): Uri | undefined { - switch (resource.type) { - case Status.INDEX_MODIFIED: - case Status.INDEX_RENAMED: - return resource.uri.with({ scheme: 'git', query: 'HEAD' }); - - case Status.MODIFIED: - const uriString = resource.uri.toString(); - const [indexStatus] = this.model.indexGroup.resources.filter(r => r.uri.toString() === uriString); - const query = indexStatus ? '~' : 'HEAD'; - return resource.uri.with({ scheme: 'git', query }); - } - } - - private getRightResource(resource: Resource): Uri | undefined { - switch (resource.type) { - case Status.INDEX_MODIFIED: - case Status.INDEX_ADDED: - case Status.INDEX_COPIED: - case Status.INDEX_RENAMED: - return resource.uri.with({ scheme: 'git' }); - - case Status.INDEX_DELETED: - case Status.DELETED: - return resource.uri.with({ scheme: 'git', query: 'HEAD' }); - - case Status.MODIFIED: - case Status.UNTRACKED: - case Status.IGNORED: - case Status.BOTH_MODIFIED: - return resource.uri; - } - } - - private getTitle(resource: Resource): string { - const basename = path.basename(resource.uri.fsPath); - - switch (resource.type) { - case Status.INDEX_MODIFIED: - case Status.INDEX_RENAMED: - return `${basename} (Index)`; - - case Status.MODIFIED: - return `${basename} (Working Tree)`; - } - - return ''; + return this.commandCenter.open(resource); } drag(resource: Resource, resourceGroup: ResourceGroup): void {