Explorar el Código

Adds blame and active line annotation support to git diff split view

Adds command (compare, copy sha/message, etc) support to git diff split view
Fixes #41 - Toggle Blame annotations on compare files page
main
Eric Amodio hace 7 años
padre
commit
4da21c3cc1
Se han modificado 22 ficheros con 65 adiciones y 47 borrados
  1. +14
    -5
      src/blameActiveLineController.ts
  2. +6
    -8
      src/blameAnnotationController.ts
  3. +5
    -7
      src/blameAnnotationProvider.ts
  4. +1
    -1
      src/commands/copyMessageToClipboard.ts
  5. +1
    -1
      src/commands/copyShaToClipboard.ts
  6. +1
    -1
      src/commands/diffLineWithPrevious.ts
  7. +1
    -1
      src/commands/diffLineWithWorking.ts
  8. +1
    -1
      src/commands/diffWithPrevious.ts
  9. +2
    -2
      src/commands/diffWithWorking.ts
  10. +1
    -1
      src/commands/showBlameHistory.ts
  11. +1
    -1
      src/commands/showFileHistory.ts
  12. +1
    -1
      src/commands/showQuickCommitDetails.ts
  13. +1
    -1
      src/commands/showQuickFileHistory.ts
  14. +1
    -1
      src/commands/showQuickRepoHistory.ts
  15. +1
    -1
      src/commands/showQuickRepoStatus.ts
  16. +3
    -2
      src/constants.ts
  17. +11
    -5
      src/git/gitUri.ts
  18. +1
    -1
      src/gitCodeLensProvider.ts
  19. +1
    -1
      src/gitContentProvider.ts
  20. +9
    -3
      src/gitProvider.ts
  21. +1
    -1
      src/gitRevisionCodeLensProvider.ts
  22. +1
    -1
      src/quickPicks/gitQuickPicks.ts

+ 14
- 5
src/blameActiveLineController.ts Ver fichero

@ -107,15 +107,24 @@ export class BlameActiveLineController extends Disposable {
this._onActiveTextEditorChanged(window.activeTextEditor);
}
private _onActiveTextEditorChanged(editor: TextEditor) {
private isEditorBlameable(editor: TextEditor): boolean {
if (!editor || !editor.document) return false;
const scheme = editor.document.uri.scheme;
if (scheme !== DocumentSchemes.File && scheme !== DocumentSchemes.Git && scheme !== DocumentSchemes.GitLensGit) return false;
if (editor.document.isUntitled && scheme !== DocumentSchemes.Git && scheme !== DocumentSchemes.GitLensGit) return false;
return this.git.isEditorBlameable(editor);
}
private async _onActiveTextEditorChanged(editor: TextEditor) {
this._currentLine = -1;
const previousEditor = this._editor;
previousEditor && previousEditor.setDecorations(activeLineDecoration, []);
if (!editor || !editor.document || (editor.document.isUntitled && editor.document.uri.scheme !== DocumentSchemes.Git) ||
(editor.document.uri.scheme !== DocumentSchemes.File && editor.document.uri.scheme !== DocumentSchemes.Git) ||
(editor.viewColumn === undefined && !this.git.hasGitUriForFile(editor))) {
if (!this.isEditorBlameable(editor)) {
this.clear(editor);
this._editor = undefined;
@ -125,7 +134,7 @@ export class BlameActiveLineController extends Disposable {
this._blameable = editor && editor.document && !editor.document.isDirty;
this._editor = editor;
this._uri = GitUri.fromUri(editor.document.uri, this.git);
this._uri = await GitUri.fromUri(editor.document.uri, this.git);
const maxLines = this._config.advanced.caching.statusBar.maxLines;
this._useCaching = this._config.advanced.caching.enabled && (maxLines <= 0 || editor.document.lineCount <= maxLines);
if (this._useCaching) {

+ 6
- 8
src/blameAnnotationController.ts Ver fichero

@ -5,7 +5,7 @@ import { BlameabilityChangeEvent, BlameabilityTracker } from './blameabilityTrac
import { BlameAnnotationProvider } from './blameAnnotationProvider';
import { TextDocumentComparer, TextEditorComparer } from './comparers';
import { IBlameConfig } from './configuration';
import { GitProvider } from './gitProvider';
import { GitProvider, GitUri } from './gitProvider';
import { Logger } from './logger';
import { WhitespaceController } from './whitespaceController';
@ -153,8 +153,7 @@ export class BlameAnnotationController extends Disposable {
}
async showBlameAnnotation(editor: TextEditor, shaOrLine?: string | number): Promise<boolean> {
if (!editor || !editor.document) return false;
if (editor.viewColumn === undefined && !this.git.hasGitUriForFile(editor)) return false;
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return false;
const currentProvider = this._annotationProviders.get(editor.viewColumn || -1);
if (currentProvider && TextEditorComparer.equals(currentProvider.editor, editor)) {
@ -162,7 +161,8 @@ export class BlameAnnotationController extends Disposable {
return true;
}
const provider = new BlameAnnotationProvider(this.context, this.git, this._whitespaceController, editor);
const gitUri = await GitUri.fromUri(editor.document.uri, this.git);
const provider = new BlameAnnotationProvider(this.context, this.git, this._whitespaceController, editor, gitUri);
if (!await provider.supportsBlame()) return false;
if (currentProvider) {
@ -191,15 +191,13 @@ export class BlameAnnotationController extends Disposable {
}
isAnnotating(editor: TextEditor): boolean {
if (!editor || !editor.document) return false;
if (editor.viewColumn === undefined && !this.git.hasGitUriForFile(editor)) return false;
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return false;
return !!this._annotationProviders.get(editor.viewColumn || -1);
}
async toggleBlameAnnotation(editor: TextEditor, shaOrLine?: string | number): Promise<boolean> {
if (!editor || !editor.document) return false;
if (editor.viewColumn === undefined && !this.git.hasGitUriForFile(editor)) return false;
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return false;
let provider = this._annotationProviders.get(editor.viewColumn || -1);
if (!provider) return this.showBlameAnnotation(editor, shaOrLine);

+ 5
- 7
src/blameAnnotationProvider.ts Ver fichero

@ -15,15 +15,13 @@ export class BlameAnnotationProvider extends Disposable {
private _blame: Promise<IGitBlame>;
private _config: IBlameConfig;
private _disposable: Disposable;
private _uri: GitUri;
constructor(context: ExtensionContext, private git: GitProvider, private whitespaceController: WhitespaceController | undefined, public editor: TextEditor) {
constructor(context: ExtensionContext, private git: GitProvider, private whitespaceController: WhitespaceController | undefined, public editor: TextEditor, private uri: GitUri) {
super(() => this.dispose());
this.document = this.editor.document;
this._uri = GitUri.fromUri(this.document.uri, this.git);
this._blame = this.git.getBlameForFile(this._uri.fsPath, this._uri.sha, this._uri.repoPath);
this._blame = this.git.getBlameForFile(this.uri.fsPath, this.uri.sha, this.uri.repoPath);
this._config = workspace.getConfiguration('gitlens').get<IBlameConfig>('blame');
@ -104,7 +102,7 @@ export class BlameAnnotationProvider extends Disposable {
private _setSelection(blame: IGitBlame, shaOrLine?: string | number) {
if (!BlameDecorations.highlight) return;
const offset = this._uri.offset;
const offset = this.uri.offset;
let sha: string;
if (typeof shaOrLine === 'string') {
@ -134,7 +132,7 @@ export class BlameAnnotationProvider extends Disposable {
}
private _getCompactGutterDecorations(blame: IGitBlame): DecorationOptions[] {
const offset = this._uri.offset;
const offset = this.uri.offset;
let count = 0;
let lastSha: string;
@ -195,7 +193,7 @@ export class BlameAnnotationProvider extends Disposable {
}
private _getExpandedGutterDecorations(blame: IGitBlame, trailing: boolean = false): DecorationOptions[] {
const offset = this._uri.offset;
const offset = this.uri.offset;
let width = 0;
if (!trailing) {

+ 1
- 1
src/commands/copyMessageToClipboard.ts Ver fichero

@ -28,7 +28,7 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
return undefined;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
if (!message) {
if (!sha) {

+ 1
- 1
src/commands/copyShaToClipboard.ts Ver fichero

@ -28,7 +28,7 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
return undefined;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
if (!sha) {
if (editor && editor.document && editor.document.isDirty) return undefined;

+ 1
- 1
src/commands/diffLineWithPrevious.ts Ver fichero

@ -20,7 +20,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
uri = editor.document.uri;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
line = line || (editor && editor.selection.active.line) || gitUri.offset;
if (!commit || GitProvider.isUncommitted(commit.sha)) {

+ 1
- 1
src/commands/diffLineWithWorking.ts Ver fichero

@ -18,7 +18,7 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
uri = editor.document.uri;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
line = line || (editor && editor.selection.active.line) || gitUri.offset;
if (!commit || GitProvider.isUncommitted(commit.sha)) {

+ 1
- 1
src/commands/diffWithPrevious.ts Ver fichero

@ -31,7 +31,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
}
if (!commit || rangeOrLine instanceof Range) {
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
try {
if (!gitUri.sha) {

+ 2
- 2
src/commands/diffWithWorking.ts Ver fichero

@ -24,7 +24,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
line = line || (editor && editor.selection.active.line) || 0;
if (!commit || GitProvider.isUncommitted(commit.sha)) {
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
try {
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath, undefined, gitUri.sha ? undefined : 1);
@ -38,7 +38,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
}
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
try {
const compare = await this.git.getVersionedFile(commit.uri.fsPath, commit.repoPath, commit.sha);

+ 1
- 1
src/commands/showBlameHistory.ts Ver fichero

@ -23,7 +23,7 @@ export class ShowBlameHistoryCommand extends EditorCommand {
position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
try {
const locations = await this.git.getBlameLocations(gitUri.fsPath, range, gitUri.sha, gitUri.repoPath, sha, line);

+ 1
- 1
src/commands/showFileHistory.ts Ver fichero

@ -22,7 +22,7 @@ export class ShowFileHistoryCommand extends EditorCommand {
position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
try {
const locations = await this.git.getLogLocations(gitUri.fsPath, gitUri.sha, gitUri.repoPath, sha, line);

+ 1
- 1
src/commands/showQuickCommitDetails.ts Ver fichero

@ -18,7 +18,7 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCommand {
uri = editor.document.uri;
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
let repoPath = gitUri.repoPath;

+ 1
- 1
src/commands/showQuickFileHistory.ts Ver fichero

@ -20,7 +20,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCommand {
return commands.executeCommand(Commands.ShowQuickRepoHistory);
}
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
if (maxCount == null) {
maxCount = this.git.config.advanced.maxQuickHistory;

+ 1
- 1
src/commands/showQuickRepoHistory.ts Ver fichero

@ -23,7 +23,7 @@ export class ShowQuickRepoHistoryCommand extends ActiveEditorCommand {
try {
let repoPath: string;
if (uri instanceof Uri) {
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
repoPath = gitUri.repoPath;
if (!repoPath) {

+ 1
- 1
src/commands/showQuickRepoStatus.ts Ver fichero

@ -19,7 +19,7 @@ export class ShowQuickRepoStatusCommand extends ActiveEditorCommand {
try {
let repoPath: string;
if (uri instanceof Uri) {
const gitUri = GitUri.fromUri(uri, this.git);
const gitUri = await GitUri.fromUri(uri, this.git);
repoPath = gitUri.repoPath;
if (!repoPath) {

+ 3
- 2
src/constants.ts Ver fichero

@ -16,10 +16,11 @@ export const BuiltInCommands = {
ToggleRenderWhitespace: 'editor.action.toggleRenderWhitespace' as BuiltInCommands
};
export type DocumentSchemes = 'file' | 'gitlens-git';
export type DocumentSchemes = 'file' | 'git' | 'gitlens-git';
export const DocumentSchemes = {
File: 'file' as DocumentSchemes,
Git: 'gitlens-git' as DocumentSchemes
Git: 'git' as DocumentSchemes,
GitLensGit: 'gitlens-git' as DocumentSchemes
};
export type WorkspaceState = 'repoPath';

+ 11
- 5
src/git/gitUri.ts Ver fichero

@ -1,4 +1,5 @@
'use strict';
import { Iterables } from '../system';
import { Uri } from 'vscode';
import { DocumentSchemes } from '../constants';
import { Git, GitProvider } from '../gitProvider';
@ -22,7 +23,7 @@ export class GitUri extends Uri {
base._fragment = uri.fragment;
this.offset = 0;
if (uri.scheme === DocumentSchemes.Git) {
if (uri.scheme === DocumentSchemes.GitLensGit) {
const data = GitProvider.fromGitContentUri(uri);
base._fsPath = data.originalFileName || data.fileName;
@ -52,12 +53,17 @@ export class GitUri extends Uri {
return Uri.file(this.sha ? this.path : this.fsPath);
}
static fromUri(uri: Uri, git?: GitProvider) {
static async fromUri(uri: Uri, git: GitProvider) {
if (uri instanceof GitUri) return uri;
if (git) {
const gitUri = git.getGitUriForFile(uri.fsPath);
if (gitUri) return gitUri;
const gitUri = git.getGitUriForFile(uri.fsPath);
if (gitUri) return gitUri;
// If this is a git uri, assume it is showing the most recent commit
if (uri.scheme === 'git' && uri.query === '~') {
const log = await git.getLogForFile(uri.fsPath, undefined, undefined, undefined, 1);
const commit = log && Iterables.first(log.commits.values());
if (commit) return new GitUri(uri, commit);
}
return new GitUri(uri);

+ 1
- 1
src/gitCodeLensProvider.ts Ver fichero

@ -69,7 +69,7 @@ export default class GitCodeLensProvider implements CodeLensProvider {
if (languageLocations.location === CodeLensLocation.None) return lenses;
const gitUri = GitUri.fromUri(document.uri, this.git);
const gitUri = await GitUri.fromUri(document.uri, this.git);
const blamePromise = this.git.getBlameForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath);
let blame: IGitBlame;

+ 1
- 1
src/gitContentProvider.ts Ver fichero

@ -7,7 +7,7 @@ import * as path from 'path';
export class GitContentProvider implements TextDocumentContentProvider {
static scheme = DocumentSchemes.Git;
static scheme = DocumentSchemes.GitLensGit;
constructor(context: ExtensionContext, private git: GitProvider) { }

+ 9
- 3
src/gitProvider.ts Ver fichero

@ -612,6 +612,12 @@ export class GitProvider extends Disposable {
return Git.getVersionedFileText(fileName, repoPath, sha);
}
isEditorBlameable(editor: TextEditor): boolean {
return (editor.viewColumn !== undefined ||
editor.document.uri.scheme === DocumentSchemes.Git ||
this.hasGitUriForFile(editor));
}
toggleCodeLens(editor: TextEditor) {
if (this.config.codeLens.visibility !== CodeLensVisibility.OnDemand ||
(!this.config.codeLens.recentChange.enabled && !this.config.codeLens.authors.enabled)) return;
@ -632,7 +638,7 @@ export class GitProvider extends Disposable {
}
static fromGitContentUri(uri: Uri): IGitUriData {
if (uri.scheme !== DocumentSchemes.Git) throw new Error(`fromGitUri(uri=${uri}) invalid scheme`);
if (uri.scheme !== DocumentSchemes.GitLensGit) throw new Error(`fromGitUri(uri=${uri}) invalid scheme`);
return GitProvider._fromGitContentUri<IGitUriData>(uri);
}
@ -658,11 +664,11 @@ export class GitProvider extends Disposable {
}
const extension = path.extname(fileName);
return Uri.parse(`${DocumentSchemes.Git}:${path.basename(fileName, extension)}:${data.sha}${extension}?${JSON.stringify(data)}`);
return Uri.parse(`${DocumentSchemes.GitLensGit}:${path.basename(fileName, extension)}:${data.sha}${extension}?${JSON.stringify(data)}`);
}
static toReferenceGitContentUri(commit: GitCommit, index: number, commitCount: number, originalFileName?: string, decoration?: string): Uri {
return GitProvider._toReferenceGitContentUri(commit, DocumentSchemes.Git, commitCount, GitProvider._toGitUriData(commit, index, originalFileName, decoration));
return GitProvider._toReferenceGitContentUri(commit, DocumentSchemes.GitLensGit, commitCount, GitProvider._toGitUriData(commit, index, originalFileName, decoration));
}
private static _toReferenceGitContentUri(commit: GitCommit, scheme: DocumentSchemes, commitCount: number, data: IGitUriData) {

+ 1
- 1
src/gitRevisionCodeLensProvider.ts Ver fichero

@ -21,7 +21,7 @@ export class GitDiffWithPreviousCodeLens extends CodeLens {
export class GitRevisionCodeLensProvider implements CodeLensProvider {
static selector: DocumentSelector = { scheme: DocumentSchemes.Git };
static selector: DocumentSelector = { scheme: DocumentSchemes.GitLensGit };
constructor(context: ExtensionContext, private git: GitProvider) { }

+ 1
- 1
src/quickPicks/gitQuickPicks.ts Ver fichero

@ -39,7 +39,7 @@ export class CommitWithFileStatusQuickPickItem extends OpenFileCommandQuickPickI
});
this.fileName = fileName;
this.gitUri = GitUri.fromUri(Uri.file(path.resolve(commit.repoPath, fileName)));
this.gitUri = new GitUri(Uri.file(path.resolve(commit.repoPath, fileName)));
this.sha = commit.sha;
this.status = status;
}

Cargando…
Cancelar
Guardar