diff --git a/src/git/gitService.ts b/src/git/gitService.ts index 2025daf..37d3e3e 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -1021,6 +1021,14 @@ export class GitService implements Disposable { return this.getBlameForRangeSync(blame, uri, range); } + @log() + async getBlameForRangeContents(uri: GitUri, range: Range, contents: string): Promise { + const blame = await this.getBlameForFileContents(uri, contents); + if (blame === undefined) return undefined; + + return this.getBlameForRangeSync(blame, uri, range); + } + @log({ args: { 0: blame => '' } }) diff --git a/src/views/nodes/lineHistoryNode.ts b/src/views/nodes/lineHistoryNode.ts index d7581e3..aa46595 100644 --- a/src/views/nodes/lineHistoryNode.ts +++ b/src/views/nodes/lineHistoryNode.ts @@ -18,7 +18,13 @@ import { insertDateMarkers } from './helpers'; import { ResourceType, SubscribeableViewNode, ViewNode } from './viewNode'; export class LineHistoryNode extends SubscribeableViewNode { - constructor(uri: GitUri, view: View, parent: ViewNode, public readonly selection: Selection) { + constructor( + uri: GitUri, + view: View, + parent: ViewNode, + public readonly selection: Selection, + private readonly _editorContents: string | undefined + ) { super(uri, view, parent); } @@ -29,10 +35,26 @@ export class LineHistoryNode extends SubscribeableViewNode { CommitFileNodeDisplayAs.CommitLabel | (this.view.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); + let selection = this.selection; + if (this.uri.sha === undefined) { // Check for any uncommitted changes in the range - const blame = await Container.git.getBlameForRange(this.uri, this.selection); + const blame = this._editorContents + ? await Container.git.getBlameForRangeContents(this.uri, selection, this._editorContents) + : await Container.git.getBlameForRange(this.uri, selection); if (blame !== undefined) { + const firstLine = blame.lines[0]; + const lastLine = blame.lines[blame.lines.length - 1]; + + // Since there could be a change in the line numbers, update the selection + const firstActive = selection.active.line === firstLine.line - 1; + selection = new Selection( + (firstActive ? lastLine : firstLine).originalLine - 1, + selection.anchor.character, + (firstActive ? firstLine : lastLine).originalLine - 1, + selection.active.character + ); + for (const commit of blame.commits.values()) { if (!commit.isUncommitted) continue; @@ -63,11 +85,7 @@ export class LineHistoryNode extends SubscribeableViewNode { commit.originalFileName || commit.fileName ); - children.splice( - 0, - 0, - new CommitFileNode(this.view, this, file, uncommitted, displayAs, this.selection) - ); + children.splice(0, 0, new CommitFileNode(this.view, this, file, uncommitted, displayAs, selection)); break; } @@ -76,14 +94,14 @@ export class LineHistoryNode extends SubscribeableViewNode { const log = await Container.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, { ref: this.uri.sha, - range: this.selection + range: selection }); if (log !== undefined) { children.push( ...insertDateMarkers( Iterables.filterMap( log.commits.values(), - c => new CommitFileNode(this.view, this, c.files[0], c, displayAs, this.selection) + c => new CommitFileNode(this.view, this, c.files[0], c, displayAs, selection) ), this ) diff --git a/src/views/nodes/lineHistoryTrackerNode.ts b/src/views/nodes/lineHistoryTrackerNode.ts index 1d79a70..8ed57a8 100644 --- a/src/views/nodes/lineHistoryTrackerNode.ts +++ b/src/views/nodes/lineHistoryTrackerNode.ts @@ -16,6 +16,7 @@ import { ResourceType, SubscribeableViewNode, unknownGitUri, ViewNode } from './ export class LineHistoryTrackerNode extends SubscribeableViewNode { private _base: string | undefined; private _child: LineHistoryNode | undefined; + private _editorContents: string | undefined; private _selection: Selection | undefined; constructor(view: LineHistoryView) { @@ -54,7 +55,7 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode