@@ -3,16 +3,14 @@ import { ThemeIcon } from 'vscode';
33import { md5 } from '@env/crypto' ;
44import type { SearchQuery } from '../../constants.search' ;
55import { executeGitCommand } from '../../git/actions' ;
6- import { GitUri } from '../../git/gitUri' ;
76import type { GitLog } from '../../git/models/log' ;
87import type { CommitsQueryResults } from '../../git/queryResults' ;
98import { getSearchQueryComparisonKey , getStoredSearchQuery } from '../../git/search' ;
10- import { debug } from '../../system/decorators/log' ;
119import { pluralize } from '../../system/string' ;
1210import type { SearchAndCompareView } from '../searchAndCompareView' ;
13- import type { PageableViewNode } from './abstract/viewNode' ;
14- import { ContextValues , getViewNodeId , ViewNode } from './abstract/viewNode' ;
15- import { ResultsCommitsNode } from './resultsCommitsNode' ;
11+ import type { ViewNode } from './abstract/viewNode' ;
12+ import { ContextValues , getViewNodeId } from './abstract/viewNode' ;
13+ import { ResultsCommitsNodeBase } from './resultsCommitsNode' ;
1614
1715interface SearchQueryResults {
1816 readonly label : string ;
@@ -21,28 +19,51 @@ interface SearchQueryResults {
2119 more ?( limit : number | undefined ) : Promise < void > ;
2220}
2321
24- export class SearchResultsNode extends ViewNode < 'search-results' , SearchAndCompareView > implements PageableViewNode {
22+ export class SearchResultsNode extends ResultsCommitsNodeBase < 'search-results' , SearchAndCompareView > {
23+ private _search : SearchQuery ;
24+ private _labels : {
25+ label : string ;
26+ queryLabel : string | { label : string ; resultsType ?: { singular : string ; plural : string } } ;
27+ resultsType ?: { singular : string ; plural : string } ;
28+ } ;
29+ private _storedAt : number ;
30+
2531 constructor (
2632 view : SearchAndCompareView ,
27- protected override readonly parent : ViewNode ,
28- public readonly repoPath : string ,
29- private _search : SearchQuery ,
30- private _labels : {
33+ parent : ViewNode ,
34+ repoPath : string ,
35+ search : SearchQuery ,
36+ labels : {
3137 label : string ;
3238 queryLabel : string | { label : string ; resultsType ?: { singular : string ; plural : string } } ;
3339 resultsType ?: { singular : string ; plural : string } ;
3440 } ,
35- private _searchQueryOrLog ?:
41+ searchQueryOrLog ?:
3642 | ( ( limit : number | undefined ) => Promise < CommitsQueryResults > )
3743 | Promise < GitLog | undefined >
3844 | GitLog
3945 | undefined ,
40- private _storedAt : number = 0 ,
46+ storedAt : number = 0 ,
4147 ) {
42- super ( 'search-results' , GitUri . fromRepoPath ( repoPath ) , view , parent ) ;
48+ const query = createSearchQuery ( view , repoPath , search , labels , searchQueryOrLog ) ;
49+ const deferred = searchQueryOrLog == null ;
50+
51+ super (
52+ 'search-results' ,
53+ view ,
54+ parent ,
55+ repoPath ,
56+ labels . label ,
57+ { query : query , deferred : deferred } ,
58+ { expand : false } ,
59+ ) ;
60+
61+ this . _search = search ;
62+ this . _labels = labels ;
63+ this . _storedAt = storedAt ;
4364
4465 this . updateContext ( { searchId : getSearchQueryComparisonKey ( this . _search ) } ) ;
45- this . _uniqueId = getViewNodeId ( this . type , this . context ) ;
66+ this . _uniqueId = getViewNodeId ( 'search-results' , this . context ) ;
4667
4768 // If this is a new search, save it
4869 if ( this . _storedAt === 0 ) {
@@ -71,39 +92,8 @@ export class SearchResultsNode extends ViewNode<'search-results', SearchAndCompa
7192 void this . remove ( true ) ;
7293 }
7394
74- private _resultsNode : ResultsCommitsNode | undefined ;
75- private ensureResults ( ) {
76- if ( this . _resultsNode == null ) {
77- let deferred ;
78- if ( this . _searchQueryOrLog == null ) {
79- deferred = true ;
80- this . _searchQueryOrLog = this . getSearchQuery ( { label : this . _labels . queryLabel } ) ;
81- } else if ( typeof this . _searchQueryOrLog !== 'function' ) {
82- this . _searchQueryOrLog = this . getSearchQuery (
83- { label : this . _labels . queryLabel } ,
84- this . _searchQueryOrLog ,
85- ) ;
86- }
87-
88- this . _resultsNode = new ResultsCommitsNode (
89- this . view ,
90- this ,
91- this . repoPath ,
92- this . _labels . label ,
93- { query : this . _searchQueryOrLog , deferred : deferred } ,
94- { expand : false } ,
95- ) ;
96- }
97-
98- return this . _resultsNode ;
99- }
100-
101- async getChildren ( ) : Promise < ViewNode [ ] > {
102- return this . ensureResults ( ) . getChildren ( ) ;
103- }
104-
105- async getTreeItem ( ) : Promise < TreeItem > {
106- const item = await this . ensureResults ( ) . getTreeItem ( ) ;
95+ override async getTreeItem ( ) : Promise < TreeItem > {
96+ const item = await super . getTreeItem ( ) ;
10797 item . id = this . id ;
10898 item . contextValue = ContextValues . SearchResults ;
10999 if ( this . view . container . git . repositoryCount > 1 ) {
@@ -115,14 +105,6 @@ export class SearchResultsNode extends ViewNode<'search-results', SearchAndCompa
115105 return item ;
116106 }
117107
118- get hasMore ( ) : boolean {
119- return this . ensureResults ( ) . hasMore ;
120- }
121-
122- async loadMore ( limit ?: number ) : Promise < void > {
123- return this . ensureResults ( ) . loadMore ( limit ) ;
124- }
125-
126108 async edit ( search ?: {
127109 pattern : SearchQuery ;
128110 labels : {
@@ -156,8 +138,6 @@ export class SearchResultsNode extends ViewNode<'search-results', SearchAndCompa
156138
157139 this . _search = search . pattern ;
158140 this . _labels = search . labels ;
159- this . _searchQueryOrLog = search . log ;
160- this . _resultsNode = undefined ;
161141
162142 // Remove the existing stored item and save a new one
163143 await this . replace ( currentId , true ) ;
@@ -166,76 +146,6 @@ export class SearchResultsNode extends ViewNode<'search-results', SearchAndCompa
166146 queueMicrotask ( ( ) => this . view . reveal ( this , { expand : true , focus : true , select : true } ) ) ;
167147 }
168148
169- @debug ( )
170- override refresh ( reset : boolean = false ) : void {
171- this . _resultsNode ?. refresh ( reset ) ;
172- }
173-
174- private getSearchLabel (
175- label :
176- | string
177- | {
178- label : string ;
179- resultsType ?: { singular : string ; plural : string } ;
180- } ,
181- log : GitLog | undefined ,
182- ) : string {
183- if ( typeof label === 'string' ) return label ;
184-
185- const count = log ?. count ?? 0 ;
186-
187- const resultsType =
188- label . resultsType === undefined
189- ? { singular : 'search result' , plural : 'search results' }
190- : label . resultsType ;
191-
192- return `${ pluralize ( resultsType . singular , count , {
193- format : c => ( log ?. hasMore ? `${ c } +` : String ( c ) ) ,
194- plural : resultsType . plural ,
195- zero : 'No' ,
196- } ) } ${ label . label } `;
197- }
198-
199- private getSearchQuery (
200- options : {
201- label :
202- | string
203- | {
204- label : string ;
205- resultsType ?: { singular : string ; plural : string } ;
206- } ;
207- } ,
208- log ?: Promise < GitLog | undefined > | GitLog ,
209- ) : ( limit : number | undefined ) => Promise < SearchQueryResults > {
210- let useCacheOnce = true ;
211-
212- return async ( limit : number | undefined ) => {
213- log = await ( log ??
214- this . view . container . git . getRepositoryService ( this . repoPath ) . commits . searchCommits ( this . search ) ) ;
215-
216- if ( ! useCacheOnce && log ?. query != null ) {
217- log = await log . query ( limit ) ;
218- }
219- useCacheOnce = false ;
220-
221- const results : Mutable < SearchQueryResults > = {
222- label : this . getSearchLabel ( options . label , log ) ,
223- log : log ,
224- hasMore : log ?. hasMore ?? false ,
225- } ;
226- if ( results . hasMore ) {
227- results . more = async ( limit : number | undefined ) => {
228- results . log = ( await results . log ?. more ?.( limit ) ) ?? results . log ;
229-
230- results . label = this . getSearchLabel ( options . label , results . log ) ;
231- results . hasMore = results . log ?. hasMore ?? true ;
232- } ;
233- }
234-
235- return results ;
236- } ;
237- }
238-
239149 private getStorageId ( ) {
240150 return md5 ( `${ this . repoPath } |${ getSearchQueryComparisonKey ( this . search ) } ` , 'base64' ) ;
241151 }
@@ -263,3 +173,71 @@ export class SearchResultsNode extends ViewNode<'search-results', SearchAndCompa
263173 ) ;
264174 }
265175}
176+
177+ function createSearchQuery (
178+ view : SearchAndCompareView ,
179+ repoPath : string ,
180+ search : SearchQuery ,
181+ labels : {
182+ label : string ;
183+ queryLabel : string | { label : string ; resultsType ?: { singular : string ; plural : string } } ;
184+ resultsType ?: { singular : string ; plural : string } ;
185+ } ,
186+ searchQueryOrLog ?:
187+ | ( ( limit : number | undefined ) => Promise < CommitsQueryResults > )
188+ | Promise < GitLog | undefined >
189+ | GitLog
190+ | undefined ,
191+ ) : ( limit : number | undefined ) => Promise < CommitsQueryResults > {
192+ if ( typeof searchQueryOrLog === 'function' ) {
193+ return searchQueryOrLog ;
194+ }
195+
196+ // Create a search query function
197+ return async ( limit : number | undefined ) => {
198+ let log = searchQueryOrLog ;
199+ if ( log == null ) {
200+ log = await view . container . git . getRepositoryService ( repoPath ) . commits . searchCommits ( search ) ;
201+ } else if ( log instanceof Promise ) {
202+ log = await log ;
203+ }
204+
205+ if ( log ?. query != null ) {
206+ log = await log . query ( limit ) ;
207+ }
208+
209+ const count = log ?. count ?? 0 ;
210+ const queryLabel = labels . queryLabel ;
211+ const resultsType =
212+ typeof queryLabel === 'string'
213+ ? { singular : 'search result' , plural : 'search results' }
214+ : queryLabel . resultsType ?? { singular : 'search result' , plural : 'search results' } ;
215+
216+ const label = `${ pluralize ( resultsType . singular , count , {
217+ format : c => ( log ?. hasMore ? `${ c } +` : String ( c ) ) ,
218+ plural : resultsType . plural ,
219+ zero : 'No' ,
220+ } ) } ${ typeof queryLabel === 'string' ? queryLabel : queryLabel . label } `;
221+
222+ const results : Mutable < SearchQueryResults > = {
223+ label : label ,
224+ log : log ,
225+ hasMore : log ?. hasMore ?? false ,
226+ } ;
227+
228+ if ( results . hasMore ) {
229+ results . more = async ( limit : number | undefined ) => {
230+ results . log = ( await results . log ?. more ?.( limit ) ) ?? results . log ;
231+ const newCount = results . log ?. count ?? 0 ;
232+ results . label = `${ pluralize ( resultsType . singular , newCount , {
233+ format : c => ( results . log ?. hasMore ? `${ c } +` : String ( c ) ) ,
234+ plural : resultsType . plural ,
235+ zero : 'No' ,
236+ } ) } ${ typeof queryLabel === 'string' ? queryLabel : queryLabel . label } `;
237+ results . hasMore = results . log ?. hasMore ?? true ;
238+ } ;
239+ }
240+
241+ return results ;
242+ } ;
243+ }
0 commit comments