Просмотр исходного кода

Adds new command bar to hover annotations

Adds new open file revision command with annotation support
main
Eric Amodio 7 лет назад
Родитель
Сommit
5e62d5e40b
10 измененных файлов: 134 добавлений и 21 удалений
  1. +32
    -10
      src/annotations/annotations.ts
  2. +6
    -1
      src/annotations/blameAnnotationProvider.ts
  3. +1
    -1
      src/annotations/recentChangesAnnotationProvider.ts
  4. +1
    -0
      src/commands.ts
  5. +2
    -0
      src/commands/common.ts
  6. +4
    -1
      src/commands/diffWith.ts
  7. +66
    -0
      src/commands/openFileRevision.ts
  8. +12
    -1
      src/constants.ts
  9. +6
    -1
      src/currentLineController.ts
  10. +4
    -6
      src/extension.ts

+ 32
- 10
src/annotations/annotations.ts Просмотреть файл

@ -1,6 +1,7 @@
import { Dates, Objects, Strings } from '../system';
import { DecorationInstanceRenderOptions, DecorationOptions, MarkdownString, ThemableDecorationRenderOptions } from 'vscode';
import { DiffWithCommand, OpenCommitInRemoteCommand, ShowQuickCommitDetailsCommand } from '../commands';
import { DecorationInstanceRenderOptions, DecorationOptions, MarkdownString, ThemableDecorationRenderOptions, window } from 'vscode';
import { FileAnnotationType } from './annotationController';
import { DiffWithCommand, OpenCommitInRemoteCommand, OpenFileRevisionCommand, ShowQuickCommitDetailsCommand, ShowQuickCommitFileDetailsCommand } from '../commands';
import { IThemeConfig, themeDefaults } from '../configuration';
import { GlyphChars } from '../constants';
import { CommitFormatter, GitCommit, GitDiffChunkLine, GitService, GitUri, ICommitFormatOptions } from '../gitService';
@ -47,18 +48,39 @@ export class Annotations {
return '#793738';
}
static getHoverMessage(commit: GitCommit, dateFormat: string | null, hasRemotes: boolean): MarkdownString {
private static getHoverCommandBar(commit: GitCommit, hasRemotes: boolean, annotationType?: FileAnnotationType) {
let commandBar = `[\`${GlyphChars.DoubleArrowLeft}\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") `;
if (commit.previousSha !== undefined) {
if (annotationType === FileAnnotationType.RecentChanges) {
annotationType = FileAnnotationType.Gutter;
}
const uri = GitService.toGitContentUri(commit.previousSha, commit.previousUri.fsPath, commit.repoPath);
const line = window.activeTextEditor!.selection.active.line;
commandBar += `[\`${GlyphChars.SquareWithTopShadow}\`](${OpenFileRevisionCommand.getMarkdownCommandArgs(uri, annotationType || FileAnnotationType.Gutter, line)} "Blame Previous Revision") `;
}
if (hasRemotes) {
commandBar += `[\`${GlyphChars.ArrowUpRight}\`](${OpenCommitInRemoteCommand.getMarkdownCommandArgs(commit.sha)} "Open in Remote") `;
}
commandBar += `[\`${GlyphChars.MiddleEllipsis}\`](${ShowQuickCommitFileDetailsCommand.getMarkdownCommandArgs(commit.sha)} "Show More Actions")`;
return commandBar;
}
static getHoverMessage(commit: GitCommit, dateFormat: string | null, hasRemotes: boolean, annotationType?: FileAnnotationType): MarkdownString {
if (dateFormat === null) {
dateFormat = 'MMMM Do, YYYY h:MMa';
}
let message = '';
let openInRemoteCommand = '';
let commandBar = '';
let showCommitDetailsCommand = '';
if (!commit.isUncommitted) {
if (hasRemotes) {
openInRemoteCommand = `${' '.repeat(2)} [\`${GlyphChars.ArrowUpRight}\`](${OpenCommitInRemoteCommand.getMarkdownCommandArgs(commit.sha)} "Open in Remote") `;
}
commandBar = `\n\n${this.getHoverCommandBar(commit, hasRemotes, annotationType)}`;
showCommitDetailsCommand = `[\`${commit.shortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.sha)} "Show Commit Details")`;
message = commit.message
@ -74,7 +96,7 @@ export class Annotations {
showCommitDetailsCommand = `\`${commit.shortSha}\``;
}
const markdown = new MarkdownString(`${showCommitDetailsCommand}   __${commit.author}__, ${commit.fromNow()}   _(${commit.formatDate(dateFormat)})_ ${openInRemoteCommand}${message}`);
const markdown = new MarkdownString(`${showCommitDetailsCommand}   __${commit.author}__, ${commit.fromNow()}   _(${commit.formatDate(dateFormat)})_ ${message}${commandBar}`);
markdown.isTrusted = true;
return markdown;
}
@ -107,8 +129,8 @@ export class Annotations {
} as DecorationOptions;
}
static detailsHover(commit: GitCommit, dateFormat: string | null, hasRemotes: boolean): DecorationOptions {
const message = this.getHoverMessage(commit, dateFormat, hasRemotes);
static detailsHover(commit: GitCommit, dateFormat: string | null, hasRemotes: boolean, annotationType?: FileAnnotationType): DecorationOptions {
const message = this.getHoverMessage(commit, dateFormat, hasRemotes, annotationType);
return {
hoverMessage: message
} as DecorationOptions;

+ 6
- 1
src/annotations/blameAnnotationProvider.ts Просмотреть файл

@ -110,9 +110,14 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
let logCommit: GitCommit | undefined = undefined;
if (!commit.isUncommitted) {
logCommit = await this.git.getLogCommit(commit.repoPath, commit.uri.fsPath, commit.sha);
if (logCommit !== undefined) {
// Preserve the previous commit from the blame commit
logCommit.previousFileName = commit.previousFileName;
logCommit.previousSha = commit.previousSha;
}
}
const message = Annotations.getHoverMessage(logCommit || commit, this._config.defaultDateFormat, this.git.hasRemotes(commit.repoPath));
const message = Annotations.getHoverMessage(logCommit || commit, this._config.defaultDateFormat, this.git.hasRemotes(commit.repoPath), this._config.blame.file.annotationType);
return new Hover(message, document.validateRange(new Range(position.line, 0, position.line, endOfLineIndex)));
}
}

+ 1
- 1
src/annotations/recentChangesAnnotationProvider.ts Просмотреть файл

@ -41,7 +41,7 @@ export class RecentChangesAnnotationProvider extends AnnotationProviderBase {
if (cfg.hover.details) {
decorators.push({
hoverMessage: Annotations.getHoverMessage(commit, dateFormat, this.git.hasRemotes(commit.repoPath)),
hoverMessage: Annotations.getHoverMessage(commit, dateFormat, this.git.hasRemotes(commit.repoPath), this._config.blame.file.annotationType),
range: range
} as DecorationOptions);
}

+ 1
- 0
src/commands.ts Просмотреть файл

@ -20,6 +20,7 @@ export * from './commands/openBranchesInRemote';
export * from './commands/openBranchInRemote';
export * from './commands/openCommitInRemote';
export * from './commands/openFileInRemote';
export * from './commands/openFileRevision';
export * from './commands/openInRemote';
export * from './commands/openRepoInRemote';
export * from './commands/resetSuppressedWarnings';

+ 2
- 0
src/commands/common.ts Просмотреть файл

@ -25,6 +25,7 @@ export type Commands =
'gitlens.openBranchInRemote' |
'gitlens.openCommitInRemote' |
'gitlens.openFileInRemote' |
'gitlens.openFileRevision' |
'gitlens.openInRemote' |
'gitlens.openRepoInRemote' |
'gitlens.resetSuppressedWarnings' |
@ -68,6 +69,7 @@ export const Commands = {
OpenBranchInRemote: 'gitlens.openBranchInRemote' as Commands,
OpenCommitInRemote: 'gitlens.openCommitInRemote' as Commands,
OpenFileInRemote: 'gitlens.openFileInRemote' as Commands,
OpenFileRevision: 'gitlens.openFileRevision' as Commands,
OpenInRemote: 'gitlens.openInRemote' as Commands,
OpenRepoInRemote: 'gitlens.openRepoInRemote' as Commands,
ResetSuppressedWarnings: 'gitlens.resetSuppressedWarnings' as Commands,

+ 4
- 1
src/commands/diffWith.ts Просмотреть файл

@ -26,7 +26,7 @@ export class DiffWithCommand extends ActiveEditorCommand {
static getMarkdownCommandArgs(args: DiffWithCommandArgs): string;
static getMarkdownCommandArgs(commit1: GitCommit, commit2: GitCommit): string;
static getMarkdownCommandArgs(argsOrCommit1: DiffWithCommandArgs | GitCommit, commit2?: GitCommit): string {
let args = argsOrCommit1;
let args: DiffWithCommandArgs | GitCommit;
if (argsOrCommit1 instanceof GitCommit) {
const commit1 = argsOrCommit1;
@ -72,6 +72,9 @@ export class DiffWithCommand extends ActiveEditorCommand {
};
}
}
else {
args = argsOrCommit1;
}
return super.getMarkdownCommandArgsCore<DiffWithCommandArgs>(Commands.DiffWith, args);
}

+ 66
- 0
src/commands/openFileRevision.ts Просмотреть файл

@ -0,0 +1,66 @@
'use strict';
import { Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { AnnotationController, FileAnnotationType } from '../annotations/annotationController';
import { ActiveEditorCommand, Commands, getCommandUri, openEditor } from './common';
import { Logger } from '../logger';
export interface OpenFileRevisionCommandArgs {
uri?: Uri;
line?: number;
showOptions?: TextDocumentShowOptions;
annotationType?: FileAnnotationType;
}
export class OpenFileRevisionCommand extends ActiveEditorCommand {
static getMarkdownCommandArgs(args: OpenFileRevisionCommandArgs): string;
static getMarkdownCommandArgs(uri: Uri, annotationType?: FileAnnotationType, line?: number): string;
static getMarkdownCommandArgs(argsOrUri: OpenFileRevisionCommandArgs | Uri, annotationType?: FileAnnotationType, line?: number): string {
let args: OpenFileRevisionCommandArgs | Uri;
if (argsOrUri instanceof Uri) {
const uri = argsOrUri;
args = {
uri: uri,
line: line,
annotationType: annotationType
};
}
else {
args = argsOrUri;
}
return super.getMarkdownCommandArgsCore<OpenFileRevisionCommandArgs>(Commands.OpenFileRevision, args);
}
constructor(private annotationController: AnnotationController) {
super(Commands.OpenFileRevision);
}
async execute(editor: TextEditor, uri?: Uri, args: OpenFileRevisionCommandArgs = {}) {
uri = getCommandUri(uri, editor);
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
try {
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
const e = await openEditor(args.uri!, args.showOptions);
if (args.annotationType === undefined) return e;
return this.annotationController.showAnnotations(e!, args.annotationType, args.line);
}
catch (ex) {
Logger.error(ex, 'OpenFileRevisionCommand');
return window.showErrorMessage(`Unable to open in file revision. See output channel for more details`);
}
}
}

+ 12
- 1
src/constants.ts Просмотреть файл

@ -72,7 +72,8 @@ export const DocumentSchemes = {
GitLensGit: 'gitlens-git' as DocumentSchemes
};
export type GlyphChars = '\u21a9' |
export type GlyphChars =
'\u21a9' |
'\u2193' |
'\u2937' |
'\u2190' |
@ -85,9 +86,14 @@ export type GlyphChars = '\u21a9' |
'\u2713' |
'\u2014' |
'\u2022' |
'\u226A' |
'\u22D8' |
'\u2026' |
'\u22EF' |
'\u270E' |
'\u00a0' |
'\u274F' |
'\u2750' |
'\u200b';
export const GlyphChars = {
ArrowBack: '\u21a9' as GlyphChars,
@ -103,9 +109,14 @@ export const GlyphChars = {
Check: '\u2713' as GlyphChars,
Dash: '\u2014' as GlyphChars,
Dot: '\u2022' as GlyphChars,
DoubleArrowLeft: '\u226A' as GlyphChars,
DoubleArrowRight: '\u22D8' as GlyphChars,
Ellipsis: '\u2026' as GlyphChars,
MiddleEllipsis: '\u22EF' as GlyphChars,
Pensil: '\u270E' as GlyphChars,
Space: '\u00a0' as GlyphChars,
SquareWithBottomShadow: '\u274F' as GlyphChars,
SquareWithTopShadow: '\u2750' as GlyphChars,
ZeroWidthSpace: '\u200b' as GlyphChars
};

+ 6
- 1
src/currentLineController.ts Просмотреть файл

@ -376,9 +376,14 @@ export class CurrentLineController extends Disposable {
let logCommit: GitCommit | undefined = undefined;
if (!commit.isUncommitted) {
logCommit = await this.git.getLogCommit(this._uri.repoPath, this._uri.fsPath, commit.sha);
if (logCommit !== undefined) {
// Preserve the previous commit from the blame commit
logCommit.previousFileName = commit.previousFileName;
logCommit.previousSha = commit.previousSha;
}
}
const decoration = Annotations.detailsHover(logCommit || commit, this._config.defaultDateFormat, this.git.hasRemotes((logCommit || commit).repoPath));
const decoration = Annotations.detailsHover(logCommit || commit, this._config.defaultDateFormat, this.git.hasRemotes((logCommit || commit).repoPath), this._config.blame.file.annotationType);
decoration.range = range;
decorationOptions.push(decoration);

+ 4
- 6
src/extension.ts Просмотреть файл

@ -4,7 +4,7 @@ import { commands, ExtensionContext, extensions, languages, window, workspace }
import { AnnotationController } from './annotations/annotationController';
import { CloseUnchangedFilesCommand, OpenChangedFilesCommand } from './commands';
import { ExternalDiffCommand } from './commands';
import { OpenBranchesInRemoteCommand, OpenBranchInRemoteCommand, OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenInRemoteCommand, OpenRepoInRemoteCommand } from './commands';
import { OpenBranchesInRemoteCommand, OpenBranchInRemoteCommand, OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenFileRevisionCommand, OpenInRemoteCommand, OpenRepoInRemoteCommand } from './commands';
import { CopyMessageToClipboardCommand, CopyShaToClipboardCommand } from './commands';
import { DiffDirectoryCommand, DiffLineWithPreviousCommand, DiffLineWithWorkingCommand, DiffWithBranchCommand, DiffWithCommand, DiffWithNextCommand, DiffWithPreviousCommand, DiffWithRevisionCommand, DiffWithWorkingCommand } from './commands';
import { ResetSuppressedWarningsCommand } from './commands';
@ -80,10 +80,6 @@ export async function activate(context: ExtensionContext) {
const gitContextTracker = new GitContextTracker(git);
context.subscriptions.push(gitContextTracker);
context.subscriptions.push(workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider(context, git)));
context.subscriptions.push(languages.registerCodeLensProvider(GitRevisionCodeLensProvider.selector, new GitRevisionCodeLensProvider(context, git)));
const annotationController = new AnnotationController(context, git, gitContextTracker);
context.subscriptions.push(annotationController);
@ -95,8 +91,9 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new Keyboard());
context.subscriptions.push(workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider(context, git)));
context.subscriptions.push(languages.registerCodeLensProvider(GitRevisionCodeLensProvider.selector, new GitRevisionCodeLensProvider(context, git)));
context.subscriptions.push(window.registerTreeDataProvider('gitlens.gitExplorer', new GitExplorer(context, git)));
context.subscriptions.push(commands.registerTextEditorCommand('gitlens.computingFileAnnotations', () => { }));
context.subscriptions.push(new CloseUnchangedFilesCommand(git));
@ -117,6 +114,7 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new OpenBranchInRemoteCommand(git));
context.subscriptions.push(new OpenCommitInRemoteCommand(git));
context.subscriptions.push(new OpenFileInRemoteCommand(git));
context.subscriptions.push(new OpenFileRevisionCommand(annotationController));
context.subscriptions.push(new OpenInRemoteCommand());
context.subscriptions.push(new OpenRepoInRemoteCommand(git));
context.subscriptions.push(new ClearFileAnnotationsCommand(annotationController));

Загрузка…
Отмена
Сохранить