11'use strict' ;
2- import { CancellationToken , CodeLens , CodeLensProvider , commands , Location , Range , SymbolInformation , SymbolKind , TextDocument , Uri } from 'vscode' ;
2+ import { CancellationToken , CodeLens , CodeLensProvider , commands , Location , Position , Range , SymbolInformation , SymbolKind , TextDocument , Uri } from 'vscode' ;
33import { Commands , VsCodeCommands } from './constants' ;
44import { IGitBlameLine , gitBlame } from './git' ;
55import { toGitBlameUri } from './contentProvider' ;
66import * as moment from 'moment' ;
77
8- export class GitCodeLens extends CodeLens {
8+ export class GitBlameCodeLens extends CodeLens {
99 constructor ( private blame : Promise < IGitBlameLine [ ] > , public repoPath : string , public fileName : string , private blameRange : Range , range : Range ) {
1010 super ( range ) ;
1111 }
@@ -14,11 +14,21 @@ export class GitCodeLens extends CodeLens {
1414 return this . blame . then ( allLines => allLines . slice ( this . blameRange . start . line , this . blameRange . end . line + 1 ) ) ;
1515 }
1616
17- static toUri ( lens : GitCodeLens , line : IGitBlameLine , lines : IGitBlameLine [ ] ) : Uri {
18- return toGitBlameUri ( Object . assign ( { repoPath : lens . repoPath , range : lens . blameRange , lines : lines } , line ) ) ;
17+ static toUri ( lens : GitBlameCodeLens , index : number , line : IGitBlameLine , lines : IGitBlameLine [ ] ) : Uri {
18+ return toGitBlameUri ( Object . assign ( { repoPath : lens . repoPath , index : index , range : lens . blameRange , lines : lines } , line ) ) ;
1919 }
2020}
2121
22+ export class GitHistoryCodeLens extends CodeLens {
23+ constructor ( public repoPath : string , public fileName : string , range : Range ) {
24+ super ( range ) ;
25+ }
26+
27+ // static toUri(lens: GitHistoryCodeLens, index: number): Uri {
28+ // return toGitBlameUri(Object.assign({ repoPath: lens.repoPath, index: index, range: lens.blameRange, lines: lines }, line));
29+ // }
30+ }
31+
2232export default class GitCodeLensProvider implements CodeLensProvider {
2333 constructor ( public repoPath : string ) { }
2434
@@ -29,39 +39,52 @@ export default class GitCodeLensProvider implements CodeLensProvider {
2939 return ( commands . executeCommand ( VsCodeCommands . ExecuteDocumentSymbolProvider , document . uri ) as Promise < SymbolInformation [ ] > ) . then ( symbols => {
3040 let lenses : CodeLens [ ] = [ ] ;
3141 symbols . forEach ( sym => this . _provideCodeLens ( document , sym , blame , lenses ) ) ;
42+
43+ // Check if we have a lens for the whole document -- if not add one
44+ if ( ! lenses . find ( l => l . range . start . line === 0 && l . range . end . line === 0 ) ) {
45+ const docRange = document . validateRange ( new Range ( 0 , 1000000 , 1000000 , 1000000 ) ) ;
46+ lenses . push ( new GitBlameCodeLens ( blame , this . repoPath , document . fileName , docRange , new Range ( 0 , 0 , 0 , docRange . start . character ) ) ) ;
47+ }
3248 return lenses ;
3349 } ) ;
3450 }
3551
3652 private _provideCodeLens ( document : TextDocument , symbol : SymbolInformation , blame : Promise < IGitBlameLine [ ] > , lenses : CodeLens [ ] ) : void {
3753 switch ( symbol . kind ) {
54+ case SymbolKind . Package :
3855 case SymbolKind . Module :
3956 case SymbolKind . Class :
4057 case SymbolKind . Interface :
41- case SymbolKind . Method :
42- case SymbolKind . Function :
4358 case SymbolKind . Constructor :
44- case SymbolKind . Field :
59+ case SymbolKind . Method :
4560 case SymbolKind . Property :
61+ case SymbolKind . Field :
62+ case SymbolKind . Function :
63+ case SymbolKind . Enum :
4664 break ;
4765 default :
4866 return ;
4967 }
5068
5169 var line = document . lineAt ( symbol . location . range . start ) ;
52- let lens = new GitCodeLens ( blame , this . repoPath , document . fileName , symbol . location . range , line . range ) ;
53- lenses . push ( lens ) ;
70+ lenses . push ( new GitBlameCodeLens ( blame , this . repoPath , document . fileName , symbol . location . range , line . range . with ( new Position ( line . range . start . line , line . firstNonWhitespaceCharacterIndex ) ) ) ) ;
71+ lenses . push ( new GitHistoryCodeLens ( this . repoPath , document . fileName , line . range . with ( new Position ( line . range . start . line , line . firstNonWhitespaceCharacterIndex + 1 ) ) ) ) ;
5472 }
5573
5674 resolveCodeLens ( lens : CodeLens , token : CancellationToken ) : Thenable < CodeLens > {
57- if ( lens instanceof GitCodeLens ) {
75+ if ( lens instanceof GitBlameCodeLens ) {
5876 return lens . getBlameLines ( ) . then ( lines => {
77+ if ( ! lines . length ) {
78+ console . error ( 'No blame lines found' , lens ) ;
79+ throw new Error ( 'No blame lines found' ) ;
80+ }
81+
5982 let recentLine = lines [ 0 ] ;
6083
6184 let locations : Location [ ] = [ ] ;
6285 if ( lines . length > 1 ) {
63- let sorted = lines . sort ( ( a , b ) => a . date . getTime ( ) - b . date . getTime ( ) ) ;
64- recentLine = sorted [ sorted . length - 1 ] ;
86+ let sorted = lines . sort ( ( a , b ) => b . date . getTime ( ) - a . date . getTime ( ) ) ;
87+ recentLine = sorted [ 0 ] ;
6588
6689 console . log ( lens . fileName , 'Blame lines:' , sorted ) ;
6790
@@ -75,20 +98,35 @@ export default class GitCodeLensProvider implements CodeLensProvider {
7598 }
7699 } ) ;
77100
78- locations = Array . from ( map . values ( ) ) . map ( l => new Location ( GitCodeLens . toUri ( lens , l [ 0 ] , l ) , lens . range . start ) )
101+ Array . from ( map . values ( ) ) . forEach ( ( lines , i ) => {
102+ const uri = GitBlameCodeLens . toUri ( lens , i + 1 , lines [ 0 ] , lines ) ;
103+ lines . forEach ( l => {
104+ locations . push ( new Location ( uri , new Position ( l . originalLine , 0 ) ) ) ;
105+ } ) ;
106+ } ) ;
107+
108+ //locations = Array.from(map.values()).map((l, i) => new Location(GitBlameCodeLens.toUri(lens, i, l[0], l), new Position(l[0].originalLine, 0)));//lens.range.start))
79109 } else {
80- locations = [ new Location ( GitCodeLens . toUri ( lens , recentLine , lines ) , lens . range . start ) ] ;
110+ locations = [ new Location ( GitBlameCodeLens . toUri ( lens , 1 , recentLine , lines ) , lens . range . start ) ] ;
81111 }
82112
83113 lens . command = {
84114 title : `${ recentLine . author } , ${ moment ( recentLine . date ) . fromNow ( ) } ` ,
85115 command : Commands . ShowBlameHistory ,
86116 arguments : [ Uri . file ( lens . fileName ) , lens . range . start , locations ]
87- // command: 'git.viewFileHistory',
88- // arguments: [Uri.file(codeLens.fileName)]
89117 } ;
90118 return lens ;
91119 } ) . catch ( ex => Promise . reject ( ex ) ) ; // TODO: Figure out a better way to stop the codelens from appearing
92120 }
121+
122+ // TODO: Play with this more -- get this to open the correct diff to the right place
123+ if ( lens instanceof GitHistoryCodeLens ) {
124+ lens . command = {
125+ title : `View Diff` ,
126+ command : 'git.viewFileHistory' , // viewLineHistory
127+ arguments : [ Uri . file ( lens . fileName ) ]
128+ } ;
129+ return Promise . resolve ( lens ) ;
130+ }
93131 }
94132}
0 commit comments