mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-19 01:35:37 -05:00
108 lines
4.4 KiB
TypeScript
108 lines
4.4 KiB
TypeScript
'use strict';
|
|
import {Disposable, EventEmitter, ExtensionContext, OverviewRulerLane, Range, TextEditor, TextEditorDecorationType, TextDocumentContentProvider, Uri, window, workspace} from 'vscode';
|
|
import {DocumentSchemes, WorkspaceState} from './constants';
|
|
import GitProvider, {IGitBlameUriData} from './gitProvider';
|
|
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 ? console.log(e.document.uri) : console.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.sha, data.repoPath).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;
|
|
});
|
|
|
|
// 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();
|
|
// TODO: This is a big hack :)
|
|
const matcher = (e: any) => (e && e._documentData && e._documentData._uri && e._documentData._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:MM a')}\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))));
|
|
// }
|
|
} |