@ -1,5 +1,6 @@
'use strict' ;
import {
ConnectRemoteProviderCommand ,
DiffWithCommand ,
InviteToLiveShareCommand ,
OpenCommitInRemoteCommand ,
@ -10,12 +11,13 @@ import {
import { DateStyle , FileAnnotationType } from '../../configuration' ;
import { GlyphChars } from '../../constants' ;
import { Container } from '../../container' ;
import { GitCommit , GitLogCommit , GitRemote , GitService , GitUri } from '../gitService' ;
import { CommitPullRequest , GitCommit, GitLogCommit , GitRemote , GitService , GitUri } from '../gitService' ;
import { Strings } from '../../system' ;
import { FormatOptions , Formatter } from './formatter' ;
import { ContactPresence } from '../../vsls/vsls' ;
import { getPresenceDataUri } from '../../avatars' ;
import { emojify } from '../../emojis' ;
import { Promises } from '../../system/promise' ;
const emptyStr = '' ;
@ -27,6 +29,7 @@ export interface CommitFormatOptions extends FormatOptions {
getBranchAndTagTips ? : ( sha : string ) = > string | undefined ;
line? : number ;
markdown? : boolean ;
pr? : CommitPullRequest | Promises . CancellationError < CommitPullRequest > ;
presence? : ContactPresence ;
previousLineDiffUris ? : { current : GitUri ; previous : GitUri | undefined } ;
remotes? : GitRemote [ ] ;
@ -48,6 +51,11 @@ export interface CommitFormatOptions extends FormatOptions {
email? : Strings.TokenOptions ;
id? : Strings.TokenOptions ;
message? : Strings.TokenOptions ;
pullRequest? : Strings.TokenOptions ;
pullRequestAgo? : Strings.TokenOptions ;
pullRequestAgoOrDate? : Strings.TokenOptions ;
pullRequestDate? : Strings.TokenOptions ;
pullRequestState? : Strings.TokenOptions ;
tips? : Strings.TokenOptions ;
} ;
}
@ -95,6 +103,26 @@ export class CommitFormatter extends Formatter {
return dateStyle === DateStyle . Absolute ? this . _date : this._dateAgo ;
}
private get _pullRequestDate() {
const { pr } = this . _options ;
if ( pr == null || pr instanceof Promises . CancellationError ) return emptyStr ;
return pr . pr ? . formatDate ( this . _options . dateFormat ) ? ? emptyStr ;
}
private get _pullRequestDateAgo() {
const { pr } = this . _options ;
if ( pr == null || pr instanceof Promises . CancellationError ) return emptyStr ;
return pr . pr ? . formatDateFromNow ( ) ? ? emptyStr ;
}
private get _pullRequestDateOrAgo() {
const dateStyle =
this . _options . dateStyle !== undefined ? this . _options.dateStyle : Container.config.defaultDateStyle ;
return dateStyle === DateStyle . Absolute ? this . _pullRequestDate : this._pullRequestDateAgo ;
}
get ago() {
return this . _padOrTruncate ( this . _dateAgo , this . _options . tokenOptions . ago ) ;
}
@ -129,21 +157,26 @@ export class CommitFormatter extends Formatter {
return emptyStr ;
}
let avatar = ` ![]( ${ this . _item
. getGravatarUri ( Container . config . defaultGravatarsStyle )
. toString ( true ) } | width = 16 , height = 16 ) ` ;
const presence = this . _options . presence ;
if ( presence != null ) {
const title = ` ${ this . _item . author } ${ this . _item . author === 'You' ? 'are' : 'is' } ${
presence . status === 'dnd' ? 'in ' : ''
presence . status === 'dnd' ? 'in ' : emptyStr
} $ { presence . statusText . toLocaleLowerCase ( ) } ` ;
avatar += ` ![ ${ title } ]( ${ getPresenceDataUri ( presence . status ) } ) ` ;
avatar = ` [ ${ avatar } ](# " ${ title } ") ` ;
return ` ${ this . _getGravatarMarkdown ( title ) } ${ this . _getPresenceMarkdown ( presence , title ) } ` ;
}
return avatar ;
return this . _getGravatarMarkdown ( this . _item . author ) ;
}
private _getGravatarMarkdown ( title : string ) {
return ` ![ ${ title } ]( ${ this . _item
. getGravatarUri ( Container . config . defaultGravatarsStyle )
. toString ( true ) } | width = 16 , height = 16 "${title}" ) ` ;
}
private _getPresenceMarkdown ( presence : ContactPresence , title : string ) {
return ` ![ ${ title } ]( ${ getPresenceDataUri ( presence . status ) } " ${ title } ") ` ;
}
get changes() {
@ -178,13 +211,13 @@ export class CommitFormatter extends Formatter {
this . _options . tokenOptions . id
) } \ ` ` ;
commands += ` **[ \` ${ GlyphChars . MuchLessThan } \` ]( ${ DiffWithCommand . getMarkdownCommandArgs ( {
commands += ` **[\` ${ GlyphChars . MuchLessThan } \` ]( ${ DiffWithCommand . getMarkdownCommandArgs ( {
lhs : {
sha : diffUris.previous.sha || '' ,
sha : diffUris.previous.sha || emptyStr ,
uri : diffUris.previous.documentUri ( )
} ,
rhs : {
sha : diffUris.current.sha || '' ,
sha : diffUris.current.sha || emptyStr ,
uri : diffUris.current.documentUri ( )
} ,
repoPath : this._item.repoPath ,
@ -202,14 +235,35 @@ export class CommitFormatter extends Formatter {
return commands ;
}
const separator = ' ' ;
commands = ` [ \` ${ this . id } \` ]( ${ ShowQuickCommitDetailsCommand . getMarkdownCommandArgs (
this . _item . sha
) } "Show Commit Details" ) ` ;
) } "Show Commit Details" ) $ { separator } ` ;
const { pr } = this . _options ;
if ( pr != null ) {
if ( pr instanceof Promises . CancellationError ) {
commands += ` [ \` PR (loading ${ GlyphChars . Ellipsis } ) \` ](# "Searching for a Pull Request (if any) that introduced this commit...") ${ separator } ` ;
} else if ( pr . pr != null ) {
commands += ` [ \` PR # ${ pr . pr . number } \` ]( ${ pr . pr . url } "Open Pull Request \\ # ${ pr . pr . number } ${
pr . remote ? . provider != null ? ` on ${ pr . remote . provider . name } ` : ''
} \ n $ { GlyphChars . Dash . repeat ( 2 ) } \ n $ { pr . pr . title } \ n $ {
pr . pr . state
} , $ { pr . pr . formatDateFromNow ( ) } " ) $ { separator } ` ;
} else if ( pr . remote ? . provider != null ) {
commands += ` [ \` Connect to ${ pr . remote . provider . name } ${
GlyphChars . Ellipsis
} \ ` ]( ${ ConnectRemoteProviderCommand . getMarkdownCommandArgs ( pr . remote ) } "Connect to ${
pr . remote . provider . name
} to enable the display of the Pull Request ( if any ) that introduced this commit " ) $ { separator } ` ;
}
}
commands += ` **[ \` ${ GlyphChars . MuchLessThan } \` ]( ${ DiffWithCommand . getMarkdownCommandArgs (
this . _item ,
this . _options . line
) } "Open Changes" ) * * ` ;
) } "Open Changes" ) * * class="nx">$ { separator } ` ;
if ( this . _item . previousSha !== undefined ) {
let annotationType = this . _options . annotationType ;
@ -226,13 +280,13 @@ export class CommitFormatter extends Formatter {
uri ,
annotationType || FileAnnotationType . Blame ,
this . _options . line
) } "Blame Previous Revision" ) * * ` ;
) } "Blame Previous Revision" ) * * class="nx">$ { separator } ` ;
}
if ( this . _options . remotes !== undefined && this . _options . remotes . length !== 0 ) {
commands += ` **[ \` ${ GlyphChars . ArrowUpRight } \` ]( ${ OpenCommitInRemoteCommand . getMarkdownCommandArgs (
this . _item . sha
) } "Open on Remote" ) * * ` ;
) } "Open on Remote" ) * * class="nx">$ { separator } ` ;
}
if ( this . _item . author !== 'You' ) {
@ -240,7 +294,7 @@ export class CommitFormatter extends Formatter {
if ( presence != null ) {
commands += ` [ \` ${ GlyphChars . Envelope } + \` ]( ${ InviteToLiveShareCommand . getMarkdownCommandArgs (
this . _item . email
) } "Invite ${this._item.author} (${presence.statusText}) to a Live Share Session" ) ` ;
) } "Invite ${this._item.author} (${presence.statusText}) to a Live Share Session" ) class="nx">$ { separator } ` ;
}
}
@ -276,31 +330,25 @@ export class CommitFormatter extends Formatter {
}
get message() {
let message : string ;
if ( this . _item . isUncommitted ) {
if (
this . _item . isUncommittedStaged ||
( this . _options . previousLineDiffUris !== undefined &&
this . _options . previousLineDiffUris . current . isUncommittedStaged )
) {
message = 'Staged changes' ;
} else {
message = 'Uncommitted changes' ;
}
} else {
if ( this . _options . truncateMessageAtNewLine ) {
const index = this . _item . message . indexOf ( '\n' ) ;
message =
index === - 1
? this . _item . message
: ` ${ this . _item . message . substring ( 0 , index ) } ${ GlyphChars . Space } ${ GlyphChars . Ellipsis } ` ;
} else {
message = this . _item . message ;
}
const staged =
this . _item . isUncommittedStaged || this . _options . previousLineDiffUris ? . current ? . isUncommittedStaged ;
return this . _padOrTruncate (
` ${ this . _options . markdown ? '\n> ' : '' } ${ staged ? 'Staged' : 'Uncommitted' } changes ` ,
this . _options . tokenOptions . message
) ;
}
message = emojify ( message ) ;
let message = this . _item . message ;
if ( this . _options . truncateMessageAtNewLine ) {
const index = message . indexOf ( '\n' ) ;
if ( index !== - 1 ) {
message = ` ${ message . substring ( 0 , index ) } ${ GlyphChars . Space } ${ GlyphChars . Ellipsis } ` ;
}
}
message = emojify ( message ) ;
message = this . _padOrTruncate ( message , this . _options . tokenOptions . message ) ;
if ( ! this . _options . markdown ) {
@ -312,6 +360,47 @@ export class CommitFormatter extends Formatter {
return ` \ n> ${ message } ` ;
}
get pullRequest() {
const { pr } = this . _options ;
if ( pr == null ) return emptyStr ;
let text ;
if ( pr instanceof Promises . CancellationError ) {
text = this . _options . markdown
? ` [PR (loading ${ GlyphChars . Ellipsis } )](# "Searching for a Pull Request (if any) that introduced this commit...") `
: ` PR (loading ${ GlyphChars . Ellipsis } ) ` ;
} else if ( pr . pr != null ) {
text = this . _options . markdown
? ` [PR # ${ pr . pr . number } ]( ${ pr . pr . url } "Open Pull Request \\ # ${ pr . pr . number } ${
pr . remote ? . provider != null ? ` on ${ pr . remote . provider . name } ` : ''
} \ n $ { GlyphChars . Dash . repeat ( 2 ) } \ n $ { pr . pr . title } \ n $ { pr . pr . state } , $ { pr . pr . formatDateFromNow ( ) } " ) `
: ` PR # ${ pr . pr . number } ` ;
} else {
return emptyStr ;
}
return this . _padOrTruncate ( text , this . _options . tokenOptions . pullRequest ) ;
}
get pullRequestAgo() {
return this . _padOrTruncate ( this . _pullRequestDateAgo , this . _options . tokenOptions . pullRequestAgo ) ;
}
get pullRequestAgoOrDate() {
return this . _padOrTruncate ( this . _pullRequestDateOrAgo , this . _options . tokenOptions . pullRequestAgoOrDate ) ;
}
get pullRequestDate() {
return this . _padOrTruncate ( this . _pullRequestDate , this . _options . tokenOptions . pullRequestDate ) ;
}
get pullRequestState() {
const { pr } = this . _options ;
if ( pr == null || pr instanceof Promises . CancellationError ) return emptyStr ;
return this . _padOrTruncate ( pr . pr ? . state ? ? emptyStr , this . _options . tokenOptions . pullRequestState ) ;
}
get sha() {
return this . id ;
}
@ -338,7 +427,12 @@ export class CommitFormatter extends Formatter {
return super . fromTemplateCore ( this , template , commit , dateFormatOrOptions ) ;
}
static has ( format : string , token : string ) {
static has ( format : string , . . . tokens : ( keyof NonNullable < CommitFormatOptions [ ' tokenOptions ' ] > ) [ ] ) {
const token =
tokens . length === 1
? tokens [ 0 ]
: ( ` ( ${ tokens . join ( '|' ) } ) ` as keyof NonNullable < CommitFormatOptions [ ' tokenOptions ' ] > ) ;
let regex = hasTokenRegexMap . get ( token ) ;
if ( regex === undefined ) {
regex = new RegExp ( ` \\ b ${ token } \\ b ` ) ;
@ -348,13 +442,3 @@ export class CommitFormatter extends Formatter {
return regex . test ( format ) ;
}
}
// const autolinks = new Autolinks();
// const text = autolinks.linkify(`\\#756
// foo
// bar
// baz \\#756
// boo\\#789
// \\#666
// gh\\-89 gh\\-89gh\\-89 GH\\-89`);
// console.log(text);