Skip to content

Commit 9da6251

Browse files
committed
Adds file history editor tracking
1 parent 7ff8b8b commit 9da6251

File tree

1 file changed

+55
-18
lines changed

1 file changed

+55
-18
lines changed

src/views/nodes/fileHistoryTrackerNode.ts

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { TextEditor } from 'vscode';
2-
import { Disposable, TreeItem, TreeItemCollapsibleState, window } from 'vscode';
1+
import type { Disposable, TextEditor } from 'vscode';
2+
import { TreeItem, TreeItemCollapsibleState, window } from 'vscode';
33
import type { GitCommitish } from '../../git/gitUri';
44
import { GitUri, unknownGitUri } from '../../git/gitUri';
55
import { ensureWorkingUri } from '../../git/gitUri.utils';
@@ -66,6 +66,7 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
6666
this.view.description = this.view.grouped ? this.view.groupedLabel : undefined;
6767

6868
this.view.message = 'There are no editors open that can provide file history information.';
69+
this.children = undefined;
6970
return [];
7071
}
7172

@@ -97,7 +98,14 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
9798
this.child = new FileHistoryNode(fileUri, this.view, this, folder, branch);
9899
}
99100

100-
return this.child.getChildren();
101+
const children = this.child.getChildren();
102+
void children.then(children => {
103+
this.children = children;
104+
if (this._selectSha != null) {
105+
setTimeout(() => void this.revealCommit(), 250);
106+
}
107+
});
108+
return children;
101109
}
102110

103111
getTreeItem(): TreeItem {
@@ -122,18 +130,16 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
122130
this.reset();
123131
}
124132

125-
const updated = await this.updateUri();
133+
const updated = await this.updateUri(this._selectSha);
126134
setLogScopeExit(scope, `, uri=${Logger.toLoggable(this._uri)}`);
127135
return { cancel: !updated };
128136
}
129137

130138
@debug()
131-
protected async subscribe(): Promise<Disposable> {
132-
await this.updateUri();
139+
protected async subscribe(): Promise<Disposable | undefined> {
140+
await this.updateUri(this._selectSha);
133141

134-
return Disposable.from(
135-
weakEvent(window.onDidChangeActiveTextEditor, debounce(this.onActiveEditorChanged, 250), this),
136-
);
142+
return weakEvent(window.onDidChangeActiveTextEditor, debounce(this.onActiveEditorChanged, 250), this);
137143
}
138144

139145
private _triggerChangeDebounced: Deferrable<() => Promise<void>> | undefined;
@@ -143,10 +149,7 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
143149
// For virtual repositories the active editor event takes a while to fire
144150
// Ultimately we need to be using the upcoming Tabs api to avoid this
145151
if (editor == null && isVirtualUri(this._uri)) {
146-
if (this._triggerChangeDebounced == null) {
147-
this._triggerChangeDebounced = debounce(() => this.triggerChange(), 1500);
148-
}
149-
152+
this._triggerChangeDebounced ??= debounce(() => this.triggerChange(), 1500);
150153
void this._triggerChangeDebounced();
151154
return;
152155
}
@@ -194,8 +197,9 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
194197
}
195198

196199
@debug()
197-
setUri(uri?: GitUri): void {
200+
setUri(uri?: GitUri, sha?: string): void {
198201
this._uri = uri ?? unknownGitUri;
202+
this._selectSha = sha ?? uri?.sha;
199203
void setContext('gitlens:views:fileHistory:canPin', this.hasUri);
200204
}
201205

@@ -208,9 +212,12 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
208212
private reset() {
209213
this.setUri();
210214
this.child = undefined;
215+
this._selectSha = undefined;
211216
}
212217

213-
private async updateUri(): Promise<boolean> {
218+
private _selectSha: string | undefined;
219+
220+
private async updateUri(sha?: string): Promise<boolean> {
214221
const editor = window.activeTextEditor;
215222
if (editor == null || !this.view.container.git.isTrackable(editor.document.uri)) {
216223
if (
@@ -225,16 +232,20 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
225232
return true;
226233
}
227234

235+
let gitUri = await GitUri.fromUri(editor.document.uri);
236+
228237
if (editor.document.uri.path === this.uri.path) {
238+
this._selectSha = sha ?? gitUri.sha;
239+
queueMicrotask(() => void this.revealCommit());
229240
return false;
230241
}
231242

232-
let gitUri = await GitUri.fromUri(editor.document.uri);
233-
234243
// If we have a sha, normalize the history to the working file (so we get a full history all the time)
235244
const uri = await ensureWorkingUri(this.view.container, gitUri);
236245

237246
if (this.hasUri && areUrisEqual(uri ?? gitUri, this.uri)) {
247+
this._selectSha = sha ?? gitUri.sha;
248+
queueMicrotask(() => void this.revealCommit());
238249
return false;
239250
}
240251

@@ -248,9 +259,35 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<'file-history-
248259
return true;
249260
}
250261

251-
this.setUri(gitUri);
262+
this.setUri(gitUri, sha);
252263
this.child = undefined;
253264

254265
return true;
255266
}
267+
268+
async revealCommit(): Promise<void> {
269+
const sha = this._selectSha;
270+
this._selectSha = undefined;
271+
272+
const { children } = this;
273+
if (!children?.length) return;
274+
275+
let node;
276+
if (sha == null || sha === 'HEAD') {
277+
[node] = children;
278+
} else {
279+
node = children.find(n =>
280+
n.is('file-commit') || n.is('commit') ? n.commit?.sha?.startsWith(sha) ?? false : false,
281+
);
282+
if (!node) {
283+
node = children[children.length - 1];
284+
if (!node.is('pager')) {
285+
node = undefined;
286+
}
287+
}
288+
}
289+
if (!node) return;
290+
291+
await this.view.reveal(node, { select: true, focus: false });
292+
}
256293
}

0 commit comments

Comments
 (0)