Skip to content

Commit b61c0f1

Browse files
authored
Git - add git blame status bar item (microsoft#234302)
* Git - improve enabliment of the editor decoration * Git - add git blame status bar item
1 parent 0fda109 commit b61c0f1

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

extensions/git/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,6 +3197,15 @@
31973197
"tags": [
31983198
"experimental"
31993199
]
3200+
},
3201+
"git.blame.statusBarItem.enabled": {
3202+
"type": "boolean",
3203+
"default": false,
3204+
"markdownDescription": "%config.blameStatusBarItem.enabled%",
3205+
"scope": "resource",
3206+
"tags": [
3207+
"experimental"
3208+
]
32003209
}
32013210
}
32023211
},

extensions/git/package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@
276276
"config.publishBeforeContinueOn.never": "Never publish unpublished Git state when using Continue Working On from a Git repository",
277277
"config.publishBeforeContinueOn.prompt": "Prompt to publish unpublished Git state when using Continue Working On from a Git repository",
278278
"config.similarityThreshold": "Controls the threshold of the similarity index (the amount of additions/deletions compared to the file's size) for changes in a pair of added/deleted files to be considered a rename. **Note:** Requires Git version `2.18.0` or later.",
279-
"config.blameEditorDecoration.enabled": "Controls whether to show git blame information in the editor using editor decorations",
279+
"config.blameEditorDecoration.enabled": "Controls whether to show git blame information in the editor using editor decorations.",
280+
"config.blameStatusBarItem.enabled": "Controls whether to show git blame information in the status bar.",
280281
"submenu.explorer": "Git",
281282
"submenu.commit": "Commit",
282283
"submenu.commit.amend": "Amend",

extensions/git/src/blame.ts

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { DecorationOptions, l10n, Position, Range, TextEditor, TextEditorChange, TextEditorDecorationType, TextEditorChangeKind, ThemeColor, Uri, window, workspace, EventEmitter, ConfigurationChangeEvent } from 'vscode';
6+
import { DecorationOptions, l10n, Position, Range, TextEditor, TextEditorChange, TextEditorDecorationType, TextEditorChangeKind, ThemeColor, Uri, window, workspace, EventEmitter, ConfigurationChangeEvent, StatusBarItem, StatusBarAlignment } from 'vscode';
77
import { Model } from './model';
88
import { dispose, fromNow, IDisposable, pathEquals } from './util';
99
import { Repository } from './repository';
@@ -113,6 +113,7 @@ export class GitBlameController {
113113

114114
constructor(private readonly _model: Model) {
115115
this._disposables.push(new GitBlameEditorDecoration(this));
116+
this._disposables.push(new GitBlameStatusBarItem(this));
116117

117118
this._model.onDidOpenRepository(this._onDidOpenRepository, this, this._disposables);
118119
this._model.onDidCloseRepository(this._onDidCloseRepository, this, this._disposables);
@@ -336,3 +337,78 @@ class GitBlameEditorDecoration {
336337
this._disposables = dispose(this._disposables);
337338
}
338339
}
340+
341+
class GitBlameStatusBarItem {
342+
private _statusBarItem: StatusBarItem | undefined;
343+
344+
private _disposables: IDisposable[] = [];
345+
346+
constructor(private readonly _controller: GitBlameController) {
347+
workspace.onDidChangeConfiguration(this._onDidChangeConfiguration, this, this._disposables);
348+
window.onDidChangeActiveTextEditor(this._onDidChangeActiveTextEditor, this, this._disposables);
349+
350+
this._controller.onDidChangeBlameInformation(e => this._updateStatusBarItem(e), this, this._disposables);
351+
}
352+
353+
private _onDidChangeConfiguration(e: ConfigurationChangeEvent): void {
354+
if (!e.affectsConfiguration('git.blame.statusBarItem.enabled')) {
355+
return;
356+
}
357+
358+
if (this._isEnabled()) {
359+
if (window.activeTextEditor) {
360+
this._updateStatusBarItem(window.activeTextEditor);
361+
}
362+
} else {
363+
this._statusBarItem?.dispose();
364+
this._statusBarItem = undefined;
365+
}
366+
}
367+
368+
private _onDidChangeActiveTextEditor(): void {
369+
if (!this._isEnabled()) {
370+
return;
371+
}
372+
373+
if (window.activeTextEditor) {
374+
this._updateStatusBarItem(window.activeTextEditor);
375+
} else {
376+
this._statusBarItem?.hide();
377+
}
378+
}
379+
380+
private _isEnabled(): boolean {
381+
const config = workspace.getConfiguration('git');
382+
return config.get<boolean>('blame.statusBarItem.enabled', false);
383+
}
384+
385+
private _updateStatusBarItem(textEditor: TextEditor): void {
386+
if (!this._isEnabled() || textEditor !== window.activeTextEditor) {
387+
return;
388+
}
389+
390+
if (!this._statusBarItem) {
391+
this._statusBarItem = window.createStatusBarItem('git.blame', StatusBarAlignment.Right, 200);
392+
this._disposables.push(this._statusBarItem);
393+
}
394+
395+
const blameInformation = this._controller.textEditorBlameInformation.get(textEditor);
396+
if (!blameInformation || blameInformation.length === 0) {
397+
this._statusBarItem.hide();
398+
return;
399+
}
400+
401+
const statueBarItemText = blameInformation[0]
402+
? typeof blameInformation[0].blameInformation === 'string'
403+
? ` ${blameInformation[0].blameInformation}`
404+
: ` ${blameInformation[0].blameInformation.authorName ?? ''} (${fromNow(blameInformation[0].blameInformation.date ?? new Date(), true, true)})`
405+
: '';
406+
407+
this._statusBarItem.text = `$(git-commit)${statueBarItemText}`;
408+
this._statusBarItem.show();
409+
}
410+
411+
dispose() {
412+
this._disposables = dispose(this._disposables);
413+
}
414+
}

0 commit comments

Comments
 (0)