|
import type { TextEditor, Uri } from 'vscode';
|
|
import { env } from 'vscode';
|
|
import { configuration } from '../configuration';
|
|
import { Commands } from '../constants';
|
|
import type { Container } from '../container';
|
|
import { GitUri } from '../git/gitUri';
|
|
import { GitRevision } from '../git/models/reference';
|
|
import { Logger } from '../logger';
|
|
import { showGenericErrorMessage } from '../messages';
|
|
import { command } from '../system/command';
|
|
import { first } from '../system/iterable';
|
|
import type { CommandContext } from './base';
|
|
import {
|
|
ActiveEditorCommand,
|
|
getCommandUri,
|
|
isCommandContextViewNodeHasBranch,
|
|
isCommandContextViewNodeHasCommit,
|
|
isCommandContextViewNodeHasTag,
|
|
} from './base';
|
|
|
|
export interface CopyShaToClipboardCommandArgs {
|
|
sha?: string;
|
|
}
|
|
|
|
@command()
|
|
export class CopyShaToClipboardCommand extends ActiveEditorCommand {
|
|
constructor(private readonly container: Container) {
|
|
super(Commands.CopyShaToClipboard);
|
|
}
|
|
|
|
protected override preExecute(context: CommandContext, args?: CopyShaToClipboardCommandArgs) {
|
|
if (isCommandContextViewNodeHasCommit(context)) {
|
|
args = { ...args };
|
|
args.sha = context.node.commit.sha;
|
|
return this.execute(
|
|
context.editor,
|
|
context.node.commit.file?.uri ?? context.node.commit.getRepository()?.uri,
|
|
args,
|
|
);
|
|
} else if (isCommandContextViewNodeHasBranch(context)) {
|
|
args = { ...args };
|
|
args.sha = context.node.branch.sha;
|
|
return this.execute(context.editor, context.node.uri, args);
|
|
} else if (isCommandContextViewNodeHasTag(context)) {
|
|
args = { ...args };
|
|
args.sha = context.node.tag.sha;
|
|
return this.execute(context.editor, context.node.uri, args);
|
|
}
|
|
|
|
return this.execute(context.editor, context.uri, args);
|
|
}
|
|
|
|
async execute(editor?: TextEditor, uri?: Uri, args?: CopyShaToClipboardCommandArgs) {
|
|
uri = getCommandUri(uri, editor);
|
|
args = { ...args };
|
|
|
|
try {
|
|
if (!args.sha) {
|
|
// If we don't have an editor then get the sha of the last commit to the branch
|
|
if (uri == null) {
|
|
const repoPath = this.container.git.getBestRepository(editor)?.path;
|
|
if (!repoPath) return;
|
|
|
|
const log = await this.container.git.getLog(repoPath, { limit: 1 });
|
|
if (log == null) return;
|
|
|
|
args.sha = first(log.commits.values())?.sha;
|
|
if (args.sha == null) return;
|
|
} else if (args.sha == null) {
|
|
const blameline = editor?.selection.active.line ?? 0;
|
|
if (blameline < 0) return;
|
|
|
|
try {
|
|
const gitUri = await GitUri.fromUri(uri);
|
|
const blame = await this.container.git.getBlameForLine(gitUri, blameline, editor?.document);
|
|
if (blame == null) return;
|
|
|
|
args.sha = blame.commit.sha;
|
|
} catch (ex) {
|
|
Logger.error(ex, 'CopyShaToClipboardCommand', `getBlameForLine(${blameline})`);
|
|
void showGenericErrorMessage('Unable to copy commit SHA');
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
await env.clipboard.writeText(
|
|
configuration.get('advanced.abbreviateShaOnCopy') ? GitRevision.shorten(args.sha) : args.sha,
|
|
);
|
|
} catch (ex) {
|
|
Logger.error(ex, 'CopyShaToClipboardCommand');
|
|
void showGenericErrorMessage('Unable to copy commit SHA');
|
|
}
|
|
}
|
|
}
|