Skip to content

Commit 5940b8b

Browse files
committed
Adds explain commit/wip to hovers
Adds Copy SHA to hover
1 parent 18c8f01 commit 5940b8b

File tree

8 files changed

+72
-22
lines changed

8 files changed

+72
-22
lines changed

docs/telemetry-events.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ void
15931593
'repoPrivacy': 'private' | 'public' | 'local',
15941594
'repository.visibility': 'private' | 'public' | 'local',
15951595
// Provided for compatibility with other GK surfaces
1596-
'source': 'account' | 'subscription' | 'graph' | 'patchDetails' | 'settings' | 'timeline' | 'home' | 'view' | 'code-suggest' | 'ai' | 'ai:picker' | 'associateIssueWithBranch' | 'cloud-patches' | 'commandPalette' | 'deeplink' | 'feature-badge' | 'feature-gate' | 'inspect' | 'inspect-overview' | 'integrations' | 'launchpad' | 'launchpad-indicator' | 'launchpad-view' | 'merge-target' | 'notification' | 'prompt' | 'quick-wizard' | 'remoteProvider' | 'startWork' | 'trial-indicator' | 'scm-input' | 'walkthrough' | 'whatsnew' | 'worktrees'
1596+
'source': 'account' | 'subscription' | 'graph' | 'patchDetails' | 'settings' | 'timeline' | 'home' | 'view' | 'code-suggest' | 'ai' | 'ai:picker' | 'associateIssueWithBranch' | 'cloud-patches' | 'commandPalette' | 'deeplink' | 'editor:hover' | 'feature-badge' | 'feature-gate' | 'inspect' | 'inspect-overview' | 'integrations' | 'launchpad' | 'launchpad-indicator' | 'launchpad-view' | 'merge-target' | 'notification' | 'prompt' | 'quick-wizard' | 'remoteProvider' | 'startWork' | 'trial-indicator' | 'scm-input' | 'walkthrough' | 'whatsnew' | 'worktrees'
15971597
}
15981598
```
15991599

src/commands/copyShaToClipboard.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { shortenRevision } from '../git/utils/revision.utils';
66
import { showGenericErrorMessage } from '../messages';
77
import { command } from '../system/-webview/command';
88
import { configuration } from '../system/-webview/configuration';
9+
import { createMarkdownCommandLink } from '../system/commands';
910
import { first } from '../system/iterable';
1011
import { Logger } from '../system/logger';
1112
import { ActiveEditorCommand } from './commandBase';
@@ -23,6 +24,13 @@ export interface CopyShaToClipboardCommandArgs {
2324

2425
@command()
2526
export class CopyShaToClipboardCommand extends ActiveEditorCommand {
27+
static createMarkdownCommandLink(sha: string): string;
28+
static createMarkdownCommandLink(args: CopyShaToClipboardCommandArgs): string;
29+
static createMarkdownCommandLink(argsOrSha: CopyShaToClipboardCommandArgs | string): string {
30+
const args = typeof argsOrSha === 'string' ? { sha: argsOrSha } : argsOrSha;
31+
return createMarkdownCommandLink<CopyShaToClipboardCommandArgs>('gitlens.copyShaToClipboard', args);
32+
}
33+
2634
constructor(private readonly container: Container) {
2735
super('gitlens.copyShaToClipboard');
2836
}

src/commands/explainCommit.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { showCommitPicker } from '../quickpicks/commitPicker';
1010
import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker';
1111
import { command } from '../system/-webview/command';
1212
import { showMarkdownPreview } from '../system/-webview/markdown';
13+
import { createMarkdownCommandLink } from '../system/commands';
1314
import { Logger } from '../system/logger';
1415
import { getNodeRepoPath } from '../views/nodes/abstract/viewNode';
1516
import { GlCommandBase } from './commandBase';
@@ -25,8 +26,12 @@ export interface ExplainCommitCommandArgs {
2526

2627
@command()
2728
export class ExplainCommitCommand extends GlCommandBase {
29+
static createMarkdownCommandLink(args: ExplainCommitCommandArgs): string {
30+
return createMarkdownCommandLink<ExplainCommitCommandArgs>('gitlens.ai.explainCommit:editor', args);
31+
}
32+
2833
constructor(private readonly container: Container) {
29-
super(['gitlens.ai.explainCommit', 'gitlens.ai.explainCommit:views']);
34+
super(['gitlens.ai.explainCommit', 'gitlens.ai.explainCommit:editor', 'gitlens.ai.explainCommit:views']);
3035
}
3136

3237
protected override preExecute(context: CommandContext, args?: ExplainCommitCommandArgs): Promise<void> {

src/commands/explainWip.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { AIExplainSource } from '../plus/ai/aiProviderService';
88
import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker';
99
import { command } from '../system/-webview/command';
1010
import { showMarkdownPreview } from '../system/-webview/markdown';
11+
import { createMarkdownCommandLink } from '../system/commands';
1112
import { Logger } from '../system/logger';
1213
import { GlCommandBase } from './commandBase';
1314
import { getCommandUri } from './commandBase.utils';
@@ -27,8 +28,12 @@ export interface ExplainWipCommandArgs {
2728

2829
@command()
2930
export class ExplainWipCommand extends GlCommandBase {
31+
static createMarkdownCommandLink(args: ExplainWipCommandArgs): string {
32+
return createMarkdownCommandLink<ExplainWipCommandArgs>('gitlens.ai.explainWip:editor', args);
33+
}
34+
3035
constructor(private readonly container: Container) {
31-
super(['gitlens.ai.explainWip', 'gitlens.ai.explainWip:views']);
36+
super(['gitlens.ai.explainWip', 'gitlens.ai.explainWip:editor', 'gitlens.ai.explainWip:views']);
3237
}
3338

3439
protected override preExecute(context: CommandContext, args?: ExplainWipCommandArgs): Promise<void> {
@@ -61,15 +66,18 @@ export class ExplainWipCommand extends GlCommandBase {
6166
}
6267

6368
try {
64-
// If args?.staged is undefined, should we get all changes (staged and unstaged)?
69+
// If args?.staged is undefined, get all changes (staged and unstaged)?
6570
let stagedLabel;
6671
let to;
6772
if (args?.staged === true) {
6873
stagedLabel = 'Staged';
6974
to = uncommittedStaged;
70-
} else {
75+
} else if (args?.staged === false) {
7176
stagedLabel = 'Unstaged';
7277
to = uncommitted;
78+
} else {
79+
stagedLabel = 'Uncommitted';
80+
to = '';
7381
}
7482

7583
const diff = await diffService.getDiff(to, undefined);

src/constants.commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ type InternalGlCommands =
119119
| `gitlens.action.${string}`
120120
| 'gitlens.changeBranchMergeTarget'
121121
| 'gitlens.diffWith'
122+
| 'gitlens.ai.explainCommit:editor'
123+
| 'gitlens.ai.explainWip:editor'
122124
| 'gitlens.openOnRemote'
123125
| 'gitlens.openWalkthrough'
124126
| 'gitlens.refreshHover'

src/constants.telemetry.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ export type Sources =
980980
| 'cloud-patches'
981981
| 'commandPalette'
982982
| 'deeplink'
983+
| 'editor:hover'
983984
| 'feature-badge'
984985
| 'feature-gate'
985986
| 'graph'

src/git/formatters/commitFormatter.ts

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import type {
77
} from '../../api/gitlens';
88
import type { MaybeEnrichedAutolink } from '../../autolinks/models/autolinks';
99
import { getPresenceDataUri } from '../../avatars';
10+
import { CopyShaToClipboardCommand } from '../../commands/copyShaToClipboard';
1011
import { DiffWithCommand } from '../../commands/diffWith';
12+
import { ExplainCommitCommand } from '../../commands/explainCommit';
13+
import { ExplainWipCommand } from '../../commands/explainWip';
1114
import { InspectCommand } from '../../commands/inspect';
1215
import { OpenCommitOnRemoteCommand } from '../../commands/openCommitOnRemote';
1316
import { OpenFileAtRevisionCommand } from '../../commands/openFileAtRevision';
@@ -46,6 +49,7 @@ import type { FormatOptions, RequiredTokenOptions } from './formatter';
4649
import { Formatter } from './formatter';
4750

4851
export interface CommitFormatOptions extends FormatOptions {
52+
aiEnabled?: boolean;
4953
avatarSize?: number;
5054
dateStyle?: DateStyle;
5155
editor?: { line: number; uri: Uri };
@@ -410,6 +414,8 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
410414
return this._padOrTruncate('', this._options.tokenOptions.commands);
411415
}
412416

417+
const separator = ' &nbsp;&nbsp;|&nbsp;&nbsp; ';
418+
413419
let commands;
414420
if (this._item.isUncommitted) {
415421
const { previousLineComparisonUris: diffUris } = this._options;
@@ -422,7 +428,7 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
422428
this._item.repoPath,
423429
)} "Inspect Commit Details")`;
424430

425-
commands += ` &nbsp;[$(chevron-left)$(compare-changes)](${DiffWithCommand.createMarkdownCommandLink({
431+
commands += ` &nbsp;[$(compare-changes)](${DiffWithCommand.createMarkdownCommandLink({
426432
lhs: { sha: diffUris.previous.sha ?? '', uri: diffUris.previous.documentUri() },
427433
rhs: { sha: diffUris.current.sha ?? '', uri: diffUris.current.documentUri() },
428434
repoPath: this._item.repoPath,
@@ -444,17 +450,27 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
444450
)} "Inspect Commit Details")`;
445451
}
446452

453+
if (this._options.aiEnabled) {
454+
commands += `${separator}[$(sparkle) Explain](${ExplainWipCommand.createMarkdownCommandLink({
455+
repoPath: this._item.repoPath,
456+
staged: undefined,
457+
source: { source: 'editor:hover', type: 'wip' },
458+
})} "Explain Changes")`;
459+
}
460+
447461
return commands;
448462
}
449463

450-
const separator = ' &nbsp;&nbsp;|&nbsp;&nbsp; ';
451-
452464
commands = `---\n\n[\`$(git-commit) ${this.id}\`](${InspectCommand.createMarkdownCommandLink(
453465
this._item.sha,
454466
this._item.repoPath,
455467
)} "Inspect Commit Details")`;
456468

457-
commands += ` &nbsp;[$(chevron-left)$(compare-changes)](${DiffWithCommand.createMarkdownCommandLink(
469+
commands += ` &nbsp;[$(copy)](${CopyShaToClipboardCommand.createMarkdownCommandLink(
470+
this._item.sha,
471+
)} "Copy SHA")`;
472+
473+
commands += ` &nbsp;[$(compare-changes)](${DiffWithCommand.createMarkdownCommandLink(
458474
this._item,
459475
editorLineToDiffRange(this._options.editor?.line),
460476
)} "Open Changes with Previous Revision")`;
@@ -472,7 +488,7 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
472488
)} "Open Blame Prior to this Change")`;
473489
}
474490

475-
commands += ` &nbsp;[$(search)](${createMarkdownCommandLink<ShowQuickCommitCommandArgs>(
491+
commands += `${separator}[$(search)](${createMarkdownCommandLink<ShowQuickCommitCommandArgs>(
476492
'gitlens.revealCommitInView',
477493
{ repoPath: this._item.repoPath, sha: this._item.sha, revealInView: true },
478494
)} "Reveal in Side Bar")`;
@@ -495,6 +511,14 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
495511
)} "Open Commit on ${providers?.length ? providers[0].name : 'Remote'}")`;
496512
}
497513

514+
if (this._options.aiEnabled) {
515+
commands += `${separator}[$(sparkle) Explain](${ExplainCommitCommand.createMarkdownCommandLink({
516+
repoPath: this._item.repoPath,
517+
rev: this._item.sha,
518+
source: { source: 'editor:hover', type: isStash(this._item) ? 'stash' : 'commit' },
519+
})} "Explain Changes")`;
520+
}
521+
498522
if (pr != null) {
499523
if (isPullRequest(pr)) {
500524
commands += `${separator}[$(git-pull-request) PR #${
@@ -532,19 +556,20 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
532556
if (Container.instance.actionRunners.count('hover.commands') > 0) {
533557
const { name, email } = this._item.author;
534558

535-
commands += `${separator}[$(organization) Team${GlyphChars.SpaceThinnest}${
536-
GlyphChars.Ellipsis
537-
}](${createMarkdownActionCommandLink<HoverCommandsActionContext>('hover.commands', {
538-
repoPath: this._item.repoPath,
539-
commit: {
540-
sha: this._item.sha,
541-
author: { name: name, email: email, presence: this._options.presence },
559+
commands += `${separator}[$(organization)](${createMarkdownActionCommandLink<HoverCommandsActionContext>(
560+
'hover.commands',
561+
{
562+
repoPath: this._item.repoPath,
563+
commit: {
564+
sha: this._item.sha,
565+
author: { name: name, email: email, presence: this._options.presence },
566+
},
567+
file:
568+
this._options.editor != null
569+
? { uri: this._options.editor?.uri.toString(), line: this._options.editor?.line }
570+
: undefined,
542571
},
543-
file:
544-
this._options.editor != null
545-
? { uri: this._options.editor?.uri.toString(), line: this._options.editor?.line }
546-
: undefined,
547-
})} "Show Team Actions")`;
572+
)} "Show Team Actions")`;
548573
}
549574

550575
const gitUri = this._item.getGitUri();

src/hovers/hovers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ export async function detailsMessage(
270270
const previousLineComparisonUris = getSettledValue(previousLineComparisonUrisResult);
271271

272272
const details = await CommitFormatter.fromTemplateAsync(options.format, commit, {
273+
aiEnabled: configuration.get('ai.enabled'),
273274
enrichedAutolinks: enrichedResult?.value != null && !enrichedResult.paused ? enrichedResult.value : undefined,
274275
dateFormat: options.dateFormat === null ? 'MMMM Do, YYYY h:mma' : options.dateFormat,
275276
editor: { line: editorLine, uri: uri },

0 commit comments

Comments
 (0)