11'use strict' ;
2- import { CancellationToken , CodeLens , CodeLensProvider , commands , Range , SymbolInformation , SymbolKind , TextDocument , Uri } from 'vscode' ;
3- import { IBlameLine , gitBlame } from './git' ;
2+ import { CancellationToken , CodeLens , CodeLensProvider , commands , Location , Range , SymbolInformation , SymbolKind , TextDocument , Uri } from 'vscode' ;
3+ import { Commands , VsCodeCommands } from './constants' ;
4+ import { IGitBlameLine , gitBlame } from './git' ;
5+ import { toGitBlameUri } from './contentProvider' ;
46import * as moment from 'moment' ;
57
68export class GitCodeLens extends CodeLens {
7- constructor ( public blame : Promise < IBlameLine [ ] > , public fileName : string , public blameRange : Range , range : Range ) {
9+ constructor ( private blame : Promise < IGitBlameLine [ ] > , public repoPath : string , public fileName : string , private blameRange : Range , range : Range ) {
810 super ( range ) ;
11+ }
12+
13+ getBlameLines ( ) : Promise < IGitBlameLine [ ] > {
14+ return this . blame . then ( allLines => allLines . slice ( this . blameRange . start . line , this . blameRange . end . line + 1 ) ) ;
15+ }
916
10- this . blame = blame ;
11- this . fileName = fileName ;
12- this . blameRange = blameRange ;
17+ static toUri ( lens : GitCodeLens , line : IGitBlameLine , lines : IGitBlameLine [ ] ) : Uri {
18+ return toGitBlameUri ( Object . assign ( { repoPath : lens . repoPath , range : lens . blameRange , lines : lines } , line ) ) ;
1319 }
1420}
1521
@@ -20,14 +26,14 @@ export default class GitCodeLensProvider implements CodeLensProvider {
2026 // TODO: Should I wait here?
2127 let blame = gitBlame ( document . fileName ) ;
2228
23- return ( commands . executeCommand ( 'vscode.executeDocumentSymbolProvider' , document . uri ) as Promise < SymbolInformation [ ] > ) . then ( symbols => {
29+ return ( commands . executeCommand ( VsCodeCommands . ExecuteDocumentSymbolProvider , document . uri ) as Promise < SymbolInformation [ ] > ) . then ( symbols => {
2430 let lenses : CodeLens [ ] = [ ] ;
2531 symbols . forEach ( sym => this . _provideCodeLens ( document , sym , blame , lenses ) ) ;
2632 return lenses ;
2733 } ) ;
2834 }
2935
30- private _provideCodeLens ( document : TextDocument , symbol : SymbolInformation , blame : Promise < IBlameLine [ ] > , lenses : CodeLens [ ] ) : void {
36+ private _provideCodeLens ( document : TextDocument , symbol : SymbolInformation , blame : Promise < IGitBlameLine [ ] > , lenses : CodeLens [ ] ) : void {
3137 switch ( symbol . kind ) {
3238 case SymbolKind . Module :
3339 case SymbolKind . Class :
@@ -43,30 +49,46 @@ export default class GitCodeLensProvider implements CodeLensProvider {
4349 }
4450
4551 var line = document . lineAt ( symbol . location . range . start ) ;
46- // if (line.text.includes(symbol.name)) {
47- // }
48-
49- let lens = new GitCodeLens ( blame , document . fileName , symbol . location . range , line . range ) ;
52+ let lens = new GitCodeLens ( blame , this . repoPath , document . fileName , symbol . location . range , line . range ) ;
5053 lenses . push ( lens ) ;
5154 }
5255
53- resolveCodeLens ( codeLens : CodeLens , token : CancellationToken ) : Thenable < CodeLens > {
54- if ( codeLens instanceof GitCodeLens ) {
55- return codeLens . blame . then ( allLines => {
56- let lines = allLines . slice ( codeLens . blameRange . start . line , codeLens . blameRange . end . line + 1 ) ;
57- let line = lines [ 0 ] ;
56+ resolveCodeLens ( lens : CodeLens , token : CancellationToken ) : Thenable < CodeLens > {
57+ if ( lens instanceof GitCodeLens ) {
58+ return lens . getBlameLines ( ) . then ( lines => {
59+ let recentLine = lines [ 0 ] ;
60+
61+ let locations : Location [ ] = [ ] ;
5862 if ( lines . length > 1 ) {
59- let sorted = lines . sort ( ( a , b ) => b . date . getTime ( ) - a . date . getTime ( ) ) ;
60- line = sorted [ 0 ] ;
63+ let sorted = lines . sort ( ( a , b ) => a . date . getTime ( ) - b . date . getTime ( ) ) ;
64+ recentLine = sorted [ sorted . length - 1 ] ;
65+
66+ console . log ( lens . fileName , 'Blame lines:' , sorted ) ;
67+
68+ let map : Map < string , IGitBlameLine [ ] > = new Map ( ) ;
69+ sorted . forEach ( l => {
70+ let item = map . get ( l . sha ) ;
71+ if ( item ) {
72+ item . push ( l ) ;
73+ } else {
74+ map . set ( l . sha , [ l ] ) ;
75+ }
76+ } ) ;
77+
78+ locations = Array . from ( map . values ( ) ) . map ( l => new Location ( GitCodeLens . toUri ( lens , l [ 0 ] , l ) , lens . range . start ) )
79+ } else {
80+ locations = [ new Location ( GitCodeLens . toUri ( lens , recentLine , lines ) , lens . range . start ) ] ;
6181 }
6282
63- codeLens . command = {
64- title : `${ line . author } , ${ moment ( line . date ) . fromNow ( ) } ` ,
65- command : 'git.viewFileHistory' ,
66- arguments : [ Uri . file ( codeLens . fileName ) ]
83+ lens . command = {
84+ title : `${ recentLine . author } , ${ moment ( recentLine . date ) . fromNow ( ) } ` ,
85+ command : Commands . ShowBlameHistory ,
86+ arguments : [ Uri . file ( lens . fileName ) , lens . range . start , locations ]
87+ // command: 'git.viewFileHistory',
88+ // arguments: [Uri.file(codeLens.fileName)]
6789 } ;
68- return codeLens ;
69- } ) ; // .catch(ex => Promise.reject(ex)); // TODO: Figure out a better way to stop the codelens from appearing
90+ return lens ;
91+ } ) . catch ( ex => Promise . reject ( ex ) ) ; // TODO: Figure out a better way to stop the codelens from appearing
7092 }
7193 }
7294}
0 commit comments