3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
- import { DecorationOptions , l10n , Position , Range , TextEditor , TextEditorChange , TextEditorDecorationType , TextEditorChangeKind , ThemeColor , Uri , window , workspace , EventEmitter , ConfigurationChangeEvent , StatusBarItem , StatusBarAlignment , Command } from 'vscode' ;
6
+ import { DecorationOptions , l10n , Position , Range , TextEditor , TextEditorChange , TextEditorDecorationType , TextEditorChangeKind , ThemeColor , Uri , window , workspace , EventEmitter , ConfigurationChangeEvent , StatusBarItem , StatusBarAlignment , Command , MarkdownString } from 'vscode' ;
7
7
import { Model } from './model' ;
8
8
import { dispose , fromNow , IDisposable , pathEquals } from './util' ;
9
9
import { Repository } from './repository' ;
@@ -86,6 +86,41 @@ function processTextEditorChangesWithBlameInformation(blameInformation: BlameInf
86
86
return changesWithBlameInformation ;
87
87
}
88
88
89
+ function getBlameInformationHover ( documentUri : Uri , blameInformation : BlameInformation | string ) : MarkdownString {
90
+ if ( typeof blameInformation === 'string' ) {
91
+ return new MarkdownString ( blameInformation , true ) ;
92
+ }
93
+
94
+ const markdownString = new MarkdownString ( ) ;
95
+ markdownString . supportThemeIcons = true ;
96
+ markdownString . isTrusted = true ;
97
+
98
+ if ( blameInformation . authorName ) {
99
+ markdownString . appendMarkdown ( `$(account) **${ blameInformation . authorName } **` ) ;
100
+
101
+ if ( blameInformation . date ) {
102
+ const dateString = new Date ( blameInformation . date ) . toLocaleString ( undefined , { year : 'numeric' , month : 'long' , day : 'numeric' , hour : 'numeric' , minute : 'numeric' } ) ;
103
+ markdownString . appendMarkdown ( `, $(history) ${ fromNow ( blameInformation . date , true , true ) } (${ dateString } )` ) ;
104
+ }
105
+
106
+ markdownString . appendMarkdown ( '\n\n' ) ;
107
+ }
108
+
109
+ markdownString . appendMarkdown ( `${ blameInformation . message } \n\n` ) ;
110
+ markdownString . appendMarkdown ( `---\n\n` ) ;
111
+
112
+ markdownString . appendMarkdown ( `[$(eye) View Commit](command:git.blameStatusBarItem.viewCommit?${ encodeURIComponent ( JSON . stringify ( [ documentUri , blameInformation . id ] ) ) } )` ) ;
113
+ markdownString . appendMarkdown ( ' | ' ) ;
114
+ markdownString . appendMarkdown ( `[$(copy) ${ blameInformation . id . substring ( 0 , 8 ) } ](command:git.blameStatusBarItem.copyContent?${ encodeURIComponent ( JSON . stringify ( blameInformation . id ) ) } )` ) ;
115
+
116
+ if ( blameInformation . message ) {
117
+ markdownString . appendMarkdown ( ' ' ) ;
118
+ markdownString . appendMarkdown ( `[$(copy) Message](command:git.blameStatusBarItem.copyContent?${ encodeURIComponent ( JSON . stringify ( blameInformation . message ) ) } )` ) ;
119
+ }
120
+
121
+ return markdownString ;
122
+ }
123
+
89
124
interface RepositoryBlameInformation {
90
125
readonly commit : string ; /* commit used for blame information */
91
126
readonly blameInformation : Map < Uri , ResourceBlameInformation > ;
@@ -314,16 +349,19 @@ class GitBlameEditorDecoration {
314
349
const contentText = typeof blame . blameInformation === 'string'
315
350
? blame . blameInformation
316
351
: `${ blame . blameInformation . message ?? '' } , ${ blame . blameInformation . authorName ?? '' } (${ fromNow ( blame . blameInformation . date ?? Date . now ( ) , true , true ) } )` ;
317
- return this . _createDecoration ( blame . lineNumber , contentText ) ;
352
+ const hoverMessage = getBlameInformationHover ( textEditor . document . uri , blame . blameInformation ) ;
353
+
354
+ return this . _createDecoration ( blame . lineNumber , contentText , hoverMessage ) ;
318
355
} ) ;
319
356
320
357
textEditor . setDecorations ( this . _decorationType , decorations ) ;
321
358
}
322
359
323
- private _createDecoration ( lineNumber : number , contentText : string ) : DecorationOptions {
360
+ private _createDecoration ( lineNumber : number , contentText : string , hoverMessage : MarkdownString ) : DecorationOptions {
324
361
const position = new Position ( lineNumber , Number . MAX_SAFE_INTEGER ) ;
325
362
326
363
return {
364
+ hoverMessage,
327
365
range : new Range ( position , position ) ,
328
366
renderOptions : {
329
367
after : {
@@ -389,6 +427,7 @@ class GitBlameStatusBarItem {
389
427
390
428
if ( ! this . _statusBarItem ) {
391
429
this . _statusBarItem = window . createStatusBarItem ( 'git.blame' , StatusBarAlignment . Right , 200 ) ;
430
+ this . _statusBarItem . name = l10n . t ( 'Git Blame Information' ) ;
392
431
this . _disposables . push ( this . _statusBarItem ) ;
393
432
}
394
433
@@ -400,11 +439,14 @@ class GitBlameStatusBarItem {
400
439
401
440
if ( typeof blameInformation [ 0 ] . blameInformation === 'string' ) {
402
441
this . _statusBarItem . text = `$(git-commit) ${ blameInformation [ 0 ] . blameInformation } ` ;
442
+ this . _statusBarItem . tooltip = getBlameInformationHover ( textEditor . document . uri , blameInformation [ 0 ] . blameInformation ) ;
443
+ this . _statusBarItem . command = undefined ;
403
444
} else {
404
445
this . _statusBarItem . text = `$(git-commit) ${ blameInformation [ 0 ] . blameInformation . authorName ?? '' } (${ fromNow ( blameInformation [ 0 ] . blameInformation . date ?? new Date ( ) , true , true ) } )` ;
446
+ this . _statusBarItem . tooltip = getBlameInformationHover ( textEditor . document . uri , blameInformation [ 0 ] . blameInformation ) ;
405
447
this . _statusBarItem . command = {
406
448
title : l10n . t ( 'View Commit' ) ,
407
- command : 'git.statusBar .viewCommit' ,
449
+ command : 'git.blameStatusBarItem .viewCommit' ,
408
450
arguments : [ textEditor . document . uri , blameInformation [ 0 ] . blameInformation . id ]
409
451
} satisfies Command ;
410
452
}
0 commit comments