mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-02-17 02:51:47 -05:00
Removes unnecessary subscriptions on invalid blame
Removes duplicate lint rule Switches on-demand CodeLens to be a global toggle
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
- Adds new `gitlens.diffLineWithWorking` command for line sensitive diffs
|
- Adds new `gitlens.diffLineWithWorking` command for line sensitive diffs
|
||||||
- Adds `gitlens.diffWithPrevious` command to the explorer context menu
|
- Adds `gitlens.diffWithPrevious` command to the explorer context menu
|
||||||
- Adds output channel logging, controlled by the `gitlens.advanced.output.level` setting
|
- Adds output channel logging, controlled by the `gitlens.advanced.output.level` setting
|
||||||
|
- Switches on-demand CodeLens to be a global toggle (rather than per file)
|
||||||
- Complete rewrite of the blame annotation provider to reduce overhead and provide better performance
|
- Complete rewrite of the blame annotation provider to reduce overhead and provide better performance
|
||||||
- Improves performance (significantly) when only showing CodeLens at the document level
|
- Improves performance (significantly) when only showing CodeLens at the document level
|
||||||
- Improves performance of status bar blame support
|
- Improves performance of status bar blame support
|
||||||
|
|||||||
@@ -44,7 +44,20 @@ export default class BlameAnnotationController extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async showBlameAnnotation(editor: TextEditor, shaOrLine?: string | number): Promise<boolean> {
|
async showBlameAnnotation(editor: TextEditor, shaOrLine?: string | number): Promise<boolean> {
|
||||||
if (!editor || !editor.document) return false;
|
if (!editor || !editor.document || editor.viewColumn === undefined) return false;
|
||||||
|
|
||||||
|
const currentProvider = this._annotationProviders.get(editor.viewColumn);
|
||||||
|
if (currentProvider && TextEditorComparer.equals(currentProvider.editor, editor)) {
|
||||||
|
await currentProvider.setSelection(shaOrLine);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = new BlameAnnotationProvider(this.context, this.git, editor);
|
||||||
|
if (!await provider.supportsBlame()) return false;
|
||||||
|
|
||||||
|
if (currentProvider) {
|
||||||
|
await this.clear(currentProvider.editor.viewColumn, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._blameAnnotationsDisposable && this._annotationProviders.size === 0) {
|
if (!this._blameAnnotationsDisposable && this._annotationProviders.size === 0) {
|
||||||
Logger.log(`Add listener registrations for blame annotations`);
|
Logger.log(`Add listener registrations for blame annotations`);
|
||||||
@@ -60,22 +73,12 @@ export default class BlameAnnotationController extends Disposable {
|
|||||||
this._visibleColumns = this._getVisibleColumns(window.visibleTextEditors);
|
this._visibleColumns = this._getVisibleColumns(window.visibleTextEditors);
|
||||||
}
|
}
|
||||||
|
|
||||||
let provider = this._annotationProviders.get(editor.viewColumn);
|
|
||||||
if (provider) {
|
|
||||||
if (TextEditorComparer.equals(provider.editor, editor)) {
|
|
||||||
await provider.setSelection(shaOrLine);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
await this.clear(provider.editor.viewColumn, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
provider = new BlameAnnotationProvider(this.context, this.git, editor);
|
|
||||||
this._annotationProviders.set(editor.viewColumn, provider);
|
this._annotationProviders.set(editor.viewColumn, provider);
|
||||||
return provider.provideBlameAnnotation(shaOrLine);
|
return provider.provideBlameAnnotation(shaOrLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleBlameAnnotation(editor: TextEditor, shaOrLine?: string | number): Promise<boolean> {
|
async toggleBlameAnnotation(editor: TextEditor, shaOrLine?: string | number): Promise<boolean> {
|
||||||
if (!editor || !editor.document) return false;
|
if (!editor || !editor.document || editor.viewColumn === undefined) return false;
|
||||||
|
|
||||||
let provider = this._annotationProviders.get(editor.viewColumn);
|
let provider = this._annotationProviders.get(editor.viewColumn);
|
||||||
if (!provider) return this.showBlameAnnotation(editor, shaOrLine);
|
if (!provider) return this.showBlameAnnotation(editor, shaOrLine);
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ export class BlameAnnotationProvider extends Disposable {
|
|||||||
return this.setSelection(e.selections[0].active.line);
|
return this.setSelection(e.selections[0].active.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async supportsBlame(): Promise<boolean> {
|
||||||
|
const blame = await this._blame;
|
||||||
|
return !!(blame && blame.lines.length);
|
||||||
|
}
|
||||||
|
|
||||||
async provideBlameAnnotation(shaOrLine?: string | number): Promise<boolean> {
|
async provideBlameAnnotation(shaOrLine?: string | number): Promise<boolean> {
|
||||||
const blame = await this._blame;
|
const blame = await this._blame;
|
||||||
if (!blame || !blame.lines.length) return false;
|
if (!blame || !blame.lines.length) return false;
|
||||||
@@ -168,7 +173,8 @@ export class BlameAnnotationProvider extends Disposable {
|
|||||||
let previous = blame.commits.get(commit.previousSha);
|
let previous = blame.commits.get(commit.previousSha);
|
||||||
if (previous) {
|
if (previous) {
|
||||||
hoverMessage = ['Uncommitted changes', `_${previous.sha}_ - ${previous.message}`, `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MMa')}`];
|
hoverMessage = ['Uncommitted changes', `_${previous.sha}_ - ${previous.message}`, `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MMa')}`];
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
hoverMessage = ['Uncommitted changes', `_${l.previousSha}_`];
|
hoverMessage = ['Uncommitted changes', `_${l.previousSha}_`];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,16 +222,19 @@ export class BlameAnnotationProvider extends Disposable {
|
|||||||
if (this._config.annotation.date) {
|
if (this._config.annotation.date) {
|
||||||
if (width > 0) {
|
if (width > 0) {
|
||||||
width += 7;
|
width += 7;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
width += 6;
|
width += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this._config.annotation.author) {
|
if (this._config.annotation.author) {
|
||||||
if (width > 5 + 6) {
|
if (width > 5 + 6) {
|
||||||
width += 12;
|
width += 12;
|
||||||
} else if (width > 0) {
|
}
|
||||||
|
else if (width > 0) {
|
||||||
width += 11;
|
width += 11;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
width += 10;
|
width += 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,7 +250,8 @@ export class BlameAnnotationProvider extends Disposable {
|
|||||||
let previous = blame.commits.get(commit.previousSha);
|
let previous = blame.commits.get(commit.previousSha);
|
||||||
if (previous) {
|
if (previous) {
|
||||||
hoverMessage = ['Uncommitted changes', `_${previous.sha}_ - ${previous.message}`, `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MMa')}`];
|
hoverMessage = ['Uncommitted changes', `_${previous.sha}_ - ${previous.message}`, `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MMa')}`];
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
hoverMessage = ['Uncommitted changes', `_${l.previousSha}_`];
|
hoverMessage = ['Uncommitted changes', `_${l.previousSha}_`];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,9 +284,11 @@ export class BlameAnnotationProvider extends Disposable {
|
|||||||
const date = this._getDate(commit);
|
const date = this._getDate(commit);
|
||||||
if (this._config.annotation.sha) {
|
if (this._config.annotation.sha) {
|
||||||
return `${commit.sha.substring(0, 8)}${(date ? `\\00a0\\2022\\00a0 ${date}` : '')}${(author ? `\\00a0\\2022\\00a0 ${author}` : '')}`;
|
return `${commit.sha.substring(0, 8)}${(date ? `\\00a0\\2022\\00a0 ${date}` : '')}${(author ? `\\00a0\\2022\\00a0 ${author}` : '')}`;
|
||||||
} else if (this._config.annotation.date) {
|
}
|
||||||
|
else if (this._config.annotation.date) {
|
||||||
return `${date}${(author ? `\\00a0\\2022\\00a0 ${author}` : '')}`;
|
return `${date}${(author ? `\\00a0\\2022\\00a0 ${author}` : '')}`;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ export default class BlameStatusBarController extends Disposable {
|
|||||||
subscriptions.push(window.onDidChangeTextEditorSelection(this._onActiveSelectionChanged, this));
|
subscriptions.push(window.onDidChangeTextEditorSelection(this._onActiveSelectionChanged, this));
|
||||||
|
|
||||||
this._statusBarDisposable = Disposable.from(...subscriptions);
|
this._statusBarDisposable = Disposable.from(...subscriptions);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this._statusBarDisposable = undefined;
|
this._statusBarDisposable = undefined;
|
||||||
this._statusBarItem = undefined;
|
this._statusBarItem = undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ async function gitCommand(cwd: string, ...args: any[]) {
|
|||||||
const msg = ex && ex.toString();
|
const msg = ex && ex.toString();
|
||||||
if (msg && (msg.includes('Not a git repository') || msg.includes('is outside repository') || msg.includes('no such path'))) {
|
if (msg && (msg.includes('Not a git repository') || msg.includes('is outside repository') || msg.includes('no such path'))) {
|
||||||
Logger.warn('git', ...args, ` cwd='${cwd}'`, msg && `\n ${msg.replace(/\r?\n|\r/g, ' ')}`);
|
Logger.warn('git', ...args, ` cwd='${cwd}'`, msg && `\n ${msg.replace(/\r?\n|\r/g, ' ')}`);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Logger.error('git', ...args, ` cwd='${cwd}'`, msg && `\n ${msg.replace(/\r?\n|\r/g, ' ')}`);
|
Logger.error('git', ...args, ` cwd='${cwd}'`, msg && `\n ${msg.replace(/\r?\n|\r/g, ' ')}`);
|
||||||
}
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
@@ -47,11 +48,9 @@ export default class Git {
|
|||||||
// Logger.error(`Git.splitPath(${fileName}) is not an absolute path!`);
|
// Logger.error(`Git.splitPath(${fileName}) is not an absolute path!`);
|
||||||
// debugger;
|
// debugger;
|
||||||
// }
|
// }
|
||||||
if (repoPath) {
|
if (repoPath) return [fileName.replace(`${repoPath}/`, ''), repoPath];
|
||||||
return [fileName.replace(`${repoPath}/`, ''), repoPath];
|
|
||||||
} else {
|
return [path.basename(fileName).replace(/\\/g, '/'), path.dirname(fileName).replace(/\\/g, '/')];
|
||||||
return [path.basename(fileName).replace(/\\/g, '/'), path.dirname(fileName).replace(/\\/g, '/')];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async repoPath(cwd: string, gitPath?: string) {
|
static async repoPath(cwd: string, gitPath?: string) {
|
||||||
|
|||||||
@@ -127,9 +127,7 @@ export default class GitCodeLensProvider implements CodeLensProvider {
|
|||||||
|
|
||||||
const line = document.lineAt(symbol.location.range.start);
|
const line = document.lineAt(symbol.location.range.start);
|
||||||
// Make sure there is only 1 lense per line
|
// Make sure there is only 1 lense per line
|
||||||
if (lenses.length && lenses[lenses.length - 1].range.start.line === line.lineNumber) {
|
if (lenses.length && lenses[lenses.length - 1].range.start.line === line.lineNumber) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let startChar = -1;
|
let startChar = -1;
|
||||||
try {
|
try {
|
||||||
@@ -138,7 +136,8 @@ export default class GitCodeLensProvider implements CodeLensProvider {
|
|||||||
catch (ex) { }
|
catch (ex) { }
|
||||||
if (startChar === -1) {
|
if (startChar === -1) {
|
||||||
startChar = line.firstNonWhitespaceCharacterIndex;
|
startChar = line.firstNonWhitespaceCharacterIndex;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
startChar += Math.floor(symbol.name.length / 2);
|
startChar += Math.floor(symbol.name.length / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'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, ExtensionContext, languages, Location, Position, Range, TextDocument, TextEditor, Uri, workspace } from 'vscode';
|
||||||
import { CodeLensVisibility, IConfig } from './configuration';
|
import { CodeLensVisibility, IConfig } from './configuration';
|
||||||
import { DocumentSchemes, WorkspaceState } from './constants';
|
import { DocumentSchemes, WorkspaceState } from './constants';
|
||||||
import Git, { GitBlameParserEnricher, GitBlameFormat, GitCommit, GitLogParserEnricher, IGitAuthor, IGitBlame, IGitBlameLine, IGitBlameLines, IGitLog } from './git/git';
|
import Git, { GitBlameParserEnricher, GitBlameFormat, GitCommit, GitLogParserEnricher, IGitAuthor, IGitBlame, IGitBlameLine, IGitBlameLines, IGitLog } from './git/git';
|
||||||
@@ -45,7 +45,6 @@ export default class GitProvider extends Disposable {
|
|||||||
private _config: IConfig;
|
private _config: IConfig;
|
||||||
private _disposable: Disposable;
|
private _disposable: Disposable;
|
||||||
private _codeLensProviderDisposable: Disposable | undefined;
|
private _codeLensProviderDisposable: Disposable | undefined;
|
||||||
private _codeLensProviderSelector: DocumentFilter;
|
|
||||||
private _gitignore: Promise<ignore.Ignore>;
|
private _gitignore: Promise<ignore.Ignore>;
|
||||||
|
|
||||||
static EmptyPromise: Promise<IGitBlame | IGitLog> = Promise.resolve(undefined);
|
static EmptyPromise: Promise<IGitBlame | IGitLog> = Promise.resolve(undefined);
|
||||||
@@ -103,9 +102,9 @@ export default class GitProvider extends Disposable {
|
|||||||
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
||||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||||
if (config.codeLens.visibility === CodeLensVisibility.Auto && (config.codeLens.recentChange.enabled || config.codeLens.authors.enabled)) {
|
if (config.codeLens.visibility === CodeLensVisibility.Auto && (config.codeLens.recentChange.enabled || config.codeLens.authors.enabled)) {
|
||||||
this._codeLensProviderSelector = GitCodeLensProvider.selector;
|
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, new GitCodeLensProvider(this.context, this));
|
||||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(this._codeLensProviderSelector, new GitCodeLensProvider(this.context, this));
|
}
|
||||||
} else {
|
else {
|
||||||
this._codeLensProviderDisposable = undefined;
|
this._codeLensProviderDisposable = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +124,8 @@ export default class GitProvider extends Disposable {
|
|||||||
disposables.push(workspace.onDidChangeTextDocument(e => removeCachedEntryFn(e.document, RemoveCacheReason.DocumentChanged)));
|
disposables.push(workspace.onDidChangeTextDocument(e => removeCachedEntryFn(e.document, RemoveCacheReason.DocumentChanged)));
|
||||||
|
|
||||||
this._cacheDisposable = Disposable.from(...disposables);
|
this._cacheDisposable = Disposable.from(...disposables);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this._cacheDisposable && this._cacheDisposable.dispose();
|
this._cacheDisposable && this._cacheDisposable.dispose();
|
||||||
this._cacheDisposable = undefined;
|
this._cacheDisposable = undefined;
|
||||||
this._cache && this._cache.clear();
|
this._cache && this._cache.clear();
|
||||||
@@ -437,34 +437,18 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleCodeLens(editor: TextEditor) {
|
toggleCodeLens(editor: TextEditor) {
|
||||||
Logger.log(`toggleCodeLens(${editor})`);
|
|
||||||
|
|
||||||
if (this._config.codeLens.visibility !== CodeLensVisibility.OnDemand ||
|
if (this._config.codeLens.visibility !== CodeLensVisibility.OnDemand ||
|
||||||
(!this._config.codeLens.recentChange.enabled && !this._config.codeLens.authors.enabled)) return;
|
(!this._config.codeLens.recentChange.enabled && !this._config.codeLens.authors.enabled)) return;
|
||||||
|
|
||||||
|
Logger.log(`toggleCodeLens(${editor})`);
|
||||||
|
|
||||||
if (this._codeLensProviderDisposable) {
|
if (this._codeLensProviderDisposable) {
|
||||||
this._codeLensProviderDisposable.dispose();
|
this._codeLensProviderDisposable.dispose();
|
||||||
|
this._codeLensProviderDisposable = undefined;
|
||||||
if (editor.document.fileName === (this._codeLensProviderSelector && this._codeLensProviderSelector.pattern)) {
|
return;
|
||||||
this._codeLensProviderDisposable = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const disposables: Disposable[] = [];
|
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, new GitCodeLensProvider(this.context, this));
|
||||||
|
|
||||||
this._codeLensProviderSelector = <DocumentFilter>{ scheme: DocumentSchemes.File, pattern: editor.document.fileName };
|
|
||||||
|
|
||||||
disposables.push(languages.registerCodeLensProvider(this._codeLensProviderSelector, new GitCodeLensProvider(this.context, this)));
|
|
||||||
|
|
||||||
disposables.push(window.onDidChangeActiveTextEditor(e => {
|
|
||||||
if (e.viewColumn && e.document !== editor.document) {
|
|
||||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
|
||||||
this._codeLensProviderDisposable = undefined;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._codeLensProviderDisposable = Disposable.from(...disposables);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static isUncommitted(sha: string) {
|
static isUncommitted(sha: string) {
|
||||||
|
|||||||
@@ -21,9 +21,6 @@
|
|||||||
"no-unsafe-finally": true,
|
"no-unsafe-finally": true,
|
||||||
"no-unused-expression": false,
|
"no-unused-expression": false,
|
||||||
"no-unused-new": true,
|
"no-unused-new": true,
|
||||||
"no-unused-variable": [
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"no-var-keyword": true,
|
"no-var-keyword": true,
|
||||||
"no-var-requires": false,
|
"no-var-requires": false,
|
||||||
"object-literal-key-quotes": [
|
"object-literal-key-quotes": [
|
||||||
|
|||||||
Reference in New Issue
Block a user