mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-03 06:51:53 +01:00
Git - more git blame code cleanup (#234739)
* Cleanup code * Fix multi-file diff editor uri/title
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DecorationOptions, l10n, Position, Range, TextEditor, TextEditorChange, TextEditorDecorationType, TextEditorChangeKind, ThemeColor, Uri, window, workspace, EventEmitter, ConfigurationChangeEvent, StatusBarItem, StatusBarAlignment, Command, MarkdownString } from 'vscode';
|
||||
import { DecorationOptions, l10n, Position, Range, TextEditor, TextEditorChange, TextEditorDecorationType, TextEditorChangeKind, ThemeColor, Uri, window, workspace, EventEmitter, ConfigurationChangeEvent, StatusBarItem, StatusBarAlignment, Command, MarkdownString, TextEditorDiffInformation } from 'vscode';
|
||||
import { Model } from './model';
|
||||
import { dispose, fromNow, IDisposable } from './util';
|
||||
import { Repository } from './repository';
|
||||
@@ -63,22 +63,6 @@ type BlameInformationTemplateTokens = {
|
||||
readonly authorDateAgo: string;
|
||||
};
|
||||
|
||||
function formatBlameInformation(template: string, blameInformation: BlameInformation): string {
|
||||
const templateTokens = {
|
||||
hash: blameInformation.hash,
|
||||
hashShort: blameInformation.hash.substring(0, 8),
|
||||
subject: blameInformation.subject ?? '',
|
||||
authorName: blameInformation.authorName ?? '',
|
||||
authorEmail: blameInformation.authorEmail ?? '',
|
||||
authorDate: new Date(blameInformation.authorDate ?? new Date()).toLocaleString(),
|
||||
authorDateAgo: fromNow(blameInformation.authorDate ?? new Date(), true, true)
|
||||
} satisfies BlameInformationTemplateTokens;
|
||||
|
||||
return template.replace(/\$\{(.+?)\}/g, (_, token) => {
|
||||
return token in templateTokens ? templateTokens[token as keyof BlameInformationTemplateTokens] : `\${${token}}`;
|
||||
});
|
||||
}
|
||||
|
||||
interface RepositoryBlameInformation {
|
||||
/**
|
||||
* Track the current HEAD of the repository so that we can clear cache entries
|
||||
@@ -182,6 +166,22 @@ export class GitBlameController {
|
||||
this._updateTextEditorBlameInformation(window.activeTextEditor);
|
||||
}
|
||||
|
||||
formatBlameInformationMessage(template: string, blameInformation: BlameInformation): string {
|
||||
const templateTokens = {
|
||||
hash: blameInformation.hash,
|
||||
hashShort: blameInformation.hash.substring(0, 8),
|
||||
subject: blameInformation.subject ?? '',
|
||||
authorName: blameInformation.authorName ?? '',
|
||||
authorEmail: blameInformation.authorEmail ?? '',
|
||||
authorDate: new Date(blameInformation.authorDate ?? new Date()).toLocaleString(),
|
||||
authorDateAgo: fromNow(blameInformation.authorDate ?? new Date(), true, true)
|
||||
} satisfies BlameInformationTemplateTokens;
|
||||
|
||||
return template.replace(/\$\{(.+?)\}/g, (_, token) => {
|
||||
return token in templateTokens ? templateTokens[token as keyof BlameInformationTemplateTokens] : `\${${token}}`;
|
||||
});
|
||||
}
|
||||
|
||||
getBlameInformationHover(documentUri: Uri, blameInformation: BlameInformation | string): MarkdownString {
|
||||
if (typeof blameInformation === 'string') {
|
||||
return new MarkdownString(blameInformation, true);
|
||||
@@ -270,6 +270,10 @@ export class GitBlameController {
|
||||
return blameInformation;
|
||||
}
|
||||
|
||||
private _findDiffInformation(textEditor: TextEditor, ref: string): TextEditorDiffInformation | undefined {
|
||||
return textEditor.diffInformation?.find(diff => diff.original && isGitUri(diff.original) && fromGitUri(diff.original).ref === ref);
|
||||
}
|
||||
|
||||
@throttle
|
||||
private async _updateTextEditorBlameInformation(textEditor: TextEditor | undefined): Promise<void> {
|
||||
if (!textEditor?.diffInformation || textEditor !== window.activeTextEditor) {
|
||||
@@ -297,9 +301,7 @@ export class GitBlameController {
|
||||
workingTreeAndIndexChanges = undefined;
|
||||
} else if (ref === '') {
|
||||
// Resource on the right-hand side of the diff editor when viewing a resource from the index.
|
||||
const diffInformationWorkingTreeAndIndex = textEditor.diffInformation
|
||||
.filter(diff => diff.original && isGitUri(diff.original))
|
||||
.find(diff => fromGitUri(diff.original!).ref === 'HEAD');
|
||||
const diffInformationWorkingTreeAndIndex = this._findDiffInformation(textEditor, 'HEAD');
|
||||
|
||||
// Working tree + index diff information is present and it is stale
|
||||
if (diffInformationWorkingTreeAndIndex && diffInformationWorkingTreeAndIndex.isStale) {
|
||||
@@ -313,9 +315,7 @@ export class GitBlameController {
|
||||
}
|
||||
} else {
|
||||
// Working tree diff information
|
||||
const diffInformationWorkingTree = textEditor.diffInformation
|
||||
.filter(diff => diff.original && isGitUri(diff.original))
|
||||
.find(diff => fromGitUri(diff.original!).ref === '');
|
||||
const diffInformationWorkingTree = this._findDiffInformation(textEditor, '');
|
||||
|
||||
// Working tree diff information is not present or it is stale
|
||||
if (!diffInformationWorkingTree || diffInformationWorkingTree.isStale) {
|
||||
@@ -323,9 +323,7 @@ export class GitBlameController {
|
||||
}
|
||||
|
||||
// Working tree + index diff information
|
||||
const diffInformationWorkingTreeAndIndex = textEditor.diffInformation
|
||||
.filter(diff => diff.original && isGitUri(diff.original))
|
||||
.find(diff => fromGitUri(diff.original!).ref === 'HEAD');
|
||||
const diffInformationWorkingTreeAndIndex = this._findDiffInformation(textEditor, 'HEAD');
|
||||
|
||||
// Working tree + index diff information is present and it is stale
|
||||
if (diffInformationWorkingTreeAndIndex && diffInformationWorkingTreeAndIndex.isStale) {
|
||||
@@ -469,7 +467,7 @@ class GitBlameEditorDecoration {
|
||||
const decorations = blameInformation.map(blame => {
|
||||
const contentText = typeof blame.blameInformation === 'string'
|
||||
? blame.blameInformation
|
||||
: formatBlameInformation(template, blame.blameInformation);
|
||||
: this._controller.formatBlameInformationMessage(template, blame.blameInformation);
|
||||
const hoverMessage = this._controller.getBlameInformationHover(textEditor.document.uri, blame.blameInformation);
|
||||
|
||||
return this._createDecoration(blame.lineNumber, contentText, hoverMessage);
|
||||
@@ -575,7 +573,7 @@ class GitBlameStatusBarItem {
|
||||
this._statusBarItem.tooltip = this._controller.getBlameInformationHover(textEditor.document.uri, blameInformation[0].blameInformation);
|
||||
this._statusBarItem.command = undefined;
|
||||
} else {
|
||||
this._statusBarItem.text = formatBlameInformation(template, blameInformation[0].blameInformation);
|
||||
this._statusBarItem.text = this._controller.formatBlameInformationMessage(template, blameInformation[0].blameInformation);
|
||||
this._statusBarItem.tooltip = this._controller.getBlameInformationHover(textEditor.document.uri, blameInformation[0].blameInformation);
|
||||
this._statusBarItem.command = {
|
||||
title: l10n.t('View Commit'),
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Model } from './model';
|
||||
import { GitResourceGroup, Repository, Resource, ResourceGroupType } from './repository';
|
||||
import { DiffEditorSelectionHunkToolbarContext, applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineChange, toLineRanges } from './staging';
|
||||
import { fromGitUri, toGitUri, isGitUri, toMergeUris, toMultiFileDiffEditorUris } from './uri';
|
||||
import { dispose, grep, isDefined, isDescendant, pathEquals, relativePath } from './util';
|
||||
import { dispose, grep, isDefined, isDescendant, pathEquals, relativePath, truncate } from './util';
|
||||
import { GitTimelineItem } from './timelineProvider';
|
||||
import { ApiRepository } from './api/api1';
|
||||
import { getRemoteSourceActions, pickRemoteSource } from './remoteSource';
|
||||
@@ -3981,8 +3981,8 @@ export class CommandCenter {
|
||||
const commitParentId = commit.parents.length > 0 ? commit.parents[0] : `${commit.hash}^`;
|
||||
const changes = await repository.diffBetween(commitParentId, commit.hash);
|
||||
|
||||
const title = `${item.shortRef} - ${commit.message}`;
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), commit.hash, { scheme: 'git-commit' });
|
||||
const title = `${item.shortRef} - ${truncate(commit.message)}`;
|
||||
const multiDiffSourceUri = Uri.from({ scheme: 'scm-history-item', path: `${repository.root}/${commitParentId}..${commit.hash}` });
|
||||
|
||||
const resources: { originalUri: Uri | undefined; modifiedUri: Uri | undefined }[] = [];
|
||||
for (const change of changes) {
|
||||
@@ -4243,14 +4243,14 @@ export class CommandCenter {
|
||||
// TODO@lszomoru - handle the case when historyItem2 is the first commit in the repository
|
||||
if (!historyItem2) {
|
||||
const commit = await repository.getCommit(historyItem1.id);
|
||||
title = `${historyItem1.id.substring(0, 8)} - ${commit.message}`;
|
||||
title = `${historyItem1.id.substring(0, 8)} - ${truncate(commit.message)}`;
|
||||
historyItemParentId = historyItem1.parentIds.length > 0 ? historyItem1.parentIds[0] : `${historyItem1.id}^`;
|
||||
} else {
|
||||
title = l10n.t('All Changes ({0} ↔ {1})', historyItem2.id.substring(0, 8), historyItem1.id.substring(0, 8));
|
||||
historyItemParentId = historyItem2.parentIds.length > 0 ? historyItem2.parentIds[0] : `${historyItem2.id}^`;
|
||||
}
|
||||
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), `${historyItemParentId}..${historyItem1.id}`, { scheme: 'git-commit', });
|
||||
const multiDiffSourceUri = Uri.from({ scheme: 'scm-history-item', path: `${repository.root}/${historyItemParentId}..${historyItem1.id}` });
|
||||
|
||||
await this._viewChanges(repository, historyItem1.id, historyItemParentId, multiDiffSourceUri, title);
|
||||
}
|
||||
@@ -4302,10 +4302,10 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
const commit = await repository.getCommit(historyItemId);
|
||||
const title = `${historyItemId.substring(0, 8)} - ${commit.message}`;
|
||||
const title = `${historyItemId.substring(0, 8)} - ${truncate(commit.message)}`;
|
||||
const historyItemParentId = commit.parents.length > 0 ? commit.parents[0] : `${historyItemId}^`;
|
||||
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), `${historyItemParentId}..${historyItemId}`, { scheme: 'git-commit', });
|
||||
const multiDiffSourceUri = Uri.from({ scheme: 'scm-history-item', path: `${repository.root}/${historyItemParentId}..${historyItemId}` });
|
||||
|
||||
const changes = await repository.diffBetween(historyItemParentId, historyItemId);
|
||||
const resources = changes.map(c => toMultiFileDiffEditorUris(c, historyItemParentId, historyItemId));
|
||||
|
||||
@@ -288,6 +288,10 @@ export function detectUnicodeEncoding(buffer: Buffer): Encoding | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function truncate(value: string, maxLength = 20): string {
|
||||
return value.length <= maxLength ? value : `${value.substring(0, maxLength)}\u2026`;
|
||||
}
|
||||
|
||||
function normalizePath(path: string): string {
|
||||
// Windows & Mac are currently being handled
|
||||
// as case insensitive file systems in VS Code.
|
||||
|
||||
Reference in New Issue
Block a user