mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-02-16 10:58:34 -05:00
Removes git-blame document scheme
Removes git-blame content provider Fixes some CodeLens issues Adds support for git uris in more places Adds git content CodeLens provider
This commit is contained in:
@@ -32,7 +32,7 @@ export default class DiffWithPreviousCommand extends EditorCommand {
|
|||||||
const gitUri = GitUri.fromUri(uri);
|
const gitUri = GitUri.fromUri(uri);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const log = await this.git.getLogForFile(gitUri.fsPath, <Range>rangeOrLine);
|
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath, <Range>rangeOrLine);
|
||||||
if (!log) return window.showWarningMessage(`Unable to open diff. File is probably not under source control`);
|
if (!log) return window.showWarningMessage(`Unable to open diff. File is probably not under source control`);
|
||||||
|
|
||||||
const sha = (commit && commit.sha) || gitUri.sha;
|
const sha = (commit && commit.sha) || gitUri.sha;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default class DiffWithWorkingCommand extends EditorCommand {
|
|||||||
const gitUri = GitUri.fromUri(uri);
|
const gitUri = GitUri.fromUri(uri);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const log = await this.git.getLogForFile(gitUri.fsPath);
|
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath);
|
||||||
if (!log) return window.showWarningMessage(`Unable to open diff. File is probably not under source control`);
|
if (!log) return window.showWarningMessage(`Unable to open diff. File is probably not under source control`);
|
||||||
|
|
||||||
commit = (gitUri.sha && log.commits.get(gitUri.sha)) || Iterables.first(log.commits.values());
|
commit = (gitUri.sha && log.commits.get(gitUri.sha)) || Iterables.first(log.commits.values());
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default class ShowBlameHistoryCommand extends EditorCommand {
|
|||||||
super(Commands.ShowBlameHistory);
|
super(Commands.ShowBlameHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, range?: Range, position?: Position) {
|
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, range?: Range, position?: Position, sha?: string, line?: number) {
|
||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
if (!editor.document) return undefined;
|
if (!editor.document) return undefined;
|
||||||
uri = editor.document.uri;
|
uri = editor.document.uri;
|
||||||
@@ -23,7 +23,7 @@ export default class ShowBlameHistoryCommand extends EditorCommand {
|
|||||||
const gitUri = GitUri.fromUri(uri);
|
const gitUri = GitUri.fromUri(uri);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const locations = await this.git.getBlameLocations(gitUri.fsPath, range);
|
const locations = await this.git.getBlameLocations(gitUri.fsPath, range, gitUri.sha, gitUri.repoPath, sha, line);
|
||||||
if (!locations) return window.showWarningMessage(`Unable to show blame history. File is probably not under source control`);
|
if (!locations) return window.showWarningMessage(`Unable to show blame history. File is probably not under source control`);
|
||||||
|
|
||||||
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, position, locations);
|
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, position, locations);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default class ShowFileHistoryCommand extends EditorCommand {
|
|||||||
const gitUri = GitUri.fromUri(uri);
|
const gitUri = GitUri.fromUri(uri);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const locations = await this.git.getLogLocations(gitUri.fsPath, sha, line);
|
const locations = await this.git.getLogLocations(gitUri.fsPath, gitUri.sha, gitUri.repoPath, sha, line);
|
||||||
if (!locations) return window.showWarningMessage(`Unable to show history. File is probably not under source control`);
|
if (!locations) return window.showWarningMessage(`Unable to show history. File is probably not under source control`);
|
||||||
|
|
||||||
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, position, locations);
|
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, position, locations);
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ export const Commands = {
|
|||||||
export type DocumentSchemes = 'file' | 'git' | 'git-blame';
|
export type DocumentSchemes = 'file' | 'git' | 'git-blame';
|
||||||
export const DocumentSchemes = {
|
export const DocumentSchemes = {
|
||||||
File: 'file' as DocumentSchemes,
|
File: 'file' as DocumentSchemes,
|
||||||
Git: 'git' as DocumentSchemes,
|
Git: 'git' as DocumentSchemes
|
||||||
GitBlame: 'git-blame' as DocumentSchemes
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkspaceState = 'hasGitHistoryExtension' | 'repoPath';
|
export type WorkspaceState = 'hasGitHistoryExtension' | 'repoPath';
|
||||||
|
|||||||
@@ -2,22 +2,21 @@
|
|||||||
import { ExtensionContext, extensions, languages, window, workspace } from 'vscode';
|
import { ExtensionContext, extensions, languages, window, workspace } from 'vscode';
|
||||||
import BlameAnnotationController from './blameAnnotationController';
|
import BlameAnnotationController from './blameAnnotationController';
|
||||||
import BlameStatusBarController from './blameStatusBarController';
|
import BlameStatusBarController from './blameStatusBarController';
|
||||||
import GitContentProvider from './gitContentProvider';
|
|
||||||
import GitBlameCodeLensProvider from './gitBlameCodeLensProvider';
|
|
||||||
import GitBlameContentProvider from './gitBlameContentProvider';
|
|
||||||
import GitProvider, { Git } from './gitProvider';
|
|
||||||
import { WorkspaceState } from './constants';
|
|
||||||
import { IAdvancedConfig } from './configuration';
|
|
||||||
import { Logger } from './logger';
|
|
||||||
import DiffWithPreviousCommand from './commands/diffWithPrevious';
|
|
||||||
import DiffLineWithPreviousCommand from './commands/diffLineWithPrevious';
|
import DiffLineWithPreviousCommand from './commands/diffLineWithPrevious';
|
||||||
import DiffWithWorkingCommand from './commands/diffWithWorking';
|
|
||||||
import DiffLineWithWorkingCommand from './commands/diffLineWithWorking';
|
import DiffLineWithWorkingCommand from './commands/diffLineWithWorking';
|
||||||
|
import DiffWithPreviousCommand from './commands/diffWithPrevious';
|
||||||
|
import DiffWithWorkingCommand from './commands/diffWithWorking';
|
||||||
import ShowBlameCommand from './commands/showBlame';
|
import ShowBlameCommand from './commands/showBlame';
|
||||||
import ShowBlameHistoryCommand from './commands/showBlameHistory';
|
import ShowBlameHistoryCommand from './commands/showBlameHistory';
|
||||||
import ShowFileHistoryCommand from './commands/showFileHistory';
|
import ShowFileHistoryCommand from './commands/showFileHistory';
|
||||||
import ToggleBlameCommand from './commands/toggleBlame';
|
import ToggleBlameCommand from './commands/toggleBlame';
|
||||||
import ToggleCodeLensCommand from './commands/toggleCodeLens';
|
import ToggleCodeLensCommand from './commands/toggleCodeLens';
|
||||||
|
import { IAdvancedConfig } from './configuration';
|
||||||
|
import { WorkspaceState } from './constants';
|
||||||
|
import GitContentProvider from './gitContentProvider';
|
||||||
|
import GitProvider, { Git } from './gitProvider';
|
||||||
|
import GitRevisionCodeLensProvider from './gitRevisionCodeLensProvider';
|
||||||
|
import { Logger } from './logger';
|
||||||
|
|
||||||
// this method is called when your extension is activated
|
// this method is called when your extension is activated
|
||||||
export async function activate(context: ExtensionContext) {
|
export async function activate(context: ExtensionContext) {
|
||||||
@@ -50,9 +49,8 @@ export async function activate(context: ExtensionContext) {
|
|||||||
context.subscriptions.push(git);
|
context.subscriptions.push(git);
|
||||||
|
|
||||||
context.subscriptions.push(workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider(context, git)));
|
context.subscriptions.push(workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider(context, git)));
|
||||||
context.subscriptions.push(workspace.registerTextDocumentContentProvider(GitBlameContentProvider.scheme, new GitBlameContentProvider(context, git)));
|
|
||||||
|
|
||||||
context.subscriptions.push(languages.registerCodeLensProvider(GitBlameCodeLensProvider.selector, new GitBlameCodeLensProvider(context, git)));
|
context.subscriptions.push(languages.registerCodeLensProvider(GitRevisionCodeLensProvider.selector, new GitRevisionCodeLensProvider(context, git)));
|
||||||
|
|
||||||
const annotationController = new BlameAnnotationController(context, git);
|
const annotationController = new BlameAnnotationController(context, git);
|
||||||
context.subscriptions.push(annotationController);
|
context.subscriptions.push(annotationController);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export default class Git {
|
|||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
if (sha) {
|
if (sha) {
|
||||||
return gitCommand(root, 'blame', format, '--root', `${sha}^`, '--', file);
|
return gitCommand(root, 'blame', format, '--root', `${sha}^!`, '--', file);
|
||||||
}
|
}
|
||||||
return gitCommand(root, 'blame', format, '--root', '--', file);
|
return gitCommand(root, 'blame', format, '--root', '--', file);
|
||||||
}
|
}
|
||||||
@@ -75,20 +75,26 @@ export default class Git {
|
|||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
if (sha) {
|
if (sha) {
|
||||||
return gitCommand(root, 'blame', `-L ${startLine},${endLine}`, format, '--root', `${sha}^`, '--', file);
|
return gitCommand(root, 'blame', `-L ${startLine},${endLine}`, format, '--root', `${sha}^!`, '--', file);
|
||||||
}
|
}
|
||||||
return gitCommand(root, 'blame', `-L ${startLine},${endLine}`, format, '--root', '--', file);
|
return gitCommand(root, 'blame', `-L ${startLine},${endLine}`, format, '--root', '--', file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static log(fileName: string, repoPath?: string) {
|
static log(fileName: string, sha?: string, repoPath?: string) {
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
|
if (sha) {
|
||||||
|
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `origin..${sha}`, '--', file);
|
||||||
|
}
|
||||||
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, file);
|
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static logRange(fileName: string, start: number, end: number, repoPath?: string) {
|
static logRange(fileName: string, start: number, end: number, sha?: string, repoPath?: string) {
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
|
if (sha) {
|
||||||
|
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `origin..${sha}`, `-L ${start},${end}:${file}`);
|
||||||
|
}
|
||||||
return gitCommand(root, 'log', `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `-L ${start},${end}:${file}`);
|
return gitCommand(root, 'log', `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `-L ${start},${end}:${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
import { CancellationToken, CodeLens, CodeLensProvider, DocumentSelector, ExtensionContext, Range, TextDocument, Uri } from 'vscode';
|
|
||||||
import { Commands, DocumentSchemes } from './constants';
|
|
||||||
import GitProvider, { GitCommit } from './gitProvider';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
export class GitDiffWithWorkingTreeCodeLens extends CodeLens {
|
|
||||||
constructor(git: GitProvider, public fileName: string, public commit: GitCommit, range: Range) {
|
|
||||||
super(range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GitDiffWithPreviousCodeLens extends CodeLens {
|
|
||||||
constructor(git: GitProvider, public fileName: string, public commit: GitCommit, range: Range) {
|
|
||||||
super(range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class GitBlameCodeLensProvider implements CodeLensProvider {
|
|
||||||
static selector: DocumentSelector = { scheme: DocumentSchemes.GitBlame };
|
|
||||||
|
|
||||||
constructor(context: ExtensionContext, private git: GitProvider) { }
|
|
||||||
|
|
||||||
provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
|
|
||||||
const data = GitProvider.fromBlameUri(document.uri);
|
|
||||||
const fileName = data.fileName;
|
|
||||||
const sha = data.sha;
|
|
||||||
|
|
||||||
return this.git.getBlameForFile(fileName).then(blame => {
|
|
||||||
const lenses: CodeLens[] = [];
|
|
||||||
if (!blame) return lenses;
|
|
||||||
|
|
||||||
const commit = blame.commits.get(sha);
|
|
||||||
const absoluteFileName = path.join(commit.repoPath, fileName);
|
|
||||||
|
|
||||||
// Add codelens to each "group" of blame lines
|
|
||||||
const lines = blame.lines.filter(l => l.sha === sha && l.originalLine >= data.range.start.line && l.originalLine <= data.range.end.line);
|
|
||||||
let lastLine = lines[0].originalLine;
|
|
||||||
lines.forEach(l => {
|
|
||||||
if (l.originalLine !== lastLine + 1) {
|
|
||||||
lenses.push(new GitDiffWithWorkingTreeCodeLens(this.git, absoluteFileName, commit, new Range(l.originalLine, 0, l.originalLine, 1)));
|
|
||||||
if (commit.previousSha) {
|
|
||||||
lenses.push(new GitDiffWithPreviousCodeLens(this.git, absoluteFileName, commit, new Range(l.originalLine, 1, l.originalLine, 2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastLine = l.originalLine;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if we have a lens for the whole document -- if not add one
|
|
||||||
if (!lenses.find(l => l.range.start.line === 0 && l.range.end.line === 0)) {
|
|
||||||
lenses.push(new GitDiffWithWorkingTreeCodeLens(this.git, absoluteFileName, commit, new Range(0, 0, 0, 1)));
|
|
||||||
if (commit.previousSha) {
|
|
||||||
lenses.push(new GitDiffWithPreviousCodeLens(this.git, absoluteFileName, commit, new Range(0, 1, 0, 2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lenses;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
resolveCodeLens(lens: CodeLens, token: CancellationToken): Thenable<CodeLens> {
|
|
||||||
if (lens instanceof GitDiffWithWorkingTreeCodeLens) return this._resolveDiffWithWorkingTreeCodeLens(lens, token);
|
|
||||||
if (lens instanceof GitDiffWithPreviousCodeLens) return this._resolveGitDiffWithPreviousCodeLens(lens, token);
|
|
||||||
return Promise.reject<CodeLens>(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
_resolveDiffWithWorkingTreeCodeLens(lens: GitDiffWithWorkingTreeCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
|
||||||
lens.command = {
|
|
||||||
title: `Compare with Working Tree`,
|
|
||||||
command: Commands.DiffWithWorking,
|
|
||||||
arguments: [
|
|
||||||
Uri.file(lens.fileName),
|
|
||||||
lens.commit.sha,
|
|
||||||
lens.commit.uri,
|
|
||||||
lens.range.start.line
|
|
||||||
]
|
|
||||||
};
|
|
||||||
return Promise.resolve(lens);
|
|
||||||
}
|
|
||||||
|
|
||||||
_resolveGitDiffWithPreviousCodeLens(lens: GitDiffWithPreviousCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
|
||||||
lens.command = {
|
|
||||||
title: `Compare with Previous (${lens.commit.previousSha})`,
|
|
||||||
command: Commands.DiffWithPrevious,
|
|
||||||
arguments: [
|
|
||||||
Uri.file(lens.fileName),
|
|
||||||
lens.commit,
|
|
||||||
lens.range.start.line
|
|
||||||
]
|
|
||||||
};
|
|
||||||
return Promise.resolve(lens);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
import { EventEmitter, ExtensionContext, OverviewRulerLane, Range, TextEditor, TextEditorDecorationType, TextDocumentContentProvider, Uri, window } from 'vscode';
|
|
||||||
import { DocumentSchemes } from './constants';
|
|
||||||
import GitProvider, { IGitBlameUriData } from './gitProvider';
|
|
||||||
import { Logger } from './logger';
|
|
||||||
import * as moment from 'moment';
|
|
||||||
|
|
||||||
export default class GitBlameContentProvider implements TextDocumentContentProvider {
|
|
||||||
static scheme = DocumentSchemes.GitBlame;
|
|
||||||
|
|
||||||
private _blameDecoration: TextEditorDecorationType;
|
|
||||||
private _onDidChange = new EventEmitter<Uri>();
|
|
||||||
//private _subscriptions: Disposable;
|
|
||||||
|
|
||||||
constructor(context: ExtensionContext, private git: GitProvider) {
|
|
||||||
this._blameDecoration = window.createTextEditorDecorationType({
|
|
||||||
dark: {
|
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.15)',
|
|
||||||
gutterIconPath: context.asAbsolutePath('images/blame-dark.png'),
|
|
||||||
overviewRulerColor: 'rgba(255, 255, 255, 0.75)'
|
|
||||||
},
|
|
||||||
light: {
|
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.15)',
|
|
||||||
gutterIconPath: context.asAbsolutePath('images/blame-light.png'),
|
|
||||||
overviewRulerColor: 'rgba(0, 0, 0, 0.75)'
|
|
||||||
},
|
|
||||||
gutterIconSize: 'contain',
|
|
||||||
overviewRulerLane: OverviewRulerLane.Right,
|
|
||||||
isWholeLine: true
|
|
||||||
});
|
|
||||||
|
|
||||||
//this._subscriptions = Disposable.from(
|
|
||||||
// window.onDidChangeActiveTextEditor(e => e ? Logger.log(e.document.uri) : Logger.log('active missing')),
|
|
||||||
//);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
this._onDidChange.dispose();
|
|
||||||
//this._subscriptions && this._subscriptions.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
get onDidChange() {
|
|
||||||
return this._onDidChange.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
public update(uri: Uri) {
|
|
||||||
this._onDidChange.fire(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
provideTextDocumentContent(uri: Uri): string | Thenable<string> {
|
|
||||||
const data = GitProvider.fromBlameUri(uri);
|
|
||||||
|
|
||||||
//const editor = this._findEditor(Uri.file(join(data.repoPath, data.file)));
|
|
||||||
|
|
||||||
return this.git.getVersionedFileText(data.originalFileName || data.fileName, data.repoPath, data.sha)
|
|
||||||
.then(text => {
|
|
||||||
this.update(uri);
|
|
||||||
|
|
||||||
// TODO: This only works on the first load -- not after since it is cached
|
|
||||||
this._tryAddBlameDecorations(uri, data);
|
|
||||||
|
|
||||||
// TODO: This needs to move to selection somehow to show on the main file editor
|
|
||||||
//this._addBlameDecorations(editor, data);
|
|
||||||
|
|
||||||
return text;
|
|
||||||
})
|
|
||||||
.catch(ex => Logger.error('[GitLens.GitBlameContentProvider]', 'getVersionedFileText', ex));
|
|
||||||
|
|
||||||
// return this.git.getVersionedFile(data.fileName, data.sha).then(dst => {
|
|
||||||
// let uri = Uri.parse(`file:${dst}`)
|
|
||||||
// return workspace.openTextDocument(uri).then(doc => {
|
|
||||||
// this.update(uri);
|
|
||||||
// return doc.getText();
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _findEditor(uri: Uri): TextEditor {
|
|
||||||
let uriString = uri.toString();
|
|
||||||
const matcher = (e: TextEditor) => (e && e.document.uri.toString()) === uriString;
|
|
||||||
if (matcher(window.activeTextEditor)) {
|
|
||||||
return window.activeTextEditor;
|
|
||||||
}
|
|
||||||
return window.visibleTextEditors.find(matcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _tryAddBlameDecorations(uri: Uri, data: IGitBlameUriData) {
|
|
||||||
// Needs to be on a timer for some reason because we won't find the editor otherwise -- is there an event?
|
|
||||||
let handle = setInterval(() => {
|
|
||||||
let editor = this._findEditor(uri);
|
|
||||||
if (!editor) return;
|
|
||||||
|
|
||||||
clearInterval(handle);
|
|
||||||
this.git.getBlameForShaRange(data.fileName, data.sha, data.range).then(blame => {
|
|
||||||
if (!blame || !blame.lines.length) return;
|
|
||||||
|
|
||||||
editor.setDecorations(this._blameDecoration, blame.lines.map(l => {
|
|
||||||
return {
|
|
||||||
range: editor.document.validateRange(new Range(l.originalLine, 0, l.originalLine, 1000000)),
|
|
||||||
hoverMessage: `${blame.commit.message}\n${blame.commit.author}\n${moment(blame.commit.date).format('MMMM Do, YYYY hh:MMa')}\n${l.sha}`
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
// private _addBlameDecorations(editor: TextEditor, data: IGitBlameUriData) {
|
|
||||||
// editor.setDecorations(this._blameDecoration, data.lines.map(l => editor.document.validateRange(new Range(l.line, 0, l.line, 1000000))));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@@ -185,7 +185,7 @@ export default class GitCodeLensProvider implements CodeLensProvider {
|
|||||||
|
|
||||||
switch (this._config.codeLens.recentChange.command) {
|
switch (this._config.codeLens.recentChange.command) {
|
||||||
case CodeLensCommand.BlameAnnotate: return this._applyBlameAnnotateCommand<GitRecentChangeCodeLens>(title, lens, blame);
|
case CodeLensCommand.BlameAnnotate: return this._applyBlameAnnotateCommand<GitRecentChangeCodeLens>(title, lens, blame);
|
||||||
case CodeLensCommand.ShowBlameHistory: return this._applyShowBlameHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame);
|
case CodeLensCommand.ShowBlameHistory: return this._applyShowBlameHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit);
|
||||||
case CodeLensCommand.ShowFileHistory: return this._applyShowFileHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit);
|
case CodeLensCommand.ShowFileHistory: return this._applyShowFileHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit);
|
||||||
case CodeLensCommand.DiffWithPrevious: return this._applyDiffWithPreviousCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit);
|
case CodeLensCommand.DiffWithPrevious: return this._applyDiffWithPreviousCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit);
|
||||||
case CodeLensCommand.GitViewHistory: return this._applyGitHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame);
|
case CodeLensCommand.GitViewHistory: return this._applyGitHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame);
|
||||||
@@ -218,27 +218,38 @@ export default class GitCodeLensProvider implements CodeLensProvider {
|
|||||||
return lens;
|
return lens;
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyShowBlameHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: IGitBlameLines) {
|
_applyShowBlameHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: IGitBlameLines, commit?: GitCommit) {
|
||||||
|
let line = lens.range.start.line;
|
||||||
|
if (commit) {
|
||||||
|
const blameLine = commit.lines.find(_ => _.line === line);
|
||||||
|
if (blameLine) {
|
||||||
|
line = blameLine.originalLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const position = lens.isFullRange ? new Position(1, 0) : lens.range.start;
|
||||||
lens.command = {
|
lens.command = {
|
||||||
title: title,
|
title: title,
|
||||||
command: Commands.ShowBlameHistory,
|
command: Commands.ShowBlameHistory,
|
||||||
arguments: [Uri.file(lens.fileName), lens.blameRange, lens.range.start]
|
arguments: [Uri.file(lens.fileName), lens.blameRange, position, commit && commit.sha, line]
|
||||||
};
|
};
|
||||||
return lens;
|
return lens;
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyShowFileHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: IGitBlameLines, commit?: GitCommit) {
|
_applyShowFileHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: IGitBlameLines, commit?: GitCommit) {
|
||||||
let line = lens.range.start.line;
|
let line = lens.range.start.line;
|
||||||
const blameLine = commit.lines.find(_ => _.line === line);
|
if (commit) {
|
||||||
if (blameLine) {
|
const blameLine = commit.lines.find(_ => _.line === line);
|
||||||
line = blameLine.originalLine;
|
if (blameLine) {
|
||||||
|
line = blameLine.originalLine;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = lens.isFullRange ? new Position(1, 0) : lens.range.start;
|
const position = lens.isFullRange ? new Position(1, 0) : lens.range.start;
|
||||||
lens.command = {
|
lens.command = {
|
||||||
title: title,
|
title: title,
|
||||||
command: Commands.ShowFileHistory,
|
command: Commands.ShowFileHistory,
|
||||||
arguments: [Uri.file(lens.fileName), position, commit.sha, line]
|
arguments: [Uri.file(lens.fileName), position, commit && commit.sha, line]
|
||||||
};
|
};
|
||||||
return lens;
|
return lens;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Functions, Iterables, Objects } from './system';
|
import { Functions, Iterables, Objects } from './system';
|
||||||
import { Disposable, DocumentFilter, ExtensionContext, languages, Location, Position, Range, TextDocument, TextEditor, Uri, window, workspace } from 'vscode';
|
import { Disposable, DocumentFilter, ExtensionContext, languages, Location, Position, Range, TextDocument, TextEditor, Uri, window, workspace } from 'vscode';
|
||||||
import { DocumentSchemes, WorkspaceState } from './constants';
|
|
||||||
import { CodeLensVisibility, IConfig } from './configuration';
|
import { CodeLensVisibility, IConfig } from './configuration';
|
||||||
|
import { DocumentSchemes, WorkspaceState } from './constants';
|
||||||
|
import Git, { GitBlameParserEnricher, GitBlameFormat, GitCommit, GitLogParserEnricher, IGitAuthor, IGitBlame, IGitBlameLine, IGitBlameLines, IGitLog } from './git/git';
|
||||||
import GitCodeLensProvider from './gitCodeLensProvider';
|
import GitCodeLensProvider from './gitCodeLensProvider';
|
||||||
import Git, { GitBlameParserEnricher, GitBlameFormat, GitCommit, GitLogParserEnricher, IGitAuthor, IGitBlame, IGitBlameCommitLines, IGitBlameLine, IGitBlameLines, IGitLog } from './git/git';
|
|
||||||
import { Logger } from './logger';
|
import { Logger } from './logger';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as ignore from 'ignore';
|
import * as ignore from 'ignore';
|
||||||
@@ -264,10 +264,10 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBlameForRange(fileName: string, range: Range): Promise<IGitBlameLines | undefined> {
|
async getBlameForRange(fileName: string, range: Range, sha?: string, repoPath?: string): Promise<IGitBlameLines | undefined> {
|
||||||
Logger.log(`getBlameForRange('${fileName}', ${range})`);
|
Logger.log(`getBlameForRange('${fileName}', ${range}, ${sha}, ${repoPath})`);
|
||||||
|
|
||||||
const blame = await this.getBlameForFile(fileName);
|
const blame = await this.getBlameForFile(fileName, sha, repoPath);
|
||||||
if (!blame) return undefined;
|
if (!blame) return undefined;
|
||||||
|
|
||||||
if (!blame.lines.length) return Object.assign({ allLines: blame.lines }, blame);
|
if (!blame.lines.length) return Object.assign({ allLines: blame.lines }, blame);
|
||||||
@@ -314,27 +314,10 @@ export default class GitProvider extends Disposable {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBlameForShaRange(fileName: string, sha: string, range: Range): Promise<IGitBlameCommitLines | undefined> {
|
async getBlameLocations(fileName: string, range: Range, sha?: string, repoPath?: string, selectedSha?: string, line?: number): Promise<Location[] | undefined> {
|
||||||
Logger.log(`getBlameForShaRange('${fileName}', ${sha}, ${range})`);
|
Logger.log(`getBlameLocations('${fileName}', ${range}, ${sha}, ${repoPath})`);
|
||||||
|
|
||||||
const blame = await this.getBlameForFile(fileName);
|
const blame = await this.getBlameForRange(fileName, range, sha, repoPath);
|
||||||
if (!blame) return undefined;
|
|
||||||
|
|
||||||
const lines = blame.lines.slice(range.start.line, range.end.line + 1).filter(l => l.sha === sha);
|
|
||||||
let commit = blame.commits.get(sha);
|
|
||||||
commit = new GitCommit(commit.repoPath, commit.sha, commit.fileName, commit.author, commit.date, commit.message,
|
|
||||||
lines, commit.originalFileName, commit.previousSha, commit.previousFileName);
|
|
||||||
return {
|
|
||||||
author: Object.assign({}, blame.authors.get(commit.author), { lineCount: commit.lines.length }),
|
|
||||||
commit: commit,
|
|
||||||
lines: lines
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async getBlameLocations(fileName: string, range: Range): Promise<Location[] | undefined> {
|
|
||||||
Logger.log(`getBlameForShaRange('${fileName}', ${range})`);
|
|
||||||
|
|
||||||
const blame = await this.getBlameForRange(fileName, range);
|
|
||||||
if (!blame) return undefined;
|
if (!blame) return undefined;
|
||||||
|
|
||||||
const commitCount = blame.commits.size;
|
const commitCount = blame.commits.size;
|
||||||
@@ -343,18 +326,21 @@ export default class GitProvider extends Disposable {
|
|||||||
Iterables.forEach(blame.commits.values(), (c, i) => {
|
Iterables.forEach(blame.commits.values(), (c, i) => {
|
||||||
if (c.isUncommitted) return;
|
if (c.isUncommitted) return;
|
||||||
|
|
||||||
const uri = GitProvider.toBlameUri(c, i + 1, commitCount, range);
|
const decoration = `\u2937 ${c.author}, ${moment(c.date).format('MMMM Do, YYYY h:MMa')}`;
|
||||||
c.lines.forEach(l => locations.push(new Location(c.originalFileName
|
const uri = c.originalFileName
|
||||||
? GitProvider.toBlameUri(c, i + 1, commitCount, range, c.originalFileName)
|
? GitProvider.toGitUri(c, i + 1, commitCount, c.originalFileName, decoration)
|
||||||
: uri,
|
: GitProvider.toGitUri(c, i + 1, commitCount, undefined, decoration);
|
||||||
new Position(l.originalLine, 0))));
|
locations.push(new Location(uri, new Position(0, 0)));
|
||||||
|
if (c.sha === selectedSha) {
|
||||||
|
locations.push(new Location(uri, new Position(line + 1, 0)));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogForFile(fileName: string, range?: Range): Promise<IGitLog | undefined> {
|
getLogForFile(fileName: string, sha?: string, repoPath?: string, range?: Range): Promise<IGitLog | undefined> {
|
||||||
Logger.log(`getLogForFile('${fileName}', ${range})`);
|
Logger.log(`getLogForFile('${fileName}', ${sha}, ${repoPath}, ${range})`);
|
||||||
fileName = Git.normalizePath(fileName);
|
fileName = Git.normalizePath(fileName);
|
||||||
|
|
||||||
const useCaching = this.UseCaching && !range;
|
const useCaching = this.UseCaching && !range;
|
||||||
@@ -377,7 +363,9 @@ export default class GitProvider extends Disposable {
|
|||||||
return <Promise<IGitLog>>GitProvider.EmptyPromise;
|
return <Promise<IGitLog>>GitProvider.EmptyPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (range ? Git.logRange(fileName, range.start.line + 1, range.end.line + 1) : Git.log(fileName))
|
return (range
|
||||||
|
? Git.logRange(fileName, range.start.line + 1, range.end.line + 1, sha, repoPath)
|
||||||
|
: Git.log(fileName, sha, repoPath))
|
||||||
.then(data => new GitLogParserEnricher().enrich(data, fileName))
|
.then(data => new GitLogParserEnricher().enrich(data, fileName))
|
||||||
.catch(ex => {
|
.catch(ex => {
|
||||||
// Trap and cache expected blame errors
|
// Trap and cache expected blame errors
|
||||||
@@ -412,10 +400,10 @@ export default class GitProvider extends Disposable {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLogLocations(fileName: string, sha?: string, line?: number): Promise<Location[] | undefined> {
|
async getLogLocations(fileName: string, sha?: string, repoPath?: string, selectedSha?: string, line?: number): Promise<Location[] | undefined> {
|
||||||
Logger.log(`getLogLocations('${fileName}', ${sha}, ${line})`);
|
Logger.log(`getLogLocations('${fileName}', ${sha}, ${repoPath}, ${selectedSha}, ${line})`);
|
||||||
|
|
||||||
const log = await this.getLogForFile(fileName);
|
const log = await this.getLogForFile(fileName, sha, repoPath);
|
||||||
if (!log) return undefined;
|
if (!log) return undefined;
|
||||||
|
|
||||||
const commitCount = log.commits.size;
|
const commitCount = log.commits.size;
|
||||||
@@ -423,12 +411,13 @@ export default class GitProvider extends Disposable {
|
|||||||
const locations: Array<Location> = [];
|
const locations: Array<Location> = [];
|
||||||
Iterables.forEach(log.commits.values(), (c, i) => {
|
Iterables.forEach(log.commits.values(), (c, i) => {
|
||||||
if (c.isUncommitted) return;
|
if (c.isUncommitted) return;
|
||||||
|
|
||||||
const decoration = `\u2937 ${c.author}, ${moment(c.date).format('MMMM Do, YYYY h:MMa')}`;
|
const decoration = `\u2937 ${c.author}, ${moment(c.date).format('MMMM Do, YYYY h:MMa')}`;
|
||||||
const uri = c.originalFileName
|
const uri = c.originalFileName
|
||||||
? GitProvider.toGitUri(c, i + 1, commitCount, c.originalFileName, decoration)
|
? GitProvider.toGitUri(c, i + 1, commitCount, c.originalFileName, decoration)
|
||||||
: GitProvider.toGitUri(c, i + 1, commitCount, undefined, decoration);
|
: GitProvider.toGitUri(c, i + 1, commitCount, undefined, decoration);
|
||||||
locations.push(new Location(uri, new Position(0, 0)));
|
locations.push(new Location(uri, new Position(0, 0)));
|
||||||
if (c.sha === sha) {
|
if (c.sha === selectedSha) {
|
||||||
locations.push(new Location(uri, new Position(line + 1, 0)));
|
locations.push(new Location(uri, new Position(line + 1, 0)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -481,14 +470,6 @@ export default class GitProvider extends Disposable {
|
|||||||
return Git.isUncommitted(sha);
|
return Git.isUncommitted(sha);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromBlameUri(uri: Uri): IGitBlameUriData {
|
|
||||||
if (uri.scheme !== DocumentSchemes.GitBlame) throw new Error(`fromGitUri(uri=${uri}) invalid scheme`);
|
|
||||||
const data = GitProvider._fromGitUri<IGitBlameUriData>(uri);
|
|
||||||
const range = <any>data.range as Position[];
|
|
||||||
data.range = new Range(range[0].line, range[0].character, range[1].line, range[1].character);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromGitUri(uri: Uri): IGitUriData {
|
static fromGitUri(uri: Uri): IGitUriData {
|
||||||
if (uri.scheme !== DocumentSchemes.Git) throw new Error(`fromGitUri(uri=${uri}) invalid scheme`);
|
if (uri.scheme !== DocumentSchemes.Git) throw new Error(`fromGitUri(uri=${uri}) invalid scheme`);
|
||||||
return GitProvider._fromGitUri<IGitUriData>(uri);
|
return GitProvider._fromGitUri<IGitUriData>(uri);
|
||||||
@@ -498,15 +479,11 @@ export default class GitProvider extends Disposable {
|
|||||||
return JSON.parse(uri.query) as T;
|
return JSON.parse(uri.query) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
static toBlameUri(commit: GitCommit, index: number, commitCount: number, range: Range, originalFileName?: string) {
|
|
||||||
return GitProvider._toGitUri(commit, DocumentSchemes.GitBlame, commitCount, GitProvider._toGitBlameUriData(commit, index, range, originalFileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
static toGitUri(commit: GitCommit, index: number, commitCount: number, originalFileName?: string, decoration?: string) {
|
static toGitUri(commit: GitCommit, index: number, commitCount: number, originalFileName?: string, decoration?: string) {
|
||||||
return GitProvider._toGitUri(commit, DocumentSchemes.Git, commitCount, GitProvider._toGitUriData(commit, index, originalFileName, decoration));
|
return GitProvider._toGitUri(commit, DocumentSchemes.Git, commitCount, GitProvider._toGitUriData(commit, index, originalFileName, decoration));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _toGitUri(commit: GitCommit, scheme: DocumentSchemes, commitCount: number, data: IGitUriData | IGitBlameUriData) {
|
private static _toGitUri(commit: GitCommit, scheme: DocumentSchemes, commitCount: number, data: IGitUriData) {
|
||||||
const pad = (n: number) => ('0000000' + n).slice(-('' + commitCount).length);
|
const pad = (n: number) => ('0000000' + n).slice(-('' + commitCount).length);
|
||||||
const ext = path.extname(data.fileName);
|
const ext = path.extname(data.fileName);
|
||||||
// const uriPath = `${dirname(data.fileName)}/${commit.sha}: ${basename(data.fileName, ext)}${ext}`;
|
// const uriPath = `${dirname(data.fileName)}/${commit.sha}: ${basename(data.fileName, ext)}${ext}`;
|
||||||
@@ -532,12 +509,6 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _toGitBlameUriData(commit: GitCommit, index: number, range: Range, originalFileName?: string) {
|
|
||||||
const data = this._toGitUriData<IGitBlameUriData>(commit, index, originalFileName);
|
|
||||||
data.range = range;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GitUri extends Uri {
|
export class GitUri extends Uri {
|
||||||
@@ -557,7 +528,7 @@ export class GitUri extends Uri {
|
|||||||
base._fragment = uri.fragment;
|
base._fragment = uri.fragment;
|
||||||
|
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
if (uri.scheme === DocumentSchemes.Git || uri.scheme === DocumentSchemes.GitBlame) {
|
if (uri.scheme === DocumentSchemes.Git) {
|
||||||
const data = GitProvider.fromGitUri(uri);
|
const data = GitProvider.fromGitUri(uri);
|
||||||
base._fsPath = data.originalFileName || data.fileName;
|
base._fsPath = data.originalFileName || data.fileName;
|
||||||
|
|
||||||
@@ -583,8 +554,4 @@ export interface IGitUriData {
|
|||||||
sha: string;
|
sha: string;
|
||||||
index: number;
|
index: number;
|
||||||
decoration?: string;
|
decoration?: string;
|
||||||
}
|
|
||||||
|
|
||||||
export interface IGitBlameUriData extends IGitUriData {
|
|
||||||
range: Range;
|
|
||||||
}
|
}
|
||||||
75
src/gitRevisionCodeLensProvider.ts
Normal file
75
src/gitRevisionCodeLensProvider.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
'use strict';
|
||||||
|
import { Iterables } from './system';
|
||||||
|
import { CancellationToken, CodeLens, CodeLensProvider, DocumentSelector, ExtensionContext, Range, TextDocument, Uri } from 'vscode';
|
||||||
|
import { Commands, DocumentSchemes } from './constants';
|
||||||
|
import GitProvider, { GitCommit, GitUri } from './gitProvider';
|
||||||
|
|
||||||
|
export class GitDiffWithWorkingCodeLens extends CodeLens {
|
||||||
|
constructor(git: GitProvider, public fileName: string, public commit: GitCommit, range: Range) {
|
||||||
|
super(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GitDiffWithPreviousCodeLens extends CodeLens {
|
||||||
|
constructor(git: GitProvider, public fileName: string, public commit: GitCommit, range: Range) {
|
||||||
|
super(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class GitRevisionCodeLensProvider implements CodeLensProvider {
|
||||||
|
static selector: DocumentSelector = { scheme: DocumentSchemes.Git };
|
||||||
|
|
||||||
|
constructor(context: ExtensionContext, private git: GitProvider) { }
|
||||||
|
|
||||||
|
async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
|
||||||
|
const gitUri = GitUri.fromUri(document.uri);
|
||||||
|
|
||||||
|
const lenses: CodeLens[] = [];
|
||||||
|
|
||||||
|
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath);
|
||||||
|
if (!log) return lenses;
|
||||||
|
|
||||||
|
const commit = (gitUri.sha && log.commits.get(gitUri.sha)) || Iterables.first(log.commits.values());
|
||||||
|
if (!commit) return lenses;
|
||||||
|
|
||||||
|
lenses.push(new GitDiffWithWorkingCodeLens(this.git, commit.uri.fsPath, commit, new Range(0, 0, 0, 1)));
|
||||||
|
|
||||||
|
if (commit.previousSha) {
|
||||||
|
lenses.push(new GitDiffWithPreviousCodeLens(this.git, commit.previousUri.fsPath, commit, new Range(0, 1, 0, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveCodeLens(lens: CodeLens, token: CancellationToken): Thenable<CodeLens> {
|
||||||
|
if (lens instanceof GitDiffWithWorkingCodeLens) return this._resolveDiffWithWorkingTreeCodeLens(lens, token);
|
||||||
|
if (lens instanceof GitDiffWithPreviousCodeLens) return this._resolveGitDiffWithPreviousCodeLens(lens, token);
|
||||||
|
return Promise.reject<CodeLens>(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
_resolveDiffWithWorkingTreeCodeLens(lens: GitDiffWithWorkingCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
||||||
|
lens.command = {
|
||||||
|
title: `Compare (${lens.commit.sha}) with Working Tree`,
|
||||||
|
command: Commands.DiffWithWorking,
|
||||||
|
arguments: [
|
||||||
|
Uri.file(lens.fileName),
|
||||||
|
lens.commit,
|
||||||
|
lens.range.start.line
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return Promise.resolve(lens);
|
||||||
|
}
|
||||||
|
|
||||||
|
_resolveGitDiffWithPreviousCodeLens(lens: GitDiffWithPreviousCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
||||||
|
lens.command = {
|
||||||
|
title: `Compare (${lens.commit.sha}) with Previous (${lens.commit.previousSha})`,
|
||||||
|
command: Commands.DiffWithPrevious,
|
||||||
|
arguments: [
|
||||||
|
Uri.file(lens.fileName),
|
||||||
|
lens.commit,
|
||||||
|
lens.range.start.line
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return Promise.resolve(lens);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user