diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 7e32a089e8c..1c63a4712d3 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -43,7 +43,8 @@ import { VariablesView } from 'vs/workbench/contrib/debug/browser/variablesView' import { ClearReplAction, Repl } from 'vs/workbench/contrib/debug/browser/repl'; import { DebugContentProvider } from 'vs/workbench/contrib/debug/common/debugContentProvider'; import { WelcomeView } from 'vs/workbench/contrib/debug/browser/welcomeView'; -import { ThemeIcon } from 'vs/platform/theme/common/themeService'; +import { ThemeIcon, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { registerColor, foreground, badgeBackground, badgeForeground, listDeemphasizedForeground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { DebugViewPaneContainer, OpenDebugConsoleAction } from 'vs/workbench/contrib/debug/browser/debugViewlet'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { CallStackEditorContribution } from 'vs/workbench/contrib/debug/browser/callStackEditorContribution'; @@ -586,3 +587,124 @@ if (isMacintosh) { registerTouchBarEntry(RESTART_SESSION_ID, RESTART_LABEL, 5, CONTEXT_IN_DEBUG_MODE, URI.parse(require.toUrl('vs/workbench/contrib/debug/browser/media/restart-tb.png'))); registerTouchBarEntry(STOP_ID, STOP_LABEL, 6, CONTEXT_IN_DEBUG_MODE, URI.parse(require.toUrl('vs/workbench/contrib/debug/browser/media/stop-tb.png'))); } + +// Color contributions + +const debugTokenExpressionName = registerColor('debugTokenExpression.name', { dark: '#c586c0', light: '#9b46b0', hc: foreground }, 'Foreground color for the token names shown in the debug views (ie. the Variables or Watch view).'); +const debugTokenExpressionValue = registerColor('debugTokenExpression.value', { dark: '#cccccc99', light: '#6c6c6ccc', hc: foreground }, 'Foreground color for the token values shown in the debug views (ie. the Variables or Watch view).'); +const debugTokenExpressionString = registerColor('debugTokenExpression.string', { dark: '#ce9178', light: '#a31515', hc: '#f48771' }, 'Foreground color for strings in the debug views (ie. the Variables or Watch view).'); +const debugTokenExpressionBoolean = registerColor('debugTokenExpression.boolean', { dark: '#4e94ce', light: '#0000ff', hc: '#75bdfe' }, 'Foreground color for booleans in the debug views (ie. the Variables or Watch view).'); +const debugTokenExpressionNumber = registerColor('debugTokenExpression.number', { dark: '#b5cea8', light: '#098658', hc: '#89d185' }, 'Foreground color for numbers in the debug views (ie. the Variables or Watch view).'); +const debugTokenExpressionError = registerColor('debugTokenExpression.error', { dark: '#f48771', light: '#e51400', hc: '#f48771' }, 'Foreground color for expression errors in the debug views (ie. the Variables or Watch view) and for error logs shown in the debug console.'); + +const debugViewExceptionLabelForeground = registerColor('debugView.exceptionLabelForeground', { dark: foreground, light: foreground, hc: foreground }, 'Foreground color for a label shown in the CALL STACK view when the debugger breaks on an exception.'); +const debugViewExceptionLabelBackground = registerColor('debugView.exceptionLabelBackground', { dark: '#6C2022', light: '#A31515', hc: '#6C2022' }, 'Background color for a label shown in the CALL STACK view when the debugger breaks on an exception.'); +const debugViewStateLabelForeground = registerColor('debugView.stateLabelForeground', { dark: foreground, light: foreground, hc: foreground }, 'Foreground color for a label in the CALL STACK view showing the current session\'s or thread\'s state.'); +const debugViewStateLabelBackground = registerColor('debugView.stateLabelBackground', { dark: '#88888844', light: '#88888844', hc: '#88888844' }, 'Background color for a label in the CALL STACK view showing the current session\'s or thread\'s state.'); +const debugViewValueChangedHighlight = registerColor('debugView.valueChangedHighlight', { dark: '#569CD6', light: '#569CD6', hc: '#569CD6' }, 'Color used to highlight value changes in the debug views (ie. in the Variables view).'); + +registerThemingParticipant((theme, collector) => { + // All these colours provide a default value so they will never be undefined, hence the `!` + const badgeBackgroundColor = theme.getColor(badgeBackground)!; + const badgeForegroundColor = theme.getColor(badgeForeground)!; + const listDeemphasizedForegroundColor = theme.getColor(listDeemphasizedForeground)!; + const debugViewExceptionLabelForegroundColor = theme.getColor(debugViewExceptionLabelForeground)!; + const debugViewExceptionLabelBackgroundColor = theme.getColor(debugViewExceptionLabelBackground)!; + const debugViewStateLabelForegroundColor = theme.getColor(debugViewStateLabelForeground)!; + const debugViewStateLabelBackgroundColor = theme.getColor(debugViewStateLabelBackground)!; + const debugViewValueChangedHighlightColor = theme.getColor(debugViewValueChangedHighlight)!; + + collector.addRule(` + /* Text colour of the call stack row's filename */ + .debug-pane .debug-call-stack .monaco-list-row:not(.selected) .stack-frame > .file .file-name { + color: ${listDeemphasizedForegroundColor} + } + + /* Line & column number "badge" for selected call stack row */ + .debug-pane .monaco-list-row.selected .line-number { + background-color: ${badgeBackgroundColor}; + color: ${badgeForegroundColor}; + } + + /* Line & column number "badge" for unselected call stack row (basically all other rows) */ + .debug-pane .line-number { + background-color: ${badgeBackgroundColor.transparent(0.6)}; + color: ${badgeForegroundColor.transparent(0.6)}; + } + + /* State "badge" displaying the active session's current state. + * Only visible when there are more active debug sessions/threads running. + */ + .debug-pane .debug-call-stack .thread > .state > .label, + .debug-pane .debug-call-stack .session > .state > .label, + .debug-pane .monaco-list-row.selected .thread > .state > .label, + .debug-pane .monaco-list-row.selected .session > .state > .label { + background-color: ${debugViewStateLabelBackgroundColor}; + color: ${debugViewStateLabelForegroundColor}; + } + + /* Info "badge" shown when the debugger pauses due to a thrown exception. */ + .debug-pane .debug-call-stack-title > .pause-message > .label.exception { + background-color: ${debugViewExceptionLabelBackgroundColor}; + color: ${debugViewExceptionLabelForegroundColor}; + } + + /* Animation of changed values in Debug viewlet */ + @keyframes debugViewletValueChanged { + 0% { background-color: ${debugViewValueChangedHighlightColor.transparent(0)} } + 5% { background-color: ${debugViewValueChangedHighlightColor.transparent(0.9)} } + 100% { background-color: ${debugViewValueChangedHighlightColor.transparent(0.3)} } + } + + .debug-pane .monaco-list-row .expression .value.changed { + background-color: ${debugViewValueChangedHighlightColor.transparent(0.3)}; + animation-name: debugViewletValueChanged; + animation-duration: 1s; + animation-fill-mode: forwards; + } + `); + + const contrastBorderColor = theme.getColor(contrastBorder); + + if (contrastBorderColor) { + collector.addRule(` + .debug-pane .line-number { + border: 1px solid ${contrastBorderColor}; + } + `); + } + + const tokenNameColor = theme.getColor(debugTokenExpressionName)!; + const tokenValueColor = theme.getColor(debugTokenExpressionValue)!; + const tokenStringColor = theme.getColor(debugTokenExpressionString)!; + const tokenBooleanColor = theme.getColor(debugTokenExpressionBoolean)!; + const tokenErrorColor = theme.getColor(debugTokenExpressionError)!; + const tokenNumberColor = theme.getColor(debugTokenExpressionNumber)!; + + collector.addRule(` + .monaco-workbench .monaco-list-row .expression .name { + color: ${tokenNameColor}; + } + + .monaco-workbench .monaco-list-row .expression .value { + color: ${tokenValueColor}; + } + + .monaco-workbench .monaco-list-row .expression .value.string { + color: ${tokenStringColor}; + } + + .monaco-workbench .monaco-list-row .expression .value.boolean { + color: ${tokenBooleanColor}; + } + + .monaco-workbench .monaco-list-row .expression .error, + .monaco-workbench .debug-pane .debug-variables .scope .error { + color: ${tokenErrorColor}; + } + + .monaco-workbench .monaco-list-row .expression .value.number { + color: ${tokenNumberColor}; + } + `); +}); diff --git a/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css b/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css index fc93ad15e0b..249207bf523 100644 --- a/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css +++ b/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css @@ -109,85 +109,10 @@ color: inherit; } -.monaco-workbench .monaco-list-row .expression .name { - color: #9b46b0; -} - .monaco-workbench .monaco-list-row .expression .name.virtual { opacity: 0.5; } -.monaco-workbench > .monaco-list-row .expression .value { - color: rgba(108, 108, 108, 0.8); -} - .monaco-workbench .monaco-list-row .expression .unavailable { font-style: italic; } - -.monaco-workbench .monaco-list-row .expression .error, -.monaco-workbench .debug-pane .debug-variables .scope .error { - color: #e51400; -} - -.monaco-workbench .monaco-list-row .expression .value.number { - color: #098658; -} - -.monaco-workbench .monaco-list-row .expression .value.boolean { - color: #0000ff; -} - -.monaco-workbench .monaco-list-row .expression .value.string { - color: #a31515; -} - -.vs-dark .monaco-workbench > .monaco-list-row .expression .value { - color: rgba(204, 204, 204, 0.6); -} - -.vs-dark .monaco-workbench .monaco-list-row .expression .error, -.vs-dark .monaco-workbench .debug-pane .debug-variables .scope .error { - color: #f48771; -} - -.vs-dark .monaco-workbench .monaco-list-row .expression .value.number { - color: #b5cea8; -} - -.hc-black .monaco-workbench .monaco-list-row .expression .value.number { - color: #89d185; -} - -.hc-black .monaco-workbench .monaco-list-row .expression .value.boolean { - color: #75bdfe; -} - -.hc-black .monaco-workbench .monaco-list-row .expression .value.string { - color: #f48771; -} - -.vs-dark .monaco-workbench .monaco-list-row .expression .value.boolean { - color: #4e94ce; -} - -.vs-dark .monaco-workbench .monaco-list-row .expression .value.string { - color: #ce9178; -} - -.hc-black .monaco-workbench .monaco-list-row .expression .error, -.hc-black .monaco-workbench .debug-pane .debug-variables .scope .error { - color: #f48771; -} - -/* Dark theme */ - -.vs-dark .monaco-workbench .monaco-list-row .expression .name { - color: #c586c0; -} - -/* High Contrast Theming */ - -.hc-black .monaco-workbench .monaco-list-row .expression .name { - color: inherit; -} diff --git a/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css b/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css index 3c06a3fdf1f..0956020cb34 100644 --- a/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css +++ b/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css @@ -63,24 +63,12 @@ /* Debug viewlet trees */ .debug-pane .line-number { - background: rgba(136, 136, 136, 0.3); border-radius: 2px; font-size: 0.9em; padding: 0 3px; line-height: 20px; } -.debug-pane .monaco-list-row.selected .line-number, -.debug-pane .monaco-list-row.selected .thread > .state > .label, -.debug-pane .monaco-list-row.selected .session > .state > .label { - background-color: #ffffff; - color: #666; -} - -.debug-pane .monaco-list:focus .monaco-list-row.selected.focused .codicon { - color: inherit !important; -} - .debug-pane .disabled { opacity: 0.65; cursor: initial; @@ -108,21 +96,6 @@ font-size: 9px; } -.debug-pane .debug-call-stack-title > .pause-message > .label.exception { - background-color: #A31515; - color: rgb(255, 255, 255); -} - -.vs-dark .debug-pane .debug-call-stack-title > .pause-message > .label.exception { - background-color: #6C2022; - color: inherit; -} - -.hc-black .debug-pane .debug-call-stack-title > .pause-message > .label.exception { - background-color: #6C2022; - color: inherit; -} - .debug-pane .debug-call-stack .thread, .debug-pane .debug-call-stack .session { display: flex; @@ -176,7 +149,6 @@ .debug-pane .debug-call-stack .thread > .state > .label, .debug-pane .debug-call-stack .session > .state > .label { - background: rgba(136, 136, 136, 0.3); border-radius: 2px; font-size: 0.8em; padding: 0 3px; @@ -220,20 +192,12 @@ display: none; } -.debug-pane .debug-call-stack .monaco-list-row:not(.selected) .stack-frame > .file { - color: rgba(108, 108, 108, 0.8); -} - .debug-pane .debug-call-stack .stack-frame > .file > .file-name { overflow: hidden; text-overflow: ellipsis; margin-right: 0.8em; } -.vs-dark .debug-pane .debug-call-stack .monaco-list-row:not(.selected) .stack-frame > .file { - color: rgba(204, 204, 204, 0.6); -} - .debug-pane .debug-call-stack .stack-frame > .file:not(:first-child) { margin-left: 0.8em; } @@ -253,10 +217,6 @@ overflow: hidden; } -.debug-pane .debug-call-stack .monaco-list:focus .monaco-list-row.selected .codicon { - color: inherit !important; -} - /* Variables & Expression view */ .debug-pane .scope { @@ -264,27 +224,10 @@ font-size: 11px; } -/* Animation of changed values in Debug viewlet */ -@keyframes debugViewletValueChanged { - 0% { background-color: rgba(86, 156, 214, 0) } - 5% { background-color: rgba(86, 156, 214, .75) } - 100% { background-color: rgba(86, 156, 214, .3) } -} - -@keyframes debugViewletValueChangedDark { - 0% { background-color: rgba(86, 156, 214, 0) } - 5% { background-color: rgba(86, 156, 214, .5) } - 100% { background-color: rgba(86, 156, 214, .2) } -} - .debug-pane .monaco-list-row .expression .value.changed { padding: 2px; margin: 4px; border-radius: 4px; - background-color: rgba(86, 156, 214, .5); - animation-name: debugViewletValueChanged; - animation-duration: .75s; - animation-fill-mode: forwards; } .debug-pane .monaco-inputbox { @@ -318,10 +261,6 @@ flex : 1; } -.vs-dark .debug-pane .monaco-list-row .expression .value.changed { - animation-name: debugViewletValueChanged; -} - .debug-pane .debug-variables .scope .error { font-style: italic; text-overflow: ellipsis; diff --git a/src/vs/workbench/contrib/debug/browser/media/repl.css b/src/vs/workbench/contrib/debug/browser/media/repl.css index cdd67e12807..f4ece53d9f0 100644 --- a/src/vs/workbench/contrib/debug/browser/media/repl.css +++ b/src/vs/workbench/contrib/debug/browser/media/repl.css @@ -81,7 +81,6 @@ .repl .repl-input-wrapper { display: flex; align-items: center; - border-top: 1px solid rgba(128, 128, 128, 0.35); } /* Only show 'stale expansion' info when the element gets expanded. */ @@ -89,10 +88,6 @@ content: ''; } -.hc-black .repl .repl-input-wrapper { - border-top-color: #6FC3DF; -} - .repl .repl-input-wrapper .repl-input-chevron { padding: 0 6px 0 8px; width: 16px; @@ -108,18 +103,6 @@ font-style: italic; } -.vs .repl .repl-tree .output.expression > .warn { - color: #cd9731; -} - -.vs-dark .repl .repl-tree .output.expression > .warn { - color: #cd9731; -} - -.hc-black .repl .repl-tree .output.expression > .warn { - color: #008000; -} - .vs .repl .repl-tree .output.expression > .annotation { color: #007ACC; } @@ -132,6 +115,18 @@ color: #0000FF; } +.vs .repl .repl-tree .output.expression > .warn { + color: #cd9731; +} + +.vs-dark .repl .repl-tree .output.expression > .warn { + color: #cd9731; +} + +.hc-black .repl .repl-tree .output.expression > .warn { + color: #008000; +} + /* ANSI Codes */ .monaco-workbench .repl .repl-tree .output.expression .code-bold { font-weight: bold; } .monaco-workbench .repl .repl-tree .output.expression .code-italic { font-style: italic; } diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 584cfebe839..532114c9265 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -5,6 +5,7 @@ import 'vs/css!./media/repl'; import { URI as uri } from 'vs/base/common/uri'; +import { Color } from 'vs/base/common/color'; import { IAction, IActionViewItem, Action } from 'vs/base/common/actions'; import * as dom from 'vs/base/browser/dom'; import * as aria from 'vs/base/browser/ui/aria/aria'; @@ -20,7 +21,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { memoize } from 'vs/base/common/decorators'; import { dispose, IDisposable, Disposable } from 'vs/base/common/lifecycle'; @@ -33,7 +34,7 @@ import { createAndBindHistoryNavigationWidgetScopedContextKeyService } from 'vs/ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; import { IDecorationOptions } from 'vs/editor/common/editorCommon'; -import { transparent, editorForeground } from 'vs/platform/theme/common/colorRegistry'; +import { transparent, editorForeground, inputBorder } from 'vs/platform/theme/common/colorRegistry'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/debugActionViewItems'; import { CompletionContext, CompletionList, CompletionProviderRegistry, CompletionItem, completionKindFromString, CompletionItemKind, CompletionItemInsertTextRule } from 'vs/editor/common/modes'; @@ -811,3 +812,13 @@ export class ClearReplAction extends Action { function getReplView(viewsService: IViewsService): Repl | undefined { return viewsService.getActiveViewWithId(REPL_VIEW_ID) as Repl ?? undefined; } + +registerThemingParticipant((theme, collector) => { + const inputBorderColor = theme.getColor(inputBorder) || Color.fromHex('#80808060'); + + collector.addRule(` + .repl .repl-input-wrapper { + border-top: 1px solid ${inputBorderColor}; + } + `); +});