diff --git a/images/dark/git-icon-orange.svg b/images/dark/git-icon-orange.svg
new file mode 100644
index 0000000..9b16645
--- /dev/null
+++ b/images/dark/git-icon-orange.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/images/dark/git-icon-progress.svg b/images/dark/git-icon-progress.svg
new file mode 100644
index 0000000..c1e501d
--- /dev/null
+++ b/images/dark/git-icon-progress.svg
@@ -0,0 +1,12 @@
+
+
diff --git a/images/light/git-icon-orange.svg b/images/light/git-icon-orange.svg
new file mode 100644
index 0000000..9b16645
--- /dev/null
+++ b/images/light/git-icon-orange.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/images/light/git-icon-progress.svg b/images/light/git-icon-progress.svg
new file mode 100644
index 0000000..d79bf7b
--- /dev/null
+++ b/images/light/git-icon-progress.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/package.json b/package.json
index b038dc5..292fcdd 100644
--- a/package.json
+++ b/package.json
@@ -819,6 +819,24 @@
}
},
{
+ "command": "gitlens.clearFileAnnotations",
+ "title": "Clear File Annotations",
+ "category": "GitLens",
+ "icon": {
+ "dark": "images/dark/git-icon-orange.svg",
+ "light": "images/light/git-icon-orange.svg"
+ }
+ },
+ {
+ "command": "gitlens.computingFileAnnotations",
+ "title": "Computing File Annotations...",
+ "category": "GitLens",
+ "icon": {
+ "dark": "images/dark/git-icon-progress.svg",
+ "light": "images/light/git-icon-progress.svg"
+ }
+ },
+ {
"command": "gitlens.toggleFileRecentChanges",
"title": "Toggle Recent File Changes Annotations",
"category": "GitLens",
@@ -1047,6 +1065,14 @@
"when": "gitlens:isBlameable"
},
{
+ "command": "gitlens.clearFileAnnotations",
+ "when": "gitlens:annotationStatus == computed"
+ },
+ {
+ "command": "gitlens.computingFileAnnotations",
+ "when": "false"
+ },
+ {
"command": "gitlens.toggleFileRecentChanges",
"when": "gitlens:isTracked"
},
@@ -1227,7 +1253,17 @@
{
"command": "gitlens.toggleFileBlame",
"alt": "gitlens.toggleFileRecentChanges",
- "when": "gitlens:isBlameable && config.gitlens.advanced.menus.editorTitle.blame",
+ "when": "gitlens:isBlameable && !gitlens:annotationStatus && config.gitlens.advanced.menus.editorTitle.blame",
+ "group": "navigation@100"
+ },
+ {
+ "command": "gitlens.computingFileAnnotations",
+ "when": "gitlens:annotationStatus == computing && config.gitlens.advanced.menus.editorTitle.blame",
+ "group": "navigation@100"
+ },
+ {
+ "command": "gitlens.clearFileAnnotations",
+ "when": "gitlens:annotationStatus == computed && config.gitlens.advanced.menus.editorTitle.blame",
"group": "navigation@100"
},
{
diff --git a/src/annotations/annotationController.ts b/src/annotations/annotationController.ts
index b5d98b7..885a94d 100644
--- a/src/annotations/annotationController.ts
+++ b/src/annotations/annotationController.ts
@@ -5,6 +5,7 @@ import { AnnotationProviderBase } from './annotationProvider';
import { Keyboard, KeyboardScope, KeyCommand, Keys } from '../keyboard';
import { TextDocumentComparer, TextEditorComparer } from '../comparers';
import { ExtensionKey, IConfig, LineHighlightLocations, themeDefaults } from '../configuration';
+import { CommandContext, setCommandContext } from '../constants';
import { BlameabilityChangeEvent, GitContextTracker, GitService, GitUri } from '../gitService';
import { GutterBlameAnnotationProvider } from './gutterBlameAnnotationProvider';
import { HoverBlameAnnotationProvider } from './hoverBlameAnnotationProvider';
@@ -203,6 +204,8 @@ export class AnnotationController extends Disposable {
if (this._annotationProviders.size === 0) {
Logger.log(`Remove listener registrations for annotations`);
+ await setCommandContext(CommandContext.AnnotationStatus, undefined);
+
this._keyboardScope && this._keyboardScope.dispose();
this._keyboardScope = undefined;
@@ -235,7 +238,16 @@ export class AnnotationController extends Disposable {
return true;
}
- return window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{message: string}>) => this._showAnnotationsCore(currentProvider, editor, type, shaOrLine, progress));
+ return window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => {
+ await setCommandContext(CommandContext.AnnotationStatus, 'computing');
+
+ const computingAnnotations = this._showAnnotationsCore(currentProvider, editor, type, shaOrLine, progress);
+ const result = await computingAnnotations;
+
+ await setCommandContext(CommandContext.AnnotationStatus, result ? 'computed' : undefined);
+
+ return computingAnnotations;
+ });
}
private async _showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string}>): Promise {
@@ -311,11 +323,12 @@ export class AnnotationController extends Disposable {
this._onDidToggleAnnotations.fire();
return true;
}
+
return false;
}
async toggleAnnotations(editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number): Promise {
- if (!editor || !editor.document || type === FileAnnotationType.RecentChanges ? !this.git.isTrackable(editor.document.uri) : !this.git.isEditorBlameable(editor)) return false;
+ if (!editor || !editor.document || (type === FileAnnotationType.RecentChanges ? !this.git.isTrackable(editor.document.uri) : !this.git.isEditorBlameable(editor))) return false;
const provider = this._annotationProviders.get(editor.viewColumn || -1);
if (provider === undefined) return this.showAnnotations(editor, type, shaOrLine);
diff --git a/src/annotations/annotationProvider.ts b/src/annotations/annotationProvider.ts
index 0a8be81..430e672 100644
--- a/src/annotations/annotationProvider.ts
+++ b/src/annotations/annotationProvider.ts
@@ -1,5 +1,5 @@
'use strict';
-import { Functions } from '../system';
+// import { Functions } from '../system';
import { Disposable, ExtensionContext, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, window, workspace } from 'vscode';
import { FileAnnotationType } from '../annotations/annotationController';
import { TextDocumentComparer } from '../comparers';
@@ -43,19 +43,12 @@ import { WhitespaceController } from './whitespaceController';
async clear() {
if (this.editor !== undefined) {
try {
- if (this.decoration !== undefined) {
- this.editor.setDecorations(this.decoration, []);
- }
-
if (this.highlightDecoration !== undefined) {
this.editor.setDecorations(this.highlightDecoration, []);
+ }
- // I have no idea why the decorators sometimes don't get removed, but if they don't try again with a tiny delay
- await Functions.wait(1);
-
- if (this.highlightDecoration === undefined) return;
-
- this.editor.setDecorations(this.highlightDecoration, []);
+ if (this.decoration !== undefined) {
+ this.editor.setDecorations(this.decoration, []);
}
}
catch (ex) { }
diff --git a/src/commands.ts b/src/commands.ts
index b46c171..6e2919f 100644
--- a/src/commands.ts
+++ b/src/commands.ts
@@ -1,6 +1,7 @@
'use strict';
export * from './commands/common';
+export * from './commands/clearFileAnnotations';
export * from './commands/closeUnchangedFiles';
export * from './commands/copyMessageToClipboard';
export * from './commands/copyShaToClipboard';
diff --git a/src/commands/clearFileAnnotations.ts b/src/commands/clearFileAnnotations.ts
new file mode 100644
index 0000000..58b93f4
--- /dev/null
+++ b/src/commands/clearFileAnnotations.ts
@@ -0,0 +1,24 @@
+'use strict';
+import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
+import { AnnotationController } from '../annotations/annotationController';
+import { Commands, EditorCommand } from './common';
+import { Logger } from '../logger';
+
+export class ClearFileAnnotationsCommand extends EditorCommand {
+
+ constructor(private annotationController: AnnotationController) {
+ super(Commands.ClearFileAnnotations);
+ }
+
+ async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise {
+ if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
+
+ try {
+ return this.annotationController.clear(editor.viewColumn || -1);
+ }
+ catch (ex) {
+ Logger.error(ex, 'ClearFileAnnotationsCommand');
+ return window.showErrorMessage(`Unable to clear file annotations. See output channel for more details`);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/commands/common.ts b/src/commands/common.ts
index 3e497ab..5b0a95a 100644
--- a/src/commands/common.ts
+++ b/src/commands/common.ts
@@ -4,7 +4,9 @@ import { ExplorerNode } from '../views/explorerNodes';
import { Logger } from '../logger';
import { Telemetry } from '../telemetry';
-export type Commands = 'gitlens.closeUnchangedFiles' |
+export type Commands =
+ 'gitlens.clearFileAnnotations' |
+ 'gitlens.closeUnchangedFiles' |
'gitlens.copyMessageToClipboard' |
'gitlens.copyShaToClipboard' |
'gitlens.diffDirectory' |
@@ -43,6 +45,7 @@ export type Commands = 'gitlens.closeUnchangedFiles' |
'gitlens.toggleFileRecentChanges' |
'gitlens.toggleLineBlame';
export const Commands = {
+ ClearFileAnnotations: 'gitlens.clearFileAnnotations' as Commands,
CloseUnchangedFiles: 'gitlens.closeUnchangedFiles' as Commands,
CopyMessageToClipboard: 'gitlens.copyMessageToClipboard' as Commands,
CopyShaToClipboard: 'gitlens.copyShaToClipboard' as Commands,
diff --git a/src/commands/showFileBlame.ts b/src/commands/showFileBlame.ts
index 7029afc..9231f98 100644
--- a/src/commands/showFileBlame.ts
+++ b/src/commands/showFileBlame.ts
@@ -17,7 +17,7 @@ export class ShowFileBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ShowFileBlameCommandArgs = {}): Promise {
- if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
+ if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
diff --git a/src/commands/showLineBlame.ts b/src/commands/showLineBlame.ts
index 5adc408..8ef5402 100644
--- a/src/commands/showLineBlame.ts
+++ b/src/commands/showLineBlame.ts
@@ -16,7 +16,7 @@ export class ShowLineBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ShowLineBlameCommandArgs = {}): Promise {
- if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
+ if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
diff --git a/src/commands/toggleFileBlame.ts b/src/commands/toggleFileBlame.ts
index f3898dd..e9e1d98 100644
--- a/src/commands/toggleFileBlame.ts
+++ b/src/commands/toggleFileBlame.ts
@@ -17,7 +17,7 @@ export class ToggleFileBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ToggleFileBlameCommandArgs = {}): Promise {
- if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
+ if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
diff --git a/src/commands/toggleFileRecentChanges.ts b/src/commands/toggleFileRecentChanges.ts
index d744f55..8b901b3 100644
--- a/src/commands/toggleFileRecentChanges.ts
+++ b/src/commands/toggleFileRecentChanges.ts
@@ -11,7 +11,7 @@ export class ToggleFileRecentChangesCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise {
- if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
+ if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
return this.annotationController.toggleAnnotations(editor, FileAnnotationType.RecentChanges);
diff --git a/src/commands/toggleLineBlame.ts b/src/commands/toggleLineBlame.ts
index 049d7dc..6ca04bf 100644
--- a/src/commands/toggleLineBlame.ts
+++ b/src/commands/toggleLineBlame.ts
@@ -16,7 +16,7 @@ export class ToggleLineBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ToggleLineBlameCommandArgs = {}): Promise {
- if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
+ if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
diff --git a/src/constants.ts b/src/constants.ts
index 8cbdb77..83690f5 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -39,13 +39,15 @@ export const BuiltInCommands = {
ToggleRenderWhitespace: 'editor.action.toggleRenderWhitespace' as BuiltInCommands
};
-export type CommandContext = 'gitlens:canToggleCodeLens' |
+export type CommandContext =
+ 'gitlens:canToggleCodeLens' |
'gitlens:enabled' |
'gitlens:hasRemotes' |
'gitlens:isBlameable' |
'gitlens:isRepository' |
'gitlens:isTracked' |
- 'gitlens:key';
+ 'gitlens:key' |
+ 'gitlens:annotationStatus';
export const CommandContext = {
CanToggleCodeLens: 'gitlens:canToggleCodeLens' as CommandContext,
Enabled: 'gitlens:enabled' as CommandContext,
@@ -53,7 +55,8 @@ export const CommandContext = {
IsBlameable: 'gitlens:isBlameable' as CommandContext,
IsRepository: 'gitlens:isRepository' as CommandContext,
IsTracked: 'gitlens:isTracked' as CommandContext,
- Key: 'gitlens:key' as CommandContext
+ Key: 'gitlens:key' as CommandContext,
+ AnnotationStatus: 'gitlens:annotationStatus' as CommandContext
};
export function setCommandContext(key: CommandContext | string, value: any) {
diff --git a/src/extension.ts b/src/extension.ts
index e2c1a9e..33a963b 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -1,13 +1,13 @@
'use strict';
// import { Objects } from './system';
-import { ExtensionContext, extensions, languages, window, workspace } from 'vscode';
+import { commands, ExtensionContext, extensions, languages, window, workspace } from 'vscode';
import { AnnotationController } from './annotations/annotationController';
import { CloseUnchangedFilesCommand, OpenChangedFilesCommand } from './commands';
import { OpenBranchInRemoteCommand, OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenInRemoteCommand, OpenRepoInRemoteCommand } from './commands';
import { CopyMessageToClipboardCommand, CopyShaToClipboardCommand } from './commands';
import { DiffDirectoryCommand, DiffLineWithPreviousCommand, DiffLineWithWorkingCommand, DiffWithBranchCommand, DiffWithNextCommand, DiffWithPreviousCommand, DiffWithRevisionCommand, DiffWithWorkingCommand } from './commands';
import { ResetSuppressedWarningsCommand } from './commands';
-import { ShowFileBlameCommand, ShowLineBlameCommand, ToggleFileBlameCommand, ToggleFileRecentChangesCommand, ToggleLineBlameCommand } from './commands';
+import { ClearFileAnnotationsCommand, ShowFileBlameCommand, ShowLineBlameCommand, ToggleFileBlameCommand, ToggleFileRecentChangesCommand, ToggleLineBlameCommand } from './commands';
import { ShowBlameHistoryCommand, ShowFileHistoryCommand } from './commands';
import { ShowLastQuickPickCommand } from './commands';
import { ShowQuickBranchHistoryCommand, ShowQuickCurrentBranchHistoryCommand, ShowQuickFileHistoryCommand } from './commands';
@@ -94,6 +94,8 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(window.registerTreeDataProvider('gitlens.stashExplorer', new StashExplorer(context, git)));
+ context.subscriptions.push(commands.registerTextEditorCommand('gitlens.computingFileAnnotations', () => { }));
+
context.subscriptions.push(new CloseUnchangedFilesCommand(git));
context.subscriptions.push(new OpenChangedFilesCommand(git));
context.subscriptions.push(new CopyMessageToClipboardCommand(git));
@@ -111,6 +113,7 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new OpenFileInRemoteCommand(git));
context.subscriptions.push(new OpenInRemoteCommand());
context.subscriptions.push(new OpenRepoInRemoteCommand(git));
+ context.subscriptions.push(new ClearFileAnnotationsCommand(annotationController));
context.subscriptions.push(new ShowFileBlameCommand(annotationController));
context.subscriptions.push(new ShowLineBlameCommand(currentLineController));
context.subscriptions.push(new ToggleFileBlameCommand(annotationController));