@codingame/monaco-vscode-scm-service-override 6.0.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/vscode/src/vs/workbench/contrib/scm/browser/activity.js +119 -174
- package/vscode/src/vs/workbench/contrib/scm/browser/media/scm.css.js +1 -1
- package/vscode/src/vs/workbench/contrib/scm/browser/menus.js +1 -1
- package/vscode/src/vs/workbench/contrib/scm/browser/scm.contribution.js +34 -10
- package/vscode/src/vs/workbench/contrib/scm/browser/scmHistory.js +180 -0
- package/vscode/src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.js +25 -22
- package/vscode/src/vs/workbench/contrib/scm/browser/scmViewPane.js +240 -65
- package/vscode/src/vs/workbench/contrib/scm/browser/util.js +7 -1
- package/vscode/src/vs/workbench/contrib/scm/common/scmService.js +34 -9
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { lastOrDefault } from 'vscode/vscode/vs/base/common/arrays';
|
|
2
|
+
import { deepClone } from 'vscode/vscode/vs/base/common/objects';
|
|
3
|
+
import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
|
|
4
|
+
|
|
5
|
+
const SWIMLANE_HEIGHT = 22;
|
|
6
|
+
const SWIMLANE_WIDTH = 11;
|
|
7
|
+
const CIRCLE_RADIUS = 4;
|
|
8
|
+
const SWIMLANE_CURVE_RADIUS = 5;
|
|
9
|
+
const graphColors = ['#007ACC', '#BC3FBC', '#BF8803', '#CC6633', '#F14C4C', '#16825D'];
|
|
10
|
+
function getNextColorIndex(colorIndex) {
|
|
11
|
+
return colorIndex < graphColors.length - 1 ? colorIndex + 1 : 1;
|
|
12
|
+
}
|
|
13
|
+
function getLabelColorIndex(historyItem, colorMap) {
|
|
14
|
+
for (const label of historyItem.labels ?? []) {
|
|
15
|
+
const colorIndex = colorMap.get(label.title);
|
|
16
|
+
if (colorIndex !== undefined) {
|
|
17
|
+
return colorIndex;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
function createPath(stroke) {
|
|
23
|
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
24
|
+
path.setAttribute('fill', 'none');
|
|
25
|
+
path.setAttribute('stroke', stroke);
|
|
26
|
+
path.setAttribute('stroke-width', '1px');
|
|
27
|
+
path.setAttribute('stroke-linecap', 'round');
|
|
28
|
+
return path;
|
|
29
|
+
}
|
|
30
|
+
function drawCircle(index, radius, fill) {
|
|
31
|
+
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
32
|
+
circle.setAttribute('cx', `${SWIMLANE_WIDTH * (index + 1)}`);
|
|
33
|
+
circle.setAttribute('cy', `${SWIMLANE_WIDTH}`);
|
|
34
|
+
circle.setAttribute('r', `${radius}`);
|
|
35
|
+
circle.setAttribute('fill', fill);
|
|
36
|
+
return circle;
|
|
37
|
+
}
|
|
38
|
+
function drawVerticalLine(x1, y1, y2, color) {
|
|
39
|
+
const path = createPath(color);
|
|
40
|
+
path.setAttribute('d', `M ${x1} ${y1} V ${y2}`);
|
|
41
|
+
return path;
|
|
42
|
+
}
|
|
43
|
+
function findLastIndex(nodes, id) {
|
|
44
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
45
|
+
if (nodes[i].id === id) {
|
|
46
|
+
return i;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return -1;
|
|
50
|
+
}
|
|
51
|
+
function renderSCMHistoryItemGraph(historyItemViewModel) {
|
|
52
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
53
|
+
svg.classList.add('graph');
|
|
54
|
+
const historyItem = historyItemViewModel.historyItem;
|
|
55
|
+
const inputSwimlanes = historyItemViewModel.inputSwimlanes;
|
|
56
|
+
const outputSwimlanes = historyItemViewModel.outputSwimlanes;
|
|
57
|
+
const inputIndex = inputSwimlanes.findIndex(node => node.id === historyItem.id);
|
|
58
|
+
const circleIndex = inputIndex !== -1 ? inputIndex : inputSwimlanes.length;
|
|
59
|
+
const circleColorIndex = circleIndex < outputSwimlanes.length ? outputSwimlanes[circleIndex].color : inputSwimlanes[circleIndex].color;
|
|
60
|
+
let outputSwimlaneIndex = 0;
|
|
61
|
+
for (let index = 0; index < inputSwimlanes.length; index++) {
|
|
62
|
+
const color = graphColors[inputSwimlanes[index].color];
|
|
63
|
+
if (inputSwimlanes[index].id === historyItem.id) {
|
|
64
|
+
if (index !== circleIndex) {
|
|
65
|
+
const d = [];
|
|
66
|
+
const path = createPath(color);
|
|
67
|
+
d.push(`M ${SWIMLANE_WIDTH * (index + 1)} 0`);
|
|
68
|
+
d.push(`A ${SWIMLANE_WIDTH} ${SWIMLANE_WIDTH} 0 0 1 ${SWIMLANE_WIDTH * (index)} ${SWIMLANE_WIDTH}`);
|
|
69
|
+
d.push(`H ${SWIMLANE_WIDTH * (circleIndex + 1)}`);
|
|
70
|
+
path.setAttribute('d', d.join(' '));
|
|
71
|
+
svg.append(path);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
outputSwimlaneIndex++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (outputSwimlaneIndex < outputSwimlanes.length &&
|
|
79
|
+
inputSwimlanes[index].id === outputSwimlanes[outputSwimlaneIndex].id) {
|
|
80
|
+
if (index === outputSwimlaneIndex) {
|
|
81
|
+
const path = drawVerticalLine(SWIMLANE_WIDTH * (index + 1), 0, SWIMLANE_HEIGHT, color);
|
|
82
|
+
svg.append(path);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const d = [];
|
|
86
|
+
const path = createPath(color);
|
|
87
|
+
d.push(`M ${SWIMLANE_WIDTH * (index + 1)} 0`);
|
|
88
|
+
d.push(`V 6`);
|
|
89
|
+
d.push(`A ${SWIMLANE_CURVE_RADIUS} ${SWIMLANE_CURVE_RADIUS} 0 0 1 ${(SWIMLANE_WIDTH * (index + 1)) - SWIMLANE_CURVE_RADIUS} ${SWIMLANE_HEIGHT / 2}`);
|
|
90
|
+
d.push(`H ${(SWIMLANE_WIDTH * (outputSwimlaneIndex + 1)) + SWIMLANE_CURVE_RADIUS}`);
|
|
91
|
+
d.push(`A ${SWIMLANE_CURVE_RADIUS} ${SWIMLANE_CURVE_RADIUS} 0 0 0 ${SWIMLANE_WIDTH * (outputSwimlaneIndex + 1)} ${(SWIMLANE_HEIGHT / 2) + SWIMLANE_CURVE_RADIUS}`);
|
|
92
|
+
d.push(`V ${SWIMLANE_HEIGHT}`);
|
|
93
|
+
path.setAttribute('d', d.join(' '));
|
|
94
|
+
svg.append(path);
|
|
95
|
+
}
|
|
96
|
+
outputSwimlaneIndex++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (let i = 1; i < historyItem.parentIds.length; i++) {
|
|
101
|
+
const parentOutputIndex = findLastIndex(outputSwimlanes, historyItem.parentIds[i]);
|
|
102
|
+
if (parentOutputIndex === -1) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const d = [];
|
|
106
|
+
const path = createPath(graphColors[outputSwimlanes[parentOutputIndex].color]);
|
|
107
|
+
d.push(`M ${SWIMLANE_WIDTH * parentOutputIndex} ${SWIMLANE_HEIGHT / 2}`);
|
|
108
|
+
d.push(`A ${SWIMLANE_WIDTH} ${SWIMLANE_WIDTH} 0 0 1 ${SWIMLANE_WIDTH * (parentOutputIndex + 1)} ${SWIMLANE_HEIGHT}`);
|
|
109
|
+
d.push(`M ${SWIMLANE_WIDTH * parentOutputIndex} ${SWIMLANE_HEIGHT / 2}`);
|
|
110
|
+
d.push(`H ${SWIMLANE_WIDTH * (circleIndex + 1)} `);
|
|
111
|
+
path.setAttribute('d', d.join(' '));
|
|
112
|
+
svg.append(path);
|
|
113
|
+
}
|
|
114
|
+
if (inputIndex !== -1) {
|
|
115
|
+
const path = drawVerticalLine(SWIMLANE_WIDTH * (circleIndex + 1), 0, SWIMLANE_HEIGHT / 2, graphColors[inputSwimlanes[inputIndex].color]);
|
|
116
|
+
svg.append(path);
|
|
117
|
+
}
|
|
118
|
+
if (historyItem.parentIds.length > 0) {
|
|
119
|
+
const path = drawVerticalLine(SWIMLANE_WIDTH * (circleIndex + 1), SWIMLANE_HEIGHT / 2, SWIMLANE_HEIGHT, graphColors[circleColorIndex]);
|
|
120
|
+
svg.append(path);
|
|
121
|
+
}
|
|
122
|
+
if (historyItem.parentIds.length > 1) {
|
|
123
|
+
const circleOuter = drawCircle(circleIndex, CIRCLE_RADIUS + 1, graphColors[circleColorIndex]);
|
|
124
|
+
svg.append(circleOuter);
|
|
125
|
+
const circleInner = drawCircle(circleIndex, CIRCLE_RADIUS - 1, graphColors[circleColorIndex]);
|
|
126
|
+
svg.append(circleInner);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
if (historyItem.labels?.some(l => ThemeIcon.isThemeIcon(l.icon) && l.icon.id === 'target')) {
|
|
130
|
+
const outerCircle = drawCircle(circleIndex, CIRCLE_RADIUS + 2, graphColors[circleColorIndex]);
|
|
131
|
+
svg.append(outerCircle);
|
|
132
|
+
}
|
|
133
|
+
const circle = drawCircle(circleIndex, CIRCLE_RADIUS, graphColors[circleColorIndex]);
|
|
134
|
+
svg.append(circle);
|
|
135
|
+
}
|
|
136
|
+
svg.style.height = `${SWIMLANE_HEIGHT}px`;
|
|
137
|
+
svg.style.width = `${SWIMLANE_WIDTH * (Math.max(inputSwimlanes.length, outputSwimlanes.length, 1) + 1)}px`;
|
|
138
|
+
return svg;
|
|
139
|
+
}
|
|
140
|
+
function toISCMHistoryItemViewModelArray(historyItems, colorMap = ( new Map())) {
|
|
141
|
+
let colorIndex = -1;
|
|
142
|
+
const viewModels = [];
|
|
143
|
+
for (let index = 0; index < historyItems.length; index++) {
|
|
144
|
+
const historyItem = historyItems[index];
|
|
145
|
+
const outputSwimlanesFromPreviousItem = lastOrDefault(viewModels)?.outputSwimlanes ?? [];
|
|
146
|
+
const inputSwimlanes = ( outputSwimlanesFromPreviousItem.map(i => deepClone(i)));
|
|
147
|
+
const outputSwimlanes = [];
|
|
148
|
+
if (historyItem.parentIds.length > 0) {
|
|
149
|
+
let firstParentAdded = false;
|
|
150
|
+
for (const node of inputSwimlanes) {
|
|
151
|
+
if (node.id === historyItem.id) {
|
|
152
|
+
if (!firstParentAdded) {
|
|
153
|
+
outputSwimlanes.push({
|
|
154
|
+
id: historyItem.parentIds[0],
|
|
155
|
+
color: getLabelColorIndex(historyItem, colorMap) ?? node.color
|
|
156
|
+
});
|
|
157
|
+
firstParentAdded = true;
|
|
158
|
+
}
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
outputSwimlanes.push(deepClone(node));
|
|
162
|
+
}
|
|
163
|
+
for (let i = firstParentAdded ? 1 : 0; i < historyItem.parentIds.length; i++) {
|
|
164
|
+
colorIndex = getLabelColorIndex(historyItem, colorMap) ?? getNextColorIndex(colorIndex);
|
|
165
|
+
outputSwimlanes.push({
|
|
166
|
+
id: historyItem.parentIds[i],
|
|
167
|
+
color: colorIndex
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
viewModels.push({
|
|
172
|
+
historyItem,
|
|
173
|
+
inputSwimlanes,
|
|
174
|
+
outputSwimlanes,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return viewModels;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { renderSCMHistoryItemGraph, toISCMHistoryItemViewModelArray };
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
|
|
2
2
|
import './media/scm.css.js';
|
|
3
|
-
import { combinedDisposable, DisposableStore
|
|
3
|
+
import { combinedDisposable, DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
4
|
+
import 'vscode/vscode/vs/base/common/arrays';
|
|
5
|
+
import 'vscode/vscode/vs/base/common/observableInternal/derived';
|
|
6
|
+
import { autorun } from 'vscode/vscode/vs/base/common/observableInternal/autorun';
|
|
7
|
+
import 'vscode/vscode/vs/base/common/observableInternal/utils';
|
|
8
|
+
import 'vscode/vscode/vs/base/common/cancellation';
|
|
4
9
|
import { append, $ } from 'vscode/vscode/vs/base/browser/dom';
|
|
5
10
|
import { ISCMViewService } from 'vscode/vscode/vs/workbench/contrib/scm/common/scm.service';
|
|
6
11
|
import { CountBadge } from 'vscode/vscode/vs/base/browser/ui/countBadge/countBadge';
|
|
7
12
|
import { IContextMenuService } from 'vscode/vscode/vs/platform/contextview/browser/contextView.service';
|
|
8
13
|
import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands.service';
|
|
9
14
|
import { ActionRunner } from 'vscode/vscode/vs/base/common/actions';
|
|
10
|
-
import { isSCMRepository, StatusBarAction, connectPrimaryMenu } from './util.js';
|
|
15
|
+
import { isSCMRepository, StatusBarAction, getRepositoryResourceCount, connectPrimaryMenu } from './util.js';
|
|
11
16
|
import { defaultCountBadgeStyles } from 'vscode/vscode/vs/platform/theme/browser/defaultStyles';
|
|
12
17
|
import { WorkbenchToolBar } from 'vscode/vscode/vs/platform/actions/browser/toolbar';
|
|
13
18
|
import { MenuItemAction, MenuId } from 'vscode/vscode/vs/platform/actions/common/actions';
|
|
@@ -15,6 +20,8 @@ import { IMenuService } from 'vscode/vscode/vs/platform/actions/common/actions.s
|
|
|
15
20
|
import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey.service';
|
|
16
21
|
import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding.service';
|
|
17
22
|
import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry.service';
|
|
23
|
+
import { IHoverService } from 'vscode/vscode/vs/platform/hover/browser/hover.service';
|
|
24
|
+
import { getDefaultHoverDelegate } from 'vscode/vscode/vs/base/browser/ui/hover/hoverDelegateFactory';
|
|
18
25
|
|
|
19
26
|
var RepositoryRenderer_1;
|
|
20
27
|
class RepositoryActionRunner extends ActionRunner {
|
|
@@ -35,13 +42,14 @@ let RepositoryRenderer = class RepositoryRenderer {
|
|
|
35
42
|
static { RepositoryRenderer_1 = this; }
|
|
36
43
|
static { this.TEMPLATE_ID = 'repository'; }
|
|
37
44
|
get templateId() { return RepositoryRenderer_1.TEMPLATE_ID; }
|
|
38
|
-
constructor(toolbarMenuId, actionViewItemProvider, scmViewService, commandService, contextKeyService, contextMenuService, keybindingService, menuService, telemetryService) {
|
|
45
|
+
constructor(toolbarMenuId, actionViewItemProvider, scmViewService, commandService, contextKeyService, contextMenuService, hoverService, keybindingService, menuService, telemetryService) {
|
|
39
46
|
this.toolbarMenuId = toolbarMenuId;
|
|
40
47
|
this.actionViewItemProvider = actionViewItemProvider;
|
|
41
48
|
this.scmViewService = scmViewService;
|
|
42
49
|
this.commandService = commandService;
|
|
43
50
|
this.contextKeyService = contextKeyService;
|
|
44
51
|
this.contextMenuService = contextMenuService;
|
|
52
|
+
this.hoverService = hoverService;
|
|
45
53
|
this.keybindingService = keybindingService;
|
|
46
54
|
this.menuService = menuService;
|
|
47
55
|
this.telemetryService = telemetryService;
|
|
@@ -52,6 +60,7 @@ let RepositoryRenderer = class RepositoryRenderer {
|
|
|
52
60
|
}
|
|
53
61
|
const provider = append(container, $('.scm-provider'));
|
|
54
62
|
const label = append(provider, $('.label'));
|
|
63
|
+
const labelCustomHover = this.hoverService.setupManagedHover(getDefaultHoverDelegate('mouse'), label, '', {});
|
|
55
64
|
const name = append(label, $('span.name'));
|
|
56
65
|
const description = append(label, $('span.description'));
|
|
57
66
|
const actions = append(provider, $('.actions'));
|
|
@@ -68,18 +77,18 @@ let RepositoryRenderer = class RepositoryRenderer {
|
|
|
68
77
|
const countContainer = append(provider, $('.count'));
|
|
69
78
|
const count = ( new CountBadge(countContainer, {}, defaultCountBadgeStyles));
|
|
70
79
|
const visibilityDisposable = toolBar.onDidChangeDropdownVisibility(e => provider.classList.toggle('active', e));
|
|
71
|
-
const templateDisposable = combinedDisposable(visibilityDisposable, toolBar);
|
|
72
|
-
return { label, name, description, countContainer, count, toolBar, elementDisposables: ( new DisposableStore()), templateDisposable };
|
|
80
|
+
const templateDisposable = combinedDisposable(labelCustomHover, visibilityDisposable, toolBar);
|
|
81
|
+
return { label, labelCustomHover, name, description, countContainer, count, toolBar, elementDisposables: ( new DisposableStore()), templateDisposable };
|
|
73
82
|
}
|
|
74
83
|
renderElement(arg, index, templateData, height) {
|
|
75
84
|
const repository = isSCMRepository(arg) ? arg : arg.element;
|
|
76
85
|
templateData.name.textContent = repository.provider.name;
|
|
77
86
|
if (repository.provider.rootUri) {
|
|
78
|
-
templateData.
|
|
87
|
+
templateData.labelCustomHover.update(`${repository.provider.label}: ${repository.provider.rootUri.fsPath}`);
|
|
79
88
|
templateData.description.textContent = repository.provider.label;
|
|
80
89
|
}
|
|
81
90
|
else {
|
|
82
|
-
templateData.
|
|
91
|
+
templateData.labelCustomHover.update(repository.provider.label);
|
|
83
92
|
templateData.description.textContent = '';
|
|
84
93
|
}
|
|
85
94
|
let statusPrimaryActions = [];
|
|
@@ -88,23 +97,16 @@ let RepositoryRenderer = class RepositoryRenderer {
|
|
|
88
97
|
const updateToolbar = () => {
|
|
89
98
|
templateData.toolBar.setActions([...statusPrimaryActions, ...menuPrimaryActions], menuSecondaryActions);
|
|
90
99
|
};
|
|
91
|
-
|
|
92
|
-
const commands = repository.provider.statusBarCommands
|
|
100
|
+
templateData.elementDisposables.add(autorun(reader => {
|
|
101
|
+
const commands = repository.provider.statusBarCommands.read(reader) ?? [];
|
|
93
102
|
statusPrimaryActions = ( commands.map(c => ( new StatusBarAction(c, this.commandService))));
|
|
94
103
|
updateToolbar();
|
|
95
|
-
|
|
104
|
+
}));
|
|
105
|
+
templateData.elementDisposables.add(autorun(reader => {
|
|
106
|
+
const count = repository.provider.count.read(reader) ?? getRepositoryResourceCount(repository.provider);
|
|
96
107
|
templateData.countContainer.setAttribute('data-count', String(count));
|
|
97
108
|
templateData.count.setCount(count);
|
|
98
|
-
};
|
|
99
|
-
let disposed = false;
|
|
100
|
-
templateData.elementDisposables.add(toDisposable(() => disposed = true));
|
|
101
|
-
templateData.elementDisposables.add(repository.provider.onDidChange(() => {
|
|
102
|
-
if (disposed) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
onDidChangeProvider();
|
|
106
109
|
}));
|
|
107
|
-
onDidChangeProvider();
|
|
108
110
|
const repositoryMenus = this.scmViewService.menus.getRepositoryMenus(repository.provider);
|
|
109
111
|
const menu = this.toolbarMenuId === MenuId.SCMTitle ? repositoryMenus.titleMenu.menu : repositoryMenus.repositoryMenu;
|
|
110
112
|
templateData.elementDisposables.add(connectPrimaryMenu(menu, (primary, secondary) => {
|
|
@@ -130,9 +132,10 @@ RepositoryRenderer = RepositoryRenderer_1 = ( __decorate([
|
|
|
130
132
|
( __param(3, ICommandService)),
|
|
131
133
|
( __param(4, IContextKeyService)),
|
|
132
134
|
( __param(5, IContextMenuService)),
|
|
133
|
-
( __param(6,
|
|
134
|
-
( __param(7,
|
|
135
|
-
( __param(8,
|
|
135
|
+
( __param(6, IHoverService)),
|
|
136
|
+
( __param(7, IKeybindingService)),
|
|
137
|
+
( __param(8, IMenuService)),
|
|
138
|
+
( __param(9, ITelemetryService))
|
|
136
139
|
], RepositoryRenderer));
|
|
137
140
|
|
|
138
141
|
export { RepositoryActionRunner, RepositoryRenderer };
|