@@ -7,6 +7,7 @@ import type { Container } from '../container';
7
7
import type { GitRemote } from '../git/models/remote' ;
8
8
import type { RemoteProviderId } from '../git/remotes/remoteProvider' ;
9
9
import { getIssueOrPullRequestHtmlIcon , getIssueOrPullRequestMarkdownIcon } from '../git/utils/-webview/icons' ;
10
+ import type { ConfiguredIntegrationsChangeEvent } from '../plus/integrations/authentication/configuredIntegrationService' ;
10
11
import type { HostingIntegration , Integration , IssueIntegration } from '../plus/integrations/integration' ;
11
12
import { IntegrationBase } from '../plus/integrations/integration' ;
12
13
import { remoteProviderIdToIntegrationId } from '../plus/integrations/integrationService' ;
@@ -18,6 +19,7 @@ import { join, map } from '../system/iterable';
18
19
import { Logger } from '../system/logger' ;
19
20
import { escapeMarkdown } from '../system/markdown' ;
20
21
import { getSettledValue , isPromise } from '../system/promise' ;
22
+ import { PromiseCache } from '../system/promiseCache' ;
21
23
import { capitalize , encodeHtmlWeak , getSuperscript } from '../system/string' ;
22
24
import type {
23
25
Autolink ,
@@ -26,24 +28,28 @@ import type {
26
28
EnrichedAutolink ,
27
29
MaybeEnrichedAutolink ,
28
30
RefSet ,
29
- } from './autolinks.utils ' ;
31
+ } from './models/ autolinks' ;
30
32
import {
31
33
ensureCachedRegex ,
32
34
getAutolinks ,
33
35
getBranchAutolinks ,
34
36
isDynamic ,
35
37
numRegex ,
36
38
supportedAutolinkIntegrations ,
37
- } from './autolinks.utils' ;
39
+ } from './utils/-webview/ autolinks.utils' ;
38
40
39
41
const emptyAutolinkMap = Object . freeze ( new Map < string , Autolink > ( ) ) ;
40
42
41
- export class Autolinks implements Disposable {
42
- protected _disposable : Disposable | undefined ;
43
+ export class AutolinksProvider implements Disposable {
44
+ private _disposable : Disposable | undefined ;
43
45
private _references : CacheableAutolinkReference [ ] = [ ] ;
46
+ private _refsetCache = new PromiseCache < string | undefined , RefSet [ ] > ( { accessTTL : 1000 * 60 * 60 } ) ;
44
47
45
48
constructor ( private readonly container : Container ) {
46
- this . _disposable = Disposable . from ( configuration . onDidChange ( this . onConfigurationChanged , this ) ) ;
49
+ this . _disposable = Disposable . from (
50
+ configuration . onDidChange ( this . onConfigurationChanged , this ) ,
51
+ container . integrations . onDidChangeConfiguredIntegrations ( this . onConfiguredIntegrationsChanged , this ) ,
52
+ ) ;
47
53
48
54
this . setAutolinksFromConfig ( ) ;
49
55
}
@@ -55,9 +61,14 @@ export class Autolinks implements Disposable {
55
61
private onConfigurationChanged ( e ?: ConfigurationChangeEvent ) {
56
62
if ( configuration . changed ( e , 'autolinks' ) ) {
57
63
this . setAutolinksFromConfig ( ) ;
64
+ this . _refsetCache . clear ( ) ;
58
65
}
59
66
}
60
67
68
+ private onConfiguredIntegrationsChanged ( _e : ConfiguredIntegrationsChangeEvent ) {
69
+ this . _refsetCache . clear ( ) ;
70
+ }
71
+
61
72
private setAutolinksFromConfig ( ) {
62
73
const autolinks = configuration . get ( 'autolinks' ) ;
63
74
// Since VS Code's configuration objects are live we need to copy them to avoid writing back to the configuration
@@ -118,57 +129,40 @@ export class Autolinks implements Disposable {
118
129
}
119
130
120
131
/** Collects custom-configured autolink references into @param refsets */
121
- private collectCustomAutolinks (
122
- remote : GitRemote | undefined ,
123
- refsets : RefSet [ ] ,
124
- options ?: { excludeCustom ?: boolean } ,
125
- ) : void {
126
- if ( this . _references . length && ( remote ?. provider == null || ! options ?. excludeCustom ) ) {
132
+ private collectCustomAutolinks ( refsets : RefSet [ ] ) : void {
133
+ if ( this . _references . length ) {
127
134
refsets . push ( [ undefined , this . _references ] ) ;
128
135
}
129
136
}
130
137
131
- private async getRefSets ( remote ?: GitRemote , options ?: { excludeCustom ?: boolean } ) {
132
- const refsets : RefSet [ ] = [ ] ;
138
+ private async getRefSets ( remote ?: GitRemote ) {
139
+ return this . _refsetCache . get ( remote ?. remoteKey , async ( ) => {
140
+ const refsets : RefSet [ ] = [ ] ;
133
141
134
- await this . collectIntegrationAutolinks ( remote , refsets ) ;
135
- this . collectRemoteAutolinks ( remote , refsets ) ;
136
- this . collectCustomAutolinks ( remote , refsets , options ) ;
142
+ await this . collectIntegrationAutolinks ( remote , refsets ) ;
143
+ this . collectRemoteAutolinks ( remote , refsets ) ;
144
+ this . collectCustomAutolinks ( refsets ) ;
137
145
138
- return refsets ;
146
+ return refsets ;
147
+ } ) ;
139
148
}
140
149
141
150
/** @returns A sorted list of autolinks. the first match is the most relevant */
142
- async getBranchAutolinks (
143
- branchName : string ,
144
- remote ?: GitRemote ,
145
- options ?: { excludeCustom ?: boolean } ,
146
- ) : Promise < Map < string , Autolink > > {
147
- const refsets = await this . getRefSets ( remote , options ) ;
151
+ async getBranchAutolinks ( branchName : string , remote ?: GitRemote ) : Promise < Map < string , Autolink > > {
152
+ const refsets = await this . getRefSets ( remote ) ;
148
153
if ( refsets . length === 0 ) return emptyAutolinkMap ;
149
154
150
155
return getBranchAutolinks ( branchName , refsets ) ;
151
156
}
152
157
153
- async getAutolinks ( message : string , remote ?: GitRemote ) : Promise < Map < string , Autolink > > ;
154
- async getAutolinks (
155
- message : string ,
156
- remote : GitRemote ,
157
- // eslint-disable-next-line @typescript-eslint/unified-signatures
158
- options ?: { excludeCustom ?: boolean } ,
159
- ) : Promise < Map < string , Autolink > > ;
160
- @debug < Autolinks [ 'getAutolinks' ] > ( {
158
+ @debug < AutolinksProvider [ 'getAutolinks' ] > ( {
161
159
args : {
162
160
0 : '<message>' ,
163
161
1 : false ,
164
162
} ,
165
163
} )
166
- async getAutolinks (
167
- message : string ,
168
- remote ?: GitRemote ,
169
- options ?: { excludeCustom ?: boolean } ,
170
- ) : Promise < Map < string , Autolink > > {
171
- const refsets = await this . getRefSets ( remote , options ) ;
164
+ async getAutolinks ( message : string , remote ?: GitRemote ) : Promise < Map < string , Autolink > > {
165
+ const refsets = await this . getRefSets ( remote ) ;
172
166
if ( refsets . length === 0 ) return emptyAutolinkMap ;
173
167
174
168
return getAutolinks ( message , refsets ) ;
@@ -191,7 +185,7 @@ export class Autolinks implements Disposable {
191
185
autolinks : Map < string , Autolink > ,
192
186
remote : GitRemote | undefined ,
193
187
) : Promise < Map < string , EnrichedAutolink > | undefined > ;
194
- @debug < Autolinks [ 'getEnrichedAutolinks' ] > ( {
188
+ @debug < AutolinksProvider [ 'getEnrichedAutolinks' ] > ( {
195
189
args : {
196
190
0 : messageOrAutolinks =>
197
191
typeof messageOrAutolinks === 'string' ? '<message>' : `autolinks=${ messageOrAutolinks . size } ` ,
@@ -264,7 +258,7 @@ export class Autolinks implements Disposable {
264
258
return enrichedAutolinks ;
265
259
}
266
260
267
- @debug < Autolinks [ 'linkify' ] > ( {
261
+ @debug < AutolinksProvider [ 'linkify' ] > ( {
268
262
args : {
269
263
0 : '<text>' ,
270
264
2 : remotes => remotes ?. length ,
0 commit comments