@theia/scm 1.75.0-next.3 → 1.75.0-next.35
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/lib/browser/decorations/scm-navigator-decorator.d.ts.map +1 -1
- package/lib/browser/decorations/scm-navigator-decorator.js +1 -0
- package/lib/browser/decorations/scm-navigator-decorator.js.map +1 -1
- package/lib/browser/scm-context-key-service.d.ts +2 -0
- package/lib/browser/scm-context-key-service.d.ts.map +1 -1
- package/lib/browser/scm-context-key-service.js +4 -0
- package/lib/browser/scm-context-key-service.js.map +1 -1
- package/lib/browser/scm-context-key-service.spec.js +7 -0
- package/lib/browser/scm-context-key-service.spec.js.map +1 -1
- package/lib/browser/scm-frontend-module.d.ts.map +1 -1
- package/lib/browser/scm-frontend-module.js +6 -0
- package/lib/browser/scm-frontend-module.js.map +1 -1
- package/lib/browser/scm-history-graph-contribution.d.ts +44 -0
- package/lib/browser/scm-history-graph-contribution.d.ts.map +1 -0
- package/lib/browser/scm-history-graph-contribution.js +226 -0
- package/lib/browser/scm-history-graph-contribution.js.map +1 -0
- package/lib/browser/scm-history-graph-contribution.spec.d.ts +2 -0
- package/lib/browser/scm-history-graph-contribution.spec.d.ts.map +1 -0
- package/lib/browser/scm-history-graph-contribution.spec.js +66 -0
- package/lib/browser/scm-history-graph-contribution.spec.js.map +1 -0
- package/lib/browser/scm-history-graph-helpers.d.ts +34 -6
- package/lib/browser/scm-history-graph-helpers.d.ts.map +1 -1
- package/lib/browser/scm-history-graph-helpers.js +71 -5
- package/lib/browser/scm-history-graph-helpers.js.map +1 -1
- package/lib/browser/scm-history-graph-helpers.spec.d.ts +2 -0
- package/lib/browser/scm-history-graph-helpers.spec.d.ts.map +1 -0
- package/lib/browser/scm-history-graph-helpers.spec.js +96 -0
- package/lib/browser/scm-history-graph-helpers.spec.js.map +1 -0
- package/lib/browser/scm-history-graph-lanes.d.ts +19 -5
- package/lib/browser/scm-history-graph-lanes.d.ts.map +1 -1
- package/lib/browser/scm-history-graph-lanes.js +25 -9
- package/lib/browser/scm-history-graph-lanes.js.map +1 -1
- package/lib/browser/scm-history-graph-lanes.spec.js +62 -25
- package/lib/browser/scm-history-graph-lanes.spec.js.map +1 -1
- package/lib/browser/scm-history-graph-model.d.ts +52 -5
- package/lib/browser/scm-history-graph-model.d.ts.map +1 -1
- package/lib/browser/scm-history-graph-model.js +108 -10
- package/lib/browser/scm-history-graph-model.js.map +1 -1
- package/lib/browser/scm-history-graph-model.spec.js +197 -4
- package/lib/browser/scm-history-graph-model.spec.js.map +1 -1
- package/lib/browser/scm-history-graph-tooltip.d.ts +27 -2
- package/lib/browser/scm-history-graph-tooltip.d.ts.map +1 -1
- package/lib/browser/scm-history-graph-tooltip.js +113 -22
- package/lib/browser/scm-history-graph-tooltip.js.map +1 -1
- package/lib/browser/scm-history-graph-tooltip.spec.d.ts +2 -0
- package/lib/browser/scm-history-graph-tooltip.spec.d.ts.map +1 -0
- package/lib/browser/scm-history-graph-tooltip.spec.js +213 -0
- package/lib/browser/scm-history-graph-tooltip.spec.js.map +1 -0
- package/lib/browser/scm-history-graph-widget.d.ts +23 -1
- package/lib/browser/scm-history-graph-widget.d.ts.map +1 -1
- package/lib/browser/scm-history-graph-widget.js +93 -24
- package/lib/browser/scm-history-graph-widget.js.map +1 -1
- package/lib/browser/scm-history-graph-widget.spec.d.ts +2 -0
- package/lib/browser/scm-history-graph-widget.spec.d.ts.map +1 -0
- package/lib/browser/scm-history-graph-widget.spec.js +100 -0
- package/lib/browser/scm-history-graph-widget.spec.js.map +1 -0
- package/lib/browser/scm-provider.d.ts +9 -1
- package/lib/browser/scm-provider.d.ts.map +1 -1
- package/lib/browser/scm-provider.js.map +1 -1
- package/lib/common/scm-preferences.d.ts +3 -0
- package/lib/common/scm-preferences.d.ts.map +1 -1
- package/lib/common/scm-preferences.js +24 -0
- package/lib/common/scm-preferences.js.map +1 -1
- package/package.json +6 -6
- package/src/browser/decorations/scm-navigator-decorator.ts +3 -2
- package/src/browser/scm-context-key-service.spec.ts +9 -0
- package/src/browser/scm-context-key-service.ts +6 -0
- package/src/browser/scm-frontend-module.ts +7 -1
- package/src/browser/scm-history-graph-contribution.spec.ts +83 -0
- package/src/browser/scm-history-graph-contribution.ts +222 -0
- package/src/browser/scm-history-graph-helpers.spec.ts +118 -0
- package/src/browser/scm-history-graph-helpers.ts +81 -6
- package/src/browser/scm-history-graph-lanes.spec.ts +70 -25
- package/src/browser/scm-history-graph-lanes.ts +48 -11
- package/src/browser/scm-history-graph-model.spec.ts +247 -12
- package/src/browser/scm-history-graph-model.ts +125 -12
- package/src/browser/scm-history-graph-tooltip.spec.ts +254 -0
- package/src/browser/scm-history-graph-tooltip.ts +144 -24
- package/src/browser/scm-history-graph-widget.spec.ts +112 -0
- package/src/browser/scm-history-graph-widget.tsx +104 -35
- package/src/browser/scm-provider.ts +9 -1
- package/src/browser/style/scm-history-graph.css +43 -2
- package/src/common/scm-preferences.ts +27 -0
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { Virtuoso } from '@theia/core/shared/react-virtuoso';
|
|
19
|
-
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
|
|
19
|
+
import { injectable, inject, postConstruct, named } from '@theia/core/shared/inversify';
|
|
20
20
|
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
|
21
21
|
import { LabelProvider } from '@theia/core/lib/browser/label-provider';
|
|
22
22
|
import { HoverService } from '@theia/core/lib/browser/hover-service';
|
|
23
|
+
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
23
24
|
import { MarkdownRenderer, MarkdownRendererFactory } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
|
|
24
25
|
import { ScmHistoryGraphModel, HistoryGraphEntry } from './scm-history-graph-model';
|
|
25
26
|
import { ScmHistoryItemRef, ScmHistoryItemChange } from './scm-provider';
|
|
@@ -28,16 +29,21 @@ import { GraphRow } from './scm-history-graph-lanes';
|
|
|
28
29
|
import URI from '@theia/core/lib/common/uri';
|
|
29
30
|
import { nls } from '@theia/core/lib/common/nls';
|
|
30
31
|
import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
|
|
32
|
+
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
33
|
+
import { Emitter, Event } from '@theia/core/lib/common/event';
|
|
34
|
+
import { DynamicToolbarWidget } from '@theia/core/lib/browser/view-container';
|
|
31
35
|
import { MenuPath } from '@theia/core/lib/common/menu/menu-types';
|
|
32
36
|
import { ContextMenuRenderer } from '@theia/core/lib/browser/context-menu-renderer';
|
|
33
37
|
import { OpenerService, open } from '@theia/core/lib/browser/opener-service';
|
|
34
38
|
import { DiffUris } from '@theia/core/lib/browser/diff-uris';
|
|
35
39
|
import { ScmContextKeyService } from './scm-context-key-service';
|
|
40
|
+
import { ScmPreferences } from '../common/scm-preferences';
|
|
36
41
|
import {
|
|
37
|
-
laneColor, getChangeStatus, getFileName, getFilePath, getRepoRelativePath,
|
|
38
|
-
getRefBadgeClass, isTagRef, isRemoteRef, deduplicateRefs, DeduplicatedRef
|
|
42
|
+
laneColor, filterRefsForBadges, getChangeStatus, getFileName, getFilePath, getRepoRelativePath,
|
|
43
|
+
getRefBadgeClass, getRefBadgePresentation, isTagRef, isRemoteRef, deduplicateRefs, DeduplicatedRef
|
|
39
44
|
} from './scm-history-graph-helpers';
|
|
40
|
-
import {
|
|
45
|
+
import { ILogger } from '@theia/core';
|
|
46
|
+
import { buildHtmlTooltip, buildProviderTooltip } from './scm-history-graph-tooltip';
|
|
41
47
|
|
|
42
48
|
/** Menu path matching the VS Code 'scm/history/title' contribution point (graph section toolbar). */
|
|
43
49
|
export const SCM_HISTORY_TITLE_MENU: MenuPath = ['plugin_scm/history/title'];
|
|
@@ -80,19 +86,24 @@ function renderJsxRefBadge(
|
|
|
80
86
|
// ── Widget ──────────────────────────────────────────────────────────────────
|
|
81
87
|
|
|
82
88
|
@injectable()
|
|
83
|
-
export class ScmHistoryGraphWidget extends ReactWidget {
|
|
89
|
+
export class ScmHistoryGraphWidget extends ReactWidget implements DynamicToolbarWidget {
|
|
84
90
|
|
|
85
91
|
static readonly ID = 'scm-history-graph-widget';
|
|
86
92
|
static readonly LABEL = nls.localizeByDefault('Graph');
|
|
87
93
|
|
|
88
94
|
@inject(ScmHistoryGraphModel) protected readonly model: ScmHistoryGraphModel;
|
|
89
95
|
@inject(HoverService) protected readonly hoverService: HoverService;
|
|
96
|
+
@inject(ClipboardService) protected readonly clipboardService: ClipboardService;
|
|
90
97
|
@inject(MarkdownRendererFactory) protected readonly markdownRendererFactory: MarkdownRendererFactory;
|
|
91
98
|
@inject(ScmService) protected readonly scmService: ScmService;
|
|
92
99
|
@inject(LabelProvider) protected readonly labelProvider: LabelProvider;
|
|
93
100
|
@inject(ContextMenuRenderer) protected readonly contextMenuRenderer: ContextMenuRenderer;
|
|
94
101
|
@inject(OpenerService) protected readonly openerService: OpenerService;
|
|
95
102
|
@inject(ScmContextKeyService) protected readonly scmContextKeys: ScmContextKeyService;
|
|
103
|
+
@inject(ScmPreferences) protected readonly scmPreferences: ScmPreferences;
|
|
104
|
+
|
|
105
|
+
@inject(ILogger) @named('scm:ScmHistoryGraphWidget')
|
|
106
|
+
protected readonly logger: ILogger;
|
|
96
107
|
|
|
97
108
|
protected selectedIndex = -1;
|
|
98
109
|
/** Currently selected change row key (`${itemId}-${ci}`), or undefined. */
|
|
@@ -103,6 +114,12 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
103
114
|
protected expandedIds = new Set<string>();
|
|
104
115
|
/** Map from commit id → in-flight CancellationTokenSource for loadChanges. */
|
|
105
116
|
protected loadChangesCts = new Map<string, CancellationTokenSource>();
|
|
117
|
+
/** Cleanup for the content of the hover currently being shown. */
|
|
118
|
+
protected readonly toDisposeOnHover = new DisposableCollection();
|
|
119
|
+
|
|
120
|
+
protected readonly onDidChangeToolbarItemsEmitter = new Emitter<void>();
|
|
121
|
+
/** Re-renders the part toolbar on model changes, e.g. to reflect the toggled state of the ref filter picker. */
|
|
122
|
+
readonly onDidChangeToolbarItems: Event<void> = this.onDidChangeToolbarItemsEmitter.event;
|
|
106
123
|
|
|
107
124
|
constructor() {
|
|
108
125
|
super();
|
|
@@ -116,10 +133,19 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
116
133
|
|
|
117
134
|
@postConstruct()
|
|
118
135
|
protected init(): void {
|
|
136
|
+
this.toDispose.push(this.onDidChangeToolbarItemsEmitter);
|
|
119
137
|
this.toDispose.push(
|
|
120
138
|
this.model.onDidChange(() => {
|
|
121
139
|
this.updateContextKeys();
|
|
122
140
|
this.update();
|
|
141
|
+
this.onDidChangeToolbarItemsEmitter.fire();
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
this.toDispose.push(
|
|
145
|
+
this.scmPreferences.onPreferenceChanged(e => {
|
|
146
|
+
if (e.preferenceName.startsWith('scm.graph.')) {
|
|
147
|
+
this.update();
|
|
148
|
+
}
|
|
123
149
|
})
|
|
124
150
|
);
|
|
125
151
|
this.toDispose.push({
|
|
@@ -131,6 +157,7 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
131
157
|
this.loadChangesCts.clear();
|
|
132
158
|
}
|
|
133
159
|
});
|
|
160
|
+
this.toDispose.push(this.toDisposeOnHover);
|
|
134
161
|
this.update();
|
|
135
162
|
}
|
|
136
163
|
|
|
@@ -138,6 +165,8 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
138
165
|
const provider = this.model.provider;
|
|
139
166
|
this.scmContextKeys.scmCurrentHistoryItemRefHasRemote.set(!!provider?.currentHistoryItemRemoteRef);
|
|
140
167
|
this.scmContextKeys.scmCurrentHistoryItemRefHasBase.set(!!provider?.currentHistoryItemBaseRef);
|
|
168
|
+
// Commands like git.pullRef/git.pushRef gate their enablement on this key.
|
|
169
|
+
this.scmContextKeys.scmCurrentHistoryItemRefInFilter.set(!!provider?.currentHistoryItemRef && this.model.isCurrentRefInFilter());
|
|
141
170
|
}
|
|
142
171
|
|
|
143
172
|
protected render(): React.ReactNode {
|
|
@@ -189,7 +218,7 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
189
218
|
className='scm-history-graph-list'
|
|
190
219
|
data={entries as HistoryGraphEntry[]}
|
|
191
220
|
itemContent={(idx, entry) => this.renderRow(entry, idx, svgWidth)}
|
|
192
|
-
endReached={hasMore && !loading ? this.handleEndReached : undefined}
|
|
221
|
+
endReached={hasMore && !loading && this.scmPreferences['scm.graph.pageOnScroll'] !== false ? this.handleEndReached : undefined}
|
|
193
222
|
overscan={500}
|
|
194
223
|
components={footer ? { Footer: footer } : {}}
|
|
195
224
|
style={{ overflowX: 'hidden' }}
|
|
@@ -208,8 +237,7 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
208
237
|
const isSelected = idx === this.selectedIndex;
|
|
209
238
|
const isExpanded = this.expandedIds.has(item.id);
|
|
210
239
|
const changes = this.expandedChanges.get(item.id);
|
|
211
|
-
|
|
212
|
-
const isHead = idx === 0 && graphRow.lane === 0;
|
|
240
|
+
const isHead = entry.isCurrent;
|
|
213
241
|
|
|
214
242
|
return (
|
|
215
243
|
<React.Fragment key={item.id}>
|
|
@@ -244,14 +272,49 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
244
272
|
}
|
|
245
273
|
|
|
246
274
|
protected handleRowMouseEnter = (e: React.MouseEvent<HTMLDivElement>, entry: HistoryGraphEntry): void => {
|
|
275
|
+
this.toDisposeOnHover.dispose();
|
|
247
276
|
this.hoverService.requestHover({
|
|
248
|
-
content:
|
|
277
|
+
content: this.buildTooltip(entry),
|
|
249
278
|
target: e.currentTarget,
|
|
250
279
|
position: 'right',
|
|
251
280
|
interactive: true,
|
|
252
281
|
});
|
|
253
282
|
};
|
|
254
283
|
|
|
284
|
+
/**
|
|
285
|
+
* Prefers the hover content supplied by the provider, so that its own links and commands
|
|
286
|
+
* (author `mailto:`, "Open Commit", remote actions) stay intact, and falls back to the hover
|
|
287
|
+
* derived from the history item's fields for providers that supply none.
|
|
288
|
+
*/
|
|
289
|
+
protected buildTooltip(entry: HistoryGraphEntry): HTMLElement {
|
|
290
|
+
const { tooltip } = entry.item;
|
|
291
|
+
if (tooltip) {
|
|
292
|
+
const provided = buildProviderTooltip(tooltip, this.markdownRenderer, this.openerService, this.toDisposeOnHover);
|
|
293
|
+
if (provided) {
|
|
294
|
+
return provided;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return buildHtmlTooltip(entry, this.markdownRenderer, this.model.provider, {
|
|
298
|
+
openCommit: () => this.openCommitFromTooltip(entry),
|
|
299
|
+
copyCommitHash: () => this.clipboardService.writeText(entry.item.id),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Selects the commit and expands its changes, closing the hover first. */
|
|
304
|
+
protected openCommitFromTooltip(entry: HistoryGraphEntry): void {
|
|
305
|
+
this.hoverService.cancelHover();
|
|
306
|
+
const idx = this.model.entries.indexOf(entry);
|
|
307
|
+
if (idx < 0) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (this.expandedIds.has(entry.item.id)) {
|
|
311
|
+
this.selectedIndex = idx;
|
|
312
|
+
this.update();
|
|
313
|
+
} else {
|
|
314
|
+
this.handleRowClick(idx, entry);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
255
318
|
protected renderChangesRows(
|
|
256
319
|
itemId: string,
|
|
257
320
|
svgWidth: number,
|
|
@@ -347,7 +410,7 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
347
410
|
open(this.openerService, new URI(change.uri));
|
|
348
411
|
}
|
|
349
412
|
} catch (err) {
|
|
350
|
-
|
|
413
|
+
this.logger.error('Failed to open change', err);
|
|
351
414
|
}
|
|
352
415
|
}
|
|
353
416
|
|
|
@@ -462,7 +525,9 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
462
525
|
|
|
463
526
|
// Commit lane lines — split at cy=11
|
|
464
527
|
// Top segment: only drawn if there is an incoming line from above
|
|
465
|
-
// (i.e. this commit was referenced as a parent by an earlier row)
|
|
528
|
+
// (i.e. this commit was referenced as a parent by an earlier row).
|
|
529
|
+
// It keeps the color inherited from the chain above, which may differ
|
|
530
|
+
// from the commit's own (ref-based) color.
|
|
466
531
|
if (row.hasTopLine) {
|
|
467
532
|
elements.push(
|
|
468
533
|
<path
|
|
@@ -471,7 +536,7 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
471
536
|
strokeWidth='1px'
|
|
472
537
|
strokeLinecap='round'
|
|
473
538
|
d={`M ${commitX} 0 V ${cy}`}
|
|
474
|
-
style={{ stroke:
|
|
539
|
+
style={{ stroke: laneColor(row.topColor) }}
|
|
475
540
|
/>
|
|
476
541
|
);
|
|
477
542
|
}
|
|
@@ -560,11 +625,14 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
560
625
|
return undefined;
|
|
561
626
|
}
|
|
562
627
|
|
|
628
|
+
const provider = this.model.provider;
|
|
629
|
+
const visibleRefs = filterRefsForBadges(refs, provider, this.scmPreferences['scm.graph.badges'] ?? 'filter', this.model.historyItemRefFilter);
|
|
630
|
+
if (visibleRefs.length === 0) {
|
|
631
|
+
return undefined;
|
|
632
|
+
}
|
|
563
633
|
const laneColorValue = entry ? laneColor(entry.graphRow.color) : undefined;
|
|
564
|
-
const deduplicated = deduplicateRefs(
|
|
565
|
-
const
|
|
566
|
-
? { backgroundColor: laneColorValue, color: 'var(--theia-scmGraph-historyItemRefForeground, var(--theia-badge-foreground))' }
|
|
567
|
-
: {};
|
|
634
|
+
const deduplicated = deduplicateRefs(visibleRefs);
|
|
635
|
+
const badgeForeground = 'var(--theia-scmGraph-historyItemRefForeground, var(--theia-badge-foreground))';
|
|
568
636
|
|
|
569
637
|
const badges: React.ReactElement[] = [];
|
|
570
638
|
for (const info of deduplicated) {
|
|
@@ -576,24 +644,25 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
576
644
|
const isRemote = isRemoteRef(ref);
|
|
577
645
|
const onContextMenu = entry ? (e: React.MouseEvent) => this.handleRefBadgeContextMenu(e, entry, ref) : undefined;
|
|
578
646
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
647
|
+
// Current/remote/base refs are colored by role, others by the row's lane color
|
|
648
|
+
const { iconClass, colorIndex } = getRefBadgePresentation(ref, provider);
|
|
649
|
+
const backgroundColor = colorIndex !== undefined ? laneColor(colorIndex) : laneColorValue;
|
|
650
|
+
const style: React.CSSProperties = backgroundColor
|
|
651
|
+
? { backgroundColor, color: badgeForeground }
|
|
652
|
+
: {};
|
|
653
|
+
|
|
654
|
+
badges.push(renderJsxRefBadge(ref, iconClass, !isTag, style, ref.id, onContextMenu));
|
|
655
|
+
if (!isTag && !isRemote && hasBoth && badges.length < 3) {
|
|
656
|
+
badges.push(
|
|
657
|
+
<span
|
|
658
|
+
key={`${ref.id}-cloud`}
|
|
659
|
+
className='scm-history-ref-badge scm-history-ref-badge-cloud'
|
|
660
|
+
title={ref.description ?? ref.name}
|
|
661
|
+
style={style}
|
|
662
|
+
>
|
|
663
|
+
<i className='codicon codicon-cloud scm-history-ref-icon' />
|
|
664
|
+
</span>
|
|
665
|
+
);
|
|
597
666
|
}
|
|
598
667
|
}
|
|
599
668
|
return badges;
|
|
@@ -690,7 +759,7 @@ export class ScmHistoryGraphWidget extends ReactWidget {
|
|
|
690
759
|
}
|
|
691
760
|
} catch (err) {
|
|
692
761
|
if (!cts.token.isCancellationRequested) {
|
|
693
|
-
|
|
762
|
+
this.logger.error('Failed to load changes', err);
|
|
694
763
|
this.expandedChanges.set(item.id, []);
|
|
695
764
|
this.update();
|
|
696
765
|
}
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { Disposable, Event } from '@theia/core/lib/common';
|
|
20
20
|
import URI from '@theia/core/lib/common/uri';
|
|
21
21
|
import { CancellationToken } from '@theia/core/lib/common/cancellation';
|
|
22
|
+
import { MarkdownString } from '@theia/core/lib/common/markdown-rendering/markdown-string';
|
|
22
23
|
|
|
23
24
|
export interface ScmProvider extends Disposable {
|
|
24
25
|
readonly id: string;
|
|
@@ -145,7 +146,14 @@ export interface ScmHistoryItem {
|
|
|
145
146
|
readonly authorIcon?: string;
|
|
146
147
|
readonly displayId?: string;
|
|
147
148
|
readonly timestamp?: number;
|
|
148
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Hover content supplied by the provider. When present, it is rendered instead of the
|
|
151
|
+
* hover the history graph derives from the other fields, so that providers stay in control
|
|
152
|
+
* of their own links and commands. May be split into sections, which are rendered separated
|
|
153
|
+
* by horizontal rules. Note that `command:` links are only executed if the containing
|
|
154
|
+
* {@link MarkdownString} declares them via {@link MarkdownString.isTrusted}.
|
|
155
|
+
*/
|
|
156
|
+
readonly tooltip?: string | MarkdownString | readonly MarkdownString[];
|
|
149
157
|
readonly statistics?: ScmHistoryItemStatistics;
|
|
150
158
|
readonly references?: readonly ScmHistoryItemRef[];
|
|
151
159
|
}
|
|
@@ -286,18 +286,59 @@
|
|
|
286
286
|
opacity: 0.6;
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
+
/* Markdown rendered into the tooltip keeps the browser's default paragraph margins,
|
|
290
|
+
which spaces the commit hover out far more than the git blame hover it mirrors. */
|
|
291
|
+
.scm-history-tooltip p {
|
|
292
|
+
margin: 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.scm-history-tooltip p + p {
|
|
296
|
+
margin-top: 4px;
|
|
297
|
+
}
|
|
298
|
+
|
|
289
299
|
/* ── Tooltip header icon alignment ──────────────────────────────────────── */
|
|
300
|
+
.scm-history-tooltip-header {
|
|
301
|
+
margin-bottom: 4px;
|
|
302
|
+
}
|
|
303
|
+
|
|
290
304
|
.scm-history-tooltip-header .icon-inline {
|
|
291
305
|
vertical-align: middle;
|
|
292
306
|
}
|
|
293
307
|
|
|
308
|
+
.scm-history-tooltip-header a {
|
|
309
|
+
color: var(--theia-textLink-foreground);
|
|
310
|
+
text-decoration: none;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.scm-history-tooltip-header a:hover {
|
|
314
|
+
text-decoration: underline;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.scm-history-tooltip-avatar {
|
|
318
|
+
width: 20px;
|
|
319
|
+
height: 20px;
|
|
320
|
+
border-radius: 50%;
|
|
321
|
+
vertical-align: middle;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* ── Tooltip actions (aligned with the git blame hover command links) ───── */
|
|
325
|
+
.scm-history-tooltip-actions a.scm-history-tooltip-action {
|
|
326
|
+
color: var(--theia-textLink-foreground);
|
|
327
|
+
cursor: pointer;
|
|
328
|
+
text-decoration: none;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.scm-history-tooltip-actions a.scm-history-tooltip-action:hover {
|
|
332
|
+
text-decoration: underline;
|
|
333
|
+
}
|
|
334
|
+
|
|
294
335
|
/* ── Tooltip stat colors (used inside .theia-hover) ─────────────────────── */
|
|
295
336
|
.scm-history-stat-added {
|
|
296
|
-
color: var(--theia-gitDecoration-addedResourceForeground, #388a34);
|
|
337
|
+
color: var(--theia-scmGraph-historyItemHoverAdditionsForeground, var(--theia-gitDecoration-addedResourceForeground, #388a34));
|
|
297
338
|
}
|
|
298
339
|
|
|
299
340
|
.scm-history-stat-deleted {
|
|
300
|
-
color: var(--theia-gitDecoration-deletedResourceForeground, #a1260d);
|
|
341
|
+
color: var(--theia-scmGraph-historyItemHoverDeletionsForeground, var(--theia-gitDecoration-deletedResourceForeground, #a1260d));
|
|
301
342
|
}
|
|
302
343
|
|
|
303
344
|
/* ── Empty state ─────────────────────────────────────────────────────────── */
|
|
@@ -35,12 +35,39 @@ export const scmPreferenceSchema: PreferenceSchema = {
|
|
|
35
35
|
],
|
|
36
36
|
description: nls.localizeByDefault('Controls the default Source Control repository view mode.'),
|
|
37
37
|
default: 'list'
|
|
38
|
+
},
|
|
39
|
+
'scm.graph.badges': {
|
|
40
|
+
type: 'string',
|
|
41
|
+
enum: ['all', 'filter'],
|
|
42
|
+
enumDescriptions: [
|
|
43
|
+
nls.localizeByDefault('Show badges of all history item groups in the Source Control Graph view.'),
|
|
44
|
+
nls.localizeByDefault('Show only the badges of history item groups used as a filter in the Source Control Graph view.')
|
|
45
|
+
],
|
|
46
|
+
description: nls.localizeByDefault(
|
|
47
|
+
// eslint-disable-next-line max-len
|
|
48
|
+
'Controls which badges are shown in the Source Control Graph view. The badges are shown on the right side of the graph indicating the names of history item groups.'),
|
|
49
|
+
default: 'filter'
|
|
50
|
+
},
|
|
51
|
+
'scm.graph.pageOnScroll': {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
description: nls.localizeByDefault('Controls whether the Source Control Graph view will load the next page of items when you scroll to the end of the list.'),
|
|
54
|
+
default: true
|
|
55
|
+
},
|
|
56
|
+
'scm.graph.pageSize': {
|
|
57
|
+
type: 'number',
|
|
58
|
+
minimum: 1,
|
|
59
|
+
maximum: 1000,
|
|
60
|
+
description: nls.localizeByDefault('The number of items to show in the Source Control Graph view by default and when loading more items.'),
|
|
61
|
+
default: 50
|
|
38
62
|
}
|
|
39
63
|
}
|
|
40
64
|
};
|
|
41
65
|
|
|
42
66
|
export interface ScmConfiguration {
|
|
43
67
|
'scm.defaultViewMode': 'tree' | 'list'
|
|
68
|
+
'scm.graph.badges': 'all' | 'filter'
|
|
69
|
+
'scm.graph.pageOnScroll': boolean
|
|
70
|
+
'scm.graph.pageSize': number
|
|
44
71
|
}
|
|
45
72
|
|
|
46
73
|
export const ScmPreferenceContribution = Symbol('ScmPreferenceContribution');
|