mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-18 17:39:47 +01:00
[theme] Provide a way to theme diff highlights. Fixes #19735
This commit is contained in:
@@ -24,6 +24,7 @@ import { IStandaloneThemeService } from 'vs/editor/common/services/standaloneThe
|
||||
import { InternalEditorAction } from 'vs/editor/common/editorAction';
|
||||
import { MenuId, MenuRegistry, IMenuItem } from 'vs/platform/actions/common/actions';
|
||||
import { IDiffEditorOptions, IEditorOptions } from "vs/editor/common/config/editorOptions";
|
||||
import { IThemeService } from "vs/platform/theme/common/themeService";
|
||||
|
||||
/**
|
||||
* The options to create an editor.
|
||||
@@ -282,14 +283,15 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
@IStandaloneThemeService standaloneColorService: IStandaloneThemeService,
|
||||
@IEditorWorkerService editorWorkerService: IEditorWorkerService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@IThemeService themeService: IThemeService
|
||||
) {
|
||||
options = options || {};
|
||||
if (typeof options.theme === 'string') {
|
||||
options.theme = standaloneColorService.setTheme(options.theme);
|
||||
}
|
||||
|
||||
super(domElement, options, editorWorkerService, contextKeyService, instantiationService, codeEditorService);
|
||||
super(domElement, options, editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService);
|
||||
|
||||
if (keybindingService instanceof StandaloneKeybindingService) {
|
||||
this._standaloneKeybindingService = keybindingService;
|
||||
|
||||
@@ -126,7 +126,8 @@ export function createDiffEditor(domElement: HTMLElement, options?: IDiffEditorC
|
||||
services.get(IContextViewService),
|
||||
services.get(IStandaloneThemeService),
|
||||
services.get(IEditorWorkerService),
|
||||
services.get(ICodeEditorService)
|
||||
services.get(ICodeEditorService),
|
||||
services.get(IStandaloneThemeService)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./media/diffEditor';
|
||||
import * as nls from 'vs/nls';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
@@ -32,6 +33,9 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
||||
import { ColorId, MetadataConsts, FontStyle } from 'vs/editor/common/modes';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import * as editorOptions from "vs/editor/common/config/editorOptions";
|
||||
import { registerThemingParticipant, IThemeService, ITheme } from "vs/platform/theme/common/themeService";
|
||||
import { registerColor } from "vs/platform/theme/common/colorRegistry";
|
||||
import { Color, RGBA } from "vs/base/common/color";
|
||||
|
||||
interface IEditorDiffDecorations {
|
||||
decorations: editorCommon.IModelDeltaDecoration[];
|
||||
@@ -60,6 +64,7 @@ interface IEditorsZones {
|
||||
interface IDiffEditorWidgetStyle {
|
||||
getEditorsDiffDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalWhitespaces: editorCommon.IEditorWhitespace[], modifiedWhitespaces: editorCommon.IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorsDiffDecorationsWithZones;
|
||||
setEnableSplitViewResizing(enableSplitViewResizing: boolean): void;
|
||||
applyColors(theme: ITheme): boolean;
|
||||
layout(): number;
|
||||
dispose(): void;
|
||||
}
|
||||
@@ -183,6 +188,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
private _editorWorkerService: IEditorWorkerService;
|
||||
protected _contextKeyService: IContextKeyService;
|
||||
private _codeEditorService: ICodeEditorService;
|
||||
private _themeService: IThemeService;
|
||||
|
||||
constructor(
|
||||
domElement: HTMLElement,
|
||||
@@ -190,7 +196,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
@IEditorWorkerService editorWorkerService: IEditorWorkerService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@IThemeService themeService: IThemeService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -198,6 +205,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._codeEditorService = codeEditorService;
|
||||
this._contextKeyService = contextKeyService.createScoped(domElement);
|
||||
this._contextKeyService.createKey('isInDiffEditor', true);
|
||||
this._themeService = themeService;
|
||||
|
||||
this.id = (++DIFF_EDITOR_ID);
|
||||
|
||||
@@ -295,6 +303,12 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
}
|
||||
|
||||
this._codeEditorService.addDiffEditor(this);
|
||||
|
||||
themeService.onThemeChange(t => {
|
||||
if (this._strategy && this._strategy.applyColors(t)) {
|
||||
this._updateDecorationsRunner.schedule();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public get ignoreTrimWhitespace(): boolean {
|
||||
@@ -521,7 +535,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
// renderSideBySide
|
||||
if (renderSideBySideChanged) {
|
||||
if (this._renderSideBySide) {
|
||||
this._setStrategy(new DiffEdtorWidgetSideBySide(this._createDataSource(), this._enableSplitViewResizing));
|
||||
this._setStrategy(new DiffEdtorWidgetSideBySide(this._createDataSource(), this._enableSplitViewResizing, ));
|
||||
} else {
|
||||
this._setStrategy(new DiffEdtorWidgetInline(this._createDataSource(), this._enableSplitViewResizing));
|
||||
}
|
||||
@@ -979,6 +993,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
}
|
||||
|
||||
this._strategy = newStrategy;
|
||||
newStrategy.applyColors(this._themeService.getTheme());
|
||||
|
||||
if (this._lineChanges) {
|
||||
this._updateDecorations();
|
||||
@@ -1091,12 +1106,23 @@ interface IDataSource {
|
||||
class DiffEditorWidgetStyle extends Disposable {
|
||||
|
||||
_dataSource: IDataSource;
|
||||
_insertColor: Color;
|
||||
_removeColor: Color;
|
||||
|
||||
constructor(dataSource: IDataSource) {
|
||||
super();
|
||||
this._dataSource = dataSource;
|
||||
}
|
||||
|
||||
public applyColors(theme: ITheme): boolean {
|
||||
let newInsertColor = (theme.getColor(diffInserted) || defaultInsertColor).transparent(2);
|
||||
let newRemoveColor = (theme.getColor(diffRemoved) || defaultRemoveColor).transparent(2);
|
||||
let hasChanges = !newInsertColor.equals(this._insertColor) || !newRemoveColor.equals(this._removeColor);
|
||||
this._insertColor = newInsertColor;
|
||||
this._removeColor = newRemoveColor;
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
public getEditorsDiffDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalWhitespaces: editorCommon.IEditorWhitespace[], modifiedWhitespaces: editorCommon.IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorsDiffDecorationsWithZones {
|
||||
// Get view zones
|
||||
modifiedWhitespaces = modifiedWhitespaces.sort((a, b) => {
|
||||
@@ -1495,14 +1521,16 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
result.decorations.push(createDecoration(lineChange.originalStartLineNumber, 1, lineChange.originalEndLineNumber, Number.MAX_VALUE, 'char-delete', true));
|
||||
}
|
||||
|
||||
let color = this._removeColor.toString();
|
||||
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
'rgba(255, 0, 0, 0.4)',
|
||||
'rgba(255, 0, 0, 0.4)',
|
||||
'rgba(255, 0, 0, 0.4)'
|
||||
color,
|
||||
color,
|
||||
color
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1563,14 +1591,15 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
if (!isChangeOrDelete(lineChange) || !lineChange.charChanges) {
|
||||
result.decorations.push(createDecoration(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedEndLineNumber, Number.MAX_VALUE, 'char-insert', true));
|
||||
}
|
||||
let color = this._insertColor.toString();
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
'rgba(155, 185, 85, 0.4)',
|
||||
'rgba(155, 185, 85, 0.4)',
|
||||
'rgba(155, 185, 85, 0.4)'
|
||||
color,
|
||||
color,
|
||||
color
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1683,14 +1712,15 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}
|
||||
});
|
||||
|
||||
let color = this._removeColor.toString();
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
'rgba(255, 0, 0, 0.4)',
|
||||
'rgba(255, 0, 0, 0.4)',
|
||||
'rgba(255, 0, 0, 0.4)'
|
||||
color,
|
||||
color,
|
||||
color
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1722,14 +1752,15 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}
|
||||
});
|
||||
|
||||
let color = this._insertColor.toString();
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
'rgba(155, 185, 85, 0.4)',
|
||||
'rgba(155, 185, 85, 0.4)',
|
||||
'rgba(155, 185, 85, 0.4)'
|
||||
color,
|
||||
color,
|
||||
color
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1915,3 +1946,33 @@ function createFakeLinesDiv(): HTMLElement {
|
||||
r.className = 'diagonal-fill';
|
||||
return r;
|
||||
}
|
||||
|
||||
const defaultInsertColor = Color.fromRGBA(new RGBA(155, 185, 85, 255 * 0.2));
|
||||
const defaultRemoveColor = Color.fromRGBA(new RGBA(255, 0, 0, 255 * 0.2));
|
||||
|
||||
export const diffInserted = registerColor('diffInserted', { dark: defaultInsertColor, light: defaultInsertColor, hc: null }, nls.localize('diffInserted', 'Background color for text that got inserted.'));
|
||||
export const diffRemoved = registerColor('diffRemoved', { dark: defaultRemoveColor, light: defaultRemoveColor, hc: null }, nls.localize('diffRemoved', 'Background color for text that got removed.'));
|
||||
export const diffInsertedOutline = registerColor('diffInsertedOutline', { dark: null, light: null, hc: '#33ff2eff' }, nls.localize('diffInsertedOutline', 'Outline color for the text that got inserted.'));
|
||||
export const diffRemovedOutline = registerColor('diffRemovedOutline', { dark: null, light: null, hc: '#FF008F' }, nls.localize('diffRemovedOutline', 'Outline color for text that got removed.'));
|
||||
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let added = theme.getColor(diffInserted);
|
||||
if (added) {
|
||||
collector.addRule(`.monaco-editor .line-insert, .monaco-editor .char-insert { background-color: ${added}; }`);
|
||||
collector.addRule(`.monaco-editor .inline-added-margin-view-zone { background-color: ${added}; }`);
|
||||
}
|
||||
let removed = theme.getColor(diffRemoved);
|
||||
if (removed) {
|
||||
collector.addRule(`.monaco-editor .line-delete, .monaco-editor .char-delete { background-color: ${removed}; }`);
|
||||
collector.addRule(`.monaco-editor .inline-deleted-margin-view-zone { background-color: ${removed}; }`);
|
||||
}
|
||||
let addedOutline = theme.getColor(diffInsertedOutline);
|
||||
if (addedOutline) {
|
||||
collector.addRule(`.monaco-editor .line-insert, .monaco-editor .char-insert { border: 1px dashed ${addedOutline}; }`);
|
||||
}
|
||||
let removedOutline = theme.getColor(diffRemovedOutline);
|
||||
if (removedOutline) {
|
||||
collector.addRule(`.monaco-editor .line-delete, .monaco-editor .char-delete { border: 1px dashed ${removedOutline}; }`);
|
||||
}
|
||||
});
|
||||
@@ -7,18 +7,20 @@
|
||||
.monaco-diff-editor .diffOverview {
|
||||
z-index: 9;
|
||||
}
|
||||
.monaco-diff-editor.vs .diffOverview { background: #f9f7f7; }
|
||||
.monaco-diff-editor.vs-dark .diffOverview { background: #1E1E1E; }
|
||||
.monaco-diff-editor.hc-black .diffOverview { background: #000; }
|
||||
|
||||
/* colors not externalized: using transparancy on background */
|
||||
.monaco-diff-editor.vs .diffOverview { background: rgba(0, 0, 0, 0.03); }
|
||||
.monaco-diff-editor.vs-dark .diffOverview { background: rgba(255, 255, 255, 0.01); }
|
||||
|
||||
.monaco-diff-editor .diffViewport {
|
||||
box-shadow: inset 0px 0px 1px 0px #B9B9B9;
|
||||
background: rgba(148, 148, 148, 0.19);
|
||||
}
|
||||
.monaco-diff-editor.vs-dark {
|
||||
background: #1E1E1E;
|
||||
background: rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
.monaco-diff-editor.vs-dark .diffViewport,
|
||||
.monaco-diff-editor.hc-black .diffViewport {
|
||||
background: rgba(255, 255, 255, 0.10);
|
||||
}
|
||||
.monaco-scrollable-element.modified-in-monaco-diff-editor.vs .scrollbar { background: rgba(0,0,0,0); }
|
||||
.monaco-scrollable-element.modified-in-monaco-diff-editor.vs-dark .scrollbar { background: rgba(0,0,0,0); }
|
||||
.monaco-scrollable-element.modified-in-monaco-diff-editor.hc-black .scrollbar { background: none; }
|
||||
@@ -34,22 +36,6 @@
|
||||
|
||||
/* ---------- Diff ---------- */
|
||||
|
||||
.monaco-editor .line-delete,
|
||||
.monaco-editor .char-delete {
|
||||
background: rgba(255, 0, 0, 0.2);
|
||||
}
|
||||
.monaco-editor.hc-black .line-delete,
|
||||
.monaco-editor.hc-black .char-delete {
|
||||
background: none;
|
||||
border: 1px dashed #FF008F;
|
||||
}
|
||||
|
||||
|
||||
.monaco-editor .line-insert,
|
||||
.monaco-editor .char-insert {
|
||||
background: rgba(155, 185, 85, 0.2);
|
||||
}
|
||||
|
||||
.monaco-editor .insert-sign, .monaco-editor .delete-sign {
|
||||
background-size: 60%;
|
||||
opacity: 0.7;
|
||||
@@ -66,22 +52,12 @@
|
||||
.monaco-editor.vs-dark .delete-sign, .monaco-editor.hc-black .delete-sign { background-image: url('deletion-inverse.svg'); }
|
||||
|
||||
.monaco-editor .inline-deleted-margin-view-zone {
|
||||
background: rgba(255, 0, 0, 0.2);
|
||||
text-align: right;
|
||||
}
|
||||
.monaco-editor .inline-added-margin-view-zone {
|
||||
background: rgba(155, 185, 85, 0.2);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
.monaco-editor.hc-black .line-insert,
|
||||
.monaco-editor.hc-black .char-insert {
|
||||
background: none;
|
||||
border: 1px dashed rgb(51, 255, 46);
|
||||
}
|
||||
|
||||
|
||||
.monaco-editor .diagonal-fill {
|
||||
background: url('diagonal-fill.png');
|
||||
}
|
||||
@@ -97,8 +73,3 @@
|
||||
.monaco-editor .view-zones .view-lines .view-line span {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* High Contrast Theming */
|
||||
.monaco-diff-editor.hc-black {
|
||||
background: #000;
|
||||
}
|
||||
Reference in New Issue
Block a user