@codingame/monaco-vscode-base-service-override 36.2.7 → 37.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-base-service-override",
3
- "version": "36.2.7",
3
+ "version": "37.1.0",
4
4
  "private": false,
5
5
  "description": "VSCode public API plugged on the monaco editor - base service-override",
6
6
  "keywords": [],
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "type": "module",
17
17
  "dependencies": {
18
- "@codingame/monaco-vscode-api": "36.2.7"
18
+ "@codingame/monaco-vscode-api": "37.1.0"
19
19
  },
20
20
  "main": "index.js",
21
21
  "module": "index.js",
@@ -20,6 +20,9 @@ async function request(options, token, isOnline) {
20
20
  if (options.disableCache) {
21
21
  fetchInit.cache = "no-store";
22
22
  }
23
+ if (options.followRedirects === 0) {
24
+ fetchInit.redirect = "manual";
25
+ }
23
26
  const res = await fetch(options.url || "", fetchInit);
24
27
  return {
25
28
  res: {
@@ -137,7 +137,7 @@ let JSONEditingService = class JSONEditingService {
137
137
  case JSONEditingErrorCode.ERROR_INVALID_FILE:
138
138
  {
139
139
  return localize(
140
- 17443,
140
+ 19504,
141
141
  "Unable to write into the file. Please open the file to correct errors/warnings in the file and try again."
142
142
  );
143
143
  }
@@ -18,7 +18,7 @@ import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/ext
18
18
  import { hash } from '@codingame/monaco-vscode-api/vscode/vs/base/common/hash';
19
19
  import { IUriIdentityService } from '@codingame/monaco-vscode-api/vscode/vs/platform/uriIdentity/common/uriIdentity.service';
20
20
  import { distinct, asArray } from '@codingame/monaco-vscode-api/vscode/vs/base/common/arrays';
21
- import { asCssVariable } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/colorUtils';
21
+ import { asCssVariableWithDefault, asCssVariable } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/colorUtils';
22
22
  import '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/colors/baseColors';
23
23
  import '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/colors/chartsColors';
24
24
  import '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/colors/editorColors';
@@ -80,7 +80,7 @@ class DecorationRule {
80
80
  } = data;
81
81
  createCSSRule(`.${this.itemColorClassName}`, `color: ${getColor(color)};`, element);
82
82
  if (ThemeIcon.isThemeIcon(letter)) {
83
- this._createIconCSSRule(letter, color, element);
83
+ this._createIconCSSRule(letter, getColor(color), element);
84
84
  } else if (letter) {
85
85
  createCSSRule(
86
86
  `.${this.itemBadgeClassName}::after`,
@@ -90,10 +90,11 @@ class DecorationRule {
90
90
  }
91
91
  }
92
92
  _appendForMany(data, element) {
93
- const {
94
- color
95
- } = data.find(d => !!d.color) ?? data[0];
96
- createCSSRule(`.${this.itemColorClassName}`, `color: ${getColor(color)};`, element);
93
+ const color = data.reduceRight(
94
+ (fallback, decoration) => decoration.color ? asCssVariableWithDefault(decoration.color, fallback) : fallback,
95
+ "inherit"
96
+ );
97
+ createCSSRule(`.${this.itemColorClassName}`, `color: ${color};`, element);
97
98
  const letters = [];
98
99
  let icon;
99
100
  for (const d of data) {
@@ -110,13 +111,13 @@ class DecorationRule {
110
111
  if (letters.length) {
111
112
  createCSSRule(
112
113
  `.${this.itemBadgeClassName}::after`,
113
- `content: "${letters.join(", ")}"; color: ${getColor(color)};`,
114
+ `content: "${letters.join(", ")}"; color: ${color};`,
114
115
  element
115
116
  );
116
117
  }
117
118
  createCSSRule(
118
119
  `.${this.bubbleBadgeClassName}::after`,
119
- `content: "\uea71"; color: ${getColor(color)}; font-family: codicon; font-size: 14px; margin-right: 14px; opacity: 0.4;`,
120
+ `content: "\uea71"; color: ${color}; font-family: codicon; font-size: 14px; margin-right: 14px; opacity: 0.4;`,
120
121
  element
121
122
  );
122
123
  }
@@ -137,7 +138,7 @@ class DecorationRule {
137
138
  createCSSRule(
138
139
  `.${this.iconBadgeClassName}::after`,
139
140
  `content: '${definition.fontCharacter}';
140
- color: ${icon.color ? getColor(icon.color.id) : getColor(color)};
141
+ color: ${icon.color ? getColor(icon.color.id) : color};
141
142
  font-family: ${stringValue(definition.font?.id ?? "codicon")};
142
143
  font-size: 16px;
143
144
  margin-right: 14px;
@@ -181,7 +182,7 @@ class DecorationStyles {
181
182
  const strikethrough = ( data.some(d => d.strikethrough));
182
183
  if (onlyChildren) {
183
184
  badgeClassName = rule.bubbleBadgeClassName;
184
- tooltip = ( localize(17482, "Contains emphasized items"));
185
+ tooltip = ( localize(19554, "Contains emphasized items"));
185
186
  }
186
187
  return {
187
188
  labelClassName,
@@ -226,7 +227,7 @@ let DecorationsService = class DecorationsService {
226
227
  this._onDidChangeDecorations = this._store.add(( new Emitter()));
227
228
  this.onDidChangeDecorations = this._onDidChangeDecorations.event;
228
229
  this._provider = ( new LinkedList());
229
- this._decorationStyles = ( new DecorationStyles(themeService));
230
+ this._decorationStyles = this._store.add(( new DecorationStyles(themeService)));
230
231
  this._data = TernarySearchTree.forUris(key => uriIdentityService.extUri.ignorePathCasing(key));
231
232
  this._store.add(this._onDidChangeDecorationsDelayed.event(event => {
232
233
  this._onDidChangeDecorations.fire(( new FileDecorationChangeEvent(event)));
@@ -3,7 +3,7 @@ import { IDisposable, Disposable } from "@codingame/monaco-vscode-api/vscode/vs/
3
3
  import { IWorkbenchEnvironmentService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service";
4
4
  import { IWorkspace, ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from "@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace";
5
5
  import { IWorkspaceContextService } from "@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace.service";
6
- import { ResourceLabelFormatter, ResourceLabelFormatting, IFormatterChangeEvent, Verbosity } from "@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label";
6
+ import { ResourceLabelFormatter, ResourceLabelFormatting, IFormatterChangeEvent, Verbosity, ResourceLabelTemplateFormatter } from "@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label";
7
7
  import { ILabelService } from "@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label.service";
8
8
  import { ILifecycleService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle.service";
9
9
  import { IPathService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/path/common/pathService.service";
@@ -16,6 +16,7 @@ export declare class LabelService extends Disposable implements ILabelService {
16
16
  private readonly remoteAgentService;
17
17
  readonly _serviceBrand: undefined;
18
18
  private formatters;
19
+ private homeFormatters;
19
20
  private readonly _onDidChangeFormatters;
20
21
  readonly onDidChangeFormatters: import("@codingame/monaco-vscode-api/vscode/vs/base/common/event").Event<IFormatterChangeEvent>;
21
22
  private readonly storedFormattersMemento;
@@ -24,6 +25,9 @@ export declare class LabelService extends Disposable implements ILabelService {
24
25
  private userHome;
25
26
  constructor(environmentService: IWorkbenchEnvironmentService, contextService: IWorkspaceContextService, pathService: IPathService, remoteAgentService: IRemoteAgentService, storageService: IStorageService, lifecycleService: ILifecycleService);
26
27
  private resolveRemoteEnvironment;
28
+ getUriHome(resource: URI): URI | undefined;
29
+ private findHomeFormatter;
30
+ private findStaticHomeFormatter;
27
31
  findFormatting(resource: URI): ResourceLabelFormatting | undefined;
28
32
  getUriLabel(resource: URI, options?: {
29
33
  relative?: boolean;
@@ -42,7 +46,8 @@ export declare class LabelService extends Disposable implements ILabelService {
42
46
  getHostLabel(scheme: string, authority?: string): string;
43
47
  getHostTooltip(scheme: string, authority?: string): string | undefined;
44
48
  registerCachedFormatter(formatter: ResourceLabelFormatter): IDisposable;
45
- registerFormatter(formatter: ResourceLabelFormatter): IDisposable;
49
+ registerFormatter(formatter: ResourceLabelFormatter | ResourceLabelTemplateFormatter): IDisposable;
50
+ private createTemplateFormatterRegistration;
46
51
  private formatUri;
47
52
  private adjustPathSeparators;
48
53
  private appendWorkspaceSuffix;
@@ -10,7 +10,7 @@ import { Registry } from '@codingame/monaco-vscode-api/vscode/vs/platform/regist
10
10
  import { IWorkbenchEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service';
11
11
  import { isWorkspace, toWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, isUntitledWorkspace, isTemporaryWorkspace, WORKSPACE_EXTENSION } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace';
12
12
  import { IWorkspaceContextService } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace.service';
13
- import { basenameOrAuthority, basename, joinPath, dirname } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
13
+ import { isEqualOrParent, relativePath, basenameOrAuthority, basename, joinPath, dirname } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
14
14
  import { getPathLabel, tildify } from '@codingame/monaco-vscode-api/vscode/vs/base/common/labels';
15
15
  import { Verbosity } from '@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label';
16
16
  import { ILabelService } from '@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label.service';
@@ -27,11 +27,12 @@ import { Schemas } from '@codingame/monaco-vscode-api/vscode/vs/base/common/netw
27
27
  import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
28
28
  import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
29
29
  import { Memento } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/memento';
30
+ import { escapeRegExpCharacters } from '@codingame/monaco-vscode-api/vscode/vs/base/common/strings';
30
31
 
31
32
  const resourceLabelFormattersExtPoint = ExtensionsRegistry.registerExtensionPoint({
32
33
  extensionPoint: "resourceLabelFormatters",
33
34
  jsonSchema: {
34
- description: ( localize(17792, "Contributes resource label formatting rules.")),
35
+ description: ( localize(19869, "Contributes resource label formatting rules.")),
35
36
  type: "array",
36
37
  items: {
37
38
  type: "object",
@@ -40,52 +41,52 @@ const resourceLabelFormattersExtPoint = ExtensionsRegistry.registerExtensionPoin
40
41
  scheme: {
41
42
  type: "string",
42
43
  description: ( localize(
43
- 17793,
44
+ 19870,
44
45
  "URI scheme on which to match the formatter on. For example \"file\". Simple glob patterns are supported."
45
46
  ))
46
47
  },
47
48
  authority: {
48
49
  type: "string",
49
50
  description: ( localize(
50
- 17794,
51
+ 19871,
51
52
  "URI authority on which to match the formatter on. Simple glob patterns are supported."
52
53
  ))
53
54
  },
54
55
  formatting: {
55
- description: ( localize(17795, "Rules for formatting uri resource labels.")),
56
+ description: ( localize(19872, "Rules for formatting uri resource labels.")),
56
57
  type: "object",
57
58
  properties: {
58
59
  label: {
59
60
  type: "string",
60
61
  description: ( localize(
61
- 17796,
62
+ 19873,
62
63
  "Label rules to display. For example: myLabel:/${path}. ${path}, ${scheme}, ${authority} and ${authoritySuffix} are supported as variables."
63
64
  ))
64
65
  },
65
66
  separator: {
66
67
  type: "string",
67
68
  description: ( localize(
68
- 17797,
69
+ 19874,
69
70
  "Separator to be used in the uri label display. '/' or '' as an example."
70
71
  ))
71
72
  },
72
73
  stripPathStartingSeparator: {
73
74
  type: "boolean",
74
75
  description: ( localize(
75
- 17798,
76
+ 19875,
76
77
  "Controls whether `${path}` substitutions should have starting separator characters stripped."
77
78
  ))
78
79
  },
79
80
  tildify: {
80
81
  type: "boolean",
81
82
  description: ( localize(
82
- 17799,
83
+ 19876,
83
84
  "Controls if the start of the uri label should be tildified when possible."
84
85
  ))
85
86
  },
86
87
  workspaceSuffix: {
87
88
  type: "string",
88
- description: ( localize(17800, "Suffix appended to the workspace label."))
89
+ description: ( localize(19877, "Suffix appended to the workspace label."))
89
90
  }
90
91
  }
91
92
  }
@@ -114,7 +115,7 @@ let ResourceLabelFormattersHandler = class ResourceLabelFormattersHandler {
114
115
  if (typeof formatter.formatting.separator !== `string`) {
115
116
  formatter.formatting.separator = sep;
116
117
  }
117
- if (!isProposedApiEnabled(added.description) && formatter.formatting.workspaceTooltip) {
118
+ if (!isProposedApiEnabled(added.description, "contribLabelFormatterWorkspaceTooltip") && formatter.formatting.workspaceTooltip) {
118
119
  formatter.formatting.workspaceTooltip = undefined;
119
120
  }
120
121
  this.formattersDisposables.set(formatter, labelService.registerFormatter(formatter));
@@ -131,6 +132,10 @@ let ResourceLabelFormattersHandler = class ResourceLabelFormattersHandler {
131
132
  ResourceLabelFormattersHandler = ( __decorate([( __param(0, ILabelService))], ResourceLabelFormattersHandler));
132
133
  ( Registry.as(Extensions.Workbench)).registerWorkbenchContribution(ResourceLabelFormattersHandler, LifecyclePhase.Restored);
133
134
  const FORMATTER_CACHE_SIZE = 50;
135
+ const homeTemplateParameterRegex = /^\$\{(?<name>[a-zA-Z_][\w]*)\}$/;
136
+ function isTemplateFormatter(formatter) {
137
+ return URI.isUri(formatter.home);
138
+ }
134
139
  let LabelService = class LabelService extends Disposable {
135
140
  constructor(
136
141
  environmentService,
@@ -145,6 +150,7 @@ let LabelService = class LabelService extends Disposable {
145
150
  this.contextService = contextService;
146
151
  this.pathService = pathService;
147
152
  this.remoteAgentService = remoteAgentService;
153
+ this.homeFormatters = [];
148
154
  this._onDidChangeFormatters = this._register(( new Emitter({
149
155
  leakWarningThreshold: 400,
150
156
  leakWarningName: "LabelService._onDidChangeFormatters"
@@ -164,27 +170,106 @@ let LabelService = class LabelService extends Disposable {
164
170
  this.os = env?.os ?? OS;
165
171
  this.userHome = await this.pathService.userHome();
166
172
  }
173
+ getUriHome(resource) {
174
+ const formatter = this.findHomeFormatter(resource);
175
+ return formatter?.home;
176
+ }
177
+ findHomeFormatter(resource) {
178
+ let bestResult = this.findStaticHomeFormatter(resource);
179
+ let bestResultIsTemplate = false;
180
+ for (const registration of this.homeFormatters) {
181
+ const formatter = registration.formatter;
182
+ if (formatter.home.scheme !== resource.scheme || (formatter.home.authority && formatter.home.authority.toLowerCase() !== resource.authority.toLowerCase())) {
183
+ continue;
184
+ }
185
+ const templateMatch = registration.templateMatcher.exec(resource.path);
186
+ if (!templateMatch) {
187
+ continue;
188
+ }
189
+ const parameters = ( new Map(Object.entries(templateMatch.groups ?? {})));
190
+ const home = resource.with({
191
+ path: templateMatch[0],
192
+ query: null,
193
+ fragment: null
194
+ });
195
+ const formatting = formatter.formatting({
196
+ resource,
197
+ home,
198
+ parameters
199
+ });
200
+ if (!formatting) {
201
+ continue;
202
+ }
203
+ const result = {
204
+ home,
205
+ formatting,
206
+ literalLabel: true,
207
+ homeLength: home.path.length,
208
+ authorityLength: formatter.home.authority.length
209
+ };
210
+ if (!bestResult || result.homeLength > bestResult.homeLength || (result.homeLength === bestResult.homeLength && result.authorityLength > bestResult.authorityLength) || (result.homeLength === bestResult.homeLength && result.authorityLength === bestResult.authorityLength && !bestResultIsTemplate)) {
211
+ bestResult = result;
212
+ bestResultIsTemplate = true;
213
+ }
214
+ }
215
+ return bestResult;
216
+ }
217
+ findStaticHomeFormatter(resource) {
218
+ let bestResult;
219
+ for (const formatter of this.formatters) {
220
+ if (!formatter.home || formatter.scheme !== resource.scheme || (formatter.authority && !match(formatter.authority, resource.authority, {
221
+ ignoreCase: true
222
+ })) || !isEqualOrParent(resource, resource.with({
223
+ path: formatter.home
224
+ }))) {
225
+ continue;
226
+ }
227
+ const result = {
228
+ home: resource.with({
229
+ path: formatter.home,
230
+ query: null,
231
+ fragment: null
232
+ }),
233
+ formatting: formatter.formatting,
234
+ literalLabel: false,
235
+ homeLength: formatter.home.length,
236
+ authorityLength: formatter.authority?.length ?? 0
237
+ };
238
+ if (!bestResult || result.homeLength > bestResult.homeLength || (result.homeLength === bestResult.homeLength && result.authorityLength > bestResult.authorityLength) || (result.homeLength === bestResult.homeLength && result.authorityLength === bestResult.authorityLength && formatter.priority)) {
239
+ bestResult = result;
240
+ }
241
+ }
242
+ return bestResult;
243
+ }
167
244
  findFormatting(resource) {
168
245
  let bestResult;
169
246
  for (const formatter of this.formatters) {
170
- if (formatter.scheme === resource.scheme) {
171
- if (!formatter.authority && (!bestResult || formatter.priority)) {
172
- bestResult = formatter;
173
- continue;
174
- }
175
- if (!formatter.authority) {
176
- continue;
177
- }
178
- if (match(formatter.authority, resource.authority, {
179
- ignoreCase: true
180
- }) && (!bestResult?.authority || formatter.authority.length > bestResult.authority.length || ((formatter.authority.length === bestResult.authority.length) && formatter.priority))) {
181
- bestResult = formatter;
182
- }
247
+ if (formatter.home || formatter.scheme !== resource.scheme) {
248
+ continue;
249
+ }
250
+ if (!formatter.authority && (!bestResult || formatter.priority)) {
251
+ bestResult = formatter;
252
+ continue;
253
+ }
254
+ if (!formatter.authority) {
255
+ continue;
256
+ }
257
+ if (match(formatter.authority, resource.authority, {
258
+ ignoreCase: true
259
+ }) && (!bestResult?.authority || formatter.authority.length > bestResult.authority.length || ((formatter.authority.length === bestResult.authority.length) && formatter.priority))) {
260
+ bestResult = formatter;
183
261
  }
184
262
  }
185
- return bestResult ? bestResult.formatting : undefined;
263
+ return bestResult?.formatting;
186
264
  }
187
265
  getUriLabel(resource, options = {}) {
266
+ const homeFormatter = options.noPrefix ? undefined : this.findHomeFormatter(resource);
267
+ if (homeFormatter) {
268
+ const separator = options.separator ?? homeFormatter.formatting.separator;
269
+ const path = relativePath(homeFormatter.home, resource);
270
+ const label = homeFormatter.literalLabel ? homeFormatter.formatting.label : this.formatUri(homeFormatter.home, homeFormatter.formatting);
271
+ return path ? `${label}${separator}${this.adjustPathSeparators(path, separator)}` : label;
272
+ }
188
273
  let formatting = this.findFormatting(resource);
189
274
  if (formatting && options.separator) {
190
275
  formatting = {
@@ -282,10 +367,10 @@ let LabelService = class LabelService extends Disposable {
282
367
  }
283
368
  doGetWorkspaceLabel(workspaceUri, options) {
284
369
  if (isUntitledWorkspace(workspaceUri, this.environmentService)) {
285
- return localize(17801, "Untitled (Workspace)");
370
+ return localize(19878, "Untitled (Workspace)");
286
371
  }
287
372
  if (isTemporaryWorkspace(workspaceUri)) {
288
- return localize(17802, "Workspace");
373
+ return localize(19879, "Workspace");
289
374
  }
290
375
  let filename = basename(workspaceUri);
291
376
  if (filename.endsWith(WORKSPACE_EXTENSION)) {
@@ -298,14 +383,14 @@ let LabelService = class LabelService extends Disposable {
298
383
  break;
299
384
  case Verbosity.LONG:
300
385
  label = ( localize(
301
- 17803,
386
+ 19880,
302
387
  "{0} (Workspace)",
303
388
  this.getUriLabel(joinPath(dirname(workspaceUri), filename))
304
389
  ));
305
390
  break;
306
391
  case Verbosity.MEDIUM:
307
392
  default:
308
- label = ( localize(17804, "{0} (Workspace)", filename));
393
+ label = ( localize(19881, "{0} (Workspace)", filename));
309
394
  break;
310
395
  }
311
396
  if (options?.verbose === Verbosity.SHORT) {
@@ -369,19 +454,64 @@ let LabelService = class LabelService extends Disposable {
369
454
  return this.registerFormatter(formatter);
370
455
  }
371
456
  registerFormatter(formatter) {
372
- this.formatters.push(formatter);
457
+ let homeRegistration;
458
+ let scheme;
459
+ if (isTemplateFormatter(formatter)) {
460
+ homeRegistration = this.createTemplateFormatterRegistration(formatter);
461
+ this.homeFormatters.push(homeRegistration);
462
+ scheme = formatter.home.scheme;
463
+ } else {
464
+ this.formatters.push(formatter);
465
+ scheme = formatter.scheme;
466
+ }
373
467
  this._onDidChangeFormatters.fire({
374
- scheme: formatter.scheme
468
+ scheme
375
469
  });
470
+ const changeListener = homeRegistration?.formatter.onDidChangeFormatting(() => this._onDidChangeFormatters.fire({
471
+ scheme
472
+ }));
376
473
  return {
377
474
  dispose: () => {
475
+ changeListener?.dispose();
378
476
  this.formatters = this.formatters.filter(f => f !== formatter);
477
+ if (homeRegistration) {
478
+ this.homeFormatters = this.homeFormatters.filter(candidate => candidate !== homeRegistration);
479
+ }
379
480
  this._onDidChangeFormatters.fire({
380
- scheme: formatter.scheme
481
+ scheme
381
482
  });
382
483
  }
383
484
  };
384
485
  }
486
+ createTemplateFormatterRegistration(formatter) {
487
+ const {
488
+ home
489
+ } = formatter;
490
+ const homePath = home.path.length > 1 ? home.path.replace(/\/+$/, "") : home.path;
491
+ const parameterNames = ( new Set());
492
+ const matcherPattern = ( homePath.split("/").map(segment => {
493
+ const parameterMatch = homeTemplateParameterRegex.exec(segment);
494
+ if (parameterMatch?.groups?.name) {
495
+ const parameterName = parameterMatch.groups.name;
496
+ if (( parameterNames.has(parameterName))) {
497
+ throw ( new Error(`Duplicate resource label home template parameter: ${parameterName}`));
498
+ }
499
+ parameterNames.add(parameterName);
500
+ return `(?<${parameterName}>(?!\\.{1,2}(?:/|$))[^/]+)`;
501
+ }
502
+ if (segment.includes("${")) {
503
+ throw ( new Error(
504
+ `Resource label home template parameters must occupy an entire path segment: ${segment}`
505
+ ));
506
+ }
507
+ return escapeRegExpCharacters(segment);
508
+ })).join("/");
509
+ const isRootHome = homePath === "" || homePath === "/";
510
+ return {
511
+ formatter,
512
+ templateMatcher: ( new RegExp(`^${matcherPattern}${isRootHome ? "" : "(?=/|$)"}`))
513
+ };
514
+ }
385
515
  formatUri(resource, formatting, forceNoTildify) {
386
516
  let label = formatting.label.replace(labelMatchingRegexp, (match, token, qsToken, qsValue) => {
387
517
  switch (token) {
@@ -15,7 +15,7 @@ import { mainWindow } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/
15
15
  let BrowserRequestService = class BrowserRequestService extends AbstractRequestService {
16
16
  constructor(remoteAgentService, configurationService, loggerService) {
17
17
  const logger = loggerService.createLogger(`network`, {
18
- name: ( localize(17912, "Network")),
18
+ name: ( localize(20013, "Network")),
19
19
  group: windowLogGroup
20
20
  });
21
21
  const logService = ( new LogService(logger));
@@ -29,13 +29,13 @@ let StoredFileWorkingCopySaveParticipant = class StoredFileWorkingCopySavePartic
29
29
  const cts = ( new CancellationTokenSource(token));
30
30
  workingCopy.model?.pushStackElement();
31
31
  progress.report({
32
- message: ( localize(18314, "Running Code Actions and Formatters..."))
32
+ message: ( localize(20416, "Running Code Actions and Formatters..."))
33
33
  });
34
34
  let bubbleCancel = false;
35
35
  await this.progressService.withProgress({
36
36
  priority: NotificationPriority.URGENT,
37
37
  location: ProgressLocation.Notification,
38
- cancellable: ( localize(18315, "Skip")),
38
+ cancellable: ( localize(20417, "Skip")),
39
39
  delay: workingCopy.isDirty() ? 5000 : 3000
40
40
  }, async progress => {
41
41
  const participants = Array.from(this.saveParticipants).sort((a, b) => {