11'use strict'
2- import { commands , DecorationOptions , Disposable , OverviewRulerLane , Position , Range , TextEditorDecorationType , Uri , window } from 'vscode' ;
2+ import { commands , DecorationOptions , Disposable , OverviewRulerLane , Position , Range , TextEditor , TextEditorEdit , TextEditorDecorationType , Uri , window } from 'vscode' ;
33import { Commands , VsCodeCommands } from './constants' ;
44import GitProvider from './gitProvider' ;
55import GitBlameController from './gitBlameController' ;
@@ -11,7 +11,7 @@ abstract class Command extends Disposable {
1111
1212 constructor ( command : Commands ) {
1313 super ( ( ) => this . dispose ( ) ) ;
14- this . _subscriptions = commands . registerCommand ( command , this . execute . bind ( this ) ) ;
14+ this . _subscriptions = commands . registerCommand ( command , this . execute , this ) ;
1515 }
1616
1717 dispose ( ) {
@@ -21,19 +21,43 @@ abstract class Command extends Disposable {
2121 abstract execute ( ...args ) : any ;
2222}
2323
24- export class BlameCommand extends Command {
24+ abstract class EditorCommand extends Disposable {
25+ private _subscriptions : Disposable ;
26+
27+ constructor ( command : Commands ) {
28+ super ( ( ) => this . dispose ( ) ) ;
29+ this . _subscriptions = commands . registerTextEditorCommand ( command , this . execute , this ) ;
30+ }
31+
32+ dispose ( ) {
33+ this . _subscriptions && this . _subscriptions . dispose ( ) ;
34+ }
35+
36+ abstract execute ( editor : TextEditor , edit : TextEditorEdit , ...args ) : any ;
37+ }
38+
39+ export class ShowBlameCommand extends EditorCommand {
2540 constructor ( private git : GitProvider , private blameController : GitBlameController ) {
2641 super ( Commands . ShowBlame ) ;
2742 }
2843
29- execute ( uri ?: Uri , range ?: Range , sha ?: string ) {
30- const editor = window . activeTextEditor ;
31- if ( ! editor ) return ;
32-
33- if ( ! range ) {
34- range = editor . document . validateRange ( new Range ( 0 , 0 , 1000000 , 1000000 ) ) ;
44+ execute ( editor : TextEditor , edit : TextEditorEdit , uri ?: Uri , sha ?: string ) {
45+ if ( sha ) {
46+ return this . blameController . toggleBlame ( editor , sha ) ;
3547 }
3648
49+ const activeLine = editor . selection . active . line ;
50+ return this . git . getBlameForLine ( editor . document . fileName , activeLine )
51+ . then ( blame => this . blameController . showBlame ( editor , blame . commit . sha ) ) ;
52+ }
53+ }
54+
55+ export class ToggleBlameCommand extends EditorCommand {
56+ constructor ( private git : GitProvider , private blameController : GitBlameController ) {
57+ super ( Commands . ToggleBlame ) ;
58+ }
59+
60+ execute ( editor : TextEditor , edit : TextEditorEdit , uri ?: Uri , sha ?: string ) {
3761 if ( sha ) {
3862 return this . blameController . toggleBlame ( editor , sha ) ;
3963 }
@@ -44,15 +68,15 @@ export class BlameCommand extends Command {
4468 }
4569}
4670
47- export class HistoryCommand extends Command {
71+ export class ShowHistoryCommand extends EditorCommand {
4872 constructor ( private git : GitProvider ) {
4973 super ( Commands . ShowHistory ) ;
5074 }
5175
52- execute ( uri ?: Uri , range ?: Range , position ?: Position ) {
76+ execute ( editor : TextEditor , edit : TextEditorEdit , uri ?: Uri , range ?: Range , position ?: Position ) {
5377 // If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
5478 if ( ! uri ) {
55- const doc = window . activeTextEditor && window . activeTextEditor . document ;
79+ const doc = editor . document ;
5680 if ( doc ) {
5781 uri = doc . uri ;
5882 range = doc . validateRange ( new Range ( 0 , 0 , 1000000 , 1000000 ) ) ;
@@ -68,28 +92,41 @@ export class HistoryCommand extends Command {
6892 }
6993}
7094
71- export class DiffWithPreviousCommand extends Command {
95+ export class DiffWithPreviousCommand extends EditorCommand {
7296 constructor ( private git : GitProvider ) {
7397 super ( Commands . DiffWithPrevious ) ;
7498 }
7599
76- execute ( uri ?: Uri , sha ?: string , compareWithSha ?: string ) {
77- // TODO: Execute these in parallel rather than series
78- return this . git . getVersionedFile ( uri . path , sha ) . then ( source => {
79- this . git . getVersionedFile ( uri . path , compareWithSha ) . then ( compare => {
100+ execute ( editor : TextEditor , edit : TextEditorEdit , uri ?: Uri , sha ?: string , compareWithSha ?: string ) {
101+ if ( ! sha ) {
102+ return this . git . getBlameForLine ( uri . path , editor . selection . active . line )
103+ . then ( blame => commands . executeCommand ( Commands . DiffWithPrevious , uri , blame . commit . sha , blame . commit . previousSha ) ) ;
104+ }
105+
106+ if ( ! compareWithSha ) {
107+ return window . showInformationMessage ( `Commit ${ sha } has no previous commit` ) ;
108+ }
109+
110+ return Promise . all ( [ this . git . getVersionedFile ( uri . path , sha ) , this . git . getVersionedFile ( uri . path , compareWithSha ) ] )
111+ . then ( values => {
112+ const [ source , compare ] = values ;
80113 const fileName = basename ( uri . path ) ;
81114 return commands . executeCommand ( VsCodeCommands . Diff , Uri . file ( compare ) , Uri . file ( source ) , `${ fileName } (${ compareWithSha } ) ↔ ${ fileName } (${ sha } )` ) ;
82- } )
83- } ) ;
115+ } ) ;
84116 }
85117}
86118
87- export class DiffWithWorkingCommand extends Command {
119+ export class DiffWithWorkingCommand extends EditorCommand {
88120 constructor ( private git : GitProvider ) {
89121 super ( Commands . DiffWithWorking ) ;
90122 }
91123
92- execute ( uri ?: Uri , sha ?: string ) {
124+ execute ( editor : TextEditor , edit : TextEditorEdit , uri ?: Uri , sha ?: string ) {
125+ if ( ! sha ) {
126+ return this . git . getBlameForLine ( uri . path , editor . selection . active . line )
127+ . then ( blame => commands . executeCommand ( Commands . DiffWithWorking , uri , blame . commit . sha ) ) ;
128+ } ;
129+
93130 return this . git . getVersionedFile ( uri . path , sha ) . then ( compare => {
94131 const fileName = basename ( uri . path ) ;
95132 return commands . executeCommand ( VsCodeCommands . Diff , Uri . file ( compare ) , uri , `${ fileName } (${ sha } ) ↔ ${ fileName } (index)` ) ;
0 commit comments