1
1
'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' ;
3
3
import { Commands , VsCodeCommands } from './constants' ;
4
4
import GitProvider from './gitProvider' ;
5
5
import GitBlameController from './gitBlameController' ;
@@ -11,7 +11,7 @@ abstract class Command extends Disposable {
11
11
12
12
constructor ( command : Commands ) {
13
13
super ( ( ) => this . dispose ( ) ) ;
14
- this . _subscriptions = commands . registerCommand ( command , this . execute . bind ( this ) ) ;
14
+ this . _subscriptions = commands . registerCommand ( command , this . execute , this ) ;
15
15
}
16
16
17
17
dispose ( ) {
@@ -21,19 +21,43 @@ abstract class Command extends Disposable {
21
21
abstract execute ( ...args ) : any ;
22
22
}
23
23
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 {
25
40
constructor ( private git : GitProvider , private blameController : GitBlameController ) {
26
41
super ( Commands . ShowBlame ) ;
27
42
}
28
43
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 ) ;
35
47
}
36
48
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 ) {
37
61
if ( sha ) {
38
62
return this . blameController . toggleBlame ( editor , sha ) ;
39
63
}
@@ -44,15 +68,15 @@ export class BlameCommand extends Command {
44
68
}
45
69
}
46
70
47
- export class HistoryCommand extends Command {
71
+ export class ShowHistoryCommand extends EditorCommand {
48
72
constructor ( private git : GitProvider ) {
49
73
super ( Commands . ShowHistory ) ;
50
74
}
51
75
52
- execute ( uri ?: Uri , range ?: Range , position ?: Position ) {
76
+ execute ( editor : TextEditor , edit : TextEditorEdit , uri ?: Uri , range ?: Range , position ?: Position ) {
53
77
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
54
78
if ( ! uri ) {
55
- const doc = window . activeTextEditor && window . activeTextEditor . document ;
79
+ const doc = editor . document ;
56
80
if ( doc ) {
57
81
uri = doc . uri ;
58
82
range = doc . validateRange ( new Range ( 0 , 0 , 1000000 , 1000000 ) ) ;
@@ -68,28 +92,41 @@ export class HistoryCommand extends Command {
68
92
}
69
93
}
70
94
71
- export class DiffWithPreviousCommand extends Command {
95
+ export class DiffWithPreviousCommand extends EditorCommand {
72
96
constructor ( private git : GitProvider ) {
73
97
super ( Commands . DiffWithPrevious ) ;
74
98
}
75
99
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 ;
80
113
const fileName = basename ( uri . path ) ;
81
114
return commands . executeCommand ( VsCodeCommands . Diff , Uri . file ( compare ) , Uri . file ( source ) , `${ fileName } (${ compareWithSha } ) ↔ ${ fileName } (${ sha } )` ) ;
82
- } )
83
- } ) ;
115
+ } ) ;
84
116
}
85
117
}
86
118
87
- export class DiffWithWorkingCommand extends Command {
119
+ export class DiffWithWorkingCommand extends EditorCommand {
88
120
constructor ( private git : GitProvider ) {
89
121
super ( Commands . DiffWithWorking ) ;
90
122
}
91
123
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
+
93
130
return this . git . getVersionedFile ( uri . path , sha ) . then ( compare => {
94
131
const fileName = basename ( uri . path ) ;
95
132
return commands . executeCommand ( VsCodeCommands . Diff , Uri . file ( compare ) , uri , `${ fileName } (${ sha } ) ↔ ${ fileName } (index)` ) ;
0 commit comments