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' ;
33import type { GitCommitish } from '../../git/gitUri' ;
44import { GitUri , unknownGitUri } from '../../git/gitUri' ;
55import { 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