mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 12:08:36 -05:00
Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)
* Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d * Fix vs unit tests and hygiene issue * Fix strict null check issue
This commit is contained in:
@@ -221,4 +221,4 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer<IExpr
|
||||
disposeTemplate(templateData: IExpressionTemplateData): void {
|
||||
dispose(templateData.toDispose);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { ICodeEditor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/zoneWidget';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IDebugService, IBreakpoint, BreakpointWidgetContext as Context, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, DEBUG_SCHEME, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, CONTEXT_IN_BREAKPOINT_WIDGET } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugService, IBreakpoint, BreakpointWidgetContext as Context, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, DEBUG_SCHEME, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, CONTEXT_IN_BREAKPOINT_WIDGET, IBreakpointUpdateData } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -184,13 +184,13 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi
|
||||
}
|
||||
|
||||
if (this.breakpoint) {
|
||||
this.debugService.updateBreakpoints(this.breakpoint.uri, {
|
||||
[this.breakpoint.getId()]: {
|
||||
condition,
|
||||
hitCondition,
|
||||
logMessage
|
||||
}
|
||||
}, false);
|
||||
const data = new Map<string, IBreakpointUpdateData>();
|
||||
data.set(this.breakpoint.getId(), {
|
||||
condition,
|
||||
hitCondition,
|
||||
logMessage
|
||||
});
|
||||
this.debugService.updateBreakpoints(this.breakpoint.uri, data, false);
|
||||
} else {
|
||||
const model = this.editor.getModel();
|
||||
if (model) {
|
||||
|
||||
@@ -61,7 +61,7 @@ export class BreakpointsView extends ViewletPanel {
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService);
|
||||
|
||||
this.minimumBodySize = this.maximumBodySize = this.getExpandedBodySize();
|
||||
this.disposables.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));
|
||||
this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));
|
||||
}
|
||||
|
||||
public renderBody(container: HTMLElement): void {
|
||||
@@ -81,9 +81,9 @@ export class BreakpointsView extends ViewletPanel {
|
||||
|
||||
CONTEXT_BREAKPOINTS_FOCUSED.bindTo(this.list.contextKeyService);
|
||||
|
||||
this.list.onContextMenu(this.onListContextMenu, this, this.disposables);
|
||||
this._register(this.list.onContextMenu(this.onListContextMenu, this));
|
||||
|
||||
this.disposables.push(this.list.onDidOpen(e => {
|
||||
this._register(this.list.onDidOpen(e => {
|
||||
let isSingleClick = false;
|
||||
let isDoubleClick = false;
|
||||
let isMiddleClick = false;
|
||||
@@ -120,7 +120,7 @@ export class BreakpointsView extends ViewletPanel {
|
||||
|
||||
this.list.splice(0, this.list.length, this.elements);
|
||||
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(visible => {
|
||||
this._register(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && this.needsRefresh) {
|
||||
this.onBreakpointsChange();
|
||||
}
|
||||
@@ -557,7 +557,6 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea
|
||||
options: {
|
||||
preserveFocus,
|
||||
selection,
|
||||
revealIfVisible: true,
|
||||
revealIfOpened: true,
|
||||
revealInCenterIfOutsideViewport: true,
|
||||
pinned: !preserveFocus
|
||||
|
||||
@@ -63,7 +63,7 @@ export class CallStackView extends ViewletPanel {
|
||||
this.callStackItemType = CONTEXT_CALLSTACK_ITEM_TYPE.bindTo(contextKeyService);
|
||||
|
||||
this.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService);
|
||||
this.disposables.push(this.contributedContextMenu);
|
||||
this._register(this.contributedContextMenu);
|
||||
|
||||
// Create scheduler to prevent unnecessary flashing of tree when reacting to changes
|
||||
this.onCallStackChangeScheduler = new RunOnceScheduler(() => {
|
||||
@@ -149,8 +149,8 @@ export class CallStackView extends ViewletPanel {
|
||||
this.tree.setInput(this.debugService.getModel()).then(undefined, onUnexpectedError);
|
||||
|
||||
const callstackNavigator = new TreeResourceNavigator2(this.tree);
|
||||
this.disposables.push(callstackNavigator);
|
||||
this.disposables.push(callstackNavigator.onDidOpenResource(e => {
|
||||
this._register(callstackNavigator);
|
||||
this._register(callstackNavigator.onDidOpenResource(e => {
|
||||
if (this.ignoreSelectionChangedEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -189,7 +189,7 @@ export class CallStackView extends ViewletPanel {
|
||||
}
|
||||
}));
|
||||
|
||||
this.disposables.push(this.debugService.getModel().onDidChangeCallStack(() => {
|
||||
this._register(this.debugService.getModel().onDidChangeCallStack(() => {
|
||||
if (!this.isBodyVisible()) {
|
||||
this.needsRefresh = true;
|
||||
return;
|
||||
@@ -200,7 +200,7 @@ export class CallStackView extends ViewletPanel {
|
||||
}
|
||||
}));
|
||||
const onCallStackChange = Event.any<any>(this.debugService.getViewModel().onDidFocusStackFrame, this.debugService.getViewModel().onDidFocusSession);
|
||||
this.disposables.push(onCallStackChange(() => {
|
||||
this._register(onCallStackChange(() => {
|
||||
if (this.ignoreFocusStackFrameEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -211,20 +211,20 @@ export class CallStackView extends ViewletPanel {
|
||||
|
||||
this.updateTreeSelection();
|
||||
}));
|
||||
this.disposables.push(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
|
||||
// Schedule the update of the call stack tree if the viewlet is opened after a session started #14684
|
||||
if (this.debugService.state === State.Stopped) {
|
||||
this.onCallStackChangeScheduler.schedule(0);
|
||||
}
|
||||
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(visible => {
|
||||
this._register(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && this.needsRefresh) {
|
||||
this.onCallStackChangeScheduler.schedule();
|
||||
}
|
||||
}));
|
||||
|
||||
this.disposables.push(this.debugService.onDidNewSession(s => {
|
||||
this._register(this.debugService.onDidNewSession(s => {
|
||||
if (s.parentSession) {
|
||||
// Auto expand sessions that have sub sessions
|
||||
this.parentSessionToExpand.add(s.parentSession);
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { RGBA, Color } from 'vs/base/common/color';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ansiColorIdentifiers } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||
|
||||
/**
|
||||
* @param text The content to stylize.
|
||||
* @returns An {@link HTMLSpanElement} that contains the potentially stylized text.
|
||||
*/
|
||||
export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTMLSpanElement {
|
||||
export function handleANSIOutput(text: string, linkDetector: LinkDetector, themeService: IThemeService): HTMLSpanElement {
|
||||
|
||||
const root: HTMLSpanElement = document.createElement('span');
|
||||
const textLength: number = text.length;
|
||||
@@ -105,23 +107,20 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML
|
||||
/**
|
||||
* Change the foreground or background color by clearing the current color
|
||||
* and adding the new one.
|
||||
* @param newClass If string or number, new class will be
|
||||
* `code-(foreground or background)-newClass`. If `undefined`, no new class
|
||||
* will be added.
|
||||
* @param colorType If `'foreground'`, will change the foreground color, if
|
||||
* `'background'`, will change the background color.
|
||||
* @param customColor If provided, this custom color will be used instead of
|
||||
* a class-defined color.
|
||||
* @param color Color to change to. If `undefined` or not provided,
|
||||
* will clear current color without adding a new one.
|
||||
*/
|
||||
function changeColor(newClass: string | number | undefined, colorType: 'foreground' | 'background', customColor?: RGBA): void {
|
||||
styleNames = styleNames.filter(style => !style.match(new RegExp(`^code-${colorType}-(\\d+|custom)$`)));
|
||||
if (newClass) {
|
||||
styleNames.push(`code-${colorType}-${newClass}`);
|
||||
}
|
||||
function changeColor(colorType: 'foreground' | 'background', color?: RGBA | undefined): void {
|
||||
if (colorType === 'foreground') {
|
||||
customFgColor = customColor;
|
||||
} else {
|
||||
customBgColor = customColor;
|
||||
customFgColor = color;
|
||||
} else if (colorType === 'background') {
|
||||
customBgColor = color;
|
||||
}
|
||||
styleNames = styleNames.filter(style => style !== `code-${colorType}-colored`);
|
||||
if (color !== undefined) {
|
||||
styleNames.push(`code-${colorType}-colored`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,22 +136,37 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML
|
||||
*/
|
||||
function setBasicFormatters(styleCodes: number[]): void {
|
||||
for (let code of styleCodes) {
|
||||
if (code === 0) {
|
||||
styleNames = [];
|
||||
} else if (code === 1) {
|
||||
styleNames.push('code-bold');
|
||||
} else if (code === 3) {
|
||||
styleNames.push('code-italic');
|
||||
} else if (code === 4) {
|
||||
styleNames.push('code-underline');
|
||||
} else if ((code >= 30 && code <= 37) || (code >= 90 && code <= 97)) {
|
||||
changeColor(code, 'foreground');
|
||||
} else if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107)) {
|
||||
changeColor(code, 'background');
|
||||
} else if (code === 39) {
|
||||
changeColor(undefined, 'foreground');
|
||||
} else if (code === 49) {
|
||||
changeColor(undefined, 'background');
|
||||
switch (code) {
|
||||
case 0: {
|
||||
styleNames = [];
|
||||
customFgColor = undefined;
|
||||
customBgColor = undefined;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
styleNames.push('code-bold');
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
styleNames.push('code-italic');
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
styleNames.push('code-underline');
|
||||
break;
|
||||
}
|
||||
case 39: {
|
||||
changeColor('foreground', undefined);
|
||||
break;
|
||||
}
|
||||
case 49: {
|
||||
changeColor('background', undefined);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
setBasicColor(code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,7 +185,7 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML
|
||||
styleCodes[3] >= 0 && styleCodes[3] <= 255 &&
|
||||
styleCodes[4] >= 0 && styleCodes[4] <= 255) {
|
||||
const customColor = new RGBA(styleCodes[2], styleCodes[3], styleCodes[4]);
|
||||
changeColor('custom', colorType, customColor);
|
||||
changeColor(colorType, customColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +202,7 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML
|
||||
const color = calcANSI8bitColor(colorNumber);
|
||||
|
||||
if (color) {
|
||||
changeColor('custom', colorType, color);
|
||||
changeColor(colorType, color);
|
||||
} else if (colorNumber >= 0 && colorNumber <= 15) {
|
||||
// Need to map to one of the four basic color ranges (30-37, 90-97, 40-47, 100-107)
|
||||
colorNumber += 30;
|
||||
@@ -199,7 +213,43 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML
|
||||
if (colorType === 'background') {
|
||||
colorNumber += 10;
|
||||
}
|
||||
changeColor(colorNumber, colorType);
|
||||
setBasicColor(colorNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and set styling for basic bright and dark ANSI color codes. Uses
|
||||
* theme colors if available. Automatically distinguishes between foreground
|
||||
* and background colors; does not support color-clearing codes 39 and 49.
|
||||
* @param styleCode Integer color code on one of the following ranges:
|
||||
* [30-37, 90-97, 40-47, 100-107]. If not on one of these ranges, will do
|
||||
* nothing.
|
||||
*/
|
||||
function setBasicColor(styleCode: number): void {
|
||||
const theme = themeService.getTheme();
|
||||
let colorType: 'foreground' | 'background' | undefined;
|
||||
let colorIndex: number | undefined;
|
||||
|
||||
if (styleCode >= 30 && styleCode <= 37) {
|
||||
colorIndex = styleCode - 30;
|
||||
colorType = 'foreground';
|
||||
} else if (styleCode >= 90 && styleCode <= 97) {
|
||||
colorIndex = (styleCode - 90) + 8; // High-intensity (bright)
|
||||
colorType = 'foreground';
|
||||
} else if (styleCode >= 40 && styleCode <= 47) {
|
||||
colorIndex = styleCode - 40;
|
||||
colorType = 'background';
|
||||
} else if (styleCode >= 100 && styleCode <= 107) {
|
||||
colorIndex = (styleCode - 100) + 8; // High-intensity (bright)
|
||||
colorType = 'background';
|
||||
}
|
||||
|
||||
if (colorIndex !== undefined && colorType) {
|
||||
const colorName = ansiColorIdentifiers[colorIndex];
|
||||
const color = theme.getColor(colorName);
|
||||
if (color) {
|
||||
changeColor(colorType, color.rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,9 +199,9 @@ export class FocusSessionActionViewItem extends SelectActionViewItem {
|
||||
) {
|
||||
super(null, action, [], -1, contextViewService, { ariaLabel: nls.localize('debugSession', 'Debug Session') });
|
||||
|
||||
this.toDispose.push(attachSelectBoxStyler(this.selectBox, themeService));
|
||||
this._register(attachSelectBoxStyler(this.selectBox, themeService));
|
||||
|
||||
this.toDispose.push(this.debugService.getViewModel().onDidFocusSession(() => {
|
||||
this._register(this.debugService.getViewModel().onDidFocusSession(() => {
|
||||
const session = this.debugService.getViewModel().focusedSession;
|
||||
if (session) {
|
||||
const index = this.getSessions().indexOf(session);
|
||||
@@ -209,8 +209,8 @@ export class FocusSessionActionViewItem extends SelectActionViewItem {
|
||||
}
|
||||
}));
|
||||
|
||||
this.toDispose.push(this.debugService.onDidNewSession(() => this.update()));
|
||||
this.toDispose.push(this.debugService.onDidEndSession(() => this.update()));
|
||||
this._register(this.debugService.onDidNewSession(() => this.update()));
|
||||
this._register(this.debugService.onDidEndSession(() => this.update()));
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
@@ -53,6 +53,11 @@ function getThreadAndRun(accessor: ServicesAccessor, thread: IThread | undefined
|
||||
const debugService = accessor.get(IDebugService);
|
||||
if (!(thread instanceof Thread)) {
|
||||
thread = debugService.getViewModel().focusedThread;
|
||||
if (!thread) {
|
||||
const focusedSession = debugService.getViewModel().focusedSession;
|
||||
const threads = focusedSession ? focusedSession.getAllThreads() : undefined;
|
||||
thread = threads && threads.length ? threads[0] : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
@@ -407,24 +412,18 @@ export function registerCommands(): void {
|
||||
const widget = editorService.activeTextEditorWidget;
|
||||
if (isCodeEditor(widget)) {
|
||||
const position = widget.getPosition();
|
||||
if (!position || !widget.hasModel()) {
|
||||
return undefined;
|
||||
}
|
||||
if (position && widget.hasModel() && debugService.getConfigurationManager().canSetBreakpointsIn(widget.getModel())) {
|
||||
const modelUri = widget.getModel().uri;
|
||||
const breakpointAlreadySet = debugService.getModel().getBreakpoints({ lineNumber: position.lineNumber, uri: modelUri })
|
||||
.some(bp => (bp.sessionAgnosticData.column === position.column || (!bp.column && position.column <= 1)));
|
||||
|
||||
const modelUri = widget.getModel().uri;
|
||||
const bp = debugService.getModel().getBreakpoints({ lineNumber: position.lineNumber, uri: modelUri })
|
||||
.filter(bp => (bp.column === position.column || !bp.column && position.column <= 1)).pop();
|
||||
|
||||
if (bp) {
|
||||
return undefined;
|
||||
}
|
||||
if (debugService.getConfigurationManager().canSetBreakpointsIn(widget.getModel())) {
|
||||
return debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber, column: position.column > 1 ? position.column : undefined }], 'debugCommands.inlineBreakpointCommand');
|
||||
if (!breakpointAlreadySet) {
|
||||
debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber, column: position.column > 1 ? position.column : undefined }], 'debugCommands.inlineBreakpointCommand');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
primary: KeyMod.Shift | KeyCode.F9,
|
||||
|
||||
@@ -180,7 +180,7 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
const data: { [id: string]: IBreakpointUpdateData } = Object.create(null);
|
||||
const data = new Map<string, IBreakpointUpdateData>();
|
||||
const breakpoints = this.debugService.getModel().getBreakpoints();
|
||||
const modelUri = modelData.model.uri;
|
||||
for (let i = 0, len = modelData.breakpointDecorations.length; i < len; i++) {
|
||||
@@ -191,10 +191,10 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
const breakpoint = breakpoints.filter(bp => bp.getId() === breakpointDecoration.modelId).pop();
|
||||
// since we know it is collapsed, it cannot grow to multiple lines
|
||||
if (breakpoint) {
|
||||
data[breakpoint.getId()] = {
|
||||
data.set(breakpoint.getId(), {
|
||||
lineNumber: decorationRange.startLineNumber,
|
||||
column: breakpoint.column ? decorationRange.startColumn : undefined,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { IContentWidget, ICodeEditor, IContentWidgetPosition, ContentWidgetPosit
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDebugService, IExpression, IExpressionContainer } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Expression } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { renderExpressionValue } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { renderExpressionValue, replaceWhitespace } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { attachStylerCallback } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -237,7 +237,7 @@ export class DebugHoverWidget implements IContentWidget {
|
||||
this.complexValueContainer.hidden = false;
|
||||
|
||||
return this.tree.setInput(expression).then(() => {
|
||||
this.complexValueTitle.textContent = expression.value;
|
||||
this.complexValueTitle.textContent = replaceWhitespace(expression.value);
|
||||
this.complexValueTitle.title = expression.value;
|
||||
this.layoutTreeAndContainer();
|
||||
this.editor.layoutContentWidget(this);
|
||||
|
||||
@@ -4,100 +4,81 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IDebugService, State, IDebugConfiguration } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Themable, STATUS_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { STATUS_BAR_DEBUGGING_FOREGROUND, isStatusbarInDebugMode } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider';
|
||||
import { IStatusbarEntry, IStatusbarService, StatusbarAlignment, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
export class DebugStatus extends Themable implements IStatusbarItem {
|
||||
private container: HTMLElement;
|
||||
private statusBarItem: HTMLElement;
|
||||
private label: HTMLElement;
|
||||
private icon: HTMLElement;
|
||||
export class DebugStatusContribution implements IWorkbenchContribution {
|
||||
|
||||
private showInStatusBar: 'never' | 'always' | 'onFirstSessionStart';
|
||||
private toDispose: IDisposable[] = [];
|
||||
private entryAccessor: IStatusbarEntryAccessor | undefined;
|
||||
|
||||
constructor(
|
||||
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
|
||||
@IDebugService private readonly debugService: IDebugService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
@IStatusbarService private readonly statusBarService: IStatusbarService,
|
||||
@IDebugService readonly debugService: IDebugService,
|
||||
@IConfigurationService readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(themeService);
|
||||
this._register(this.debugService.getConfigurationManager().onDidSelectConfiguration(e => {
|
||||
this.setLabel();
|
||||
}));
|
||||
this._register(this.debugService.onDidChangeState(state => {
|
||||
if (state !== State.Inactive && this.showInStatusBar === 'onFirstSessionStart') {
|
||||
this.doRender();
|
||||
} else {
|
||||
if (this.showInStatusBar !== 'never') {
|
||||
this.updateStyles();
|
||||
}
|
||||
|
||||
const addStatusBarEntry = () => {
|
||||
this.entryAccessor = this.statusBarService.addEntry(this.entry, 'status.debug', nls.localize('status.debug', "Debug"), StatusbarAlignment.LEFT, 30 /* Low Priority */);
|
||||
};
|
||||
|
||||
const setShowInStatusBar = () => {
|
||||
this.showInStatusBar = configurationService.getValue<IDebugConfiguration>('debug').showInStatusBar;
|
||||
if (this.showInStatusBar === 'always' && !this.entryAccessor) {
|
||||
addStatusBarEntry();
|
||||
}
|
||||
};
|
||||
setShowInStatusBar();
|
||||
|
||||
this.toDispose.push(this.debugService.onDidChangeState(state => {
|
||||
if (state !== State.Inactive && this.showInStatusBar === 'onFirstSessionStart' && !this.entryAccessor) {
|
||||
addStatusBarEntry();
|
||||
}
|
||||
}));
|
||||
this.showInStatusBar = configurationService.getValue<IDebugConfiguration>('debug').showInStatusBar;
|
||||
this._register(configurationService.onDidChangeConfiguration(e => {
|
||||
this.toDispose.push(configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('debug.showInStatusBar')) {
|
||||
this.showInStatusBar = configurationService.getValue<IDebugConfiguration>('debug').showInStatusBar;
|
||||
if (this.showInStatusBar === 'always') {
|
||||
this.doRender();
|
||||
}
|
||||
if (this.statusBarItem) {
|
||||
dom.toggleClass(this.statusBarItem, 'hidden', this.showInStatusBar === 'never');
|
||||
setShowInStatusBar();
|
||||
if (this.entryAccessor && this.showInStatusBar === 'never') {
|
||||
this.entryAccessor.dispose();
|
||||
this.entryAccessor = undefined;
|
||||
}
|
||||
}
|
||||
}));
|
||||
this.toDispose.push(this.debugService.getConfigurationManager().onDidSelectConfiguration(e => {
|
||||
if (this.entryAccessor) {
|
||||
this.entryAccessor.update(this.entry);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
protected updateStyles(): void {
|
||||
if (this.icon) {
|
||||
if (isStatusbarInDebugMode(this.debugService)) {
|
||||
this.icon.style.backgroundColor = this.getColor(STATUS_BAR_DEBUGGING_FOREGROUND);
|
||||
} else {
|
||||
this.icon.style.backgroundColor = this.getColor(STATUS_BAR_FOREGROUND);
|
||||
}
|
||||
private getText(): string {
|
||||
const manager = this.debugService.getConfigurationManager();
|
||||
const name = manager.selectedConfiguration.name || '';
|
||||
const nameAndLaunchPresent = name && manager.selectedConfiguration.launch;
|
||||
if (nameAndLaunchPresent) {
|
||||
return '$(play) ' + (manager.getLaunches().length > 1 ? `${name} (${manager.selectedConfiguration.launch!.name})` : name);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public render(container: HTMLElement): IDisposable {
|
||||
this.container = container;
|
||||
if (this.showInStatusBar === 'always') {
|
||||
this.doRender();
|
||||
}
|
||||
// noop, we render when we decide is best
|
||||
return this;
|
||||
private get entry(): IStatusbarEntry {
|
||||
return {
|
||||
text: this.getText(),
|
||||
tooltip: nls.localize('selectAndStartDebug', "Select and start debug configuration"),
|
||||
command: 'workbench.action.debug.selectandstart'
|
||||
};
|
||||
}
|
||||
|
||||
private doRender(): void {
|
||||
if (!this.statusBarItem && this.container) {
|
||||
this.statusBarItem = dom.append(this.container, $('.debug-statusbar-item'));
|
||||
this._register(dom.addDisposableListener(this.statusBarItem, 'click', () => this.quickOpenService.show('debug ')));
|
||||
this.statusBarItem.title = nls.localize('selectAndStartDebug', "Select and start debug configuration");
|
||||
const a = dom.append(this.statusBarItem, $('a'));
|
||||
this.icon = dom.append(a, $('.icon'));
|
||||
this.label = dom.append(a, $('span.label'));
|
||||
this.setLabel();
|
||||
}
|
||||
|
||||
this.updateStyles();
|
||||
}
|
||||
|
||||
private setLabel(): void {
|
||||
if (this.label && this.statusBarItem) {
|
||||
const manager = this.debugService.getConfigurationManager();
|
||||
const name = manager.selectedConfiguration.name || '';
|
||||
const nameAndLaunchPresent = name && manager.selectedConfiguration.launch;
|
||||
dom.toggleClass(this.statusBarItem, 'hidden', this.showInStatusBar === 'never' || !nameAndLaunchPresent);
|
||||
if (nameAndLaunchPresent) {
|
||||
this.label.textContent = manager.getLaunches().length > 1 ? `${name} (${manager.selectedConfiguration.launch!.name})` : name;
|
||||
}
|
||||
dispose(): void {
|
||||
if (this.entryAccessor) {
|
||||
this.entryAccessor.dispose();
|
||||
}
|
||||
dispose(this.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
|
||||
|
||||
const actionBarContainer = dom.append(this.$el, dom.$('div.action-bar-container'));
|
||||
this.debugToolBarMenu = menuService.createMenu(MenuId.DebugToolBar, contextKeyService);
|
||||
this.toDispose.push(this.debugToolBarMenu);
|
||||
this._register(this.debugToolBarMenu);
|
||||
|
||||
this.activeActions = [];
|
||||
this.actionBar = this._register(new ActionBar(actionBarContainer, {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { StartAction, ConfigureAction, SelectAndStartAction, FocusSessionAction
|
||||
import { StartDebugActionViewItem, FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/debugActionViewItems';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IProgressService, IProgressRunner } from 'vs/platform/progress/common/progress';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
@@ -37,7 +37,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
export class DebugViewlet extends ViewContainerViewlet {
|
||||
|
||||
private startDebugActionViewItem: StartDebugActionViewItem;
|
||||
private progressRunner: IProgressRunner;
|
||||
private progressResolve: (() => void) | undefined;
|
||||
private breakpointView: ViewletPanel;
|
||||
private panelListeners = new Map<string, IDisposable>();
|
||||
private debugToolBarMenu: IMenu;
|
||||
@@ -112,7 +112,7 @@ export class DebugViewlet extends ViewContainerViewlet {
|
||||
|
||||
if (!this.debugToolBarMenu) {
|
||||
this.debugToolBarMenu = this.menuService.createMenu(MenuId.DebugToolBar, this.contextKeyService);
|
||||
this.toDispose.push(this.debugToolBarMenu);
|
||||
this._register(this.debugToolBarMenu);
|
||||
}
|
||||
return DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
|
||||
}
|
||||
@@ -153,12 +153,15 @@ export class DebugViewlet extends ViewContainerViewlet {
|
||||
}
|
||||
|
||||
private onDebugServiceStateChange(state: State): void {
|
||||
if (this.progressRunner) {
|
||||
this.progressRunner.done();
|
||||
if (this.progressResolve) {
|
||||
this.progressResolve();
|
||||
this.progressResolve = undefined;
|
||||
}
|
||||
|
||||
if (state === State.Initializing) {
|
||||
this.progressRunner = this.progressService.show(true);
|
||||
this.progressService.withProgress({ location: VIEWLET_ID }, _progress => {
|
||||
return new Promise(resolve => this.progressResolve = resolve);
|
||||
});
|
||||
}
|
||||
|
||||
this.updateToolBar();
|
||||
|
||||
@@ -35,12 +35,12 @@ export class ExceptionWidget extends ZoneWidget {
|
||||
this._backgroundColor = Color.white;
|
||||
|
||||
this._applyTheme(themeService.getTheme());
|
||||
this._disposables.push(themeService.onThemeChange(this._applyTheme.bind(this)));
|
||||
this._disposables.add(themeService.onThemeChange(this._applyTheme.bind(this)));
|
||||
|
||||
this.create();
|
||||
const onDidLayoutChangeScheduler = new RunOnceScheduler(() => this._doLayout(undefined, undefined), 50);
|
||||
this._disposables.push(this.editor.onDidLayoutChange(() => onDidLayoutChangeScheduler.schedule()));
|
||||
this._disposables.push(onDidLayoutChangeScheduler);
|
||||
this._disposables.add(this.editor.onDidLayoutChange(() => onDidLayoutChangeScheduler.schedule()));
|
||||
this._disposables.add(onDidLayoutChangeScheduler);
|
||||
}
|
||||
|
||||
private _applyTheme(theme: ITheme): void {
|
||||
|
||||
@@ -19,7 +19,7 @@ export class LinkDetector {
|
||||
// group 2: drive letter on windows with trailing backslash or leading slash on mac/linux
|
||||
// group 3: line number, matched by (:(\d+))
|
||||
// group 4: column number, matched by ((?::(\d+))?)
|
||||
// eg: at Context.<anonymous> (c:\Users\someone\Desktop\mocha-runner\test\test.js:26:11)
|
||||
// e.g.: at Context.<anonymous> (c:\Users\someone\Desktop\mocha-runner\test\test.js:26:11)
|
||||
/(?![\(])(?:file:\/\/)?((?:([a-zA-Z]+:)|[^\(\)<>\'\"\[\]:\s]+)(?:[\\/][^\(\)<>\'\"\[\]:]*)?\.[a-zA-Z]+[0-9]*):(\d+)(?::(\d+))?/g
|
||||
];
|
||||
|
||||
|
||||
@@ -45,16 +45,15 @@ type LoadedScriptsItem = BaseTreeItem;
|
||||
class BaseTreeItem {
|
||||
|
||||
private _showedMoreThanOne: boolean;
|
||||
private _children: { [key: string]: BaseTreeItem; };
|
||||
private _children = new Map<string, BaseTreeItem>();
|
||||
private _source: Source;
|
||||
|
||||
constructor(private _parent: BaseTreeItem | undefined, private _label: string) {
|
||||
this._children = {};
|
||||
this._showedMoreThanOne = false;
|
||||
}
|
||||
|
||||
isLeaf(): boolean {
|
||||
return Object.keys(this._children).length === 0;
|
||||
return this._children.size === 0;
|
||||
}
|
||||
|
||||
getSession(): IDebugSession | undefined {
|
||||
@@ -66,12 +65,12 @@ class BaseTreeItem {
|
||||
|
||||
setSource(session: IDebugSession, source: Source): void {
|
||||
this._source = source;
|
||||
this._children = {};
|
||||
this._children.clear();
|
||||
if (source.raw && source.raw.sources) {
|
||||
for (const src of source.raw.sources) {
|
||||
if (src.name && src.path) {
|
||||
const s = new BaseTreeItem(this, src.name);
|
||||
this._children[src.path] = s;
|
||||
this._children.set(src.path, s);
|
||||
const ss = session.getSource(src);
|
||||
s.setSource(session, ss);
|
||||
}
|
||||
@@ -80,26 +79,26 @@ class BaseTreeItem {
|
||||
}
|
||||
|
||||
createIfNeeded<T extends BaseTreeItem>(key: string, factory: (parent: BaseTreeItem, label: string) => T): T {
|
||||
let child = <T>this._children[key];
|
||||
let child = <T>this._children.get(key);
|
||||
if (!child) {
|
||||
child = factory(this, key);
|
||||
this._children[key] = child;
|
||||
this._children.set(key, child);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
getChild(key: string): BaseTreeItem {
|
||||
return this._children[key];
|
||||
getChild(key: string): BaseTreeItem | undefined {
|
||||
return this._children.get(key);
|
||||
}
|
||||
|
||||
remove(key: string): void {
|
||||
delete this._children[key];
|
||||
this._children.delete(key);
|
||||
}
|
||||
|
||||
removeFromParent(): void {
|
||||
if (this._parent) {
|
||||
this._parent.remove(this._label);
|
||||
if (Object.keys(this._parent._children).length === 0) {
|
||||
if (this._parent._children.size === 0) {
|
||||
this._parent.removeFromParent();
|
||||
}
|
||||
}
|
||||
@@ -142,7 +141,7 @@ class BaseTreeItem {
|
||||
if (child) {
|
||||
return child.hasChildren();
|
||||
}
|
||||
return Object.keys(this._children).length > 0;
|
||||
return this._children.size > 0;
|
||||
}
|
||||
|
||||
// skips intermediate single-child nodes
|
||||
@@ -151,7 +150,10 @@ class BaseTreeItem {
|
||||
if (child) {
|
||||
return child.getChildren();
|
||||
}
|
||||
const array = Object.keys(this._children).map(key => this._children[key]);
|
||||
const array: BaseTreeItem[] = [];
|
||||
for (let child of this._children.values()) {
|
||||
array.push(child);
|
||||
}
|
||||
return Promise.resolve(array.sort((a, b) => this.compare(a, b)));
|
||||
}
|
||||
|
||||
@@ -199,12 +201,11 @@ class BaseTreeItem {
|
||||
|
||||
private oneChild(): BaseTreeItem | undefined {
|
||||
if (SMART && !this._source && !this._showedMoreThanOne && !(this instanceof RootFolderTreeItem) && !(this instanceof SessionTreeItem)) {
|
||||
const keys = Object.keys(this._children);
|
||||
if (keys.length === 1) {
|
||||
return this._children[keys[0]];
|
||||
if (this._children.size === 1) {
|
||||
return this._children.values().next().value;
|
||||
}
|
||||
// if a node had more than one child once, it will never be skipped again
|
||||
if (keys.length > 1) {
|
||||
if (this._children.size > 1) {
|
||||
this._showedMoreThanOne = true;
|
||||
}
|
||||
}
|
||||
@@ -243,7 +244,7 @@ class SessionTreeItem extends BaseTreeItem {
|
||||
|
||||
private _session: IDebugSession;
|
||||
private _initialized: boolean;
|
||||
private _map: Map<string, BaseTreeItem>;
|
||||
private _map = new Map<string, BaseTreeItem>();
|
||||
private _labelService: ILabelService;
|
||||
|
||||
constructor(labelService: ILabelService, parent: BaseTreeItem, session: IDebugSession, private _environmentService: IEnvironmentService, private rootProvider: IWorkspaceContextService) {
|
||||
@@ -251,7 +252,6 @@ class SessionTreeItem extends BaseTreeItem {
|
||||
this._labelService = labelService;
|
||||
this._initialized = false;
|
||||
this._session = session;
|
||||
this._map = new Map();
|
||||
}
|
||||
|
||||
getSession(): IDebugSession {
|
||||
@@ -417,7 +417,7 @@ export class LoadedScriptsView extends ViewletPanel {
|
||||
const root = new RootTreeItem(this.debugService.getModel(), this.environmentService, this.contextService, this.labelService);
|
||||
|
||||
this.treeLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility });
|
||||
this.disposables.push(this.treeLabels);
|
||||
this._register(this.treeLabels);
|
||||
|
||||
this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, this.treeContainer, new LoadedScriptsDelegate(),
|
||||
[new LoadedScriptsRenderer(this.treeLabels)],
|
||||
@@ -443,11 +443,11 @@ export class LoadedScriptsView extends ViewletPanel {
|
||||
this.tree.updateChildren();
|
||||
}
|
||||
}, 300);
|
||||
this.disposables.push(this.changeScheduler);
|
||||
this._register(this.changeScheduler);
|
||||
|
||||
const loadedScriptsNavigator = new TreeResourceNavigator2(this.tree);
|
||||
this.disposables.push(loadedScriptsNavigator);
|
||||
this.disposables.push(loadedScriptsNavigator.onDidOpenResource(e => {
|
||||
this._register(loadedScriptsNavigator);
|
||||
this._register(loadedScriptsNavigator.onDidOpenResource(e => {
|
||||
if (e.element instanceof BaseTreeItem) {
|
||||
const source = e.element.getSource();
|
||||
if (source && source.available) {
|
||||
@@ -457,7 +457,7 @@ export class LoadedScriptsView extends ViewletPanel {
|
||||
}
|
||||
}));
|
||||
|
||||
this.disposables.push(this.tree.onDidChangeFocus(() => {
|
||||
this._register(this.tree.onDidChangeFocus(() => {
|
||||
const focus = this.tree.getFocus();
|
||||
if (focus instanceof SessionTreeItem) {
|
||||
this.loadedScriptsItemType.set('session');
|
||||
@@ -467,7 +467,7 @@ export class LoadedScriptsView extends ViewletPanel {
|
||||
}));
|
||||
|
||||
const registerLoadedSourceListener = (session: IDebugSession) => {
|
||||
this.disposables.push(session.onDidLoadedSource(event => {
|
||||
this._register(session.onDidLoadedSource(event => {
|
||||
let sessionRoot: SessionTreeItem;
|
||||
switch (event.reason) {
|
||||
case 'new':
|
||||
@@ -501,17 +501,17 @@ export class LoadedScriptsView extends ViewletPanel {
|
||||
}));
|
||||
};
|
||||
|
||||
this.disposables.push(this.debugService.onDidNewSession(registerLoadedSourceListener));
|
||||
this._register(this.debugService.onDidNewSession(registerLoadedSourceListener));
|
||||
this.debugService.getModel().getSessions().forEach(registerLoadedSourceListener);
|
||||
|
||||
this.disposables.push(this.debugService.onDidEndSession(session => {
|
||||
this._register(this.debugService.onDidEndSession(session => {
|
||||
root.remove(session.getId());
|
||||
this.changeScheduler.schedule();
|
||||
}));
|
||||
|
||||
this.changeScheduler.schedule(0);
|
||||
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(visible => {
|
||||
this._register(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && this.treeNeedsRefreshOnVisible) {
|
||||
this.changeScheduler.schedule();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,5 @@
|
||||
|
||||
.monaco-editor .zone-widget .zone-widget-container.breakpoint-widget .inputContainer {
|
||||
flex: 1;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
@@ -110,25 +110,6 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Debug status */
|
||||
/* A very precise css rule to overwrite the display set in statusbar.css */
|
||||
.monaco-workbench .part.statusbar > .statusbar-item > .debug-statusbar-item > a {
|
||||
display: flex;
|
||||
padding: 0 5px 0 5px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.statusbar .debug-statusbar-item.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.statusbar .debug-statusbar-item .icon {
|
||||
-webkit-mask: url('start.svg') no-repeat 50% 50%;
|
||||
-webkit-mask-size: 16px;
|
||||
display: inline-block;
|
||||
padding-right: 2px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.monaco-workbench .debug-view-content .monaco-list-row .monaco-tl-contents {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -142,6 +123,7 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: var(--monaco-monospace-font);
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.monaco-workbench.mac .debug-viewlet .monaco-list-row .expression,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
text-overflow: ellipsis;
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
border-bottom: 1px solid rgba(128, 128, 128, 0.35);
|
||||
}
|
||||
|
||||
@@ -60,10 +61,6 @@
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .monaco-tl-contents .value {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .error {
|
||||
color: #E51400;
|
||||
}
|
||||
|
||||
@@ -246,10 +246,6 @@
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
.monaco-workbench .debug-viewlet .monaco-list-row .expression {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-call-stack .error {
|
||||
font-style: italic;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -127,61 +127,6 @@
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-italic { font-style: italic; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-underline { text-decoration: underline; }
|
||||
|
||||
/* Regular and bright color codes are currently treated the same. */
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-30, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-90 { color: gray; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-31, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-91 { color: #BE1717; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-32, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-92 { color: #338A2F; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-33, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-93 { color: #BEB817; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-34, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-94 { color: darkblue; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-35, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-95 { color: darkmagenta; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-36, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-96 { color: darkcyan; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-foreground-37, .monaco-workbench .repl .repl-tree .output.expression .code-foreground-97 { color: #BDBDBD; }
|
||||
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-40, .monaco-workbench .repl .repl-tree .output.expression .code-background-100 { background-color: gray; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-41, .monaco-workbench .repl .repl-tree .output.expression .code-background-101 { background-color: #BE1717; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-42, .monaco-workbench .repl .repl-tree .output.expression .code-background-102 { background-color: #338A2F; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-43, .monaco-workbench .repl .repl-tree .output.expression .code-background-103 { background-color: #BEB817; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-44, .monaco-workbench .repl .repl-tree .output.expression .code-background-104 { background-color: darkblue; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-45, .monaco-workbench .repl .repl-tree .output.expression .code-background-105 { background-color: darkmagenta; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-46, .monaco-workbench .repl .repl-tree .output.expression .code-background-106 { background-color: darkcyan; }
|
||||
.monaco-workbench .repl .repl-tree .output.expression .code-background-47, .monaco-workbench .repl .repl-tree .output.expression .code-background-107 { background-color: #BDBDBD; }
|
||||
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-30, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-90 { color: #A0A0A0; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-31, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-91 { color: #A74747; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-32, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-92 { color: #348F34; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-33, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-93 { color: #5F4C29; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-34, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-94 { color: #6286BB; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-35, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-95 { color: #914191; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-36, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-96 { color: #218D8D; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-37, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-foreground-97 { color: #707070; }
|
||||
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-40, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-100 { background-color: #A0A0A0; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-41, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-101 { background-color: #A74747; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-42, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-102 { background-color: #348F34; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-43, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-103 { background-color: #5F4C29; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-44, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-104 { background-color: #6286BB; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-45, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-105 { background-color: #914191; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-46, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-106 { background-color: #218D8D; }
|
||||
.vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-47, .vs-dark .monaco-workbench .repl .repl-tree .output.expression .code-background-107 { background-color: #707070; }
|
||||
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-30, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-90 { color: gray; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-31, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-91 { color: #A74747; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-32, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-92 { color: #348F34; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-33, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-93 { color: #5F4C29; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-34, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-94 { color: #6286BB; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-35, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-95 { color: #914191; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-36, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-96 { color: #218D8D; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-37, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-foreground-97 { color: #707070; }
|
||||
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-40, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-100 { background-color: gray; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-41, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-101 { background-color: #A74747; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-42, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-102 { background-color: #348F34; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-43, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-103 { background-color: #5F4C29; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-44, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-104 { background-color: #6286BB; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-45, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-105 { background-color: #914191; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-46, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-106 { background-color: #218D8D; }
|
||||
.hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-47, .hc-black .monaco-workbench .repl .repl-tree .output.expression .code-background-107 { background-color: #707070; }
|
||||
|
||||
/* Links */
|
||||
.monaco-workbench .repl .repl-tree .output.expression a {
|
||||
text-decoration: underline;
|
||||
|
||||
@@ -11,7 +11,7 @@ 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';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import severity from 'vs/base/common/severity';
|
||||
import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
@@ -76,6 +76,7 @@ interface IPrivateReplService {
|
||||
getVisibleContent(): string;
|
||||
selectSession(session?: IDebugSession): void;
|
||||
clearRepl(): void;
|
||||
focusRepl(): void;
|
||||
}
|
||||
|
||||
function revealLastElement(tree: WorkbenchAsyncDataTree<any, any, any>) {
|
||||
@@ -133,15 +134,16 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
}
|
||||
this.selectSession();
|
||||
}));
|
||||
this._register(this.debugService.onWillNewSession(() => {
|
||||
this._register(this.debugService.onWillNewSession(newSession => {
|
||||
// Need to listen to output events for sessions which are not yet fully initialised
|
||||
const input = this.tree.getInput();
|
||||
if (!input || input.state === State.Inactive) {
|
||||
this.selectSession();
|
||||
this.selectSession(newSession);
|
||||
}
|
||||
this.updateTitleArea();
|
||||
}));
|
||||
this._register(this.themeService.onThemeChange(() => {
|
||||
this.refreshReplElements(false);
|
||||
if (this.isVisible()) {
|
||||
this.updateInputDecoration();
|
||||
}
|
||||
@@ -181,6 +183,10 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
this.navigateHistory(false);
|
||||
}
|
||||
|
||||
focusRepl(): void {
|
||||
this.tree.domFocus();
|
||||
}
|
||||
|
||||
private onDidFontChange(): void {
|
||||
if (this.styleElement) {
|
||||
const debugConsole = this.configurationService.getValue<IDebugConfiguration>('debug').console;
|
||||
@@ -282,7 +288,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
const lineDelimiter = this.textResourcePropertiesService.getEOL(this.model.uri);
|
||||
const traverseAndAppend = (node: ITreeNode<IReplElement, FuzzyScore>) => {
|
||||
node.children.forEach(child => {
|
||||
text += child.element.toString() + lineDelimiter;
|
||||
text += child.element.toString().trimRight() + lineDelimiter;
|
||||
if (!child.collapsed && child.children.length) {
|
||||
traverseAndAppend(child);
|
||||
}
|
||||
@@ -381,7 +387,16 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
supportDynamicHeights: true
|
||||
}) as WorkbenchAsyncDataTree<IDebugSession, IReplElement, FuzzyScore>;
|
||||
|
||||
this.toDispose.push(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
let lastSelectedString: string;
|
||||
this._register(this.tree.onMouseClick(() => {
|
||||
const selection = window.getSelection();
|
||||
if (!selection || selection.type !== 'Range' || lastSelectedString === selection.toString()) {
|
||||
// only focus the input if the user is not currently selecting.
|
||||
this.replInput.focus();
|
||||
}
|
||||
lastSelectedString = selection ? selection.toString() : '';
|
||||
}));
|
||||
// Make sure to select the session if debugging is already active
|
||||
this.selectSession();
|
||||
this.styleElement = dom.createStyleSheet(this.container);
|
||||
@@ -606,7 +621,8 @@ class ReplSimpleElementsRenderer implements ITreeRenderer<SimpleReplElement, Fuz
|
||||
constructor(
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService private readonly themeService: IThemeService
|
||||
) { }
|
||||
|
||||
get templateId(): string {
|
||||
@@ -649,7 +665,7 @@ class ReplSimpleElementsRenderer implements ITreeRenderer<SimpleReplElement, Fuz
|
||||
dom.clearNode(templateData.value);
|
||||
// Reset classes to clear ansi decorations since templates are reused
|
||||
templateData.value.className = 'value';
|
||||
const result = handleANSIOutput(element.value, this.linkDetector);
|
||||
const result = handleANSIOutput(element.value, this.linkDetector, this.themeService);
|
||||
templateData.value.appendChild(result);
|
||||
|
||||
dom.addClass(templateData.value, (element.severity === severity.Warning) ? 'warn' : (element.severity === severity.Error) ? 'error' : (element.severity === severity.Ignore) ? 'ignore' : 'info');
|
||||
@@ -832,6 +848,28 @@ class AcceptReplInputAction extends EditorAction {
|
||||
}
|
||||
}
|
||||
|
||||
class FilterReplAction extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'repl.action.filter',
|
||||
label: nls.localize('repl.action.filter', "REPL Focus Content to Filter"),
|
||||
alias: 'REPL Filter',
|
||||
precondition: CONTEXT_IN_DEBUG_REPL,
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.textInputFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_F,
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
|
||||
SuggestController.get(editor).acceptSelectedSuggestion();
|
||||
accessor.get(IPrivateReplService).focusRepl();
|
||||
}
|
||||
}
|
||||
|
||||
class ReplCopyAllAction extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
@@ -851,6 +889,7 @@ class ReplCopyAllAction extends EditorAction {
|
||||
|
||||
registerEditorAction(AcceptReplInputAction);
|
||||
registerEditorAction(ReplCopyAllAction);
|
||||
registerEditorAction(FilterReplAction);
|
||||
|
||||
class SelectReplActionViewItem extends FocusSessionActionViewItem {
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ export class StatusBarColorProvider extends Themable implements IWorkbenchContri
|
||||
this.styleElement = createStyleSheet(container);
|
||||
}
|
||||
|
||||
this.styleElement.innerHTML = `.monaco-workbench .part.statusbar > .statusbar-item.has-beak:before { border-bottom-color: ${backgroundColor} !important; }`;
|
||||
this.styleElement.innerHTML = `.monaco-workbench .part.statusbar > .items-container > .statusbar-item.has-beak:before { border-bottom-color: ${backgroundColor} !important; }`;
|
||||
}
|
||||
|
||||
private getColorKey(noFolderColor: string, debuggingColor: string, normalColor: string): string {
|
||||
@@ -115,6 +115,6 @@ export function isStatusbarInDebugMode(debugService: IDebugService): boolean {
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const statusBarItemDebuggingForeground = theme.getColor(STATUS_BAR_DEBUGGING_FOREGROUND);
|
||||
if (statusBarItemDebuggingForeground) {
|
||||
collector.addRule(`.monaco-workbench .part.statusbar.debugging > .statusbar-item .mask-icon { background-color: ${statusBarItemDebuggingForeground} !important; }`);
|
||||
collector.addRule(`.monaco-workbench .part.statusbar.debugging > .items-container > .statusbar-item .mask-icon { background-color: ${statusBarItemDebuggingForeground} !important; }`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -88,7 +88,7 @@ export class VariablesView extends ViewletPanel {
|
||||
this.toolbar.setActions([collapseAction])();
|
||||
this.tree.updateChildren();
|
||||
|
||||
this.disposables.push(this.debugService.getViewModel().onDidFocusStackFrame(sf => {
|
||||
this._register(this.debugService.getViewModel().onDidFocusStackFrame(sf => {
|
||||
if (!this.isBodyVisible()) {
|
||||
this.needsRefresh = true;
|
||||
return;
|
||||
@@ -99,16 +99,16 @@ export class VariablesView extends ViewletPanel {
|
||||
const timeout = sf.explicit ? 0 : undefined;
|
||||
this.onFocusStackFrameScheduler.schedule(timeout);
|
||||
}));
|
||||
this.disposables.push(variableSetEmitter.event(() => this.tree.updateChildren()));
|
||||
this.disposables.push(this.tree.onMouseDblClick(e => this.onMouseDblClick(e)));
|
||||
this.disposables.push(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this._register(variableSetEmitter.event(() => this.tree.updateChildren()));
|
||||
this._register(this.tree.onMouseDblClick(e => this.onMouseDblClick(e)));
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(visible => {
|
||||
this._register(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && this.needsRefresh) {
|
||||
this.onFocusStackFrameScheduler.schedule();
|
||||
}
|
||||
}));
|
||||
this.disposables.push(this.debugService.getViewModel().onDidSelectExpression(e => {
|
||||
this._register(this.debugService.getViewModel().onDidSelectExpression(e => {
|
||||
if (e instanceof Variable) {
|
||||
this.tree.rerender(e);
|
||||
}
|
||||
|
||||
@@ -76,16 +76,16 @@ export class WatchExpressionsView extends ViewletPanel {
|
||||
const removeAllWatchExpressionsAction = new RemoveAllWatchExpressionsAction(RemoveAllWatchExpressionsAction.ID, RemoveAllWatchExpressionsAction.LABEL, this.debugService, this.keybindingService);
|
||||
this.toolbar.setActions([addWatchExpressionAction, collapseAction, removeAllWatchExpressionsAction])();
|
||||
|
||||
this.disposables.push(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this.disposables.push(this.tree.onMouseDblClick(e => this.onMouseDblClick(e)));
|
||||
this.disposables.push(this.debugService.getModel().onDidChangeWatchExpressions(we => {
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this._register(this.tree.onMouseDblClick(e => this.onMouseDblClick(e)));
|
||||
this._register(this.debugService.getModel().onDidChangeWatchExpressions(we => {
|
||||
if (!this.isBodyVisible()) {
|
||||
this.needsRefresh = true;
|
||||
} else {
|
||||
this.tree.updateChildren();
|
||||
}
|
||||
}));
|
||||
this.disposables.push(this.debugService.getViewModel().onDidFocusStackFrame(() => {
|
||||
this._register(this.debugService.getViewModel().onDidFocusStackFrame(() => {
|
||||
if (!this.isBodyVisible()) {
|
||||
this.needsRefresh = true;
|
||||
return;
|
||||
@@ -95,14 +95,14 @@ export class WatchExpressionsView extends ViewletPanel {
|
||||
this.onWatchExpressionsUpdatedScheduler.schedule();
|
||||
}
|
||||
}));
|
||||
this.disposables.push(variableSetEmitter.event(() => this.tree.updateChildren()));
|
||||
this._register(variableSetEmitter.event(() => this.tree.updateChildren()));
|
||||
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(visible => {
|
||||
this._register(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && this.needsRefresh) {
|
||||
this.onWatchExpressionsUpdatedScheduler.schedule();
|
||||
}
|
||||
}));
|
||||
this.disposables.push(this.debugService.getViewModel().onDidSelectExpression(e => {
|
||||
this._register(this.debugService.getViewModel().onDidSelectExpression(e => {
|
||||
if (e instanceof Expression && e.name) {
|
||||
this.tree.rerender(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user