Ver código fonte

Adds highlight changes cmd to status bar/code lens

Fixes issues with editor.id no longer being available
main
Eric Amodio 3 anos atrás
pai
commit
08aed2116e
21 arquivos alterados com 370 adições e 113 exclusões
  1. +12
    -2
      CHANGELOG.md
  2. +47
    -7
      package.json
  3. +24
    -16
      src/annotations/annotationProvider.ts
  4. +7
    -2
      src/annotations/blameAnnotationProvider.ts
  5. +42
    -29
      src/annotations/fileAnnotationController.ts
  6. +17
    -10
      src/annotations/gutterBlameAnnotationProvider.ts
  7. +53
    -13
      src/annotations/gutterChangesAnnotationProvider.ts
  8. +11
    -4
      src/annotations/gutterHeatmapBlameAnnotationProvider.ts
  9. +45
    -0
      src/codelens/codeLensProvider.ts
  10. +1
    -1
      src/commands/closeUnchangedFiles.ts
  11. +1
    -0
      src/commands/common.ts
  12. +1
    -1
      src/commands/gitCommands.actions.ts
  13. +1
    -1
      src/commands/openWorkingFile.ts
  14. +35
    -13
      src/commands/toggleFileAnnotations.ts
  15. +1
    -7
      src/comparers.ts
  16. +6
    -0
      src/config.ts
  17. +8
    -1
      src/container.ts
  18. +31
    -2
      src/statusbar/statusBarController.ts
  19. +6
    -4
      src/views/viewCommands.ts
  20. +14
    -0
      src/webviews/apps/settings/partials/code-lens.html
  21. +7
    -0
      src/webviews/apps/settings/partials/status-bar.html

+ 12
- 2
CHANGELOG.md Ver arquivo

@ -9,8 +9,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Added
- Adds a new _Open Blame Prior to Change_ command (`gitlens.openBlamePriorToChange`) to open the blame of prior revision of the selected line in the current file — closes [#1014](https://github.com/eamodio/vscode-gitlens/issues/1014)
- Adds new Git code lens action options, _Opens the commit on the remote service (when available)_, _Copies the remote commit url to the clipboard (when available)_, _Opens the file revision on the remote service (when available)_, and _Copies the remote file revision url to the clipboard (when available)_
- Adds new status bar blame action options, _Opens the commit on the remote service (when available)_, _Copies the remote commit url to the clipboard (when available)_, _Opens the file revision on the remote service (when available)_, and _Copies the remote file revision url to the clipboard (when available)_ — closes [#1378](https://github.com/eamodio/vscode-gitlens/issues/1378)
- Adds new Git code lens action options
- _Opens the commit on the remote service (when available)_ and _Copies the remote commit url to the clipboard (when available)_
- _Opens the file revision on the remote service (when available)_ and _Copies the remote file revision url to the clipboard (when available)_
- _Toggles the file heatmap_
- _Toggles the file changes since before the commit_
- _Toggles the file changes from the commit_
- Adds new status bar blame action options
- _Opens the commit on the remote service (when available)_ and _Copies the remote commit url to the clipboard (when available)_ — closes [#1378](https://github.com/eamodio/vscode-gitlens/issues/1378)
- _Opens the file revision on the remote service (when available)_ and _Copies the remote file revision url to the clipboard (when available)_
- _Toggles the file heatmap_
- _Toggles the file changes since before the commit_
- _Toggles the file changes from the commit_
### Changed

+ 47
- 7
package.json Ver arquivo

@ -115,6 +115,7 @@
"onCommand:gitlens.toggleFileHeatmapInDiffLeft",
"onCommand:gitlens.toggleFileHeatmapInDiffRight",
"onCommand:gitlens.toggleFileChanges",
"onCommand:gitlens.toggleFileChangesOnly",
"onCommand:gitlens.toggleLineBlame",
"onCommand:gitlens.toggleCodeLens",
"onCommand:gitlens.gitCommands",
@ -393,6 +394,9 @@
"type": "string",
"enum": [
"gitlens.toggleFileBlame",
"gitlens.toggleFileHeatmap",
"gitlens.toggleFileChanges",
"gitlens.toggleFileChangesOnly",
"gitlens.diffWithPrevious",
"gitlens.revealCommitInView",
"gitlens.showCommitsInView",
@ -407,6 +411,9 @@
],
"enumDescriptions": [
"Toggles file blame",
"Toggles file heatmap",
"Toggles file changes since before the commit",
"Toggles file changes from the commit",
"Compares the current committed file with the previous commit",
"Reveals the commit in the Side Bar",
"Searches for commits within the range",
@ -454,23 +461,37 @@
"type": "string",
"enum": [
"gitlens.toggleFileBlame",
"gitlens.toggleFileHeatmap",
"gitlens.toggleFileChanges",
"gitlens.toggleFileChangesOnly",
"gitlens.diffWithPrevious",
"gitlens.revealCommitInView",
"gitlens.showCommitsInView",
"gitlens.showQuickCommitDetails",
"gitlens.showQuickCommitFileDetails",
"gitlens.showQuickFileHistory",
"gitlens.showQuickRepoHistory"
"gitlens.showQuickRepoHistory",
"gitlens.openCommitOnRemote",
"gitlens.copyRemoteCommitUrl",
"gitlens.openFileOnRemote",
"gitlens.copyRemoteFileUrl"
],
"enumDescriptions": [
"Toggles file blame",
"Toggles file heatmap",
"Toggles file changes since before the commit",
"Toggles file changes from the commit",
"Compares the current committed file with the previous commit",
"Reveals the commit in the Side Bar",
"Searches for the commit",
"Shows a commit details quick pick",
"Shows a commit file details quick pick",
"Shows a file history quick pick",
"Shows a branch history quick pick"
"Shows a commit details quick pick menu",
"Shows a commit file details quick pick menu",
"Shows a file history quick pick menu",
"Shows a branch history quick pick menu",
"Opens the commit on the remote service (when available)",
"Copies the remote commit url to the clipboard (when available)",
"Opens the file revision on the remote service (when available)",
"Copies the remote file url to the clipboard (when available)"
]
}
],
@ -1608,6 +1629,9 @@
"default": "gitlens.showQuickCommitDetails",
"enum": [
"gitlens.toggleFileBlame",
"gitlens.toggleFileHeatmap",
"gitlens.toggleFileChanges",
"gitlens.toggleFileChangesOnly",
"gitlens.toggleCodeLens",
"gitlens.diffWithPrevious",
"gitlens.diffWithWorking",
@ -1624,6 +1648,9 @@
],
"enumDescriptions": [
"Toggles file blame",
"Toggles file heatmap",
"Toggles file changes since before the commit",
"Toggles file changes from the commit",
"Toggles Git code lens",
"Compares the current line commit with the previous",
"Compares the current line commit with the working tree",
@ -3161,6 +3188,15 @@
}
},
{
"command": "gitlens.toggleFileChangesOnly",
"title": "Toggle File Changes",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-git.svg",
"light": "images/light/icon-git.svg"
}
},
{
"command": "gitlens.toggleLineBlame",
"title": "Toggle Line Blame",
"category": "GitLens"
@ -3697,12 +3733,12 @@
},
{
"command": "gitlens.views.highlightChanges",
"title": "Highlight Changes",
"title": "Highlight All Changes Since Before this Commit",
"category": "GitLens"
},
{
"command": "gitlens.views.highlightRevisionChanges",
"title": "Highlight Revision Changes",
"title": "Highlight Changes from this Commit",
"category": "GitLens"
},
{
@ -5077,6 +5113,10 @@
"when": "gitlens:activeFileStatus =~ /blameable/"
},
{
"command": "gitlens.toggleFileChangesOnly",
"when": "false"
},
{
"command": "gitlens.toggleLineBlame",
"when": "!gitlens:disabled"
},

+ 24
- 16
src/annotations/annotationProvider.ts Ver arquivo

@ -20,14 +20,19 @@ export enum AnnotationStatus {
Computed = 'computed',
}
export interface AnnotationContext {
selection?: { sha?: string; line?: undefined } | { sha?: undefined; line?: number } | false;
}
export type TextEditorCorrelationKey = string;
export abstract class AnnotationProviderBase implements Disposable {
export abstract class AnnotationProviderBase<TContext extends AnnotationContext = AnnotationContext>
implements Disposable {
static getCorrelationKey(editor: TextEditor | undefined): TextEditorCorrelationKey {
return editor != null ? (editor as any).id : '';
return `${editor?.document.uri.toString()}|${editor?.viewColumn}`;
}
annotationType: FileAnnotationType | undefined;
annotationContext: TContext | undefined;
correlationKey: TextEditorCorrelationKey;
document: TextDocument;
status: AnnotationStatus | undefined;
@ -37,7 +42,11 @@ export abstract class AnnotationProviderBase implements Disposable {
| undefined;
protected disposable: Disposable;
constructor(public editor: TextEditor, protected readonly trackedDocument: TrackedDocument<GitDocumentState>) {
constructor(
public readonly annotationType: FileAnnotationType,
public editor: TextEditor,
protected readonly trackedDocument: TrackedDocument<GitDocumentState>,
) {
this.correlationKey = AnnotationProviderBase.getCorrelationKey(this.editor);
this.document = this.editor.document;
@ -55,20 +64,15 @@ export abstract class AnnotationProviderBase implements Disposable {
private onTextEditorSelectionChanged(e: TextEditorSelectionChangeEvent) {
if (this.document !== e.textEditor.document) return;
void this.selection(e.selections[0].active.line);
}
get editorId(): string {
if (this.editor?.document == null) return '';
return (this.editor as any).id;
void this.selection({ line: e.selections[0].active.line });
}
get editorUri(): Uri | undefined {
if (this.editor?.document == null) return undefined;
return this.editor.document.uri;
return this.editor?.document?.uri;
}
clear() {
this.annotationContext = undefined;
this.status = undefined;
if (this.editor == null) return;
@ -83,6 +87,10 @@ export abstract class AnnotationProviderBase implements Disposable {
}
}
mustReopen(_context?: TContext): boolean {
return false;
}
async restore(editor: TextEditor) {
// If the editor isn't disposed then we don't need to do anything
// Explicitly check for `false`
@ -109,10 +117,10 @@ export abstract class AnnotationProviderBase implements Disposable {
}
}
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
async provideAnnotation(context?: TContext): Promise<boolean> {
this.status = AnnotationStatus.Computing;
try {
if (await this.onProvideAnnotation(shaOrLine)) {
if (await this.onProvideAnnotation(context)) {
this.status = AnnotationStatus.Computed;
return true;
}
@ -124,9 +132,9 @@ export abstract class AnnotationProviderBase implements Disposable {
return false;
}
protected abstract onProvideAnnotation(shaOrLine?: string | number): Promise<boolean>;
protected abstract onProvideAnnotation(context?: TContext): Promise<boolean>;
abstract selection(shaOrLine?: string | number): Promise<void>;
abstract selection(selection?: TContext['selection']): Promise<void>;
protected setDecorations(
decorations: { decorationType: TextEditorDecorationType; rangesOrOptions: Range[] | DecorationOptions[] }[],

+ 7
- 2
src/annotations/blameAnnotationProvider.ts Ver arquivo

@ -2,6 +2,7 @@
import { CancellationToken, Disposable, Hover, languages, Position, Range, TextDocument, TextEditor } from 'vscode';
import { AnnotationProviderBase } from './annotationProvider';
import { ComputedHeatmap, getHeatmapColors } from './annotations';
import { FileAnnotationType } from '../config';
import { Container } from '../container';
import { GitBlame, GitBlameCommit, GitCommit } from '../git/git';
import { GitUri } from '../git/gitUri';
@ -13,8 +14,12 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
protected blame: Promise<GitBlame | undefined>;
protected hoverProviderDisposable: Disposable | undefined;
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
super(editor, trackedDocument);
constructor(
annotationType: FileAnnotationType,
editor: TextEditor,
trackedDocument: TrackedDocument<GitDocumentState>,
) {
super(annotationType, editor, trackedDocument);
this.blame = editor.document.isDirty
? Container.git.getBlameForFileContents(this.trackedDocument.uri, editor.document.getText())

+ 42
- 29
src/annotations/fileAnnotationController.ts Ver arquivo

@ -18,7 +18,12 @@ import {
window,
workspace,
} from 'vscode';
import { AnnotationProviderBase, AnnotationStatus, TextEditorCorrelationKey } from './annotationProvider';
import {
AnnotationContext,
AnnotationProviderBase,
AnnotationStatus,
TextEditorCorrelationKey,
} from './annotationProvider';
import {
AnnotationsToggleMode,
BlameHighlightLocations,
@ -29,7 +34,7 @@ import {
import { Colors, ContextKeys, isTextEditor, setContext } from '../constants';
import { Container } from '../container';
import { GutterBlameAnnotationProvider } from './gutterBlameAnnotationProvider';
import { GutterChangesAnnotationProvider } from './gutterChangesAnnotationProvider';
import { ChangesAnnotationContext, GutterChangesAnnotationProvider } from './gutterChangesAnnotationProvider';
import { GutterHeatmapBlameAnnotationProvider } from './gutterHeatmapBlameAnnotationProvider';
import { KeyboardScope } from '../keyboard';
import { Logger } from '../logger';
@ -72,7 +77,7 @@ export class FileAnnotationController implements Disposable {
private _editor: TextEditor | undefined;
private _keyboardScope: KeyboardScope | undefined = undefined;
private readonly _toggleModes: Map<FileAnnotationType, AnnotationsToggleMode>;
private _annotationType: FileAnnotationType | undefined = undefined;
private _windowAnnotationType?: FileAnnotationType | undefined = undefined;
constructor() {
this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this));
@ -235,7 +240,7 @@ export class FileAnnotationController implements Disposable {
// Logger.log('AnnotationController.onActiveTextEditorChanged', editor && editor.document.uri.fsPath);
if (this.isInWindowToggle()) {
await this.show(editor, this._annotationType!);
await this.show(editor, this._windowAnnotationType!);
return;
}
@ -306,9 +311,8 @@ export class FileAnnotationController implements Disposable {
void provider.restore(e);
}
}
isInWindowToggle(): boolean {
return this.getToggleMode(this._annotationType) === AnnotationsToggleMode.Window;
return this.getToggleMode(this._windowAnnotationType) === AnnotationsToggleMode.Window;
}
private getToggleMode(annotationType: FileAnnotationType | undefined): AnnotationsToggleMode {
@ -326,7 +330,7 @@ export class FileAnnotationController implements Disposable {
}
async clearAll() {
this._annotationType = undefined;
this._windowAnnotationType = undefined;
for (const [key] of this._annotationProviders) {
await this.clearCore(key, AnnotationClearReason.Disposing);
}
@ -347,18 +351,22 @@ export class FileAnnotationController implements Disposable {
return this._annotationProviders.get(AnnotationProviderBase.getCorrelationKey(editor));
}
async show(editor: TextEditor | undefined, type: FileAnnotationType, context?: AnnotationContext): Promise<boolean>;
async show(
editor: TextEditor | undefined,
type: FileAnnotationType.Changes,
context?: ChangesAnnotationContext,
): Promise<boolean>;
async show(
editor: TextEditor | undefined,
type: FileAnnotationType,
shaOrLine?: string | number,
context?: AnnotationContext | ChangesAnnotationContext,
): Promise<boolean> {
if (this.getToggleMode(type) === AnnotationsToggleMode.Window) {
let first = this._annotationType == null;
const reset =
(!first && this._annotationType !== type) ||
(this._annotationType === FileAnnotationType.Changes && typeof shaOrLine === 'string');
let first = this._windowAnnotationType == null;
const reset = !first && this._windowAnnotationType !== type;
this._annotationType = type;
this._windowAnnotationType = type;
if (reset) {
await this.clearAll();
@ -382,8 +390,8 @@ export class FileAnnotationController implements Disposable {
const currentProvider = this.getProvider(editor);
if (currentProvider?.annotationType === type) {
await currentProvider.provideAnnotation(shaOrLine);
await currentProvider.selection(shaOrLine);
await currentProvider.provideAnnotation(context);
await currentProvider.selection(context?.selection);
return true;
}
@ -392,13 +400,7 @@ export class FileAnnotationController implements Disposable {
async (progress: Progress<{ message: string }>) => {
await setContext(ContextKeys.AnnotationStatus, AnnotationStatus.Computing);
const computingAnnotations = this.showAnnotationsCore(
currentProvider,
editor,
type,
shaOrLine,
progress,
);
const computingAnnotations = this.showAnnotationsCore(currentProvider, editor, type, context, progress);
const provider = await computingAnnotations;
if (editor === this._editor) {
@ -415,7 +417,19 @@ export class FileAnnotationController implements Disposable {
async toggle(
editor: TextEditor | undefined,
type: FileAnnotationType,
shaOrLine?: string | number,
context?: AnnotationContext,
on?: boolean,
): Promise<boolean>;
async toggle(
editor: TextEditor | undefined,
type: FileAnnotationType.Changes,
context?: ChangesAnnotationContext,
on?: boolean,
): Promise<boolean>;
async toggle(
editor: TextEditor | undefined,
type: FileAnnotationType,
context?: AnnotationContext | ChangesAnnotationContext,
on?: boolean,
): Promise<boolean> {
if (editor != null) {
@ -426,10 +440,9 @@ export class FileAnnotationController implements Disposable {
}
const provider = this.getProvider(editor);
if (provider == null) return this.show(editor, type, shaOrLine);
if (provider == null) return this.show(editor, type, context);
const reopen =
provider.annotationType !== type || (type === FileAnnotationType.Changes && typeof shaOrLine === 'string');
const reopen = provider.annotationType !== type || provider.mustReopen(context);
if (on === true && !reopen) return true;
if (this.isInWindowToggle()) {
@ -440,7 +453,7 @@ export class FileAnnotationController implements Disposable {
if (!reopen) return false;
return this.show(editor, type, shaOrLine);
return this.show(editor, type, context);
}
private async attachKeyboardHook() {
@ -495,7 +508,7 @@ export class FileAnnotationController implements Disposable {
currentProvider: AnnotationProviderBase | undefined,
editor: TextEditor,
type: FileAnnotationType,
shaOrLine?: string | number,
context?: AnnotationContext | ChangesAnnotationContext,
progress?: Progress<{ message: string }>,
): Promise<AnnotationProviderBase | undefined> {
if (progress != null) {
@ -558,7 +571,7 @@ export class FileAnnotationController implements Disposable {
}
this._annotationProviders.set(provider.correlationKey, provider);
if (await provider.provideAnnotation(shaOrLine)) {
if (await provider.provideAnnotation(context)) {
this._onDidToggleAnnotations.fire();
return provider;
}

+ 17
- 10
src/annotations/gutterBlameAnnotationProvider.ts Ver arquivo

@ -1,6 +1,7 @@
'use strict';
import { DecorationOptions, Range, ThemableDecorationAttachmentRenderOptions } from 'vscode';
import { DecorationOptions, Range, TextEditor, ThemableDecorationAttachmentRenderOptions } from 'vscode';
import { Annotations } from './annotations';
import { AnnotationContext } from './annotationProvider';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
import { FileAnnotationType, GravatarDefaultStyle } from '../configuration';
import { GlyphChars } from '../constants';
@ -9,8 +10,14 @@ import { Decorations } from './fileAnnotationController';
import { CommitFormatOptions, CommitFormatter, GitBlame, GitBlameCommit } from '../git/git';
import { Logger } from '../logger';
import { Arrays, Iterables, log, Strings } from '../system';
import { GitDocumentState } from '../trackers/gitDocumentTracker';
import { TrackedDocument } from '../trackers/trackedDocument';
export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
super(FileAnnotationType.Blame, editor, trackedDocument);
}
clear() {
super.clear();
@ -22,10 +29,10 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
}
@log()
async onProvideAnnotation(_shaOrLine?: string | number, _type?: FileAnnotationType): Promise<boolean> {
async onProvideAnnotation(context?: AnnotationContext, _type?: FileAnnotationType): Promise<boolean> {
const cc = Logger.getCorrelationContext();
this.annotationType = FileAnnotationType.Blame;
this.annotationContext = context;
const blame = await this.getBlame();
if (blame == null) return false;
@ -167,8 +174,8 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
}
@log({ args: false })
async selection(shaOrLine?: string | number, blame?: GitBlame) {
if (Decorations.gutterBlameHighlight == null) return;
async selection(selection?: AnnotationContext['selection'], blame?: GitBlame): Promise<void> {
if (selection === false || Decorations.gutterBlameHighlight == null) return;
if (blame == null) {
blame = await this.blame;
@ -176,11 +183,11 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
}
let sha: string | undefined = undefined;
if (typeof shaOrLine === 'string') {
sha = shaOrLine;
} else if (typeof shaOrLine === 'number') {
if (shaOrLine >= 0) {
const commitLine = blame.lines[shaOrLine];
if (selection?.sha != null) {
sha = selection.sha;
} else if (selection?.line != null) {
if (selection.line >= 0) {
const commitLine = blame.lines[selection.line];
sha = commitLine?.sha;
}
} else {

+ 53
- 13
src/annotations/gutterChangesAnnotationProvider.ts Ver arquivo

@ -13,7 +13,7 @@ import {
TextEditorDecorationType,
TextEditorRevealType,
} from 'vscode';
import { AnnotationProviderBase } from './annotationProvider';
import { AnnotationContext, AnnotationProviderBase } from './annotationProvider';
import { FileAnnotationType } from '../configuration';
import { Container } from '../container';
import { Decorations } from './fileAnnotationController';
@ -23,12 +23,21 @@ import { Logger } from '../logger';
import { log, Strings } from '../system';
import { GitDocumentState, TrackedDocument } from '../trackers/gitDocumentTracker';
export class GutterChangesAnnotationProvider extends AnnotationProviderBase {
export interface ChangesAnnotationContext extends AnnotationContext {
sha?: string;
only?: boolean;
}
export class GutterChangesAnnotationProvider extends AnnotationProviderBase<ChangesAnnotationContext> {
private state: { commit: GitLogCommit | undefined; diffs: GitDiff[] } | undefined;
private hoverProviderDisposable: Disposable | undefined;
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
super(editor, trackedDocument);
super(FileAnnotationType.Changes, editor, trackedDocument);
}
mustReopen(context?: ChangesAnnotationContext): boolean {
return this.annotationContext?.sha !== context?.sha || this.annotationContext?.only !== context?.only;
}
clear() {
@ -40,7 +49,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase {
super.clear();
}
selection(_shaOrLine?: string | number): Promise<void> {
selection(_selection?: AnnotationContext['selection']): Promise<void> {
return Promise.resolve();
}
@ -49,18 +58,17 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase {
}
@log()
async onProvideAnnotation(shaOrLine?: string | number): Promise<boolean> {
async onProvideAnnotation(context?: ChangesAnnotationContext): Promise<boolean> {
const cc = Logger.getCorrelationContext();
this.annotationType = FileAnnotationType.Changes;
if (this.mustReopen(context)) {
this.clear();
}
this.annotationContext = context;
let ref1 = this.trackedDocument.uri.sha;
let ref2;
if (typeof shaOrLine === 'string') {
if (shaOrLine !== this.trackedDocument.uri.sha) {
ref2 = `${shaOrLine}^`;
}
}
let ref2 = context?.sha != null && context.sha !== ref1 ? `${context.sha}^` : undefined;
let commit: GitLogCommit | undefined;
@ -148,10 +156,37 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase {
{ decorationType: TextEditorDecorationType; rangesOrOptions: DecorationOptions[] }
>();
// If we want to only show changes from the specified sha, get the blame so we can compare with "visible" shas
const blame =
context?.sha != null && context?.only
? this.editor?.document.isDirty
? await Container.git.getBlameForFileContents(
this.trackedDocument.uri,
this.editor.document.getText(),
)
: await Container.git.getBlameForFile(this.trackedDocument.uri)
: undefined;
let selection: Selection | undefined;
for (const diff of diffs) {
for (const hunk of diff.hunks) {
// Only show "visible" hunks
if (blame != null) {
let skip = true;
const sha = context!.sha;
for (let i = hunk.current.position.start - 1; i < hunk.current.position.end; i++) {
if (blame.lines[i].sha === sha) {
skip = false;
}
}
if (skip) {
continue;
}
}
// Subtract 2 because editor lines are 0-based and we will be adding 1 in the first iteration of the loop
let count = Math.max(hunk.current.position.start - 2, -1);
let index = -1;
@ -161,6 +196,11 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase {
if (hunkLine.current?.state === 'unchanged') continue;
// Uncomment this if we want to only show "visible" lines, rather than just visible hunks
// if (blame != null && blame.lines[count].sha !== context!.sha) {
// continue;
// }
const range = this.editor.document.validateRange(
new Range(new Position(count, 0), new Position(count, Number.MAX_SAFE_INTEGER)),
);
@ -225,7 +265,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase {
Logger.log(cc, `${Strings.getDurationMilliseconds(start)} ms to apply recent changes annotations`);
if (selection != null) {
if (selection != null && context?.selection !== false) {
this.editor.selection = selection;
this.editor.revealRange(selection, TextEditorRevealType.InCenterIfOutsideViewport);
}

+ 11
- 4
src/annotations/gutterHeatmapBlameAnnotationProvider.ts Ver arquivo

@ -1,18 +1,25 @@
'use strict';
import { Range, TextEditorDecorationType } from 'vscode';
import { Range, TextEditor, TextEditorDecorationType } from 'vscode';
import { Annotations } from './annotations';
import { AnnotationContext } from './annotationProvider';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
import { FileAnnotationType } from '../configuration';
import { GitBlameCommit } from '../git/git';
import { Logger } from '../logger';
import { log, Strings } from '../system';
import { GitDocumentState } from '../trackers/gitDocumentTracker';
import { TrackedDocument } from '../trackers/trackedDocument';
export class GutterHeatmapBlameAnnotationProvider extends BlameAnnotationProviderBase {
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
super(FileAnnotationType.Heatmap, editor, trackedDocument);
}
@log()
async onProvideAnnotation(_shaOrLine?: string | number, _type?: FileAnnotationType): Promise<boolean> {
async onProvideAnnotation(context?: AnnotationContext, _type?: FileAnnotationType): Promise<boolean> {
const cc = Logger.getCorrelationContext();
this.annotationType = FileAnnotationType.Heatmap;
this.annotationContext = context;
const blame = await this.getBlame();
if (blame == null) return false;
@ -55,7 +62,7 @@ export class GutterHeatmapBlameAnnotationProvider extends BlameAnnotationProvide
return true;
}
selection(_shaOrLine?: string | number): Promise<void> {
selection(_selection?: AnnotationContext['selection']): Promise<void> {
return Promise.resolve();
}
}

+ 45
- 0
src/codelens/codeLensProvider.ts Ver arquivo

@ -20,10 +20,12 @@ import {
import {
Commands,
DiffWithPreviousCommandArgs,
OpenOnRemoteCommandArgs,
ShowCommitsInViewCommandArgs,
ShowQuickCommitCommandArgs,
ShowQuickCommitFileCommandArgs,
ShowQuickFileHistoryCommandArgs,
ToggleFileChangesAnnotationCommandArgs,
} from '../commands';
import {
CodeLensCommand,
@ -31,6 +33,7 @@ import {
CodeLensLanguageScope,
CodeLensScopes,
configuration,
FileAnnotationType,
} from '../configuration';
import { BuiltInCommands, DocumentSchemes } from '../constants';
import { Container } from '../container';
@ -555,6 +558,12 @@ export class GitCodeLensProvider implements CodeLensProvider {
return this.applyShowQuickFileHistoryCommand<GitRecentChangeCodeLens>(title, lens);
case CodeLensCommand.ToggleFileBlame:
return this.applyToggleFileBlameCommand<GitRecentChangeCodeLens>(title, lens);
case CodeLensCommand.ToggleFileChanges:
return this.applyToggleFileChangesCommand<GitRecentChangeCodeLens>(title, lens, recentCommit);
case CodeLensCommand.ToggleFileChangesOnly:
return this.applyToggleFileChangesCommand<GitRecentChangeCodeLens>(title, lens, recentCommit, true);
case CodeLensCommand.ToggleFileHeatmap:
return this.applyToggleFileHeatmapCommand<GitRecentChangeCodeLens>(title, lens);
default:
return lens;
}
@ -614,6 +623,12 @@ export class GitCodeLensProvider implements CodeLensProvider {
return this.applyShowQuickFileHistoryCommand<GitAuthorsCodeLens>(title, lens);
case CodeLensCommand.ToggleFileBlame:
return this.applyToggleFileBlameCommand<GitAuthorsCodeLens>(title, lens);
case CodeLensCommand.ToggleFileChanges:
return this.applyToggleFileChangesCommand<GitAuthorsCodeLens>(title, lens, commit);
case CodeLensCommand.ToggleFileChangesOnly:
return this.applyToggleFileChangesCommand<GitAuthorsCodeLens>(title, lens, commit, true);
case CodeLensCommand.ToggleFileHeatmap:
return this.applyToggleFileHeatmapCommand<GitAuthorsCodeLens>(title, lens);
default:
return lens;
}
@ -796,6 +811,36 @@ export class GitCodeLensProvider implements CodeLensProvider {
return lens;
}
private applyToggleFileChangesCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(
title: string,
lens: T,
commit: GitCommit,
only?: boolean,
): T {
const commandArgs: ToggleFileChangesAnnotationCommandArgs = {
type: FileAnnotationType.Changes,
context: { sha: commit.sha, only: only, selection: false },
};
lens.command = {
title: title,
command: Commands.ToggleFileChanges,
arguments: [lens.uri!.toFileUri(), commandArgs],
};
return lens;
}
private applyToggleFileHeatmapCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(
title: string,
lens: T,
): T {
lens.command = {
title: title,
command: Commands.ToggleFileHeatmap,
arguments: [lens.uri!.toFileUri()],
};
return lens;
}
private applyCommandWithNoClickAction<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(
title: string,
lens: T,

+ 1
- 1
src/commands/closeUnchangedFiles.ts Ver arquivo

@ -59,7 +59,7 @@ export class CloseUnchangedFilesCommand extends Command {
if (editor != null) {
let found = false;
for (const e of editors) {
if (TextEditorComparer.equals(e, editor, { useId: true, usePosition: true })) {
if (TextEditorComparer.equals(e, editor, { usePosition: true })) {
found = true;
break;
}

+ 1
- 0
src/commands/common.ts Ver arquivo

@ -155,6 +155,7 @@ export enum Commands {
ToggleFileBlameInDiffLeft = 'gitlens.toggleFileBlameInDiffLeft',
ToggleFileBlameInDiffRight = 'gitlens.toggleFileBlameInDiffRight',
ToggleFileChanges = 'gitlens.toggleFileChanges',
ToggleFileChangesOnly = 'gitlens.toggleFileChangesOnly',
ToggleFileHeatmap = 'gitlens.toggleFileHeatmap',
ToggleFileHeatmapInDiffLeft = 'gitlens.toggleFileHeatmapInDiffLeft',
ToggleFileHeatmapInDiffRight = 'gitlens.toggleFileHeatmapInDiffRight',

+ 1
- 1
src/commands/gitCommands.actions.ts Ver arquivo

@ -558,7 +558,7 @@ export namespace GitActions {
const editor = await findOrOpenEditor(uri, opts);
if (annotationType != null && editor != null) {
void (await Container.fileAnnotations.show(editor, annotationType, line));
void (await Container.fileAnnotations.show(editor, annotationType, { selection: { line: line } }));
}
}

+ 1
- 1
src/commands/openWorkingFile.ts Ver arquivo

@ -58,7 +58,7 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand {
const e = await findOrOpenEditor(args.uri, { ...args.showOptions, throwOnError: true });
if (args.annotationType === undefined) return;
void (await Container.fileAnnotations.show(e, args.annotationType, args.line));
void (await Container.fileAnnotations.show(e, args.annotationType, { selection: { line: args.line } }));
} catch (ex) {
Logger.error(ex, 'OpenWorkingFileCommand');
void Messages.showGenericErrorMessage('Unable to open working file');

+ 35
- 13
src/commands/toggleFileAnnotations.ts Ver arquivo

@ -1,5 +1,7 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { AnnotationContext } from '../annotations/annotationProvider';
import { ChangesAnnotationContext } from '../annotations/gutterChangesAnnotationProvider';
import { ActiveEditorCommand, command, Commands, EditorCommand } from './common';
import { UriComparer } from '../comparers';
import { FileAnnotationType } from '../configuration';
@ -34,20 +36,37 @@ export class ClearFileAnnotationsCommand extends EditorCommand {
}
}
export interface ToggleFileAnnotationCommandArgs {
export interface ToggleFileBlameAnnotationCommandArgs {
type: FileAnnotationType.Blame;
context?: AnnotationContext;
on?: boolean;
sha?: string;
type?: FileAnnotationType;
}
export interface ToggleFileChangesAnnotationCommandArgs {
type: FileAnnotationType.Changes;
context?: ChangesAnnotationContext;
on?: boolean;
}
export interface ToggleFileHeatmapAnnotationCommandArgs {
type: FileAnnotationType.Heatmap;
context?: AnnotationContext;
on?: boolean;
}
export type ToggleFileAnnotationCommandArgs =
| ToggleFileBlameAnnotationCommandArgs
| ToggleFileChangesAnnotationCommandArgs
| ToggleFileHeatmapAnnotationCommandArgs;
@command()
export class ToggleFileBlameCommand extends ActiveEditorCommand {
constructor() {
super([Commands.ToggleFileBlame, Commands.ToggleFileBlameInDiffLeft, Commands.ToggleFileBlameInDiffRight]);
}
execute(editor: TextEditor, uri?: Uri, args?: ToggleFileAnnotationCommandArgs): Promise<void> {
return toggleFileAnnotations(editor, uri, {
execute(editor: TextEditor, uri?: Uri, args?: ToggleFileBlameAnnotationCommandArgs): Promise<void> {
return toggleFileAnnotations<ToggleFileBlameAnnotationCommandArgs>(editor, uri, {
...args,
type: FileAnnotationType.Blame,
});
@ -60,8 +79,8 @@ export class ToggleFileChangesCommand extends ActiveEditorCommand {
super(Commands.ToggleFileChanges);
}
execute(editor: TextEditor, uri?: Uri, args?: ToggleFileAnnotationCommandArgs): Promise<void> {
return toggleFileAnnotations(editor, uri, {
execute(editor: TextEditor, uri?: Uri, args?: ToggleFileChangesAnnotationCommandArgs): Promise<void> {
return toggleFileAnnotations<ToggleFileChangesAnnotationCommandArgs>(editor, uri, {
...args,
type: FileAnnotationType.Changes,
});
@ -78,18 +97,18 @@ export class ToggleFileHeatmapCommand extends ActiveEditorCommand {
]);
}
execute(editor: TextEditor, uri?: Uri, args?: ToggleFileAnnotationCommandArgs): Promise<void> {
return toggleFileAnnotations(editor, uri, {
execute(editor: TextEditor, uri?: Uri, args?: ToggleFileHeatmapAnnotationCommandArgs): Promise<void> {
return toggleFileAnnotations<ToggleFileHeatmapAnnotationCommandArgs>(editor, uri, {
...args,
type: FileAnnotationType.Heatmap,
});
}
}
async function toggleFileAnnotations(
async function toggleFileAnnotations<TArgs extends ToggleFileAnnotationCommandArgs>(
editor: TextEditor,
uri: Uri | undefined,
args: ToggleFileAnnotationCommandArgs,
args: TArgs,
): Promise<void> {
// Handle the case where we are focused on a non-editor editor (output, debug console)
if (editor != null && !isTextEditor(editor)) {
@ -108,8 +127,11 @@ async function toggleFileAnnotations(
void (await Container.fileAnnotations.toggle(
editor,
args.type!,
args.sha ?? editor?.selection.active.line,
args.type,
{
selection: args.context?.selection ?? { line: editor?.selection.active.line },
...args.context,
},
args.on,
));
} catch (ex) {

+ 1
- 7
src/comparers.ts Ver arquivo

@ -21,19 +21,13 @@ class TextEditorComparer extends Comparer {
equals(
lhs: TextEditor | undefined,
rhs: TextEditor | undefined,
options: { useId: boolean; usePosition: boolean } = { useId: false, usePosition: false },
options: { usePosition: boolean } = { usePosition: false },
) {
if (lhs === rhs) return true;
if (lhs == null || rhs == null) return false;
if (options.usePosition && lhs.viewColumn !== rhs.viewColumn) return false;
if (options.useId && (lhs.document != null || rhs.document != null)) {
if ((lhs as any).id !== (rhs as any).id) return false;
return true;
}
return lhs.document === rhs.document;
}
}

+ 6
- 0
src/config.ts Ver arquivo

@ -194,6 +194,9 @@ export enum CodeLensCommand {
ShowQuickCurrentBranchHistory = 'gitlens.showQuickRepoHistory',
ShowQuickFileHistory = 'gitlens.showQuickFileHistory',
ToggleFileBlame = 'gitlens.toggleFileBlame',
ToggleFileChanges = 'gitlens.toggleFileChanges',
ToggleFileChangesOnly = 'gitlens.toggleFileChangesOnly',
ToggleFileHeatmap = 'gitlens.toggleFileHeatmap',
}
export enum CodeLensScopes {
@ -266,6 +269,9 @@ export enum StatusBarCommand {
ShowQuickFileHistory = 'gitlens.showQuickFileHistory',
ToggleCodeLens = 'gitlens.toggleCodeLens',
ToggleFileBlame = 'gitlens.toggleFileBlame',
ToggleFileChanges = 'gitlens.toggleFileChanges',
ToggleFileChangesOnly = 'gitlens.toggleFileChangesOnly',
ToggleFileHeatmap = 'gitlens.toggleFileHeatmap',
}
export enum TagSorting {

+ 8
- 1
src/container.ts Ver arquivo

@ -7,7 +7,13 @@ import { ActionRunners } from './api/actionRunners';
import { resetAvatarCache } from './avatars';
import { GitCodeLensController } from './codelens/codeLensController';
import { Commands, ToggleFileAnnotationCommandArgs } from './commands';
import { AnnotationsToggleMode, Config, configuration, ConfigurationWillChangeEvent } from './configuration';
import {
AnnotationsToggleMode,
Config,
configuration,
ConfigurationWillChangeEvent,
FileAnnotationType,
} from './configuration';
import { GitFileSystemProvider } from './git/fsProvider';
import { GitService } from './git/gitService';
import { LineHoverController } from './hovers/lineHoverController';
@ -369,6 +375,7 @@ export class Container {
if (command != null) {
const commandArgs: ToggleFileAnnotationCommandArgs = {
type: mode.annotations as FileAnnotationType,
on: true,
};
// Make sure to delay the execution by a bit so that the configuration changes get propegated first

+ 31
- 2
src/statusbar/statusBarController.ts Ver arquivo

@ -9,8 +9,8 @@ import {
TextEditor,
window,
} from 'vscode';
import { Commands } from '../commands';
import { configuration, StatusBarCommand } from '../configuration';
import { Commands, ToggleFileChangesAnnotationCommandArgs } from '../commands';
import { configuration, FileAnnotationType, StatusBarCommand } from '../configuration';
import { GlyphChars, isTextEditor } from '../constants';
import { Container } from '../container';
import { CommitFormatter, GitBlameCommit, PullRequest } from '../git/git';
@ -228,6 +228,35 @@ export class StatusBarController implements Disposable {
case StatusBarCommand.ToggleFileBlame:
this._statusBarBlame.tooltip = 'Toggle File Blame';
break;
case StatusBarCommand.ToggleFileChanges: {
const commandArgs: ToggleFileChangesAnnotationCommandArgs = {
type: FileAnnotationType.Changes,
context: { sha: commit.sha, only: false, selection: false },
};
this._statusBarBlame.command = {
title: 'Toggle File Changes',
command: Commands.ToggleFileChanges,
arguments: [commit.uri, commandArgs],
};
this._statusBarBlame.tooltip = 'Toggle File Changes';
break;
}
case StatusBarCommand.ToggleFileChangesOnly: {
const commandArgs: ToggleFileChangesAnnotationCommandArgs = {
type: FileAnnotationType.Changes,
context: { sha: commit.sha, only: true, selection: false },
};
this._statusBarBlame.command = {
title: 'Toggle File Changes',
command: Commands.ToggleFileChanges,
arguments: [commit.uri, commandArgs],
};
this._statusBarBlame.tooltip = 'Toggle File Changes';
break;
}
case StatusBarCommand.ToggleFileHeatmap:
this._statusBarBlame.tooltip = 'Toggle File Heatmap';
break;
}
this._statusBarBlame.show();

+ 6
- 4
src/views/viewCommands.ts Ver arquivo

@ -367,11 +367,11 @@ export class ViewCommands {
return;
}
void (await this.openFile(node));
void (await this.openFile(node, { preserveFocus: true, preview: true }));
void (await Container.fileAnnotations.toggle(
window.activeTextEditor,
FileAnnotationType.Changes,
node.ref.ref,
{ sha: node.ref.ref },
true,
));
}
@ -389,11 +389,11 @@ export class ViewCommands {
return;
}
void (await this.openRevision(node, { showOptions: { preserveFocus: true, preview: true } }));
void (await this.openFile(node, { preserveFocus: true, preview: true }));
void (await Container.fileAnnotations.toggle(
window.activeTextEditor,
FileAnnotationType.Changes,
node.ref.ref,
{ sha: node.ref.ref, only: true },
true,
));
}
@ -962,6 +962,7 @@ export class ViewCommands {
@debug()
private openFile(
node: ViewRefFileNode | MergeConflictFileNode | StatusFileNode | FileHistoryNode | LineHistoryNode,
options?: TextDocumentShowOptions,
) {
if (
!(node instanceof ViewRefFileNode) &&
@ -976,6 +977,7 @@ export class ViewCommands {
return GitActions.Commit.openFile(node.uri, {
preserveFocus: true,
preview: false,
...options,
});
}

+ 14
- 0
src/webviews/apps/settings/partials/code-lens.html Ver arquivo

@ -67,6 +67,13 @@
disabled
>
<option value="gitlens.toggleFileBlame">toggles the file blame</option>
<option value="gitlens.toggleFileHeatmap">toggles the file heatmap</option>
<option value="gitlens.toggleFileChanges">
toggles the file changes since before the commit
</option>
<option value="gitlens.toggleFileChangesOnly">
toggles the file changes from the commit
</option>
<option value="gitlens.diffWithPrevious">
opens changes with the previous revision
</option>
@ -140,6 +147,13 @@
disabled
>
<option value="gitlens.toggleFileBlame">toggles the file blame</option>
<option value="gitlens.toggleFileHeatmap">toggles the file heatmap</option>
<option value="gitlens.toggleFileChanges">
toggles the file changes since before the commit
</option>
<option value="gitlens.toggleFileChangesOnly">
toggles the file changes from the commit
</option>
<option value="gitlens.diffWithPrevious">
opens changes with the previous revision
</option>

+ 7
- 0
src/webviews/apps/settings/partials/status-bar.html Ver arquivo

@ -86,6 +86,13 @@
<div class="select-container">
<select id="statusBar.command" name="statusBar.command" data-setting disabled>
<option value="gitlens.toggleFileBlame">toggles the file blame</option>
<option value="gitlens.toggleFileHeatmap">toggles the file heatmap</option>
<option value="gitlens.toggleFileChanges">
toggles the file changes since before the commit
</option>
<option value="gitlens.toggleFileChangesOnly">
toggles the file changes from the commit
</option>
<option value="gitlens.toggleCodeLens">toggles the Git code lens</option>
<option value="gitlens.diffWithPrevious">
opens line changes with the previous revision

Carregando…
Cancelar
Salvar