@codingame/monaco-vscode-scm-service-override 1.83.15

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.
@@ -0,0 +1,2245 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import './media/scm.css.js';
3
+ import { Event, Emitter } from 'monaco-editor/esm/vs/base/common/event.js';
4
+ import { basename, dirname } from 'monaco-editor/esm/vs/base/common/resources.js';
5
+ import { Disposable, DisposableStore, toDisposable, combinedDisposable, MutableDisposable, dispose } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
6
+ import { ViewAction, ViewPane } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
7
+ import { append, $, asCSSUrl, Dimension, trackFocus, clearNode } from 'monaco-editor/esm/vs/base/browser/dom.js';
8
+ import { VIEW_PANE_ID, SCMInputChangeReason, ISCMViewService, ISCMService, REPOSITORIES_VIEW_PANE_ID } from 'vscode/vscode/vs/workbench/contrib/scm/common/scm';
9
+ import { ResourceLabels } from 'vscode/vscode/vs/workbench/browser/labels';
10
+ import { CountBadge } from 'monaco-editor/esm/vs/base/browser/ui/countBadge/countBadge.js';
11
+ import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
12
+ import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
13
+ import { IContextMenuService, IContextViewService } from 'monaco-editor/esm/vs/platform/contextview/browser/contextView.js';
14
+ import { RawContextKey, ContextKeyExpr, IContextKeyService } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey.js';
15
+ import { ICommandService } from 'monaco-editor/esm/vs/platform/commands/common/commands.js';
16
+ import { IKeybindingService } from 'monaco-editor/esm/vs/platform/keybinding/common/keybinding.js';
17
+ import { MenuId, MenuRegistry, registerAction2, MenuItemAction, IMenuService, Action2 } from 'monaco-editor/esm/vs/platform/actions/common/actions.js';
18
+ import { Action, Separator, ActionRunner } from 'monaco-editor/esm/vs/base/common/actions.js';
19
+ import { ActionBar } from 'monaco-editor/esm/vs/base/browser/ui/actionbar/actionbar.js';
20
+ import { IThemeService } from 'monaco-editor/esm/vs/platform/theme/common/themeService.js';
21
+ import { connectPrimaryMenuToInlineActionBar, getActionViewItemProvider, isSCMRepository, isSCMResourceGroup, isSCMInput, isSCMActionButton, collectContextMenuActions, isSCMResource } from './util.js';
22
+ import { WorkbenchCompressibleObjectTree } from 'monaco-editor/esm/vs/platform/list/browser/listService.js';
23
+ import { IConfigurationService } from 'monaco-editor/esm/vs/platform/configuration/common/configuration.js';
24
+ import { disposableTimeout, ThrottledDelayer } from 'monaco-editor/esm/vs/base/common/async.js';
25
+ import { ResourceTree } from '../../../../base/common/resourceTree.js';
26
+ import { Iterable } from 'monaco-editor/esm/vs/base/common/iterator.js';
27
+ import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
28
+ import { FileKind } from 'monaco-editor/esm/vs/platform/files/common/files.js';
29
+ import { compareFileNames, comparePaths } from 'monaco-editor/esm/vs/base/common/comparers.js';
30
+ import { createMatches } from 'monaco-editor/esm/vs/base/common/filters.js';
31
+ import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
32
+ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
33
+ import { flatten, coalesce } from 'monaco-editor/esm/vs/base/common/arrays.js';
34
+ import { memoize } from 'monaco-editor/esm/vs/base/common/decorators.js';
35
+ import { WillSaveStateReason, IStorageService } from 'monaco-editor/esm/vs/platform/storage/common/storage.js';
36
+ import { EditorResourceAccessor, SideBySideEditor } from 'vscode/vscode/vs/workbench/common/editor';
37
+ import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vscode/vscode/vs/workbench/common/theme';
38
+ import { CodeEditorWidget } from 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js';
39
+ import { getSimpleEditorOptions } from 'vscode/vscode/vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
40
+ import { IModelService } from 'monaco-editor/esm/vs/editor/common/services/model.js';
41
+ import { EditorExtensionsRegistry } from 'monaco-editor/esm/vs/editor/browser/editorExtensions.js';
42
+ import { MenuPreventer } from 'vscode/vscode/vs/workbench/contrib/codeEditor/browser/menuPreventer';
43
+ import { SelectionClipboardContributionID } from 'vscode/vscode/vs/workbench/contrib/codeEditor/browser/selectionClipboard';
44
+ import { ContextMenuController } from 'monaco-editor/esm/vs/editor/contrib/contextmenu/browser/contextmenu.js';
45
+ import * as platform from 'monaco-editor/esm/vs/base/common/platform.js';
46
+ import { format, compare } from 'monaco-editor/esm/vs/base/common/strings.js';
47
+ import { SuggestController } from 'monaco-editor/esm/vs/editor/contrib/suggest/browser/suggestController.js';
48
+ import { SnippetController2 } from 'monaco-editor/esm/vs/editor/contrib/snippet/browser/snippetController2.js';
49
+ import { ServiceCollection } from 'monaco-editor/esm/vs/platform/instantiation/common/serviceCollection.js';
50
+ import { ModesHoverController } from 'monaco-editor/esm/vs/editor/contrib/hover/browser/hover.js';
51
+ import { ColorDetector } from 'monaco-editor/esm/vs/editor/contrib/colorPicker/browser/colorDetector.js';
52
+ import { LinkDetector } from 'monaco-editor/esm/vs/editor/contrib/links/browser/links.js';
53
+ import { IOpenerService } from 'monaco-editor/esm/vs/platform/opener/common/opener.js';
54
+ import { ITelemetryService } from 'monaco-editor/esm/vs/platform/telemetry/common/telemetry.js';
55
+ import { ILanguageService } from 'monaco-editor/esm/vs/editor/common/languages/language.js';
56
+ import { ILabelService } from 'monaco-editor/esm/vs/platform/label/common/label.js';
57
+ import { DEFAULT_FONT_FAMILY } from 'vscode/vscode/vs/workbench/browser/style';
58
+ import { Codicon } from 'monaco-editor/esm/vs/base/common/codicons.js';
59
+ import { ThemeIcon } from 'monaco-editor/esm/vs/base/common/themables.js';
60
+ import { RepositoryRenderer } from './scmRepositoryRenderer.js';
61
+ import { ColorScheme } from 'monaco-editor/esm/vs/platform/theme/common/theme.js';
62
+ import { IUriIdentityService } from 'monaco-editor/esm/vs/platform/uriIdentity/common/uriIdentity.js';
63
+ import { API_OPEN_EDITOR_COMMAND_ID, API_OPEN_DIFF_EDITOR_COMMAND_ID } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorCommands';
64
+ import { createAndFillInContextMenuActions } from 'monaco-editor/esm/vs/platform/actions/browser/menuEntryActionViewItem.js';
65
+ import { IWorkspaceContextService } from 'monaco-editor/esm/vs/platform/workspace/common/workspace.js';
66
+ import { MarkdownRenderer, openLinkFromMarkdown } from 'monaco-editor/esm/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.js';
67
+ import { ButtonWithDropdown, Button } from 'monaco-editor/esm/vs/base/browser/ui/button/button.js';
68
+ import { INotificationService } from 'monaco-editor/esm/vs/platform/notification/common/notification.js';
69
+ import { RepositoryContextKeys } from './scmViewService.js';
70
+ import { DragAndDropController } from 'monaco-editor/esm/vs/editor/contrib/dnd/browser/dnd.js';
71
+ import { DropIntoEditorController } from 'monaco-editor/esm/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.js';
72
+ import { MessageController } from 'monaco-editor/esm/vs/editor/contrib/message/browser/messageController.js';
73
+ import { registerColor, contrastBorder } from 'monaco-editor/esm/vs/platform/theme/common/colorRegistry.js';
74
+ import { defaultCountBadgeStyles, defaultButtonStyles } from 'monaco-editor/esm/vs/platform/theme/browser/defaultStyles.js';
75
+ import { InlineCompletionsController } from 'monaco-editor/esm/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.js';
76
+ import { CodeActionController } from 'monaco-editor/esm/vs/editor/contrib/codeAction/browser/codeActionController.js';
77
+ import { ITextModelService } from 'monaco-editor/esm/vs/editor/common/services/resolverService.js';
78
+ import { Schemas } from 'monaco-editor/esm/vs/base/common/network.js';
79
+ import { fillEditorsDragData } from 'vscode/vscode/vs/workbench/browser/dnd';
80
+ import { CodeDataTransfers } from 'monaco-editor/esm/vs/platform/dnd/browser/dnd.js';
81
+ import { FormatOnType } from 'monaco-editor/esm/vs/editor/contrib/format/browser/formatActions.js';
82
+
83
+ var ActionButtonRenderer_1, InputRenderer_1, ResourceGroupRenderer_1, ResourceRenderer_1, SCMInputWidget_1;
84
+ let ActionButtonRenderer = class ActionButtonRenderer {
85
+ static { ActionButtonRenderer_1 = this; }
86
+ static { this.DEFAULT_HEIGHT = 30; }
87
+ static { this.TEMPLATE_ID = 'actionButton'; }
88
+ get templateId() { return ActionButtonRenderer_1.TEMPLATE_ID; }
89
+ constructor(commandService, contextMenuService, notificationService) {
90
+ this.commandService = commandService;
91
+ this.contextMenuService = contextMenuService;
92
+ this.notificationService = notificationService;
93
+ this.actionButtons = ( new Map());
94
+ }
95
+ renderTemplate(container) {
96
+ container.parentElement.parentElement.querySelector('.monaco-tl-twistie').classList.add('force-no-twistie');
97
+ container.parentElement.parentElement.classList.add('cursor-default', 'force-no-hover');
98
+ const buttonContainer = append(container, $('.button-container'));
99
+ const actionButton = ( new SCMActionButton(
100
+ buttonContainer,
101
+ this.contextMenuService,
102
+ this.commandService,
103
+ this.notificationService
104
+ ));
105
+ return { actionButton, disposable: Disposable.None, templateDisposable: actionButton };
106
+ }
107
+ renderElement(node, index, templateData, height) {
108
+ templateData.disposable.dispose();
109
+ const disposables = ( new DisposableStore());
110
+ const actionButton = node.element;
111
+ templateData.actionButton.setButton(node.element.button);
112
+ this.actionButtons.set(actionButton, templateData.actionButton);
113
+ disposables.add({ dispose: () => this.actionButtons.delete(actionButton) });
114
+ templateData.disposable = disposables;
115
+ }
116
+ renderCompressedElements() {
117
+ throw new Error('Should never happen since node is incompressible');
118
+ }
119
+ focusActionButton(actionButton) {
120
+ this.actionButtons.get(actionButton)?.focus();
121
+ }
122
+ disposeElement(node, index, template) {
123
+ template.disposable.dispose();
124
+ }
125
+ disposeTemplate(templateData) {
126
+ templateData.disposable.dispose();
127
+ templateData.templateDisposable.dispose();
128
+ }
129
+ };
130
+ ActionButtonRenderer = ActionButtonRenderer_1 = ( __decorate([
131
+ ( __param(0, ICommandService)),
132
+ ( __param(1, IContextMenuService)),
133
+ ( __param(2, INotificationService))
134
+ ], ActionButtonRenderer));
135
+ class SCMTreeDragAndDrop {
136
+ constructor(instantiationService) {
137
+ this.instantiationService = instantiationService;
138
+ }
139
+ getDragURI(element) {
140
+ if (isSCMResource(element)) {
141
+ return ( element.sourceUri.toString());
142
+ }
143
+ return null;
144
+ }
145
+ onDragStart(data, originalEvent) {
146
+ const items = SCMTreeDragAndDrop.getResourcesFromDragAndDropData(data);
147
+ if (originalEvent.dataTransfer && items?.length) {
148
+ this.instantiationService.invokeFunction(accessor => fillEditorsDragData(accessor, items, originalEvent));
149
+ const fileResources = ( items.filter(s => s.scheme === Schemas.file).map(r => r.fsPath));
150
+ if (fileResources.length) {
151
+ originalEvent.dataTransfer.setData(CodeDataTransfers.FILES, JSON.stringify(fileResources));
152
+ }
153
+ }
154
+ }
155
+ getDragLabel(elements, originalEvent) {
156
+ if (elements.length === 1) {
157
+ const element = elements[0];
158
+ if (isSCMResource(element)) {
159
+ return basename(element.sourceUri);
160
+ }
161
+ }
162
+ return String(elements.length);
163
+ }
164
+ onDragOver(data, targetElement, targetIndex, originalEvent) {
165
+ return true;
166
+ }
167
+ drop(data, targetElement, targetIndex, originalEvent) { }
168
+ static getResourcesFromDragAndDropData(data) {
169
+ const uris = [];
170
+ for (const element of [...(data.context ?? []), ...data.elements]) {
171
+ if (isSCMResource(element)) {
172
+ uris.push(element.sourceUri);
173
+ }
174
+ }
175
+ return uris;
176
+ }
177
+ dispose() { }
178
+ }
179
+ let InputRenderer = class InputRenderer {
180
+ static { InputRenderer_1 = this; }
181
+ static { this.DEFAULT_HEIGHT = 26; }
182
+ static { this.TEMPLATE_ID = 'input'; }
183
+ get templateId() { return InputRenderer_1.TEMPLATE_ID; }
184
+ constructor(outerLayout, overflowWidgetsDomNode, updateHeight, instantiationService) {
185
+ this.outerLayout = outerLayout;
186
+ this.overflowWidgetsDomNode = overflowWidgetsDomNode;
187
+ this.updateHeight = updateHeight;
188
+ this.instantiationService = instantiationService;
189
+ this.inputWidgets = ( new Map());
190
+ this.contentHeights = ( new WeakMap());
191
+ this.editorSelections = ( new WeakMap());
192
+ }
193
+ renderTemplate(container) {
194
+ container.parentElement.parentElement.querySelector('.monaco-tl-twistie').classList.add('force-no-twistie');
195
+ container.parentElement.parentElement.classList.add('force-no-hover');
196
+ const templateDisposable = ( new DisposableStore());
197
+ const inputElement = append(container, $('.scm-input'));
198
+ const inputWidget = this.instantiationService.createInstance(SCMInputWidget, inputElement, this.overflowWidgetsDomNode);
199
+ templateDisposable.add(inputWidget);
200
+ return { inputWidget, inputWidgetHeight: InputRenderer_1.DEFAULT_HEIGHT, elementDisposables: ( new DisposableStore()), templateDisposable };
201
+ }
202
+ renderElement(node, index, templateData) {
203
+ const input = node.element;
204
+ templateData.inputWidget.setInput(input);
205
+ this.inputWidgets.set(input, templateData.inputWidget);
206
+ templateData.elementDisposables.add({
207
+ dispose: () => this.inputWidgets.delete(input)
208
+ });
209
+ const selections = this.editorSelections.get(input);
210
+ if (selections) {
211
+ templateData.inputWidget.selections = selections;
212
+ }
213
+ templateData.elementDisposables.add(toDisposable(() => {
214
+ const selections = templateData.inputWidget.selections;
215
+ if (selections) {
216
+ this.editorSelections.set(input, selections);
217
+ }
218
+ }));
219
+ const onDidChangeContentHeight = () => {
220
+ const contentHeight = templateData.inputWidget.getContentHeight();
221
+ this.contentHeights.set(input, contentHeight);
222
+ if (templateData.inputWidgetHeight !== contentHeight) {
223
+ this.updateHeight(input, contentHeight + 10);
224
+ templateData.inputWidgetHeight = contentHeight;
225
+ templateData.inputWidget.layout();
226
+ }
227
+ };
228
+ const startListeningContentHeightChange = () => {
229
+ templateData.elementDisposables.add(templateData.inputWidget.onDidChangeContentHeight(onDidChangeContentHeight));
230
+ onDidChangeContentHeight();
231
+ };
232
+ const timeout = disposableTimeout(startListeningContentHeightChange, 0);
233
+ templateData.elementDisposables.add(timeout);
234
+ const layoutEditor = () => templateData.inputWidget.layout();
235
+ templateData.elementDisposables.add(this.outerLayout.onDidChange(layoutEditor));
236
+ layoutEditor();
237
+ }
238
+ renderCompressedElements() {
239
+ throw new Error('Should never happen since node is incompressible');
240
+ }
241
+ disposeElement(group, index, template) {
242
+ template.elementDisposables.clear();
243
+ }
244
+ disposeTemplate(templateData) {
245
+ templateData.templateDisposable.dispose();
246
+ }
247
+ getHeight(input) {
248
+ return (this.contentHeights.get(input) ?? InputRenderer_1.DEFAULT_HEIGHT) + 10;
249
+ }
250
+ getRenderedInputWidget(input) {
251
+ return this.inputWidgets.get(input);
252
+ }
253
+ getFocusedInput() {
254
+ for (const [input, inputWidget] of this.inputWidgets) {
255
+ if (inputWidget.hasFocus()) {
256
+ return input;
257
+ }
258
+ }
259
+ return undefined;
260
+ }
261
+ clearValidation() {
262
+ for (const [, inputWidget] of this.inputWidgets) {
263
+ inputWidget.clearValidation();
264
+ }
265
+ }
266
+ };
267
+ InputRenderer = InputRenderer_1 = ( __decorate([
268
+ ( __param(3, IInstantiationService))
269
+ ], InputRenderer));
270
+ let ResourceGroupRenderer = class ResourceGroupRenderer {
271
+ static { ResourceGroupRenderer_1 = this; }
272
+ static { this.TEMPLATE_ID = 'resource group'; }
273
+ get templateId() { return ResourceGroupRenderer_1.TEMPLATE_ID; }
274
+ constructor(actionViewItemProvider, scmViewService) {
275
+ this.actionViewItemProvider = actionViewItemProvider;
276
+ this.scmViewService = scmViewService;
277
+ }
278
+ renderTemplate(container) {
279
+ container.parentElement.parentElement.querySelector('.monaco-tl-twistie').classList.add('force-twistie');
280
+ const element = append(container, $('.resource-group'));
281
+ const name = append(element, $('.name'));
282
+ const actionsContainer = append(element, $('.actions'));
283
+ const actionBar = ( new ActionBar(actionsContainer, { actionViewItemProvider: this.actionViewItemProvider }));
284
+ const countContainer = append(element, $('.count'));
285
+ const count = ( new CountBadge(countContainer, {}, defaultCountBadgeStyles));
286
+ const disposables = combinedDisposable(actionBar);
287
+ return { name, count, actionBar, elementDisposables: ( new DisposableStore()), disposables };
288
+ }
289
+ renderElement(node, index, template) {
290
+ const group = node.element;
291
+ template.name.textContent = group.label;
292
+ template.actionBar.clear();
293
+ template.actionBar.context = group;
294
+ template.count.setCount(group.elements.length);
295
+ const menus = this.scmViewService.menus.getRepositoryMenus(group.provider);
296
+ template.elementDisposables.add(connectPrimaryMenuToInlineActionBar(menus.getResourceGroupMenu(group), template.actionBar));
297
+ }
298
+ renderCompressedElements(node, index, templateData, height) {
299
+ throw new Error('Should never happen since node is incompressible');
300
+ }
301
+ disposeElement(group, index, template) {
302
+ template.elementDisposables.clear();
303
+ }
304
+ disposeTemplate(template) {
305
+ template.elementDisposables.dispose();
306
+ template.disposables.dispose();
307
+ }
308
+ };
309
+ ResourceGroupRenderer = ResourceGroupRenderer_1 = ( __decorate([
310
+ ( __param(1, ISCMViewService))
311
+ ], ResourceGroupRenderer));
312
+ class RepositoryPaneActionRunner extends ActionRunner {
313
+ constructor(getSelectedResources) {
314
+ super();
315
+ this.getSelectedResources = getSelectedResources;
316
+ }
317
+ async runAction(action, context) {
318
+ if (!(action instanceof MenuItemAction)) {
319
+ return super.runAction(action, context);
320
+ }
321
+ const selection = this.getSelectedResources();
322
+ const contextIsSelected = ( selection.some(s => s === context));
323
+ const actualContext = contextIsSelected ? selection : [context];
324
+ const args = flatten(( actualContext.map(e => ResourceTree.isResourceNode(e) ? ResourceTree.collect(e) : [e])));
325
+ await action.run(...args);
326
+ }
327
+ }
328
+ let ResourceRenderer = class ResourceRenderer {
329
+ static { ResourceRenderer_1 = this; }
330
+ static { this.TEMPLATE_ID = 'resource'; }
331
+ get templateId() { return ResourceRenderer_1.TEMPLATE_ID; }
332
+ constructor(viewModelProvider, labels, actionViewItemProvider, actionRunner, labelService, scmViewService, themeService) {
333
+ this.viewModelProvider = viewModelProvider;
334
+ this.labels = labels;
335
+ this.actionViewItemProvider = actionViewItemProvider;
336
+ this.actionRunner = actionRunner;
337
+ this.labelService = labelService;
338
+ this.scmViewService = scmViewService;
339
+ this.themeService = themeService;
340
+ this.disposables = ( new DisposableStore());
341
+ this.renderedResources = ( new Map());
342
+ themeService.onDidColorThemeChange(this.onDidColorThemeChange, this, this.disposables);
343
+ }
344
+ renderTemplate(container) {
345
+ const element = append(container, $('.resource'));
346
+ const name = append(element, $('.name'));
347
+ const fileLabel = this.labels.create(name, { supportDescriptionHighlights: true, supportHighlights: true });
348
+ const actionsContainer = append(fileLabel.element, $('.actions'));
349
+ const actionBar = ( new ActionBar(actionsContainer, {
350
+ actionViewItemProvider: this.actionViewItemProvider,
351
+ actionRunner: this.actionRunner
352
+ }));
353
+ const decorationIcon = append(element, $('.decoration-icon'));
354
+ const actionBarMenuListener = ( new MutableDisposable());
355
+ const disposables = combinedDisposable(actionBar, fileLabel, actionBarMenuListener);
356
+ return { element, name, fileLabel, decorationIcon, actionBar, actionBarMenu: undefined, actionBarMenuListener, elementDisposables: ( new DisposableStore()), disposables };
357
+ }
358
+ renderElement(node, index, template) {
359
+ const resourceOrFolder = node.element;
360
+ const iconResource = ResourceTree.isResourceNode(resourceOrFolder) ? resourceOrFolder.element : resourceOrFolder;
361
+ const uri = ResourceTree.isResourceNode(resourceOrFolder) ? resourceOrFolder.uri : resourceOrFolder.sourceUri;
362
+ const fileKind = ResourceTree.isResourceNode(resourceOrFolder) ? FileKind.FOLDER : FileKind.FILE;
363
+ const viewModel = this.viewModelProvider();
364
+ const tooltip = !ResourceTree.isResourceNode(resourceOrFolder) && resourceOrFolder.decorations.tooltip || '';
365
+ let matches;
366
+ let descriptionMatches;
367
+ let strikethrough;
368
+ if (ResourceTree.isResourceNode(resourceOrFolder)) {
369
+ if (resourceOrFolder.element) {
370
+ const menus = this.scmViewService.menus.getRepositoryMenus(resourceOrFolder.element.resourceGroup.provider);
371
+ this._renderActionBar(template, resourceOrFolder, menus.getResourceMenu(resourceOrFolder.element));
372
+ template.element.classList.toggle('faded', resourceOrFolder.element.decorations.faded);
373
+ strikethrough = resourceOrFolder.element.decorations.strikeThrough;
374
+ }
375
+ else {
376
+ const menus = this.scmViewService.menus.getRepositoryMenus(resourceOrFolder.context.provider);
377
+ this._renderActionBar(template, resourceOrFolder, menus.getResourceFolderMenu(resourceOrFolder.context));
378
+ matches = createMatches(node.filterData);
379
+ template.element.classList.remove('faded');
380
+ }
381
+ }
382
+ else {
383
+ const menus = this.scmViewService.menus.getRepositoryMenus(resourceOrFolder.resourceGroup.provider);
384
+ this._renderActionBar(template, resourceOrFolder, menus.getResourceMenu(resourceOrFolder));
385
+ [matches, descriptionMatches] = this._processFilterData(uri, node.filterData);
386
+ template.element.classList.toggle('faded', resourceOrFolder.decorations.faded);
387
+ strikethrough = resourceOrFolder.decorations.strikeThrough;
388
+ }
389
+ const renderedData = {
390
+ tooltip,
391
+ uri,
392
+ fileLabelOptions: {
393
+ hidePath: viewModel.mode === "tree" ,
394
+ fileKind,
395
+ matches,
396
+ descriptionMatches,
397
+ strikethrough
398
+ },
399
+ iconResource
400
+ };
401
+ this.renderIcon(template, renderedData);
402
+ this.renderedResources.set(template, renderedData);
403
+ template.elementDisposables.add(toDisposable(() => this.renderedResources.delete(template)));
404
+ template.element.setAttribute('data-tooltip', tooltip);
405
+ }
406
+ disposeElement(resource, index, template) {
407
+ template.elementDisposables.clear();
408
+ }
409
+ renderCompressedElements(node, index, template, height) {
410
+ const compressed = node.element;
411
+ const folder = compressed.elements[compressed.elements.length - 1];
412
+ const label = ( compressed.elements.map(e => e.name));
413
+ const fileKind = FileKind.FOLDER;
414
+ const matches = createMatches(node.filterData);
415
+ template.fileLabel.setResource({ resource: folder.uri, name: label }, {
416
+ fileDecorations: { colors: false, badges: true },
417
+ fileKind,
418
+ matches,
419
+ separator: this.labelService.getSeparator(folder.uri.scheme)
420
+ });
421
+ const menus = this.scmViewService.menus.getRepositoryMenus(folder.context.provider);
422
+ this._renderActionBar(template, folder, menus.getResourceFolderMenu(folder.context));
423
+ template.name.classList.remove('strike-through');
424
+ template.element.classList.remove('faded');
425
+ template.decorationIcon.style.display = 'none';
426
+ template.decorationIcon.style.backgroundImage = '';
427
+ template.element.setAttribute('data-tooltip', '');
428
+ }
429
+ disposeCompressedElements(node, index, template, height) {
430
+ template.elementDisposables.clear();
431
+ }
432
+ disposeTemplate(template) {
433
+ template.elementDisposables.dispose();
434
+ template.disposables.dispose();
435
+ }
436
+ _renderActionBar(template, resourceOrFolder, menu) {
437
+ if (!template.actionBarMenu || template.actionBarMenu !== menu) {
438
+ template.actionBar.clear();
439
+ template.actionBarMenu = menu;
440
+ template.actionBarMenuListener.value = connectPrimaryMenuToInlineActionBar(menu, template.actionBar);
441
+ }
442
+ template.actionBar.context = resourceOrFolder;
443
+ }
444
+ _processFilterData(uri, filterData) {
445
+ if (!filterData) {
446
+ return [undefined, undefined];
447
+ }
448
+ if (!filterData.label) {
449
+ const matches = createMatches(filterData);
450
+ return [matches, undefined];
451
+ }
452
+ const fileName = basename(uri);
453
+ const label = filterData.label;
454
+ const pathLength = label.length - fileName.length;
455
+ const matches = createMatches(filterData.score);
456
+ if (label === fileName) {
457
+ return [matches, undefined];
458
+ }
459
+ const labelMatches = [];
460
+ const descriptionMatches = [];
461
+ for (const match of matches) {
462
+ if (match.start > pathLength) {
463
+ labelMatches.push({
464
+ start: match.start - pathLength,
465
+ end: match.end - pathLength
466
+ });
467
+ }
468
+ else if (match.end < pathLength) {
469
+ descriptionMatches.push(match);
470
+ }
471
+ else {
472
+ labelMatches.push({
473
+ start: 0,
474
+ end: match.end - pathLength
475
+ });
476
+ descriptionMatches.push({
477
+ start: match.start,
478
+ end: pathLength
479
+ });
480
+ }
481
+ }
482
+ return [labelMatches, descriptionMatches];
483
+ }
484
+ onDidColorThemeChange() {
485
+ for (const [template, data] of this.renderedResources) {
486
+ this.renderIcon(template, data);
487
+ }
488
+ }
489
+ renderIcon(template, data) {
490
+ const theme = this.themeService.getColorTheme();
491
+ const icon = theme.type === ColorScheme.LIGHT ? data.iconResource?.decorations.icon : data.iconResource?.decorations.iconDark;
492
+ template.fileLabel.setFile(data.uri, {
493
+ ...data.fileLabelOptions,
494
+ fileDecorations: { colors: false, badges: !icon },
495
+ });
496
+ if (icon) {
497
+ if (ThemeIcon.isThemeIcon(icon)) {
498
+ template.decorationIcon.className = `decoration-icon ${ThemeIcon.asClassName(icon)}`;
499
+ if (icon.color) {
500
+ template.decorationIcon.style.color = theme.getColor(icon.color.id)?.toString() ?? '';
501
+ }
502
+ template.decorationIcon.style.display = '';
503
+ template.decorationIcon.style.backgroundImage = '';
504
+ }
505
+ else {
506
+ template.decorationIcon.className = 'decoration-icon';
507
+ template.decorationIcon.style.color = '';
508
+ template.decorationIcon.style.display = '';
509
+ template.decorationIcon.style.backgroundImage = asCSSUrl(icon);
510
+ }
511
+ template.decorationIcon.title = data.tooltip;
512
+ }
513
+ else {
514
+ template.decorationIcon.className = 'decoration-icon';
515
+ template.decorationIcon.style.color = '';
516
+ template.decorationIcon.style.display = 'none';
517
+ template.decorationIcon.style.backgroundImage = '';
518
+ template.decorationIcon.title = '';
519
+ }
520
+ }
521
+ dispose() {
522
+ this.disposables.dispose();
523
+ }
524
+ };
525
+ ResourceRenderer = ResourceRenderer_1 = ( __decorate([
526
+ ( __param(4, ILabelService)),
527
+ ( __param(5, ISCMViewService)),
528
+ ( __param(6, IThemeService))
529
+ ], ResourceRenderer));
530
+ class ListDelegate {
531
+ constructor(inputRenderer) {
532
+ this.inputRenderer = inputRenderer;
533
+ }
534
+ getHeight(element) {
535
+ if (isSCMInput(element)) {
536
+ return this.inputRenderer.getHeight(element);
537
+ }
538
+ else if (isSCMActionButton(element)) {
539
+ return ActionButtonRenderer.DEFAULT_HEIGHT + 10;
540
+ }
541
+ else {
542
+ return 22;
543
+ }
544
+ }
545
+ getTemplateId(element) {
546
+ if (isSCMRepository(element)) {
547
+ return RepositoryRenderer.TEMPLATE_ID;
548
+ }
549
+ else if (isSCMInput(element)) {
550
+ return InputRenderer.TEMPLATE_ID;
551
+ }
552
+ else if (isSCMActionButton(element)) {
553
+ return ActionButtonRenderer.TEMPLATE_ID;
554
+ }
555
+ else if (ResourceTree.isResourceNode(element) || isSCMResource(element)) {
556
+ return ResourceRenderer.TEMPLATE_ID;
557
+ }
558
+ else {
559
+ return ResourceGroupRenderer.TEMPLATE_ID;
560
+ }
561
+ }
562
+ }
563
+ class SCMTreeFilter {
564
+ filter(element) {
565
+ if (ResourceTree.isResourceNode(element)) {
566
+ return true;
567
+ }
568
+ else if (isSCMResourceGroup(element)) {
569
+ return element.elements.length > 0 || !element.hideWhenEmpty;
570
+ }
571
+ else {
572
+ return true;
573
+ }
574
+ }
575
+ }
576
+ class SCMTreeSorter {
577
+ get viewModel() { return this.viewModelProvider(); }
578
+ constructor(viewModelProvider) {
579
+ this.viewModelProvider = viewModelProvider;
580
+ }
581
+ compare(one, other) {
582
+ if (isSCMRepository(one)) {
583
+ if (!isSCMRepository(other)) {
584
+ throw new Error('Invalid comparison');
585
+ }
586
+ return 0;
587
+ }
588
+ if (isSCMInput(one)) {
589
+ return -1;
590
+ }
591
+ else if (isSCMInput(other)) {
592
+ return 1;
593
+ }
594
+ if (isSCMActionButton(one)) {
595
+ return -1;
596
+ }
597
+ else if (isSCMActionButton(other)) {
598
+ return 1;
599
+ }
600
+ if (isSCMResourceGroup(one)) {
601
+ if (!isSCMResourceGroup(other)) {
602
+ throw new Error('Invalid comparison');
603
+ }
604
+ return 0;
605
+ }
606
+ if (this.viewModel.mode === "list" ) {
607
+ if (this.viewModel.sortKey === "name" ) {
608
+ const oneName = basename(one.sourceUri);
609
+ const otherName = basename(other.sourceUri);
610
+ return compareFileNames(oneName, otherName);
611
+ }
612
+ if (this.viewModel.sortKey === "status" ) {
613
+ const oneTooltip = one.decorations.tooltip ?? '';
614
+ const otherTooltip = other.decorations.tooltip ?? '';
615
+ if (oneTooltip !== otherTooltip) {
616
+ return compare(oneTooltip, otherTooltip);
617
+ }
618
+ }
619
+ const onePath = one.sourceUri.fsPath;
620
+ const otherPath = other.sourceUri.fsPath;
621
+ return comparePaths(onePath, otherPath);
622
+ }
623
+ const oneIsDirectory = ResourceTree.isResourceNode(one);
624
+ const otherIsDirectory = ResourceTree.isResourceNode(other);
625
+ if (oneIsDirectory !== otherIsDirectory) {
626
+ return oneIsDirectory ? -1 : 1;
627
+ }
628
+ const oneName = ResourceTree.isResourceNode(one) ? one.name : basename(one.sourceUri);
629
+ const otherName = ResourceTree.isResourceNode(other) ? other.name : basename(other.sourceUri);
630
+ return compareFileNames(oneName, otherName);
631
+ }
632
+ }
633
+ SCMTreeSorter.__decorator = ( __decorate([
634
+ memoize
635
+ ], SCMTreeSorter.prototype, "viewModel", null));
636
+ let SCMTreeKeyboardNavigationLabelProvider = class SCMTreeKeyboardNavigationLabelProvider {
637
+ constructor(viewModelProvider, labelService) {
638
+ this.viewModelProvider = viewModelProvider;
639
+ this.labelService = labelService;
640
+ }
641
+ getKeyboardNavigationLabel(element) {
642
+ if (ResourceTree.isResourceNode(element)) {
643
+ return element.name;
644
+ }
645
+ else if (isSCMRepository(element) || isSCMInput(element) || isSCMActionButton(element)) {
646
+ return undefined;
647
+ }
648
+ else if (isSCMResourceGroup(element)) {
649
+ return element.label;
650
+ }
651
+ else {
652
+ const viewModel = this.viewModelProvider();
653
+ if (viewModel.mode === "list" ) {
654
+ const fileName = basename(element.sourceUri);
655
+ const filePath = this.labelService.getUriLabel(element.sourceUri, { relative: true });
656
+ return [fileName, filePath];
657
+ }
658
+ else {
659
+ return basename(element.sourceUri);
660
+ }
661
+ }
662
+ }
663
+ getCompressedNodeKeyboardNavigationLabel(elements) {
664
+ const folders = elements;
665
+ return ( folders.map(e => e.name)).join('/');
666
+ }
667
+ };
668
+ SCMTreeKeyboardNavigationLabelProvider = ( __decorate([
669
+ ( __param(1, ILabelService))
670
+ ], SCMTreeKeyboardNavigationLabelProvider));
671
+ function getSCMResourceId(element) {
672
+ if (ResourceTree.isResourceNode(element)) {
673
+ const group = element.context;
674
+ return `folder:${group.provider.id}/${group.id}/$FOLDER/${( element.uri.toString())}`;
675
+ }
676
+ else if (isSCMRepository(element)) {
677
+ const provider = element.provider;
678
+ return `repo:${provider.id}`;
679
+ }
680
+ else if (isSCMInput(element)) {
681
+ const provider = element.repository.provider;
682
+ return `input:${provider.id}`;
683
+ }
684
+ else if (isSCMActionButton(element)) {
685
+ const provider = element.repository.provider;
686
+ return `actionButton:${provider.id}`;
687
+ }
688
+ else if (isSCMResource(element)) {
689
+ const group = element.resourceGroup;
690
+ const provider = group.provider;
691
+ return `resource:${provider.id}/${group.id}/${( element.sourceUri.toString())}`;
692
+ }
693
+ else {
694
+ const provider = element.provider;
695
+ return `group:${provider.id}/${element.id}`;
696
+ }
697
+ }
698
+ class SCMResourceIdentityProvider {
699
+ getId(element) {
700
+ return getSCMResourceId(element);
701
+ }
702
+ }
703
+ let SCMAccessibilityProvider = class SCMAccessibilityProvider {
704
+ constructor(labelService, workspaceContextService) {
705
+ this.labelService = labelService;
706
+ this.workspaceContextService = workspaceContextService;
707
+ }
708
+ getWidgetAriaLabel() {
709
+ return ( localizeWithPath(
710
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
711
+ 'scm',
712
+ "Source Control Management"
713
+ ));
714
+ }
715
+ getAriaLabel(element) {
716
+ if (ResourceTree.isResourceNode(element)) {
717
+ return this.labelService.getUriLabel(element.uri, { relative: true, noPrefix: true }) || element.name;
718
+ }
719
+ else if (isSCMRepository(element)) {
720
+ let folderName = '';
721
+ if (element.provider.rootUri) {
722
+ const folder = this.workspaceContextService.getWorkspaceFolder(element.provider.rootUri);
723
+ if (folder?.uri.toString() === ( element.provider.rootUri.toString())) {
724
+ folderName = folder.name;
725
+ }
726
+ else {
727
+ folderName = basename(element.provider.rootUri);
728
+ }
729
+ }
730
+ return `${folderName} ${element.provider.label}`;
731
+ }
732
+ else if (isSCMInput(element)) {
733
+ return ( localizeWithPath(
734
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
735
+ 'input',
736
+ "Source Control Input"
737
+ ));
738
+ }
739
+ else if (isSCMActionButton(element)) {
740
+ return element.button?.command.title ?? '';
741
+ }
742
+ else if (isSCMResourceGroup(element)) {
743
+ return element.label;
744
+ }
745
+ else {
746
+ const result = [];
747
+ result.push(basename(element.sourceUri));
748
+ if (element.decorations.tooltip) {
749
+ result.push(element.decorations.tooltip);
750
+ }
751
+ const path = this.labelService.getUriLabel(dirname(element.sourceUri), { relative: true, noPrefix: true });
752
+ if (path) {
753
+ result.push(path);
754
+ }
755
+ return result.join(', ');
756
+ }
757
+ }
758
+ };
759
+ SCMAccessibilityProvider = ( __decorate([
760
+ ( __param(0, ILabelService)),
761
+ ( __param(1, IWorkspaceContextService))
762
+ ], SCMAccessibilityProvider));
763
+ function isRepositoryItem(item) {
764
+ return Array.isArray(item.groupItems);
765
+ }
766
+ function asTreeElement(node, forceIncompressible, viewState) {
767
+ const element = (node.childrenCount === 0 && node.element) ? node.element : node;
768
+ const collapsed = viewState ? viewState.collapsed.indexOf(getSCMResourceId(element)) > -1 : false;
769
+ return {
770
+ element,
771
+ children: ( Iterable.map(node.children, node => asTreeElement(node, false, viewState))),
772
+ incompressible: !!node.element || forceIncompressible,
773
+ collapsed,
774
+ collapsible: node.childrenCount > 0
775
+ };
776
+ }
777
+ const Menus = {
778
+ ViewSort: ( new MenuId('SCMViewSort')),
779
+ Repositories: ( new MenuId('SCMRepositories')),
780
+ };
781
+ const ContextKeys = {
782
+ ViewModelMode: ( new RawContextKey('scmViewModelMode', "list" )),
783
+ ViewModelSortKey: ( new RawContextKey('scmViewModelSortKey', "path" )),
784
+ ViewModelAreAllRepositoriesCollapsed: ( new RawContextKey('scmViewModelAreAllRepositoriesCollapsed', false)),
785
+ ViewModelIsAnyRepositoryCollapsible: ( new RawContextKey('scmViewModelIsAnyRepositoryCollapsible', false)),
786
+ SCMProvider: ( new RawContextKey('scmProvider', undefined)),
787
+ SCMProviderRootUri: ( new RawContextKey('scmProviderRootUri', undefined)),
788
+ SCMProviderHasRootUri: ( new RawContextKey('scmProviderHasRootUri', undefined)),
789
+ RepositoryCount: ( new RawContextKey('scmRepositoryCount', 0)),
790
+ RepositoryVisibilityCount: ( new RawContextKey('scmRepositoryVisibleCount', 0)),
791
+ RepositoryVisibility(repository) {
792
+ return ( new RawContextKey(`scmRepositoryVisible:${repository.provider.id}`, false));
793
+ }
794
+ };
795
+ MenuRegistry.appendMenuItem(MenuId.SCMTitle, {
796
+ title: ( localizeWithPath(
797
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
798
+ 'sortAction',
799
+ "View & Sort"
800
+ )),
801
+ submenu: Menus.ViewSort,
802
+ when: ( ContextKeyExpr.and(( ContextKeyExpr.equals('view', VIEW_PANE_ID)), ( ContextKeys.RepositoryCount.notEqualsTo(0)))),
803
+ group: '0_view&sort'
804
+ });
805
+ MenuRegistry.appendMenuItem(Menus.ViewSort, {
806
+ title: ( localizeWithPath(
807
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
808
+ 'repositories',
809
+ "Repositories"
810
+ )),
811
+ submenu: Menus.Repositories,
812
+ group: '0_repositories'
813
+ });
814
+ class RepositoryVisibilityAction extends Action2 {
815
+ constructor(repository) {
816
+ const title = repository.provider.rootUri ? basename(repository.provider.rootUri) : repository.provider.label;
817
+ super({
818
+ id: `workbench.scm.action.toggleRepositoryVisibility.${repository.provider.id}`,
819
+ title,
820
+ f1: false,
821
+ precondition: ( ContextKeyExpr.or(( ContextKeys.RepositoryVisibilityCount.notEqualsTo(1)), ( ContextKeys.RepositoryVisibility(repository).isEqualTo(false)))),
822
+ toggled: ( ContextKeys.RepositoryVisibility(repository).isEqualTo(true)),
823
+ menu: { id: Menus.Repositories, group: '0_repositories' }
824
+ });
825
+ this.repository = repository;
826
+ }
827
+ run(accessor) {
828
+ const scmViewService = accessor.get(ISCMViewService);
829
+ scmViewService.toggleVisibility(this.repository);
830
+ }
831
+ }
832
+ let RepositoryVisibilityActionController = class RepositoryVisibilityActionController {
833
+ constructor(scmViewService, scmService, contextKeyService) {
834
+ this.scmViewService = scmViewService;
835
+ this.contextKeyService = contextKeyService;
836
+ this.items = ( new Map());
837
+ this.disposables = ( new DisposableStore());
838
+ this.repositoryCountContextKey = ContextKeys.RepositoryCount.bindTo(contextKeyService);
839
+ this.repositoryVisibilityCountContextKey = ContextKeys.RepositoryVisibilityCount.bindTo(contextKeyService);
840
+ scmViewService.onDidChangeVisibleRepositories(this.onDidChangeVisibleRepositories, this, this.disposables);
841
+ scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables);
842
+ scmService.onDidRemoveRepository(this.onDidRemoveRepository, this, this.disposables);
843
+ for (const repository of scmService.repositories) {
844
+ this.onDidAddRepository(repository);
845
+ }
846
+ }
847
+ onDidAddRepository(repository) {
848
+ const action = registerAction2(class extends RepositoryVisibilityAction {
849
+ constructor() {
850
+ super(repository);
851
+ }
852
+ });
853
+ const contextKey = ContextKeys.RepositoryVisibility(repository).bindTo(this.contextKeyService);
854
+ contextKey.set(this.scmViewService.isVisible(repository));
855
+ this.items.set(repository, {
856
+ contextKey,
857
+ dispose() {
858
+ contextKey.reset();
859
+ action.dispose();
860
+ }
861
+ });
862
+ this.updateRepositoriesCounts();
863
+ }
864
+ onDidRemoveRepository(repository) {
865
+ this.items.get(repository)?.dispose();
866
+ this.items.delete(repository);
867
+ this.updateRepositoriesCounts();
868
+ }
869
+ onDidChangeVisibleRepositories() {
870
+ let count = 0;
871
+ for (const [repository, item] of this.items) {
872
+ const isVisible = this.scmViewService.isVisible(repository);
873
+ item.contextKey.set(isVisible);
874
+ if (isVisible) {
875
+ count++;
876
+ }
877
+ }
878
+ this.repositoryCountContextKey.set(this.items.size);
879
+ this.repositoryVisibilityCountContextKey.set(count);
880
+ }
881
+ updateRepositoriesCounts() {
882
+ this.repositoryCountContextKey.set(this.items.size);
883
+ this.repositoryVisibilityCountContextKey.set(Iterable.reduce(( this.items.keys()), (r, repository) => r + (this.scmViewService.isVisible(repository) ? 1 : 0), 0));
884
+ }
885
+ dispose() {
886
+ this.disposables.dispose();
887
+ dispose(( this.items.values()));
888
+ this.items.clear();
889
+ }
890
+ };
891
+ RepositoryVisibilityActionController = ( __decorate([
892
+ ( __param(0, ISCMViewService)),
893
+ ( __param(1, ISCMService)),
894
+ ( __param(2, IContextKeyService))
895
+ ], RepositoryVisibilityActionController));
896
+ let ViewModel = class ViewModel {
897
+ get mode() { return this._mode; }
898
+ set mode(mode) {
899
+ if (this._mode === mode) {
900
+ return;
901
+ }
902
+ this._mode = mode;
903
+ for (const [, item] of this.items) {
904
+ for (const groupItem of item.groupItems) {
905
+ groupItem.tree.clear();
906
+ if (mode === "tree" ) {
907
+ for (const resource of groupItem.resources) {
908
+ groupItem.tree.add(resource.sourceUri, resource);
909
+ }
910
+ }
911
+ }
912
+ }
913
+ this.sortKey = this.getViewModelSortKey();
914
+ this.refresh();
915
+ this._onDidChangeMode.fire(mode);
916
+ this.modeContextKey.set(mode);
917
+ this.storageService.store(`scm.viewMode`, mode, 1 , 0 );
918
+ }
919
+ get sortKey() { return this._sortKey; }
920
+ set sortKey(sortKey) {
921
+ if (this._sortKey === sortKey) {
922
+ return;
923
+ }
924
+ this._sortKey = sortKey;
925
+ this.refresh();
926
+ this._onDidChangeSortKey.fire(sortKey);
927
+ this.sortKeyContextKey.set(sortKey);
928
+ if (this._mode === "list" ) {
929
+ this.storageService.store(`scm.viewSortKey`, sortKey, 1 , 0 );
930
+ }
931
+ }
932
+ get treeViewState() {
933
+ if (this.visible && this._treeViewStateIsStale) {
934
+ this.updateViewState();
935
+ this._treeViewStateIsStale = false;
936
+ }
937
+ return this._treeViewState;
938
+ }
939
+ constructor(tree, inputRenderer, instantiationService, editorService, configurationService, scmViewService, storageService, uriIdentityService, contextKeyService) {
940
+ this.tree = tree;
941
+ this.inputRenderer = inputRenderer;
942
+ this.instantiationService = instantiationService;
943
+ this.editorService = editorService;
944
+ this.configurationService = configurationService;
945
+ this.scmViewService = scmViewService;
946
+ this.storageService = storageService;
947
+ this.uriIdentityService = uriIdentityService;
948
+ this._onDidChangeMode = ( new Emitter());
949
+ this.onDidChangeMode = this._onDidChangeMode.event;
950
+ this._onDidChangeSortKey = ( new Emitter());
951
+ this.onDidChangeSortKey = this._onDidChangeSortKey.event;
952
+ this.visible = false;
953
+ this._treeViewStateIsStale = false;
954
+ this.items = ( new Map());
955
+ this.visibilityDisposables = ( new DisposableStore());
956
+ this.alwaysShowRepositories = false;
957
+ this.showActionButton = false;
958
+ this.firstVisible = true;
959
+ this.disposables = ( new DisposableStore());
960
+ this._mode = this.getViewModelMode();
961
+ this._sortKey = this.getViewModelSortKey();
962
+ const storageViewState = this.storageService.get(`scm.viewState`, 1 );
963
+ if (storageViewState) {
964
+ try {
965
+ this._treeViewState = JSON.parse(storageViewState);
966
+ }
967
+ catch { }
968
+ }
969
+ this.modeContextKey = ContextKeys.ViewModelMode.bindTo(contextKeyService);
970
+ this.modeContextKey.set(this._mode);
971
+ this.sortKeyContextKey = ContextKeys.ViewModelSortKey.bindTo(contextKeyService);
972
+ this.sortKeyContextKey.set(this._sortKey);
973
+ this.areAllRepositoriesCollapsedContextKey = ContextKeys.ViewModelAreAllRepositoriesCollapsed.bindTo(contextKeyService);
974
+ this.isAnyRepositoryCollapsibleContextKey = ContextKeys.ViewModelIsAnyRepositoryCollapsible.bindTo(contextKeyService);
975
+ this.scmProviderContextKey = ContextKeys.SCMProvider.bindTo(contextKeyService);
976
+ this.scmProviderRootUriContextKey = ContextKeys.SCMProviderRootUri.bindTo(contextKeyService);
977
+ this.scmProviderHasRootUriContextKey = ContextKeys.SCMProviderHasRootUri.bindTo(contextKeyService);
978
+ configurationService.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
979
+ this.onDidChangeConfiguration();
980
+ Event.filter(this.tree.onDidChangeCollapseState, e => isSCMRepository(e.node.element), this.disposables)(this.updateRepositoryCollapseAllContextKeys, this, this.disposables);
981
+ this.disposables.add(this.tree.onDidChangeCollapseState(() => this._treeViewStateIsStale = true));
982
+ this.disposables.add(this.storageService.onWillSaveState(e => {
983
+ if (e.reason === WillSaveStateReason.SHUTDOWN) {
984
+ this.storageService.store(`scm.viewState`, JSON.stringify(this.treeViewState), 1 , 1 );
985
+ }
986
+ this.mode = this.getViewModelMode();
987
+ this.sortKey = this.getViewModelSortKey();
988
+ }));
989
+ this.disposables.add(this.storageService.onDidChangeValue(1 , undefined, this.disposables)(e => {
990
+ switch (e.key) {
991
+ case 'scm.viewMode':
992
+ this.mode = this.getViewModelMode();
993
+ break;
994
+ case 'scm.viewSortKey':
995
+ this.sortKey = this.getViewModelSortKey();
996
+ break;
997
+ }
998
+ }));
999
+ }
1000
+ onDidChangeConfiguration(e) {
1001
+ if (!e || e.affectsConfiguration('scm.alwaysShowRepositories') || e.affectsConfiguration('scm.showActionButton')) {
1002
+ this.alwaysShowRepositories = this.configurationService.getValue('scm.alwaysShowRepositories');
1003
+ this.showActionButton = this.configurationService.getValue('scm.showActionButton');
1004
+ this.refresh();
1005
+ }
1006
+ }
1007
+ _onDidChangeVisibleRepositories({ added, removed }) {
1008
+ for (const repository of added) {
1009
+ const disposable = combinedDisposable(repository.provider.groups.onDidSplice(splice => this._onDidSpliceGroups(item, splice)), repository.input.onDidChangeVisibility(() => this.refresh(item)), repository.provider.onDidChange(() => {
1010
+ if (this.showActionButton) {
1011
+ this.refresh(item);
1012
+ }
1013
+ }));
1014
+ const groupItems = ( repository.provider.groups.elements.map(group => this.createGroupItem(group)));
1015
+ const item = {
1016
+ element: repository, groupItems, dispose() {
1017
+ dispose(this.groupItems);
1018
+ disposable.dispose();
1019
+ }
1020
+ };
1021
+ this.items.set(repository, item);
1022
+ }
1023
+ for (const repository of removed) {
1024
+ const item = this.items.get(repository);
1025
+ item.dispose();
1026
+ this.items.delete(repository);
1027
+ }
1028
+ this.refresh();
1029
+ }
1030
+ _onDidSpliceGroups(item, { start, deleteCount, toInsert }) {
1031
+ const itemsToInsert = ( toInsert.map(group => this.createGroupItem(group)));
1032
+ const itemsToDispose = item.groupItems.splice(start, deleteCount, ...itemsToInsert);
1033
+ for (const item of itemsToDispose) {
1034
+ item.dispose();
1035
+ }
1036
+ this.refresh();
1037
+ }
1038
+ createGroupItem(group) {
1039
+ const tree = ( new ResourceTree(
1040
+ group,
1041
+ group.provider.rootUri || URI.file('/'),
1042
+ this.uriIdentityService.extUri
1043
+ ));
1044
+ const resources = [...group.elements];
1045
+ const disposable = combinedDisposable(group.onDidChange(() => this.tree.refilter()), group.onDidSplice(splice => this._onDidSpliceGroup(item, splice)));
1046
+ const item = { element: group, resources, tree, dispose() { disposable.dispose(); } };
1047
+ if (this._mode === "tree" ) {
1048
+ for (const resource of resources) {
1049
+ item.tree.add(resource.sourceUri, resource);
1050
+ }
1051
+ }
1052
+ return item;
1053
+ }
1054
+ _onDidSpliceGroup(item, { start, deleteCount, toInsert }) {
1055
+ const before = item.resources.length;
1056
+ const deleted = item.resources.splice(start, deleteCount, ...toInsert);
1057
+ const after = item.resources.length;
1058
+ if (this._mode === "tree" ) {
1059
+ for (const resource of deleted) {
1060
+ item.tree.delete(resource.sourceUri);
1061
+ }
1062
+ for (const resource of toInsert) {
1063
+ item.tree.add(resource.sourceUri, resource);
1064
+ }
1065
+ }
1066
+ if (before !== after && (before === 0 || after === 0)) {
1067
+ this.refresh();
1068
+ }
1069
+ else {
1070
+ this.refresh(item);
1071
+ }
1072
+ }
1073
+ setVisible(visible) {
1074
+ if (visible) {
1075
+ this.scmViewService.onDidChangeVisibleRepositories(this._onDidChangeVisibleRepositories, this, this.visibilityDisposables);
1076
+ this._onDidChangeVisibleRepositories({ added: this.scmViewService.visibleRepositories, removed: Iterable.empty() });
1077
+ if (typeof this.scrollTop === 'number') {
1078
+ this.tree.scrollTop = this.scrollTop;
1079
+ this.scrollTop = undefined;
1080
+ }
1081
+ this.editorService.onDidActiveEditorChange(this.onDidActiveEditorChange, this, this.visibilityDisposables);
1082
+ this.onDidActiveEditorChange();
1083
+ }
1084
+ else {
1085
+ this.updateViewState();
1086
+ this.visibilityDisposables.clear();
1087
+ this._onDidChangeVisibleRepositories({ added: Iterable.empty(), removed: [...( this.items.keys())] });
1088
+ this.scrollTop = this.tree.scrollTop;
1089
+ }
1090
+ this.visible = visible;
1091
+ this.updateRepositoryCollapseAllContextKeys();
1092
+ }
1093
+ refresh(item) {
1094
+ if (!this.alwaysShowRepositories && this.items.size === 1) {
1095
+ const provider = Iterable.first(( this.items.values())).element.provider;
1096
+ this.scmProviderContextKey.set(provider.contextValue);
1097
+ this.scmProviderRootUriContextKey.set(provider.rootUri?.toString());
1098
+ this.scmProviderHasRootUriContextKey.set(!!provider.rootUri);
1099
+ }
1100
+ else {
1101
+ this.scmProviderContextKey.set(undefined);
1102
+ this.scmProviderRootUriContextKey.set(undefined);
1103
+ this.scmProviderHasRootUriContextKey.set(false);
1104
+ }
1105
+ const focusedInput = this.inputRenderer.getFocusedInput();
1106
+ if (!this.alwaysShowRepositories && (this.items.size === 1 && (!item || isRepositoryItem(item)))) {
1107
+ const item = Iterable.first(( this.items.values()));
1108
+ this.tree.setChildren(null, this.render(item, this.treeViewState).children);
1109
+ }
1110
+ else if (item) {
1111
+ this.tree.setChildren(item.element, this.render(item, this.treeViewState).children);
1112
+ }
1113
+ else {
1114
+ const items = coalesce(( this.scmViewService.visibleRepositories.map(r => this.items.get(r))));
1115
+ this.tree.setChildren(null, ( items.map(item => this.render(item, this.treeViewState))));
1116
+ }
1117
+ if (focusedInput) {
1118
+ this.inputRenderer.getRenderedInputWidget(focusedInput)?.focus();
1119
+ }
1120
+ this.updateRepositoryCollapseAllContextKeys();
1121
+ }
1122
+ render(item, treeViewState) {
1123
+ if (isRepositoryItem(item)) {
1124
+ const children = [];
1125
+ const hasSomeChanges = ( item.groupItems.some(item => item.element.elements.length > 0));
1126
+ if (item.element.input.visible) {
1127
+ children.push({ element: item.element.input, incompressible: true, collapsible: false });
1128
+ }
1129
+ if (hasSomeChanges || (this.items.size === 1 && (!this.showActionButton || !item.element.provider.actionButton))) {
1130
+ children.push(...( item.groupItems.map(i => this.render(i, treeViewState))));
1131
+ }
1132
+ if (this.showActionButton && item.element.provider.actionButton) {
1133
+ const button = {
1134
+ element: {
1135
+ type: 'actionButton',
1136
+ repository: item.element,
1137
+ button: item.element.provider.actionButton,
1138
+ },
1139
+ incompressible: true,
1140
+ collapsible: false
1141
+ };
1142
+ children.push(button);
1143
+ }
1144
+ const collapsed = treeViewState ? treeViewState.collapsed.indexOf(getSCMResourceId(item.element)) > -1 : false;
1145
+ return { element: item.element, children, incompressible: true, collapsed, collapsible: true };
1146
+ }
1147
+ else {
1148
+ const children = this.mode === "list"
1149
+ ? ( Iterable.map(item.resources, element => ({ element, incompressible: true })))
1150
+ : ( Iterable.map(item.tree.root.children, node => asTreeElement(node, true, treeViewState)));
1151
+ const collapsed = treeViewState ? treeViewState.collapsed.indexOf(getSCMResourceId(item.element)) > -1 : false;
1152
+ return { element: item.element, children, incompressible: true, collapsed, collapsible: true };
1153
+ }
1154
+ }
1155
+ updateViewState() {
1156
+ const collapsed = [];
1157
+ const visit = (node) => {
1158
+ if (node.element && node.collapsible && node.collapsed) {
1159
+ collapsed.push(getSCMResourceId(node.element));
1160
+ }
1161
+ for (const child of node.children) {
1162
+ visit(child);
1163
+ }
1164
+ };
1165
+ visit(this.tree.getNode());
1166
+ this._treeViewState = { collapsed };
1167
+ }
1168
+ onDidActiveEditorChange() {
1169
+ if (!this.configurationService.getValue('scm.autoReveal')) {
1170
+ return;
1171
+ }
1172
+ if (this.firstVisible) {
1173
+ this.firstVisible = false;
1174
+ this.visibilityDisposables.add(disposableTimeout(() => this.onDidActiveEditorChange(), 250));
1175
+ return;
1176
+ }
1177
+ const uri = EditorResourceAccessor.getOriginalUri(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.PRIMARY });
1178
+ if (!uri) {
1179
+ return;
1180
+ }
1181
+ for (const repository of this.scmViewService.visibleRepositories) {
1182
+ const item = this.items.get(repository);
1183
+ if (!item) {
1184
+ continue;
1185
+ }
1186
+ for (let j = item.groupItems.length - 1; j >= 0; j--) {
1187
+ const groupItem = item.groupItems[j];
1188
+ const resource = this.mode === "tree"
1189
+ ? groupItem.tree.getNode(uri)?.element
1190
+ : groupItem.resources.find(r => this.uriIdentityService.extUri.isEqual(r.sourceUri, uri));
1191
+ if (resource) {
1192
+ this.tree.reveal(resource);
1193
+ this.tree.setSelection([resource]);
1194
+ this.tree.setFocus([resource]);
1195
+ return;
1196
+ }
1197
+ }
1198
+ }
1199
+ }
1200
+ focus() {
1201
+ if (this.tree.getFocus().length === 0) {
1202
+ for (const repository of this.scmViewService.visibleRepositories) {
1203
+ const widget = this.inputRenderer.getRenderedInputWidget(repository.input);
1204
+ if (widget) {
1205
+ widget.focus();
1206
+ return;
1207
+ }
1208
+ }
1209
+ }
1210
+ this.tree.domFocus();
1211
+ }
1212
+ updateRepositoryCollapseAllContextKeys() {
1213
+ if (!this.visible || this.scmViewService.visibleRepositories.length === 1) {
1214
+ this.isAnyRepositoryCollapsibleContextKey.set(false);
1215
+ this.areAllRepositoriesCollapsedContextKey.set(false);
1216
+ return;
1217
+ }
1218
+ this.isAnyRepositoryCollapsibleContextKey.set(( this.scmViewService.visibleRepositories.some(r => this.tree.hasElement(r) && this.tree.isCollapsible(r))));
1219
+ this.areAllRepositoriesCollapsedContextKey.set(this.scmViewService.visibleRepositories.every(r => this.tree.hasElement(r) && (!this.tree.isCollapsible(r) || this.tree.isCollapsed(r))));
1220
+ }
1221
+ collapseAllRepositories() {
1222
+ for (const repository of this.scmViewService.visibleRepositories) {
1223
+ if (this.tree.isCollapsible(repository)) {
1224
+ this.tree.collapse(repository);
1225
+ }
1226
+ }
1227
+ }
1228
+ expandAllRepositories() {
1229
+ for (const repository of this.scmViewService.visibleRepositories) {
1230
+ if (this.tree.isCollapsible(repository)) {
1231
+ this.tree.expand(repository);
1232
+ }
1233
+ }
1234
+ }
1235
+ getViewModelMode() {
1236
+ let mode = this.configurationService.getValue('scm.defaultViewMode') === 'list' ? "list" : "tree" ;
1237
+ const storageMode = this.storageService.get(`scm.viewMode`, 1 );
1238
+ if (typeof storageMode === 'string') {
1239
+ mode = storageMode;
1240
+ }
1241
+ return mode;
1242
+ }
1243
+ getViewModelSortKey() {
1244
+ if (this._mode === "tree" ) {
1245
+ return "path" ;
1246
+ }
1247
+ let viewSortKey;
1248
+ const viewSortKeyString = this.configurationService.getValue('scm.defaultViewSortKey');
1249
+ switch (viewSortKeyString) {
1250
+ case 'name':
1251
+ viewSortKey = "name" ;
1252
+ break;
1253
+ case 'status':
1254
+ viewSortKey = "status" ;
1255
+ break;
1256
+ default:
1257
+ viewSortKey = "path" ;
1258
+ break;
1259
+ }
1260
+ const storageSortKey = this.storageService.get(`scm.viewSortKey`, 1 );
1261
+ if (typeof storageSortKey === 'string') {
1262
+ viewSortKey = storageSortKey;
1263
+ }
1264
+ return viewSortKey;
1265
+ }
1266
+ dispose() {
1267
+ this.visibilityDisposables.dispose();
1268
+ this.disposables.dispose();
1269
+ dispose(( this.items.values()));
1270
+ this.items.clear();
1271
+ }
1272
+ };
1273
+ ViewModel = ( __decorate([
1274
+ ( __param(2, IInstantiationService)),
1275
+ ( __param(3, IEditorService)),
1276
+ ( __param(4, IConfigurationService)),
1277
+ ( __param(5, ISCMViewService)),
1278
+ ( __param(6, IStorageService)),
1279
+ ( __param(7, IUriIdentityService)),
1280
+ ( __param(8, IContextKeyService))
1281
+ ], ViewModel));
1282
+ class SetListViewModeAction extends ViewAction {
1283
+ constructor(menu = {}) {
1284
+ super({
1285
+ id: 'workbench.scm.action.setListViewMode',
1286
+ title: ( localizeWithPath(
1287
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1288
+ 'setListViewMode',
1289
+ "View as List"
1290
+ )),
1291
+ viewId: VIEW_PANE_ID,
1292
+ f1: false,
1293
+ icon: Codicon.listTree,
1294
+ toggled: ( ContextKeys.ViewModelMode.isEqualTo("list" )),
1295
+ menu: { id: Menus.ViewSort, group: '1_viewmode', ...menu }
1296
+ });
1297
+ }
1298
+ async runInView(_, view) {
1299
+ view.viewModel.mode = "list" ;
1300
+ }
1301
+ }
1302
+ class SetListViewModeNavigationAction extends SetListViewModeAction {
1303
+ constructor() {
1304
+ super({
1305
+ id: MenuId.SCMTitle,
1306
+ when: ( ContextKeyExpr.and(( ContextKeyExpr.equals('view', VIEW_PANE_ID)), ( ContextKeys.RepositoryCount.notEqualsTo(0)), ( ContextKeys.ViewModelMode.isEqualTo("tree" )))),
1307
+ group: 'navigation',
1308
+ order: -1000
1309
+ });
1310
+ }
1311
+ }
1312
+ class SetTreeViewModeAction extends ViewAction {
1313
+ constructor(menu = {}) {
1314
+ super({
1315
+ id: 'workbench.scm.action.setTreeViewMode',
1316
+ title: ( localizeWithPath(
1317
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1318
+ 'setTreeViewMode',
1319
+ "View as Tree"
1320
+ )),
1321
+ viewId: VIEW_PANE_ID,
1322
+ f1: false,
1323
+ icon: Codicon.listFlat,
1324
+ toggled: ( ContextKeys.ViewModelMode.isEqualTo("tree" )),
1325
+ menu: { id: Menus.ViewSort, group: '1_viewmode', ...menu }
1326
+ });
1327
+ }
1328
+ async runInView(_, view) {
1329
+ view.viewModel.mode = "tree" ;
1330
+ }
1331
+ }
1332
+ class SetTreeViewModeNavigationAction extends SetTreeViewModeAction {
1333
+ constructor() {
1334
+ super({
1335
+ id: MenuId.SCMTitle,
1336
+ when: ( ContextKeyExpr.and(( ContextKeyExpr.equals('view', VIEW_PANE_ID)), ( ContextKeys.RepositoryCount.notEqualsTo(0)), ( ContextKeys.ViewModelMode.isEqualTo("list" )))),
1337
+ group: 'navigation',
1338
+ order: -1000
1339
+ });
1340
+ }
1341
+ }
1342
+ registerAction2(SetListViewModeAction);
1343
+ registerAction2(SetTreeViewModeAction);
1344
+ registerAction2(SetListViewModeNavigationAction);
1345
+ registerAction2(SetTreeViewModeNavigationAction);
1346
+ class RepositorySortAction extends ViewAction {
1347
+ constructor(sortKey, title) {
1348
+ super({
1349
+ id: `workbench.scm.action.repositories.setSortKey.${sortKey}`,
1350
+ title,
1351
+ viewId: VIEW_PANE_ID,
1352
+ f1: false,
1353
+ toggled: ( RepositoryContextKeys.RepositorySortKey.isEqualTo(sortKey)),
1354
+ menu: [
1355
+ {
1356
+ id: Menus.Repositories,
1357
+ group: '1_sort'
1358
+ },
1359
+ {
1360
+ id: MenuId.ViewTitle,
1361
+ when: ( ContextKeyExpr.equals('view', REPOSITORIES_VIEW_PANE_ID)),
1362
+ group: '1_sort',
1363
+ },
1364
+ ]
1365
+ });
1366
+ this.sortKey = sortKey;
1367
+ }
1368
+ runInView(accessor) {
1369
+ accessor.get(ISCMViewService).toggleSortKey(this.sortKey);
1370
+ }
1371
+ }
1372
+ class RepositorySortByDiscoveryTimeAction extends RepositorySortAction {
1373
+ constructor() {
1374
+ super("discoveryTime" , ( localizeWithPath(
1375
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1376
+ 'repositorySortByDiscoveryTime',
1377
+ "Sort by Discovery Time"
1378
+ )));
1379
+ }
1380
+ }
1381
+ class RepositorySortByNameAction extends RepositorySortAction {
1382
+ constructor() {
1383
+ super("name" , ( localizeWithPath(
1384
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1385
+ 'repositorySortByName',
1386
+ "Sort by Name"
1387
+ )));
1388
+ }
1389
+ }
1390
+ class RepositorySortByPathAction extends RepositorySortAction {
1391
+ constructor() {
1392
+ super("path" , ( localizeWithPath(
1393
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1394
+ 'repositorySortByPath',
1395
+ "Sort by Path"
1396
+ )));
1397
+ }
1398
+ }
1399
+ registerAction2(RepositorySortByDiscoveryTimeAction);
1400
+ registerAction2(RepositorySortByNameAction);
1401
+ registerAction2(RepositorySortByPathAction);
1402
+ class SetSortKeyAction extends ViewAction {
1403
+ constructor(sortKey, title) {
1404
+ super({
1405
+ id: `workbench.scm.action.setSortKey.${sortKey}`,
1406
+ title,
1407
+ viewId: VIEW_PANE_ID,
1408
+ f1: false,
1409
+ toggled: ( ContextKeys.ViewModelSortKey.isEqualTo(sortKey)),
1410
+ precondition: ( ContextKeys.ViewModelMode.isEqualTo("list" )),
1411
+ menu: { id: Menus.ViewSort, group: '2_sort' }
1412
+ });
1413
+ this.sortKey = sortKey;
1414
+ }
1415
+ async runInView(_, view) {
1416
+ view.viewModel.sortKey = this.sortKey;
1417
+ }
1418
+ }
1419
+ class SetSortByNameAction extends SetSortKeyAction {
1420
+ constructor() {
1421
+ super("name" , ( localizeWithPath(
1422
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1423
+ 'sortChangesByName',
1424
+ "Sort Changes by Name"
1425
+ )));
1426
+ }
1427
+ }
1428
+ class SetSortByPathAction extends SetSortKeyAction {
1429
+ constructor() {
1430
+ super("path" , ( localizeWithPath(
1431
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1432
+ 'sortChangesByPath',
1433
+ "Sort Changes by Path"
1434
+ )));
1435
+ }
1436
+ }
1437
+ class SetSortByStatusAction extends SetSortKeyAction {
1438
+ constructor() {
1439
+ super("status" , ( localizeWithPath(
1440
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1441
+ 'sortChangesByStatus',
1442
+ "Sort Changes by Status"
1443
+ )));
1444
+ }
1445
+ }
1446
+ registerAction2(SetSortByNameAction);
1447
+ registerAction2(SetSortByPathAction);
1448
+ registerAction2(SetSortByStatusAction);
1449
+ class CollapseAllRepositoriesAction extends ViewAction {
1450
+ constructor() {
1451
+ super({
1452
+ id: `workbench.scm.action.collapseAllRepositories`,
1453
+ title: ( localizeWithPath(
1454
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1455
+ 'collapse all',
1456
+ "Collapse All Repositories"
1457
+ )),
1458
+ viewId: VIEW_PANE_ID,
1459
+ f1: false,
1460
+ icon: Codicon.collapseAll,
1461
+ menu: {
1462
+ id: MenuId.SCMTitle,
1463
+ group: 'navigation',
1464
+ when: ( ContextKeyExpr.and(( ContextKeyExpr.equals('view', VIEW_PANE_ID)), ( ContextKeys.ViewModelIsAnyRepositoryCollapsible.isEqualTo(true)), ( ContextKeys.ViewModelAreAllRepositoriesCollapsed.isEqualTo(false))))
1465
+ }
1466
+ });
1467
+ }
1468
+ async runInView(_, view) {
1469
+ view.viewModel.collapseAllRepositories();
1470
+ }
1471
+ }
1472
+ class ExpandAllRepositoriesAction extends ViewAction {
1473
+ constructor() {
1474
+ super({
1475
+ id: `workbench.scm.action.expandAllRepositories`,
1476
+ title: ( localizeWithPath(
1477
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
1478
+ 'expand all',
1479
+ "Expand All Repositories"
1480
+ )),
1481
+ viewId: VIEW_PANE_ID,
1482
+ f1: false,
1483
+ icon: Codicon.expandAll,
1484
+ menu: {
1485
+ id: MenuId.SCMTitle,
1486
+ group: 'navigation',
1487
+ when: ( ContextKeyExpr.and(( ContextKeyExpr.equals('view', VIEW_PANE_ID)), ( ContextKeys.ViewModelIsAnyRepositoryCollapsible.isEqualTo(true)), ( ContextKeys.ViewModelAreAllRepositoriesCollapsed.isEqualTo(true))))
1488
+ }
1489
+ });
1490
+ }
1491
+ async runInView(_, view) {
1492
+ view.viewModel.expandAllRepositories();
1493
+ }
1494
+ }
1495
+ registerAction2(CollapseAllRepositoriesAction);
1496
+ registerAction2(ExpandAllRepositoriesAction);
1497
+ let SCMInputWidget = class SCMInputWidget {
1498
+ static { SCMInputWidget_1 = this; }
1499
+ static { this.ValidationTimeouts = {
1500
+ [2 ]: 5000,
1501
+ [1 ]: 8000,
1502
+ [0 ]: 10000
1503
+ }; }
1504
+ get input() {
1505
+ return this.model?.input;
1506
+ }
1507
+ async setInput(input) {
1508
+ if (input === this.input) {
1509
+ return;
1510
+ }
1511
+ this.clearValidation();
1512
+ this.editorContainer.classList.remove('synthetic-focus');
1513
+ this.repositoryDisposables.clear();
1514
+ this.repositoryIdContextKey.set(input?.repository.id);
1515
+ if (!input) {
1516
+ this.model?.textModelRef?.dispose();
1517
+ this.inputEditor.setModel(undefined);
1518
+ this.model = undefined;
1519
+ return;
1520
+ }
1521
+ const uri = input.repository.provider.inputBoxDocumentUri;
1522
+ if (this.configurationService.getValue('editor.wordBasedSuggestions', { resource: uri }) !== false) {
1523
+ this.configurationService.updateValue('editor.wordBasedSuggestions', false, { resource: uri }, 8 );
1524
+ }
1525
+ const modelValue = { input, textModelRef: undefined };
1526
+ this.model = modelValue;
1527
+ const modelRef = await this.textModelService.createModelReference(uri);
1528
+ if (this.model !== modelValue) {
1529
+ modelRef.dispose();
1530
+ return;
1531
+ }
1532
+ modelValue.textModelRef = modelRef;
1533
+ const textModel = modelRef.object.textEditorModel;
1534
+ this.inputEditor.setModel(textModel);
1535
+ const validationDelayer = ( new ThrottledDelayer(200));
1536
+ const validate = async () => {
1537
+ const position = this.inputEditor.getSelection()?.getStartPosition();
1538
+ const offset = position && textModel.getOffsetAt(position);
1539
+ const value = textModel.getValue();
1540
+ this.setValidation(await input.validateInput(value, offset || 0));
1541
+ };
1542
+ const triggerValidation = () => validationDelayer.trigger(validate);
1543
+ this.repositoryDisposables.add(validationDelayer);
1544
+ this.repositoryDisposables.add(this.inputEditor.onDidChangeCursorPosition(triggerValidation));
1545
+ const opts = this.modelService.getCreationOptions(textModel.getLanguageId(), textModel.uri, textModel.isForSimpleWidget);
1546
+ const onEnter = Event.filter(this.inputEditor.onKeyDown, e => e.keyCode === 3 , this.repositoryDisposables);
1547
+ this.repositoryDisposables.add(onEnter(() => textModel.detectIndentation(opts.insertSpaces, opts.tabSize)));
1548
+ textModel.setValue(input.value);
1549
+ this.repositoryDisposables.add(input.onDidChange(({ value, reason }) => {
1550
+ if (value === textModel.getValue()) {
1551
+ return;
1552
+ }
1553
+ textModel.setValue(value);
1554
+ const position = reason === SCMInputChangeReason.HistoryPrevious
1555
+ ? textModel.getFullModelRange().getStartPosition()
1556
+ : textModel.getFullModelRange().getEndPosition();
1557
+ this.inputEditor.setPosition(position);
1558
+ this.inputEditor.revealPositionInCenterIfOutsideViewport(position);
1559
+ }));
1560
+ this.repositoryDisposables.add(input.onDidChangeFocus(() => this.focus()));
1561
+ this.repositoryDisposables.add(input.onDidChangeValidationMessage((e) => this.setValidation(e, { focus: true, timeout: true })));
1562
+ this.repositoryDisposables.add(input.onDidChangeValidateInput((e) => triggerValidation()));
1563
+ const updatePlaceholderVisibility = () => this.placeholderTextContainer.classList.toggle('hidden', textModel.getValueLength() > 0);
1564
+ this.repositoryDisposables.add(textModel.onDidChangeContent(() => {
1565
+ input.setValue(textModel.getValue(), true);
1566
+ updatePlaceholderVisibility();
1567
+ triggerValidation();
1568
+ }));
1569
+ updatePlaceholderVisibility();
1570
+ const updatePlaceholderText = () => {
1571
+ const binding = this.keybindingService.lookupKeybinding('scm.acceptInput');
1572
+ const label = binding ? binding.getLabel() : (platform.isMacintosh ? 'Cmd+Enter' : 'Ctrl+Enter');
1573
+ const placeholderText = format(input.placeholder, label);
1574
+ this.inputEditor.updateOptions({ ariaLabel: placeholderText });
1575
+ this.placeholderTextContainer.textContent = placeholderText;
1576
+ };
1577
+ this.repositoryDisposables.add(input.onDidChangePlaceholder(updatePlaceholderText));
1578
+ this.repositoryDisposables.add(this.keybindingService.onDidUpdateKeybindings(updatePlaceholderText));
1579
+ updatePlaceholderText();
1580
+ let commitTemplate = '';
1581
+ const updateTemplate = () => {
1582
+ if (typeof input.repository.provider.commitTemplate === 'undefined' || !input.visible) {
1583
+ return;
1584
+ }
1585
+ const oldCommitTemplate = commitTemplate;
1586
+ commitTemplate = input.repository.provider.commitTemplate;
1587
+ const value = textModel.getValue();
1588
+ if (value && value !== oldCommitTemplate) {
1589
+ return;
1590
+ }
1591
+ textModel.setValue(commitTemplate);
1592
+ };
1593
+ this.repositoryDisposables.add(input.repository.provider.onDidChangeCommitTemplate(updateTemplate, this));
1594
+ updateTemplate();
1595
+ const updateEnablement = (enabled) => {
1596
+ this.inputEditor.updateOptions({ readOnly: !enabled });
1597
+ };
1598
+ this.repositoryDisposables.add(input.onDidChangeEnablement(enabled => updateEnablement(enabled)));
1599
+ updateEnablement(input.enabled);
1600
+ }
1601
+ get selections() {
1602
+ return this.inputEditor.getSelections();
1603
+ }
1604
+ set selections(selections) {
1605
+ if (selections) {
1606
+ this.inputEditor.setSelections(selections);
1607
+ }
1608
+ }
1609
+ setValidation(validation, options) {
1610
+ if (this._validationTimer) {
1611
+ clearTimeout(this._validationTimer);
1612
+ this._validationTimer = 0;
1613
+ }
1614
+ this.validation = validation;
1615
+ this.renderValidation();
1616
+ if (options?.focus && !this.hasFocus()) {
1617
+ this.focus();
1618
+ }
1619
+ if (validation && options?.timeout) {
1620
+ this._validationTimer = setTimeout(() => this.setValidation(undefined), SCMInputWidget_1.ValidationTimeouts[validation.type]);
1621
+ }
1622
+ }
1623
+ constructor(container, overflowWidgetsDomNode, contextKeyService, modelService, textModelService, keybindingService, configurationService, instantiationService, scmViewService, contextViewService, openerService) {
1624
+ this.modelService = modelService;
1625
+ this.textModelService = textModelService;
1626
+ this.keybindingService = keybindingService;
1627
+ this.configurationService = configurationService;
1628
+ this.instantiationService = instantiationService;
1629
+ this.scmViewService = scmViewService;
1630
+ this.contextViewService = contextViewService;
1631
+ this.openerService = openerService;
1632
+ this.defaultInputFontFamily = DEFAULT_FONT_FAMILY;
1633
+ this.disposables = ( new DisposableStore());
1634
+ this.repositoryDisposables = ( new DisposableStore());
1635
+ this.validationDisposable = Disposable.None;
1636
+ this.validationHasFocus = false;
1637
+ this.lastLayoutWasTrash = false;
1638
+ this.shouldFocusAfterLayout = false;
1639
+ this.element = append(container, $('.scm-editor'));
1640
+ this.editorContainer = append(this.element, $('.scm-editor-container'));
1641
+ this.placeholderTextContainer = append(this.editorContainer, $('.scm-editor-placeholder'));
1642
+ const fontFamily = this.getInputEditorFontFamily();
1643
+ const fontSize = this.getInputEditorFontSize();
1644
+ const lineHeight = this.computeLineHeight(fontSize);
1645
+ this.setPlaceholderFontStyles(fontFamily, fontSize, lineHeight);
1646
+ const contextKeyService2 = contextKeyService.createScoped(this.element);
1647
+ this.repositoryIdContextKey = contextKeyService2.createKey('scmRepository', undefined);
1648
+ const editorOptions = {
1649
+ ...getSimpleEditorOptions(configurationService),
1650
+ lineDecorationsWidth: 6,
1651
+ dragAndDrop: true,
1652
+ cursorWidth: 1,
1653
+ fontSize: fontSize,
1654
+ lineHeight: lineHeight,
1655
+ fontFamily: fontFamily,
1656
+ wrappingStrategy: 'advanced',
1657
+ wrappingIndent: 'none',
1658
+ padding: { top: 2, bottom: 2 },
1659
+ quickSuggestions: false,
1660
+ scrollbar: { alwaysConsumeMouseWheel: false },
1661
+ overflowWidgetsDomNode,
1662
+ formatOnType: true,
1663
+ renderWhitespace: 'none',
1664
+ dropIntoEditor: { enabled: true }
1665
+ };
1666
+ const codeEditorWidgetOptions = {
1667
+ isSimpleWidget: true,
1668
+ contributions: EditorExtensionsRegistry.getSomeEditorContributions([
1669
+ ColorDetector.ID,
1670
+ ContextMenuController.ID,
1671
+ DragAndDropController.ID,
1672
+ DropIntoEditorController.ID,
1673
+ LinkDetector.ID,
1674
+ MenuPreventer.ID,
1675
+ MessageController.ID,
1676
+ ModesHoverController.ID,
1677
+ SelectionClipboardContributionID,
1678
+ SnippetController2.ID,
1679
+ SuggestController.ID,
1680
+ InlineCompletionsController.ID,
1681
+ CodeActionController.ID,
1682
+ FormatOnType.ID
1683
+ ])
1684
+ };
1685
+ const services = ( new ServiceCollection([IContextKeyService, contextKeyService2]));
1686
+ const instantiationService2 = instantiationService.createChild(services);
1687
+ this.inputEditor = instantiationService2.createInstance(CodeEditorWidget, this.editorContainer, editorOptions, codeEditorWidgetOptions);
1688
+ this.disposables.add(this.inputEditor);
1689
+ this.disposables.add(this.inputEditor.onDidFocusEditorText(() => {
1690
+ if (this.input?.repository) {
1691
+ this.scmViewService.focus(this.input.repository);
1692
+ }
1693
+ this.editorContainer.classList.add('synthetic-focus');
1694
+ this.renderValidation();
1695
+ }));
1696
+ this.disposables.add(this.inputEditor.onDidBlurEditorText(() => {
1697
+ this.editorContainer.classList.remove('synthetic-focus');
1698
+ setTimeout(() => {
1699
+ if (!this.validation || !this.validationHasFocus) {
1700
+ this.clearValidation();
1701
+ }
1702
+ }, 0);
1703
+ }));
1704
+ const firstLineKey = contextKeyService2.createKey('scmInputIsInFirstPosition', false);
1705
+ const lastLineKey = contextKeyService2.createKey('scmInputIsInLastPosition', false);
1706
+ this.disposables.add(this.inputEditor.onDidChangeCursorPosition(({ position }) => {
1707
+ const viewModel = this.inputEditor._getViewModel();
1708
+ const lastLineNumber = viewModel.getLineCount();
1709
+ const lastLineCol = viewModel.getLineLength(lastLineNumber) + 1;
1710
+ const viewPosition = viewModel.coordinatesConverter.convertModelPositionToViewPosition(position);
1711
+ firstLineKey.set(viewPosition.lineNumber === 1 && viewPosition.column === 1);
1712
+ lastLineKey.set(viewPosition.lineNumber === lastLineNumber && viewPosition.column === lastLineCol);
1713
+ }));
1714
+ const relevantSettings = [
1715
+ 'scm.inputFontFamily',
1716
+ 'editor.fontFamily',
1717
+ 'scm.inputFontSize',
1718
+ 'editor.accessibilitySupport',
1719
+ 'editor.cursorBlinking'
1720
+ ];
1721
+ const onRelevantSettingChanged = Event.filter(this.configurationService.onDidChangeConfiguration, (e) => {
1722
+ for (const setting of relevantSettings) {
1723
+ if (e.affectsConfiguration(setting)) {
1724
+ return true;
1725
+ }
1726
+ }
1727
+ return false;
1728
+ }, this.disposables);
1729
+ this.disposables.add(onRelevantSettingChanged(() => {
1730
+ const fontFamily = this.getInputEditorFontFamily();
1731
+ const fontSize = this.getInputEditorFontSize();
1732
+ const lineHeight = this.computeLineHeight(fontSize);
1733
+ const accessibilitySupport = this.configurationService.getValue('editor.accessibilitySupport');
1734
+ const cursorBlinking = this.configurationService.getValue('editor.cursorBlinking');
1735
+ this.inputEditor.updateOptions({
1736
+ fontFamily: fontFamily,
1737
+ fontSize: fontSize,
1738
+ lineHeight: lineHeight,
1739
+ accessibilitySupport,
1740
+ cursorBlinking
1741
+ });
1742
+ this.setPlaceholderFontStyles(fontFamily, fontSize, lineHeight);
1743
+ }));
1744
+ this.onDidChangeContentHeight = Event.signal(Event.filter(this.inputEditor.onDidContentSizeChange, e => e.contentHeightChanged, this.disposables));
1745
+ }
1746
+ getContentHeight() {
1747
+ const editorContentHeight = this.inputEditor.getContentHeight();
1748
+ return Math.min(editorContentHeight, 134);
1749
+ }
1750
+ layout() {
1751
+ const editorHeight = this.getContentHeight();
1752
+ const dimension = ( new Dimension(this.element.clientWidth - 2, editorHeight));
1753
+ if (dimension.width < 0) {
1754
+ this.lastLayoutWasTrash = true;
1755
+ return;
1756
+ }
1757
+ this.lastLayoutWasTrash = false;
1758
+ this.inputEditor.layout(dimension);
1759
+ this.renderValidation();
1760
+ if (this.shouldFocusAfterLayout) {
1761
+ this.shouldFocusAfterLayout = false;
1762
+ this.focus();
1763
+ }
1764
+ }
1765
+ focus() {
1766
+ if (this.lastLayoutWasTrash) {
1767
+ this.lastLayoutWasTrash = false;
1768
+ this.shouldFocusAfterLayout = true;
1769
+ return;
1770
+ }
1771
+ this.inputEditor.focus();
1772
+ this.editorContainer.classList.add('synthetic-focus');
1773
+ }
1774
+ hasFocus() {
1775
+ return this.inputEditor.hasTextFocus();
1776
+ }
1777
+ renderValidation() {
1778
+ this.clearValidation();
1779
+ this.editorContainer.classList.toggle('validation-info', this.validation?.type === 2 );
1780
+ this.editorContainer.classList.toggle('validation-warning', this.validation?.type === 1 );
1781
+ this.editorContainer.classList.toggle('validation-error', this.validation?.type === 0 );
1782
+ if (!this.validation || !this.inputEditor.hasTextFocus()) {
1783
+ return;
1784
+ }
1785
+ const disposables = ( new DisposableStore());
1786
+ this.validationDisposable = this.contextViewService.showContextView({
1787
+ getAnchor: () => this.editorContainer,
1788
+ render: container => {
1789
+ this.editorContainer.style.borderBottomLeftRadius = '0';
1790
+ this.editorContainer.style.borderBottomRightRadius = '0';
1791
+ const validationContainer = append(container, $('.scm-editor-validation-container'));
1792
+ validationContainer.classList.toggle('validation-info', this.validation.type === 2 );
1793
+ validationContainer.classList.toggle('validation-warning', this.validation.type === 1 );
1794
+ validationContainer.classList.toggle('validation-error', this.validation.type === 0 );
1795
+ validationContainer.style.width = `${this.editorContainer.clientWidth + 2}px`;
1796
+ const element = append(validationContainer, $('.scm-editor-validation'));
1797
+ const message = this.validation.message;
1798
+ if (typeof message === 'string') {
1799
+ element.textContent = message;
1800
+ }
1801
+ else {
1802
+ const tracker = trackFocus(element);
1803
+ disposables.add(tracker);
1804
+ disposables.add(tracker.onDidFocus(() => (this.validationHasFocus = true)));
1805
+ disposables.add(tracker.onDidBlur(() => {
1806
+ this.validationHasFocus = false;
1807
+ this.editorContainer.style.borderBottomLeftRadius = '2px';
1808
+ this.editorContainer.style.borderBottomRightRadius = '2px';
1809
+ this.contextViewService.hideContextView();
1810
+ }));
1811
+ const renderer = disposables.add(this.instantiationService.createInstance(MarkdownRenderer, {}));
1812
+ const renderedMarkdown = renderer.render(message, {
1813
+ actionHandler: {
1814
+ callback: (link) => {
1815
+ openLinkFromMarkdown(this.openerService, link, message.isTrusted);
1816
+ this.editorContainer.style.borderBottomLeftRadius = '2px';
1817
+ this.editorContainer.style.borderBottomRightRadius = '2px';
1818
+ this.contextViewService.hideContextView();
1819
+ },
1820
+ disposables: disposables
1821
+ },
1822
+ });
1823
+ disposables.add(renderedMarkdown);
1824
+ element.appendChild(renderedMarkdown.element);
1825
+ }
1826
+ const actionsContainer = append(validationContainer, $('.scm-editor-validation-actions'));
1827
+ const actionbar = ( new ActionBar(actionsContainer));
1828
+ const action = ( new Action('scmInputWidget.validationMessage.close', ( localizeWithPath('vs/workbench/contrib/scm/browser/scmViewPane', 'label.close', "Close")), ThemeIcon.asClassName(Codicon.close), true, () => {
1829
+ this.contextViewService.hideContextView();
1830
+ this.editorContainer.style.borderBottomLeftRadius = '2px';
1831
+ this.editorContainer.style.borderBottomRightRadius = '2px';
1832
+ }));
1833
+ disposables.add(actionbar);
1834
+ actionbar.push(action, { icon: true, label: false });
1835
+ return Disposable.None;
1836
+ },
1837
+ onHide: () => {
1838
+ this.validationHasFocus = false;
1839
+ this.editorContainer.style.borderBottomLeftRadius = '2px';
1840
+ this.editorContainer.style.borderBottomRightRadius = '2px';
1841
+ disposables.dispose();
1842
+ },
1843
+ anchorAlignment: 0
1844
+ });
1845
+ }
1846
+ getInputEditorFontFamily() {
1847
+ const inputFontFamily = this.configurationService.getValue('scm.inputFontFamily').trim();
1848
+ if (inputFontFamily.toLowerCase() === 'editor') {
1849
+ return this.configurationService.getValue('editor.fontFamily').trim();
1850
+ }
1851
+ if (inputFontFamily.length !== 0 && inputFontFamily.toLowerCase() !== 'default') {
1852
+ return inputFontFamily;
1853
+ }
1854
+ return this.defaultInputFontFamily;
1855
+ }
1856
+ getInputEditorFontSize() {
1857
+ return this.configurationService.getValue('scm.inputFontSize');
1858
+ }
1859
+ computeLineHeight(fontSize) {
1860
+ return Math.round(fontSize * 1.5);
1861
+ }
1862
+ setPlaceholderFontStyles(fontFamily, fontSize, lineHeight) {
1863
+ this.placeholderTextContainer.style.fontFamily = fontFamily;
1864
+ this.placeholderTextContainer.style.fontSize = `${fontSize}px`;
1865
+ this.placeholderTextContainer.style.lineHeight = `${lineHeight}px`;
1866
+ }
1867
+ clearValidation() {
1868
+ this.validationDisposable.dispose();
1869
+ this.validationHasFocus = false;
1870
+ }
1871
+ dispose() {
1872
+ this.setInput(undefined);
1873
+ this.repositoryDisposables.dispose();
1874
+ this.clearValidation();
1875
+ this.disposables.dispose();
1876
+ }
1877
+ };
1878
+ SCMInputWidget = SCMInputWidget_1 = ( __decorate([
1879
+ ( __param(2, IContextKeyService)),
1880
+ ( __param(3, IModelService)),
1881
+ ( __param(4, ITextModelService)),
1882
+ ( __param(5, IKeybindingService)),
1883
+ ( __param(6, IConfigurationService)),
1884
+ ( __param(7, IInstantiationService)),
1885
+ ( __param(8, ISCMViewService)),
1886
+ ( __param(9, IContextViewService)),
1887
+ ( __param(10, IOpenerService))
1888
+ ], SCMInputWidget));
1889
+ let SCMViewPane = class SCMViewPane extends ViewPane {
1890
+ get viewModel() { return this._viewModel; }
1891
+ constructor(options, scmService, scmViewService, keybindingService, themeService, contextMenuService, commandService, editorService, instantiationService, viewDescriptorService, configurationService, contextKeyService, menuService, openerService, telemetryService) {
1892
+ super({ ...options, titleMenuId: MenuId.SCMTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
1893
+ this.scmService = scmService;
1894
+ this.scmViewService = scmViewService;
1895
+ this.commandService = commandService;
1896
+ this.editorService = editorService;
1897
+ this.menuService = menuService;
1898
+ this.disposables = ( new DisposableStore());
1899
+ this._onDidLayout = ( new Emitter());
1900
+ this.layoutCache = {
1901
+ height: undefined,
1902
+ width: undefined,
1903
+ onDidChange: this._onDidLayout.event
1904
+ };
1905
+ this._register(this.instantiationService.createInstance(ScmInputContentProvider));
1906
+ this._register(Event.any(this.scmService.onDidAddRepository, this.scmService.onDidRemoveRepository)(() => this._onDidChangeViewWelcomeState.fire()));
1907
+ }
1908
+ renderBody(container) {
1909
+ super.renderBody(container);
1910
+ this.listContainer = append(container, $('.scm-view.show-file-icons'));
1911
+ const overflowWidgetsDomNode = $('.scm-overflow-widgets-container.monaco-editor');
1912
+ const updateActionsVisibility = () => this.listContainer.classList.toggle('show-actions', this.configurationService.getValue('scm.alwaysShowActions'));
1913
+ this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.alwaysShowActions'), this.disposables)(updateActionsVisibility));
1914
+ updateActionsVisibility();
1915
+ const updateProviderCountVisibility = () => {
1916
+ const value = this.configurationService.getValue('scm.providerCountBadge');
1917
+ this.listContainer.classList.toggle('hide-provider-counts', value === 'hidden');
1918
+ this.listContainer.classList.toggle('auto-provider-counts', value === 'auto');
1919
+ };
1920
+ this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.providerCountBadge'), this.disposables)(updateProviderCountVisibility));
1921
+ updateProviderCountVisibility();
1922
+ this.inputRenderer = this.instantiationService.createInstance(InputRenderer, this.layoutCache, overflowWidgetsDomNode, (input, height) => this.tree.updateElementHeight(input, height));
1923
+ const delegate = ( new ListDelegate(this.inputRenderer));
1924
+ this.actionButtonRenderer = this.instantiationService.createInstance(ActionButtonRenderer);
1925
+ this.listLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility });
1926
+ this._register(this.listLabels);
1927
+ const actionRunner = ( new RepositoryPaneActionRunner(() => this.getSelectedResources()));
1928
+ this._register(actionRunner);
1929
+ this._register(actionRunner.onWillRun(() => this.tree.domFocus()));
1930
+ const renderers = [
1931
+ this.instantiationService.createInstance(RepositoryRenderer, getActionViewItemProvider(this.instantiationService)),
1932
+ this.inputRenderer,
1933
+ this.actionButtonRenderer,
1934
+ this.instantiationService.createInstance(ResourceGroupRenderer, getActionViewItemProvider(this.instantiationService)),
1935
+ this._register(this.instantiationService.createInstance(ResourceRenderer, () => this._viewModel, this.listLabels, getActionViewItemProvider(this.instantiationService), actionRunner))
1936
+ ];
1937
+ const filter = ( new SCMTreeFilter());
1938
+ const sorter = ( new SCMTreeSorter(() => this._viewModel));
1939
+ const keyboardNavigationLabelProvider = this.instantiationService.createInstance(SCMTreeKeyboardNavigationLabelProvider, () => this._viewModel);
1940
+ const identityProvider = ( new SCMResourceIdentityProvider());
1941
+ const dnd = ( new SCMTreeDragAndDrop(this.instantiationService));
1942
+ this.tree = this.instantiationService.createInstance(WorkbenchCompressibleObjectTree, 'SCM Tree Repo', this.listContainer, delegate, renderers, {
1943
+ transformOptimization: false,
1944
+ identityProvider,
1945
+ dnd,
1946
+ horizontalScrolling: false,
1947
+ setRowLineHeight: false,
1948
+ filter,
1949
+ sorter,
1950
+ keyboardNavigationLabelProvider,
1951
+ overrideStyles: {
1952
+ listBackground: this.viewDescriptorService.getViewLocationById(this.id) === 1 ? PANEL_BACKGROUND : SIDE_BAR_BACKGROUND
1953
+ },
1954
+ accessibilityProvider: this.instantiationService.createInstance(SCMAccessibilityProvider)
1955
+ });
1956
+ this._register(this.tree.onDidOpen(this.open, this));
1957
+ this._register(this.tree.onContextMenu(this.onListContextMenu, this));
1958
+ this._register(this.tree.onDidScroll(this.inputRenderer.clearValidation, this.inputRenderer));
1959
+ this._register(this.tree);
1960
+ append(this.listContainer, overflowWidgetsDomNode);
1961
+ this._register(this.instantiationService.createInstance(RepositoryVisibilityActionController));
1962
+ this._viewModel = this.instantiationService.createInstance(ViewModel, this.tree, this.inputRenderer);
1963
+ this._register(this._viewModel);
1964
+ this.listContainer.classList.add('file-icon-themable-tree');
1965
+ this.listContainer.classList.add('show-file-icons');
1966
+ this.updateIndentStyles(this.themeService.getFileIconTheme());
1967
+ this._register(this.themeService.onDidFileIconThemeChange(this.updateIndentStyles, this));
1968
+ this._register(this._viewModel.onDidChangeMode(this.onDidChangeMode, this));
1969
+ this._register(this.onDidChangeBodyVisibility(this._viewModel.setVisible, this._viewModel));
1970
+ this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.alwaysShowRepositories'), this.disposables)(this.updateActions, this));
1971
+ this.updateActions();
1972
+ }
1973
+ updateIndentStyles(theme) {
1974
+ this.listContainer.classList.toggle('list-view-mode', this._viewModel.mode === "list" );
1975
+ this.listContainer.classList.toggle('tree-view-mode', this._viewModel.mode === "tree" );
1976
+ this.listContainer.classList.toggle('align-icons-and-twisties', (this._viewModel.mode === "list" && theme.hasFileIcons) || (theme.hasFileIcons && !theme.hasFolderIcons));
1977
+ this.listContainer.classList.toggle('hide-arrows', this._viewModel.mode === "tree" && theme.hidesExplorerArrows === true);
1978
+ }
1979
+ onDidChangeMode() {
1980
+ this.updateIndentStyles(this.themeService.getFileIconTheme());
1981
+ }
1982
+ layoutBody(height = this.layoutCache.height, width = this.layoutCache.width) {
1983
+ if (height === undefined) {
1984
+ return;
1985
+ }
1986
+ if (width !== undefined) {
1987
+ super.layoutBody(height, width);
1988
+ }
1989
+ this.layoutCache.height = height;
1990
+ this.layoutCache.width = width;
1991
+ this._onDidLayout.fire();
1992
+ this.listContainer.style.height = `${height}px`;
1993
+ this.tree.layout(height, width);
1994
+ }
1995
+ focus() {
1996
+ super.focus();
1997
+ if (this.isExpanded()) {
1998
+ this._viewModel.focus();
1999
+ }
2000
+ }
2001
+ async open(e) {
2002
+ if (!e.element) {
2003
+ return;
2004
+ }
2005
+ else if (isSCMRepository(e.element)) {
2006
+ this.scmViewService.focus(e.element);
2007
+ return;
2008
+ }
2009
+ else if (isSCMResourceGroup(e.element)) {
2010
+ const provider = e.element.provider;
2011
+ const repository = Iterable.find(this.scmService.repositories, r => r.provider === provider);
2012
+ if (repository) {
2013
+ this.scmViewService.focus(repository);
2014
+ }
2015
+ return;
2016
+ }
2017
+ else if (ResourceTree.isResourceNode(e.element)) {
2018
+ const provider = e.element.context.provider;
2019
+ const repository = Iterable.find(this.scmService.repositories, r => r.provider === provider);
2020
+ if (repository) {
2021
+ this.scmViewService.focus(repository);
2022
+ }
2023
+ return;
2024
+ }
2025
+ else if (isSCMInput(e.element)) {
2026
+ this.scmViewService.focus(e.element.repository);
2027
+ const widget = this.inputRenderer.getRenderedInputWidget(e.element);
2028
+ if (widget) {
2029
+ widget.focus();
2030
+ this.tree.setFocus([], e.browserEvent);
2031
+ const selection = this.tree.getSelection();
2032
+ if (selection.length === 1 && selection[0] === e.element) {
2033
+ setTimeout(() => this.tree.setSelection([]));
2034
+ }
2035
+ }
2036
+ return;
2037
+ }
2038
+ else if (isSCMActionButton(e.element)) {
2039
+ this.scmViewService.focus(e.element.repository);
2040
+ this.actionButtonRenderer.focusActionButton(e.element);
2041
+ this.tree.setFocus([], e.browserEvent);
2042
+ return;
2043
+ }
2044
+ if (e.element.command?.id === API_OPEN_EDITOR_COMMAND_ID || e.element.command?.id === API_OPEN_DIFF_EDITOR_COMMAND_ID) {
2045
+ await this.commandService.executeCommand(e.element.command.id, ...(e.element.command.arguments || []), e);
2046
+ }
2047
+ else {
2048
+ await e.element.open(!!e.editorOptions.preserveFocus);
2049
+ if (e.editorOptions.pinned) {
2050
+ const activeEditorPane = this.editorService.activeEditorPane;
2051
+ activeEditorPane?.group.pinEditor(activeEditorPane.input);
2052
+ }
2053
+ }
2054
+ const provider = e.element.resourceGroup.provider;
2055
+ const repository = Iterable.find(this.scmService.repositories, r => r.provider === provider);
2056
+ if (repository) {
2057
+ this.scmViewService.focus(repository);
2058
+ }
2059
+ }
2060
+ onListContextMenu(e) {
2061
+ if (!e.element) {
2062
+ const menu = this.menuService.createMenu(Menus.ViewSort, this.contextKeyService);
2063
+ const actions = [];
2064
+ createAndFillInContextMenuActions(menu, undefined, actions);
2065
+ return this.contextMenuService.showContextMenu({
2066
+ getAnchor: () => e.anchor,
2067
+ getActions: () => actions,
2068
+ onHide: () => {
2069
+ menu.dispose();
2070
+ }
2071
+ });
2072
+ }
2073
+ const element = e.element;
2074
+ let context = element;
2075
+ let actions = [];
2076
+ if (isSCMRepository(element)) {
2077
+ const menus = this.scmViewService.menus.getRepositoryMenus(element.provider);
2078
+ const menu = menus.repositoryMenu;
2079
+ context = element.provider;
2080
+ actions = collectContextMenuActions(menu);
2081
+ }
2082
+ else if (isSCMInput(element) || isSCMActionButton(element)) ;
2083
+ else if (isSCMResourceGroup(element)) {
2084
+ const menus = this.scmViewService.menus.getRepositoryMenus(element.provider);
2085
+ const menu = menus.getResourceGroupMenu(element);
2086
+ actions = collectContextMenuActions(menu);
2087
+ }
2088
+ else if (ResourceTree.isResourceNode(element)) {
2089
+ if (element.element) {
2090
+ const menus = this.scmViewService.menus.getRepositoryMenus(element.element.resourceGroup.provider);
2091
+ const menu = menus.getResourceMenu(element.element);
2092
+ actions = collectContextMenuActions(menu);
2093
+ }
2094
+ else {
2095
+ const menus = this.scmViewService.menus.getRepositoryMenus(element.context.provider);
2096
+ const menu = menus.getResourceFolderMenu(element.context);
2097
+ actions = collectContextMenuActions(menu);
2098
+ }
2099
+ }
2100
+ else {
2101
+ const menus = this.scmViewService.menus.getRepositoryMenus(element.resourceGroup.provider);
2102
+ const menu = menus.getResourceMenu(element);
2103
+ actions = collectContextMenuActions(menu);
2104
+ }
2105
+ const actionRunner = ( new RepositoryPaneActionRunner(() => this.getSelectedResources()));
2106
+ actionRunner.onWillRun(() => this.tree.domFocus());
2107
+ this.contextMenuService.showContextMenu({
2108
+ getAnchor: () => e.anchor,
2109
+ getActions: () => actions,
2110
+ getActionsContext: () => context,
2111
+ actionRunner
2112
+ });
2113
+ }
2114
+ getSelectedResources() {
2115
+ return this.tree.getSelection()
2116
+ .filter(r => !!r && !isSCMResourceGroup(r));
2117
+ }
2118
+ shouldShowWelcome() {
2119
+ return this.scmService.repositoryCount === 0;
2120
+ }
2121
+ getActionsContext() {
2122
+ return this.scmViewService.visibleRepositories.length === 1 ? this.scmViewService.visibleRepositories[0].provider : undefined;
2123
+ }
2124
+ dispose() {
2125
+ this.disposables.dispose();
2126
+ super.dispose();
2127
+ }
2128
+ };
2129
+ SCMViewPane = ( __decorate([
2130
+ ( __param(1, ISCMService)),
2131
+ ( __param(2, ISCMViewService)),
2132
+ ( __param(3, IKeybindingService)),
2133
+ ( __param(4, IThemeService)),
2134
+ ( __param(5, IContextMenuService)),
2135
+ ( __param(6, ICommandService)),
2136
+ ( __param(7, IEditorService)),
2137
+ ( __param(8, IInstantiationService)),
2138
+ ( __param(9, IViewDescriptorService)),
2139
+ ( __param(10, IConfigurationService)),
2140
+ ( __param(11, IContextKeyService)),
2141
+ ( __param(12, IMenuService)),
2142
+ ( __param(13, IOpenerService)),
2143
+ ( __param(14, ITelemetryService))
2144
+ ], SCMViewPane));
2145
+ registerColor('scm.providerBorder', { dark: '#454545', light: '#C8C8C8', hcDark: contrastBorder, hcLight: contrastBorder }, ( localizeWithPath(
2146
+ 'vs/workbench/contrib/scm/browser/scmViewPane',
2147
+ 'scm.providerBorder',
2148
+ "SCM Provider separator border."
2149
+ )));
2150
+ class SCMActionButton {
2151
+ constructor(container, contextMenuService, commandService, notificationService) {
2152
+ this.container = container;
2153
+ this.contextMenuService = contextMenuService;
2154
+ this.commandService = commandService;
2155
+ this.notificationService = notificationService;
2156
+ this.disposables = ( new MutableDisposable());
2157
+ }
2158
+ dispose() {
2159
+ this.disposables?.dispose();
2160
+ }
2161
+ setButton(button) {
2162
+ this.clear();
2163
+ if (!button) {
2164
+ return;
2165
+ }
2166
+ if (button.secondaryCommands?.length) {
2167
+ const actions = [];
2168
+ for (let index = 0; index < button.secondaryCommands.length; index++) {
2169
+ const commands = button.secondaryCommands[index];
2170
+ for (const command of commands) {
2171
+ actions.push(( new Action(
2172
+ command.id,
2173
+ command.title,
2174
+ undefined,
2175
+ true,
2176
+ async () => await this.executeCommand(command.id, ...(command.arguments || []))
2177
+ )));
2178
+ }
2179
+ if (commands.length) {
2180
+ actions.push(( new Separator()));
2181
+ }
2182
+ }
2183
+ actions.pop();
2184
+ this.button = ( new ButtonWithDropdown(this.container, {
2185
+ actions: actions,
2186
+ addPrimaryActionToDropdown: false,
2187
+ contextMenuProvider: this.contextMenuService,
2188
+ title: button.command.tooltip,
2189
+ supportIcons: true,
2190
+ ...defaultButtonStyles
2191
+ }));
2192
+ }
2193
+ else {
2194
+ this.button = ( new Button(
2195
+ this.container,
2196
+ { supportIcons: true, supportShortLabel: !!button.description, title: button.command.tooltip, ...defaultButtonStyles }
2197
+ ));
2198
+ }
2199
+ this.button.enabled = button.enabled;
2200
+ this.button.label = button.command.title;
2201
+ if (this.button instanceof Button && button.description) {
2202
+ this.button.labelShort = button.description;
2203
+ }
2204
+ this.button.onDidClick(async () => await this.executeCommand(button.command.id, ...(button.command.arguments || [])), null, this.disposables.value);
2205
+ this.disposables.value.add(this.button);
2206
+ }
2207
+ focus() {
2208
+ this.button?.focus();
2209
+ }
2210
+ clear() {
2211
+ this.disposables.value = ( new DisposableStore());
2212
+ this.button = undefined;
2213
+ clearNode(this.container);
2214
+ }
2215
+ async executeCommand(commandId, ...args) {
2216
+ try {
2217
+ await this.commandService.executeCommand(commandId, ...args);
2218
+ }
2219
+ catch (ex) {
2220
+ this.notificationService.error(ex);
2221
+ }
2222
+ }
2223
+ }
2224
+ let ScmInputContentProvider = class ScmInputContentProvider extends Disposable {
2225
+ constructor(textModelService, _modelService, _languageService) {
2226
+ super();
2227
+ this._modelService = _modelService;
2228
+ this._languageService = _languageService;
2229
+ this._register(textModelService.registerTextModelContentProvider(Schemas.vscodeSourceControl, this));
2230
+ }
2231
+ async provideTextContent(resource) {
2232
+ const existing = this._modelService.getModel(resource);
2233
+ if (existing) {
2234
+ return existing;
2235
+ }
2236
+ return this._modelService.createModel('', this._languageService.createById('scminput'), resource);
2237
+ }
2238
+ };
2239
+ ScmInputContentProvider = ( __decorate([
2240
+ ( __param(0, ITextModelService)),
2241
+ ( __param(1, IModelService)),
2242
+ ( __param(2, ILanguageService))
2243
+ ], ScmInputContentProvider));
2244
+
2245
+ export { ActionButtonRenderer, SCMAccessibilityProvider, SCMActionButton, SCMTreeKeyboardNavigationLabelProvider, SCMTreeSorter, SCMViewPane };