mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-25 14:20:30 -04:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
247
src/vs/workbench/parts/debug/browser/baseDebugView.ts
Normal file
247
src/vs/workbench/parts/debug/browser/baseDebugView.ts
Normal file
@@ -0,0 +1,247 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IExpression, IDebugService, IEnablement } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Expression, Variable } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ITree, ContextMenuEvent, IActionProvider } from 'vs/base/parts/tree/browser/tree';
|
||||
import { InputBox, IInputValidationOptions } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
|
||||
import { IControllerOptions } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { WorkbenchTreeController } from 'vs/platform/list/browser/listService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
export const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
|
||||
export const twistiePixels = 20;
|
||||
const booleanRegex = /^true|false$/i;
|
||||
const stringRegex = /^(['"]).*\1$/;
|
||||
const $ = dom.$;
|
||||
|
||||
export interface IRenderValueOptions {
|
||||
preserveWhitespace?: boolean;
|
||||
showChanged?: boolean;
|
||||
maxValueLength?: number;
|
||||
showHover?: boolean;
|
||||
colorize?: boolean;
|
||||
}
|
||||
|
||||
export interface IVariableTemplateData {
|
||||
expression: HTMLElement;
|
||||
name: HTMLElement;
|
||||
value: HTMLElement;
|
||||
}
|
||||
|
||||
export function renderViewTree(container: HTMLElement): HTMLElement {
|
||||
const treeContainer = document.createElement('div');
|
||||
dom.addClass(treeContainer, 'debug-view-content');
|
||||
container.appendChild(treeContainer);
|
||||
return treeContainer;
|
||||
}
|
||||
|
||||
function replaceWhitespace(value: string): string {
|
||||
const map: { [x: string]: string } = { '\n': '\\n', '\r': '\\r', '\t': '\\t' };
|
||||
return value.replace(/[\n\r\t]/g, char => map[char]);
|
||||
}
|
||||
|
||||
export function renderExpressionValue(expressionOrValue: IExpression | string, container: HTMLElement, options: IRenderValueOptions): void {
|
||||
let value = typeof expressionOrValue === 'string' ? expressionOrValue : expressionOrValue.value;
|
||||
|
||||
// remove stale classes
|
||||
container.className = 'value';
|
||||
// when resolving expressions we represent errors from the server as a variable with name === null.
|
||||
if (value === null || ((expressionOrValue instanceof Expression || expressionOrValue instanceof Variable) && !expressionOrValue.available)) {
|
||||
dom.addClass(container, 'unavailable');
|
||||
if (value !== Expression.DEFAULT_VALUE) {
|
||||
dom.addClass(container, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
if (options.colorize && typeof expressionOrValue !== 'string') {
|
||||
if (expressionOrValue.type === 'number' || expressionOrValue.type === 'boolean' || expressionOrValue.type === 'string') {
|
||||
dom.addClass(container, expressionOrValue.type);
|
||||
} else if (!isNaN(+value)) {
|
||||
dom.addClass(container, 'number');
|
||||
} else if (booleanRegex.test(value)) {
|
||||
dom.addClass(container, 'boolean');
|
||||
} else if (stringRegex.test(value)) {
|
||||
dom.addClass(container, 'string');
|
||||
}
|
||||
}
|
||||
|
||||
if (options.showChanged && (<any>expressionOrValue).valueChanged && value !== Expression.DEFAULT_VALUE) {
|
||||
// value changed color has priority over other colors.
|
||||
container.className = 'value changed';
|
||||
}
|
||||
|
||||
if (options.maxValueLength && value.length > options.maxValueLength) {
|
||||
value = value.substr(0, options.maxValueLength) + '...';
|
||||
}
|
||||
if (value && !options.preserveWhitespace) {
|
||||
container.textContent = replaceWhitespace(value);
|
||||
} else {
|
||||
container.textContent = value;
|
||||
}
|
||||
if (options.showHover) {
|
||||
container.title = value;
|
||||
}
|
||||
}
|
||||
|
||||
export function renderVariable(tree: ITree, variable: Variable, data: IVariableTemplateData, showChanged: boolean): void {
|
||||
if (variable.available) {
|
||||
data.name.textContent = replaceWhitespace(variable.name);
|
||||
data.name.title = variable.type ? variable.type : variable.name;
|
||||
dom.toggleClass(data.name, 'virtual', !!variable.presentationHint && variable.presentationHint.kind === 'virtual');
|
||||
}
|
||||
|
||||
if (variable.value) {
|
||||
data.name.textContent += variable.name ? ':' : '';
|
||||
renderExpressionValue(variable, data.value, {
|
||||
showChanged,
|
||||
maxValueLength: MAX_VALUE_RENDER_LENGTH_IN_VIEWLET,
|
||||
preserveWhitespace: false,
|
||||
showHover: true,
|
||||
colorize: true
|
||||
});
|
||||
} else {
|
||||
data.value.textContent = '';
|
||||
data.value.title = '';
|
||||
}
|
||||
}
|
||||
|
||||
export interface IRenameBoxOptions {
|
||||
initialValue: string;
|
||||
ariaLabel: string;
|
||||
placeholder?: string;
|
||||
validationOptions?: IInputValidationOptions;
|
||||
}
|
||||
|
||||
export function renderRenameBox(debugService: IDebugService, contextViewService: IContextViewService, themeService: IThemeService, tree: ITree, element: any, container: HTMLElement, options: IRenameBoxOptions): void {
|
||||
let inputBoxContainer = dom.append(container, $('.inputBoxContainer'));
|
||||
let inputBox = new InputBox(inputBoxContainer, contextViewService, {
|
||||
validationOptions: options.validationOptions,
|
||||
placeholder: options.placeholder,
|
||||
ariaLabel: options.ariaLabel
|
||||
});
|
||||
const styler = attachInputBoxStyler(inputBox, themeService);
|
||||
|
||||
inputBox.value = options.initialValue ? options.initialValue : '';
|
||||
inputBox.focus();
|
||||
inputBox.select();
|
||||
|
||||
let disposed = false;
|
||||
const toDispose: IDisposable[] = [inputBox, styler];
|
||||
|
||||
const wrapUp = once((renamed: boolean) => {
|
||||
if (!disposed) {
|
||||
disposed = true;
|
||||
if (element instanceof Expression && renamed && inputBox.value) {
|
||||
debugService.renameWatchExpression(element.getId(), inputBox.value);
|
||||
debugService.getViewModel().setSelectedExpression(undefined);
|
||||
} else if (element instanceof Expression && !element.name) {
|
||||
debugService.removeWatchExpressions(element.getId());
|
||||
debugService.getViewModel().setSelectedExpression(undefined);
|
||||
} else if (element instanceof Variable) {
|
||||
element.errorMessage = null;
|
||||
if (renamed && element.value !== inputBox.value) {
|
||||
element.setVariable(inputBox.value)
|
||||
// if everything went fine we need to refresh ui elements since the variable update can change watch and variables view
|
||||
.done(() => {
|
||||
tree.refresh(element, false);
|
||||
// Need to force watch expressions to update since a variable change can have an effect on watches
|
||||
debugService.focusStackFrame(debugService.getViewModel().focusedStackFrame);
|
||||
}, onUnexpectedError);
|
||||
}
|
||||
}
|
||||
|
||||
tree.DOMFocus();
|
||||
tree.setFocus(element);
|
||||
|
||||
// need to remove the input box since this template will be reused.
|
||||
container.removeChild(inputBoxContainer);
|
||||
dispose(toDispose);
|
||||
}
|
||||
});
|
||||
|
||||
toDispose.push(dom.addStandardDisposableListener(inputBox.inputElement, 'keydown', (e: IKeyboardEvent) => {
|
||||
const isEscape = e.equals(KeyCode.Escape);
|
||||
const isEnter = e.equals(KeyCode.Enter);
|
||||
if (isEscape || isEnter) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
wrapUp(isEnter);
|
||||
}
|
||||
}));
|
||||
toDispose.push(dom.addDisposableListener(inputBox.inputElement, 'blur', () => {
|
||||
wrapUp(true);
|
||||
}));
|
||||
}
|
||||
|
||||
export class BaseDebugController extends WorkbenchTreeController {
|
||||
|
||||
private contributedContextMenu: IMenu;
|
||||
|
||||
constructor(
|
||||
private actionProvider: IActionProvider,
|
||||
menuId: MenuId,
|
||||
options: IControllerOptions,
|
||||
@IDebugService protected debugService: IDebugService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
) {
|
||||
super(options, configurationService);
|
||||
|
||||
this.contributedContextMenu = menuService.createMenu(menuId, contextKeyService);
|
||||
}
|
||||
|
||||
public onContextMenu(tree: ITree, element: IEnablement, event: ContextMenuEvent, focusElement = true): boolean {
|
||||
if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') {
|
||||
return false;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (focusElement) {
|
||||
tree.setFocus(element);
|
||||
}
|
||||
|
||||
if (this.actionProvider.hasSecondaryActions(tree, element)) {
|
||||
const anchor = { x: event.posx, y: event.posy };
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => anchor,
|
||||
getActions: () => this.actionProvider.getSecondaryActions(tree, element).then(actions => {
|
||||
fillInActions(this.contributedContextMenu, { arg: this.getContext(element) }, actions, this.contextMenuService);
|
||||
return actions;
|
||||
}),
|
||||
onHide: (wasCancelled?: boolean) => {
|
||||
if (wasCancelled) {
|
||||
tree.DOMFocus();
|
||||
}
|
||||
},
|
||||
getActionsContext: () => element
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected getContext(element: any): any {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/zoneWidget';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IDebugService, IBreakpoint, IRawBreakpoint } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugService, IBreakpoint } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { attachInputBoxStyler, attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
@@ -71,7 +71,7 @@ export class BreakpointWidget extends ZoneWidget {
|
||||
|
||||
this.hitCountContext = breakpoint && breakpoint.hitCondition && !breakpoint.condition;
|
||||
const selected = this.hitCountContext ? 1 : 0;
|
||||
const selectBox = new SelectBox([nls.localize('expression', "Expression"), nls.localize('hitCount', "Hit Count")], selected);
|
||||
const selectBox = new SelectBox([nls.localize('expression', "Expression"), nls.localize('hitCount', "Hit Count")], selected, this.contextViewService);
|
||||
this.toDispose.push(attachSelectBoxStyler(selectBox, this.themeService));
|
||||
selectBox.render(dom.append(container, $('.breakpoint-select-container')));
|
||||
selectBox.onDidSelect(e => {
|
||||
@@ -109,31 +109,38 @@ export class BreakpointWidget extends ZoneWidget {
|
||||
const oldBreakpoint = this.debugService.getModel().getBreakpoints()
|
||||
.filter(bp => bp.lineNumber === this.lineNumber && bp.column === this.column && bp.uri.toString() === uri.toString()).pop();
|
||||
|
||||
const raw: IRawBreakpoint = {
|
||||
lineNumber: this.lineNumber,
|
||||
column: oldBreakpoint ? oldBreakpoint.column : undefined,
|
||||
enabled: true,
|
||||
condition: oldBreakpoint && oldBreakpoint.condition,
|
||||
hitCondition: oldBreakpoint && oldBreakpoint.hitCondition
|
||||
};
|
||||
let condition = oldBreakpoint && oldBreakpoint.condition;
|
||||
let hitCondition = oldBreakpoint && oldBreakpoint.hitCondition;
|
||||
|
||||
if (this.hitCountContext) {
|
||||
raw.hitCondition = this.inputBox.value;
|
||||
hitCondition = this.inputBox.value;
|
||||
if (this.conditionInput) {
|
||||
raw.condition = this.conditionInput;
|
||||
condition = this.conditionInput;
|
||||
}
|
||||
} else {
|
||||
raw.condition = this.inputBox.value;
|
||||
condition = this.inputBox.value;
|
||||
if (this.hitCountInput) {
|
||||
raw.hitCondition = this.hitCountInput;
|
||||
hitCondition = this.hitCountInput;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldBreakpoint) {
|
||||
this.debugService.removeBreakpoints(oldBreakpoint.getId()).done(null, errors.onUnexpectedError);
|
||||
this.debugService.updateBreakpoints(oldBreakpoint.uri, {
|
||||
[oldBreakpoint.getId()]: {
|
||||
condition,
|
||||
hitCondition,
|
||||
verified: oldBreakpoint.verified
|
||||
}
|
||||
}, false);
|
||||
} else {
|
||||
this.debugService.addBreakpoints(uri, [{
|
||||
lineNumber: this.lineNumber,
|
||||
column: oldBreakpoint ? oldBreakpoint.column : undefined,
|
||||
enabled: true,
|
||||
condition,
|
||||
hitCondition
|
||||
}]).done(null, errors.onUnexpectedError);
|
||||
}
|
||||
|
||||
this.debugService.addBreakpoints(uri, [raw]).done(null, errors.onUnexpectedError);
|
||||
}
|
||||
|
||||
this.dispose();
|
||||
|
||||
617
src/vs/workbench/parts/debug/browser/breakpointsView.ts
Normal file
617
src/vs/workbench/parts/debug/browser/breakpointsView.ts
Normal file
@@ -0,0 +1,617 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINTS_FOCUSED, EDITOR_CONTRIBUTION_ID, State, DEBUG_SCHEME, IFunctionBreakpoint, IExceptionBreakpoint, IEnablement, IDebugEditorContribution } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { AddFunctionBreakpointAction, ToggleBreakpointsActivatedAction, RemoveAllBreakpointsAction, RemoveBreakpointAction, EnableAllBreakpointsAction, DisableAllBreakpointsAction, ReapplyBreakpointsAction } from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { Constants } from 'vs/editor/common/core/uint';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { getPathLabel } from 'vs/base/common/labels';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IDelegate, IListContextMenuEvent, IRenderer } from 'vs/base/browser/ui/list/list';
|
||||
import { IEditorService, IEditor } from 'vs/platform/editor/common/editor';
|
||||
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { WorkbenchList } from 'vs/platform/list/browser/listService';
|
||||
import { ViewsViewletPanel, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
export class BreakpointsView extends ViewsViewletPanel {
|
||||
|
||||
private static readonly MAX_VISIBLE_FILES = 9;
|
||||
private static readonly MEMENTO = 'breakopintsview.memento';
|
||||
private settings: any;
|
||||
private list: WorkbenchList<IEnablement>;
|
||||
private needsRefresh: boolean;
|
||||
|
||||
constructor(
|
||||
options: IViewletViewOptions,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IContextViewService private contextViewService: IContextViewService,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService);
|
||||
|
||||
this.minimumBodySize = this.maximumBodySize = this.getExpandedBodySize();
|
||||
this.settings = options.viewletSettings;
|
||||
this.disposables.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));
|
||||
}
|
||||
|
||||
public renderBody(container: HTMLElement): void {
|
||||
dom.addClass(container, 'debug-breakpoints');
|
||||
const delegate = new BreakpointsDelegate(this.debugService);
|
||||
|
||||
this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [
|
||||
this.instantiationService.createInstance(BreakpointsRenderer),
|
||||
new ExceptionBreakpointsRenderer(this.debugService),
|
||||
this.instantiationService.createInstance(FunctionBreakpointsRenderer),
|
||||
new FunctionBreakpointInputRenderer(this.debugService, this.contextViewService, this.themeService)
|
||||
], {
|
||||
identityProvider: element => element.getId(),
|
||||
multipleSelectionSupport: false
|
||||
}) as WorkbenchList<IEnablement>;
|
||||
|
||||
CONTEXT_BREAKPOINTS_FOCUSED.bindTo(this.list.contextKeyService);
|
||||
|
||||
this.list.onContextMenu(this.onListContextMenu, this, this.disposables);
|
||||
|
||||
this.disposables.push(this.list.onOpen(e => {
|
||||
let isSingleClick = false;
|
||||
let isDoubleClick = false;
|
||||
let openToSide = false;
|
||||
|
||||
const browserEvent = e.browserEvent;
|
||||
if (browserEvent instanceof MouseEvent) {
|
||||
isSingleClick = browserEvent.detail === 1;
|
||||
isDoubleClick = browserEvent.detail === 2;
|
||||
openToSide = (browserEvent.ctrlKey || browserEvent.metaKey || browserEvent.altKey);
|
||||
}
|
||||
|
||||
const focused = this.list.getFocusedElements();
|
||||
const element = focused.length ? focused[0] : undefined;
|
||||
if (element instanceof Breakpoint) {
|
||||
openBreakpointSource(element, openToSide, isSingleClick, this.debugService, this.editorService).done(undefined, onUnexpectedError);
|
||||
}
|
||||
if (isDoubleClick && element instanceof FunctionBreakpoint && element !== this.debugService.getViewModel().getSelectedFunctionBreakpoint()) {
|
||||
this.debugService.getViewModel().setSelectedFunctionBreakpoint(element);
|
||||
this.onBreakpointsChange();
|
||||
}
|
||||
}));
|
||||
|
||||
this.list.splice(0, this.list.length, this.elements);
|
||||
}
|
||||
|
||||
protected layoutBody(size: number): void {
|
||||
if (this.list) {
|
||||
this.list.layout(size);
|
||||
}
|
||||
}
|
||||
|
||||
private onListContextMenu(e: IListContextMenuEvent<IEnablement>): void {
|
||||
const actions: IAction[] = [];
|
||||
const element = e.element;
|
||||
|
||||
if (element instanceof Breakpoint || element instanceof FunctionBreakpoint) {
|
||||
actions.push(new Action('workbench.action.debug.openEditorAndEditBreakpoint', nls.localize('editConditionalBreakpoint', "Edit Breakpoint..."), undefined, true, () => {
|
||||
if (element instanceof Breakpoint) {
|
||||
return openBreakpointSource(element, false, false, this.debugService, this.editorService).then(editor => {
|
||||
const codeEditor = editor.getControl();
|
||||
if (isCodeEditor(codeEditor)) {
|
||||
codeEditor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID).showBreakpointWidget(element.lineNumber, element.column);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.debugService.getViewModel().setSelectedFunctionBreakpoint(element);
|
||||
this.onBreakpointsChange();
|
||||
return undefined;
|
||||
}));
|
||||
actions.push(new Separator());
|
||||
}
|
||||
|
||||
actions.push(new RemoveBreakpointAction(RemoveBreakpointAction.ID, RemoveBreakpointAction.LABEL, this.debugService, this.keybindingService));
|
||||
|
||||
|
||||
if (this.debugService.getModel().getBreakpoints().length + this.debugService.getModel().getFunctionBreakpoints().length > 1) {
|
||||
actions.push(new RemoveAllBreakpointsAction(RemoveAllBreakpointsAction.ID, RemoveAllBreakpointsAction.LABEL, this.debugService, this.keybindingService));
|
||||
actions.push(new Separator());
|
||||
|
||||
actions.push(new EnableAllBreakpointsAction(EnableAllBreakpointsAction.ID, EnableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService));
|
||||
actions.push(new DisableAllBreakpointsAction(DisableAllBreakpointsAction.ID, DisableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService));
|
||||
}
|
||||
|
||||
actions.push(new Separator());
|
||||
actions.push(new ReapplyBreakpointsAction(ReapplyBreakpointsAction.ID, ReapplyBreakpointsAction.LABEL, this.debugService, this.keybindingService));
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => e.anchor,
|
||||
getActions: () => TPromise.as(actions),
|
||||
getActionsContext: () => element
|
||||
});
|
||||
}
|
||||
|
||||
public getActions(): IAction[] {
|
||||
return [
|
||||
new AddFunctionBreakpointAction(AddFunctionBreakpointAction.ID, AddFunctionBreakpointAction.LABEL, this.debugService, this.keybindingService),
|
||||
new ToggleBreakpointsActivatedAction(ToggleBreakpointsActivatedAction.ID, ToggleBreakpointsActivatedAction.ACTIVATE_LABEL, this.debugService, this.keybindingService),
|
||||
new RemoveAllBreakpointsAction(RemoveAllBreakpointsAction.ID, RemoveAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)
|
||||
];
|
||||
}
|
||||
|
||||
public setExpanded(expanded: boolean): void {
|
||||
super.setExpanded(expanded);
|
||||
if (expanded && this.needsRefresh) {
|
||||
this.onBreakpointsChange();
|
||||
}
|
||||
}
|
||||
|
||||
public setVisible(visible: boolean): TPromise<void> {
|
||||
return super.setVisible(visible).then(() => {
|
||||
if (visible && this.needsRefresh) {
|
||||
this.onBreakpointsChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private onBreakpointsChange(): void {
|
||||
if (this.isExpanded() && this.isVisible()) {
|
||||
this.minimumBodySize = this.getExpandedBodySize();
|
||||
if (this.maximumBodySize < Number.POSITIVE_INFINITY) {
|
||||
this.maximumBodySize = this.minimumBodySize;
|
||||
}
|
||||
if (this.list) {
|
||||
this.list.splice(0, this.list.length, this.elements);
|
||||
this.needsRefresh = false;
|
||||
}
|
||||
} else {
|
||||
this.needsRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
private get elements(): IEnablement[] {
|
||||
const model = this.debugService.getModel();
|
||||
const elements = (<IEnablement[]>model.getExceptionBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getBreakpoints());
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
private getExpandedBodySize(): number {
|
||||
const model = this.debugService.getModel();
|
||||
const length = model.getBreakpoints().length + model.getExceptionBreakpoints().length + model.getFunctionBreakpoints().length;
|
||||
return Math.min(BreakpointsView.MAX_VISIBLE_FILES, length) * 22;
|
||||
}
|
||||
|
||||
public shutdown(): void {
|
||||
this.settings[BreakpointsView.MEMENTO] = !this.isExpanded();
|
||||
}
|
||||
}
|
||||
|
||||
class BreakpointsDelegate implements IDelegate<IEnablement> {
|
||||
|
||||
constructor(private debugService: IDebugService) {
|
||||
// noop
|
||||
}
|
||||
|
||||
getHeight(element: IEnablement): number {
|
||||
return 22;
|
||||
}
|
||||
|
||||
getTemplateId(element: IEnablement): string {
|
||||
if (element instanceof Breakpoint) {
|
||||
return BreakpointsRenderer.ID;
|
||||
}
|
||||
if (element instanceof FunctionBreakpoint) {
|
||||
const selected = this.debugService.getViewModel().getSelectedFunctionBreakpoint();
|
||||
if (!element.name || (selected && selected.getId() === element.getId())) {
|
||||
return FunctionBreakpointInputRenderer.ID;
|
||||
}
|
||||
|
||||
return FunctionBreakpointsRenderer.ID;
|
||||
}
|
||||
if (element instanceof ExceptionBreakpoint) {
|
||||
return ExceptionBreakpointsRenderer.ID;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface IBaseBreakpointTemplateData {
|
||||
breakpoint: HTMLElement;
|
||||
name: HTMLElement;
|
||||
checkbox: HTMLInputElement;
|
||||
context: IEnablement;
|
||||
toDispose: IDisposable[];
|
||||
}
|
||||
|
||||
interface IBaseBreakpointWithIconTemplateData extends IBaseBreakpointTemplateData {
|
||||
icon: HTMLElement;
|
||||
}
|
||||
|
||||
interface IBreakpointTemplateData extends IBaseBreakpointWithIconTemplateData {
|
||||
lineNumber: HTMLElement;
|
||||
filePath: HTMLElement;
|
||||
}
|
||||
|
||||
interface IInputTemplateData {
|
||||
inputBox: InputBox;
|
||||
breakpoint: IFunctionBreakpoint;
|
||||
reactedOnEvent: boolean;
|
||||
toDispose: IDisposable[];
|
||||
}
|
||||
|
||||
class BreakpointsRenderer implements IRenderer<IBreakpoint, IBreakpointTemplateData> {
|
||||
|
||||
constructor(
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@ITextFileService private textFileService: ITextFileService
|
||||
) {
|
||||
// noop
|
||||
}
|
||||
|
||||
static readonly ID = 'breakpoints';
|
||||
|
||||
get templateId() {
|
||||
return BreakpointsRenderer.ID;
|
||||
}
|
||||
|
||||
renderTemplate(container: HTMLElement): IBreakpointTemplateData {
|
||||
const data: IBreakpointTemplateData = Object.create(null);
|
||||
data.breakpoint = dom.append(container, $('.breakpoint'));
|
||||
|
||||
data.icon = $('.icon');
|
||||
data.checkbox = <HTMLInputElement>$('input');
|
||||
data.checkbox.type = 'checkbox';
|
||||
data.toDispose = [];
|
||||
data.toDispose.push(dom.addStandardDisposableListener(data.checkbox, 'change', (e) => {
|
||||
this.debugService.enableOrDisableBreakpoints(!data.context.enabled, data.context);
|
||||
}));
|
||||
|
||||
dom.append(data.breakpoint, data.icon);
|
||||
dom.append(data.breakpoint, data.checkbox);
|
||||
|
||||
data.name = dom.append(data.breakpoint, $('span.name'));
|
||||
|
||||
data.filePath = dom.append(data.breakpoint, $('span.file-path'));
|
||||
const lineNumberContainer = dom.append(data.breakpoint, $('.line-number-container'));
|
||||
data.lineNumber = dom.append(lineNumberContainer, $('span.line-number'));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
renderElement(breakpoint: IBreakpoint, index: number, data: IBreakpointTemplateData): void {
|
||||
data.context = breakpoint;
|
||||
dom.toggleClass(data.breakpoint, 'disabled', !this.debugService.getModel().areBreakpointsActivated());
|
||||
|
||||
data.name.textContent = basename(getPathLabel(breakpoint.uri, this.contextService));
|
||||
data.lineNumber.textContent = breakpoint.lineNumber.toString();
|
||||
if (breakpoint.column) {
|
||||
data.lineNumber.textContent += `:${breakpoint.column}`;
|
||||
}
|
||||
data.filePath.textContent = getPathLabel(resources.dirname(breakpoint.uri), this.contextService, this.environmentService);
|
||||
data.checkbox.checked = breakpoint.enabled;
|
||||
|
||||
const { message, className } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, breakpoint);
|
||||
data.icon.className = className + ' icon';
|
||||
data.icon.title = message ? message : '';
|
||||
|
||||
const debugActive = this.debugService.state === State.Running || this.debugService.state === State.Stopped;
|
||||
if (debugActive && !breakpoint.verified) {
|
||||
dom.addClass(data.breakpoint, 'disabled');
|
||||
if (breakpoint.message) {
|
||||
data.breakpoint.title = breakpoint.message;
|
||||
}
|
||||
} else if (breakpoint.condition || breakpoint.hitCondition) {
|
||||
data.breakpoint.title = breakpoint.condition ? breakpoint.condition : breakpoint.hitCondition;
|
||||
}
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IBreakpointTemplateData): void {
|
||||
dispose(templateData.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
class ExceptionBreakpointsRenderer implements IRenderer<IExceptionBreakpoint, IBaseBreakpointTemplateData> {
|
||||
|
||||
constructor(
|
||||
private debugService: IDebugService
|
||||
) {
|
||||
// noop
|
||||
}
|
||||
|
||||
static readonly ID = 'exceptionbreakpoints';
|
||||
|
||||
get templateId() {
|
||||
return ExceptionBreakpointsRenderer.ID;
|
||||
}
|
||||
|
||||
renderTemplate(container: HTMLElement): IBaseBreakpointTemplateData {
|
||||
const data: IBreakpointTemplateData = Object.create(null);
|
||||
data.breakpoint = dom.append(container, $('.breakpoint'));
|
||||
|
||||
data.checkbox = <HTMLInputElement>$('input');
|
||||
data.checkbox.type = 'checkbox';
|
||||
data.toDispose = [];
|
||||
data.toDispose.push(dom.addStandardDisposableListener(data.checkbox, 'change', (e) => {
|
||||
this.debugService.enableOrDisableBreakpoints(!data.context.enabled, data.context);
|
||||
}));
|
||||
|
||||
dom.append(data.breakpoint, data.checkbox);
|
||||
|
||||
data.name = dom.append(data.breakpoint, $('span.name'));
|
||||
dom.addClass(data.breakpoint, 'exception');
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
renderElement(exceptionBreakpoint: IExceptionBreakpoint, index: number, data: IBaseBreakpointTemplateData): void {
|
||||
data.context = exceptionBreakpoint;
|
||||
data.name.textContent = exceptionBreakpoint.label || `${exceptionBreakpoint.filter} exceptions`;
|
||||
data.breakpoint.title = data.name.textContent;
|
||||
data.checkbox.checked = exceptionBreakpoint.enabled;
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IBaseBreakpointTemplateData): void {
|
||||
dispose(templateData.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionBreakpointsRenderer implements IRenderer<FunctionBreakpoint, IBaseBreakpointWithIconTemplateData> {
|
||||
|
||||
constructor(
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@ITextFileService private textFileService: ITextFileService
|
||||
) {
|
||||
// noop
|
||||
}
|
||||
|
||||
static readonly ID = 'functionbreakpoints';
|
||||
|
||||
get templateId() {
|
||||
return FunctionBreakpointsRenderer.ID;
|
||||
}
|
||||
|
||||
renderTemplate(container: HTMLElement): IBaseBreakpointWithIconTemplateData {
|
||||
const data: IBreakpointTemplateData = Object.create(null);
|
||||
data.breakpoint = dom.append(container, $('.breakpoint'));
|
||||
|
||||
data.icon = $('.icon');
|
||||
data.checkbox = <HTMLInputElement>$('input');
|
||||
data.checkbox.type = 'checkbox';
|
||||
data.toDispose = [];
|
||||
data.toDispose.push(dom.addStandardDisposableListener(data.checkbox, 'change', (e) => {
|
||||
this.debugService.enableOrDisableBreakpoints(!data.context.enabled, data.context);
|
||||
}));
|
||||
|
||||
dom.append(data.breakpoint, data.icon);
|
||||
dom.append(data.breakpoint, data.checkbox);
|
||||
|
||||
data.name = dom.append(data.breakpoint, $('span.name'));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
renderElement(functionBreakpoint: FunctionBreakpoint, index: number, data: IBaseBreakpointWithIconTemplateData): void {
|
||||
data.context = functionBreakpoint;
|
||||
data.name.textContent = functionBreakpoint.name;
|
||||
const { className, message } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, functionBreakpoint);
|
||||
data.icon.className = className + ' icon';
|
||||
data.icon.title = message ? message : '';
|
||||
data.checkbox.checked = functionBreakpoint.enabled;
|
||||
data.breakpoint.title = functionBreakpoint.name;
|
||||
|
||||
// Mark function breakpoints as disabled if deactivated or if debug type does not support them #9099
|
||||
const process = this.debugService.getViewModel().focusedProcess;
|
||||
dom.toggleClass(data.breakpoint, 'disalbed', (process && !process.session.capabilities.supportsFunctionBreakpoints) || !this.debugService.getModel().areBreakpointsActivated());
|
||||
if (process && !process.session.capabilities.supportsFunctionBreakpoints) {
|
||||
data.breakpoint.title = nls.localize('functionBreakpointsNotSupported', "Function breakpoints are not supported by this debug type");
|
||||
}
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IBaseBreakpointWithIconTemplateData): void {
|
||||
dispose(templateData.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionBreakpointInputRenderer implements IRenderer<IFunctionBreakpoint, IInputTemplateData> {
|
||||
|
||||
constructor(
|
||||
private debugService: IDebugService,
|
||||
private contextViewService: IContextViewService,
|
||||
private themeService: IThemeService
|
||||
) {
|
||||
// noop
|
||||
}
|
||||
|
||||
static readonly ID = 'functionbreakpointinput';
|
||||
|
||||
get templateId() {
|
||||
return FunctionBreakpointInputRenderer.ID;
|
||||
}
|
||||
|
||||
renderTemplate(container: HTMLElement): IInputTemplateData {
|
||||
const template: IInputTemplateData = Object.create(null);
|
||||
const inputBoxContainer = dom.append(container, $('.inputBoxContainer'));
|
||||
const inputBox = new InputBox(inputBoxContainer, this.contextViewService, {
|
||||
placeholder: nls.localize('functionBreakpointPlaceholder', "Function to break on"),
|
||||
ariaLabel: nls.localize('functionBreakPointInputAriaLabel', "Type function breakpoint")
|
||||
});
|
||||
const styler = attachInputBoxStyler(inputBox, this.themeService);
|
||||
const toDispose: IDisposable[] = [inputBox, styler];
|
||||
|
||||
const wrapUp = (renamed: boolean) => {
|
||||
if (!template.reactedOnEvent) {
|
||||
template.reactedOnEvent = true;
|
||||
this.debugService.getViewModel().setSelectedFunctionBreakpoint(undefined);
|
||||
if (inputBox.value && (renamed || template.breakpoint.name)) {
|
||||
this.debugService.renameFunctionBreakpoint(template.breakpoint.getId(), renamed ? inputBox.value : template.breakpoint.name).done(null, onUnexpectedError);
|
||||
} else {
|
||||
this.debugService.removeFunctionBreakpoints(template.breakpoint.getId()).done(null, onUnexpectedError);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(dom.addStandardDisposableListener(inputBox.inputElement, 'keydown', (e: IKeyboardEvent) => {
|
||||
const isEscape = e.equals(KeyCode.Escape);
|
||||
const isEnter = e.equals(KeyCode.Enter);
|
||||
if (isEscape || isEnter) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
wrapUp(isEnter);
|
||||
}
|
||||
}));
|
||||
toDispose.push(dom.addDisposableListener(inputBox.inputElement, 'blur', () => {
|
||||
if (!template.breakpoint.name) {
|
||||
wrapUp(true);
|
||||
}
|
||||
}));
|
||||
|
||||
template.inputBox = inputBox;
|
||||
template.toDispose = toDispose;
|
||||
return template;
|
||||
}
|
||||
|
||||
renderElement(functionBreakpoint: IFunctionBreakpoint, index: number, data: IInputTemplateData): void {
|
||||
data.breakpoint = functionBreakpoint;
|
||||
data.reactedOnEvent = false;
|
||||
data.inputBox.value = functionBreakpoint.name || '';
|
||||
data.inputBox.focus();
|
||||
data.inputBox.select();
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IInputTemplateData): void {
|
||||
dispose(templateData.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
export function openBreakpointSource(breakpoint: Breakpoint, sideBySide: boolean, preserveFocus: boolean, debugService: IDebugService, editorService: IEditorService): TPromise<IEditor> {
|
||||
if (breakpoint.uri.scheme === DEBUG_SCHEME && debugService.state === State.Inactive) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
const selection = breakpoint.endLineNumber ? {
|
||||
startLineNumber: breakpoint.lineNumber,
|
||||
endLineNumber: breakpoint.endLineNumber,
|
||||
startColumn: breakpoint.column,
|
||||
endColumn: breakpoint.endColumn
|
||||
} : {
|
||||
startLineNumber: breakpoint.lineNumber,
|
||||
startColumn: breakpoint.column || 1,
|
||||
endLineNumber: breakpoint.lineNumber,
|
||||
endColumn: breakpoint.column || Constants.MAX_SAFE_SMALL_INTEGER
|
||||
};
|
||||
|
||||
return editorService.openEditor({
|
||||
resource: breakpoint.uri,
|
||||
options: {
|
||||
preserveFocus,
|
||||
selection,
|
||||
revealIfVisible: true,
|
||||
revealInCenterIfOutsideViewport: true,
|
||||
pinned: !preserveFocus
|
||||
}
|
||||
}, sideBySide);
|
||||
}
|
||||
|
||||
export function getBreakpointMessageAndClassName(debugService: IDebugService, textFileService: ITextFileService, breakpoint: IBreakpoint | FunctionBreakpoint): { message?: string, className: string } {
|
||||
const state = debugService.state;
|
||||
const debugActive = state === State.Running || state === State.Stopped;
|
||||
|
||||
if (!breakpoint.enabled || !debugService.getModel().areBreakpointsActivated()) {
|
||||
return {
|
||||
className: breakpoint instanceof FunctionBreakpoint ? 'debug-function-breakpoint-disabled' : 'debug-breakpoint-disabled',
|
||||
message: nls.localize('breakpointDisabledHover', "Disabled breakpoint"),
|
||||
};
|
||||
}
|
||||
|
||||
const appendMessage = (text: string): string => {
|
||||
return !(breakpoint instanceof FunctionBreakpoint) && breakpoint.message ? text.concat(', ' + breakpoint.message) : text;
|
||||
};
|
||||
if (debugActive && !breakpoint.verified) {
|
||||
return {
|
||||
className: breakpoint instanceof FunctionBreakpoint ? 'debug-function-breakpoint-unverified' : 'debug-breakpoint-unverified',
|
||||
message: appendMessage(nls.localize('breakpointUnverifieddHover', "Unverified breakpoint")),
|
||||
};
|
||||
}
|
||||
|
||||
const process = debugService.getViewModel().focusedProcess;
|
||||
if (breakpoint instanceof FunctionBreakpoint) {
|
||||
if (process && !process.session.capabilities.supportsFunctionBreakpoints) {
|
||||
return {
|
||||
className: 'debug-function-breakpoint-unverified',
|
||||
message: nls.localize('functionBreakpointUnsupported', "Function breakpoints not supported by this debug type"),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
className: 'debug-function-breakpoint',
|
||||
};
|
||||
}
|
||||
|
||||
if (debugActive && textFileService.isDirty(breakpoint.uri)) {
|
||||
return {
|
||||
className: 'debug-breakpoint-unverified',
|
||||
message: appendMessage(nls.localize('breakpointDirtydHover', "Unverified breakpoint. File is modified, please restart debug session.")),
|
||||
};
|
||||
}
|
||||
|
||||
if (breakpoint.condition || breakpoint.hitCondition) {
|
||||
if (process && breakpoint.condition && !process.session.capabilities.supportsConditionalBreakpoints) {
|
||||
return {
|
||||
className: 'debug-breakpoint-unsupported',
|
||||
message: nls.localize('conditionalBreakpointUnsupported', "Conditional breakpoints not supported by this debug type"),
|
||||
};
|
||||
}
|
||||
if (process && breakpoint.hitCondition && !process.session.capabilities.supportsHitConditionalBreakpoints) {
|
||||
return {
|
||||
className: 'debug-breakpoint-unsupported',
|
||||
message: nls.localize('hitBreakpointUnsupported', "Hit conditional breakpoints not supported by this debug type"),
|
||||
};
|
||||
}
|
||||
|
||||
if (breakpoint.condition && breakpoint.hitCondition) {
|
||||
return {
|
||||
className: 'debug-breakpoint-conditional',
|
||||
message: appendMessage(`Expression: ${breakpoint.condition}\nHitCount: ${breakpoint.hitCondition}`)
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
className: 'debug-breakpoint-conditional',
|
||||
message: appendMessage(breakpoint.condition ? breakpoint.condition : breakpoint.hitCondition)
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
className: 'debug-breakpoint',
|
||||
message: breakpoint.message
|
||||
};
|
||||
}
|
||||
@@ -19,6 +19,8 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { selectBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -40,10 +42,12 @@ export class StartDebugActionItem implements IActionItem {
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private commandService: ICommandService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
) {
|
||||
this.toDispose = [];
|
||||
this.selectBox = new SelectBox([], -1);
|
||||
this.selectBox = new SelectBox([], -1, contextViewService);
|
||||
this.toDispose.push(attachSelectBoxStyler(this.selectBox, themeService, {
|
||||
selectBackground: SIDE_BAR_BACKGROUND
|
||||
}));
|
||||
@@ -151,12 +155,13 @@ export class StartDebugActionItem implements IActionItem {
|
||||
this.options = [];
|
||||
const manager = this.debugService.getConfigurationManager();
|
||||
const launches = manager.getLaunches();
|
||||
manager.getLaunches().forEach(launch =>
|
||||
const inWorkspace = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE;
|
||||
launches.forEach(launch =>
|
||||
launch.getConfigurationNames().forEach(name => {
|
||||
if (name === manager.selectedName && launch === manager.selectedLaunch) {
|
||||
if (name === manager.selectedConfiguration.name && launch === manager.selectedConfiguration.launch) {
|
||||
this.selected = this.options.length;
|
||||
}
|
||||
const label = launches.length > 1 ? `${name} (${launch.workspace.name})` : name;
|
||||
const label = inWorkspace ? `${name} (${launch.name})` : name;
|
||||
this.options.push({ label, handler: () => { manager.selectConfiguration(launch, name); return true; } });
|
||||
}));
|
||||
|
||||
@@ -166,11 +171,11 @@ export class StartDebugActionItem implements IActionItem {
|
||||
this.options.push({ label: StartDebugActionItem.SEPARATOR, handler: undefined });
|
||||
|
||||
const disabledIdx = this.options.length - 1;
|
||||
launches.forEach(l => {
|
||||
const label = launches.length > 1 ? nls.localize("addConfigTo", "Add Config ({0})...", l.workspace.name) : nls.localize('addConfiguration', "Add Configuration...");
|
||||
launches.filter(l => !l.hidden).forEach(l => {
|
||||
const label = inWorkspace ? nls.localize("addConfigTo", "Add Config ({0})...", l.name) : nls.localize('addConfiguration', "Add Configuration...");
|
||||
this.options.push({
|
||||
label, handler: () => {
|
||||
this.commandService.executeCommand('debug.addConfiguration', l.workspace.uri.toString()).done(undefined, errors.onUnexpectedError);
|
||||
this.commandService.executeCommand('debug.addConfiguration', l.uri.toString()).done(undefined, errors.onUnexpectedError);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@@ -184,9 +189,10 @@ export class FocusProcessActionItem extends SelectActionItem {
|
||||
constructor(
|
||||
action: IAction,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IThemeService themeService: IThemeService
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextViewService contextViewService: IContextViewService
|
||||
) {
|
||||
super(null, action, [], -1);
|
||||
super(null, action, [], -1, contextViewService);
|
||||
|
||||
this.toDispose.push(attachSelectBoxStyler(this.selectBox, themeService));
|
||||
|
||||
|
||||
@@ -6,14 +6,12 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import * as lifecycle from 'vs/base/common/lifecycle';
|
||||
import severity from 'vs/base/common/severity';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IDebugService, State, IProcess, IThread, IEnablement, IBreakpoint, IStackFrame, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, IExpression, REPL_ID, ProcessState }
|
||||
from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Variable, Expression, Thread, Breakpoint, Process } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
@@ -22,6 +20,9 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { TogglePanelAction } from 'vs/workbench/browser/panel';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { CollapseAction } from 'vs/workbench/browser/viewlet';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
|
||||
export abstract class AbstractDebugAction extends Action {
|
||||
|
||||
@@ -71,13 +72,14 @@ export abstract class AbstractDebugAction extends Action {
|
||||
}
|
||||
|
||||
export class ConfigureAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.configure';
|
||||
static readonly ID = 'workbench.action.debug.configure';
|
||||
static LABEL = nls.localize('openLaunchJson', "Open {0}", 'launch.json');
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IDebugService debugService: IDebugService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IMessageService private messageService: IMessageService
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
||||
) {
|
||||
super(id, label, 'debug-action configure', debugService, keybindingService);
|
||||
this.toDispose.push(debugService.getConfigurationManager().onDidSelectConfiguration(() => this.updateClass()));
|
||||
@@ -85,7 +87,7 @@ export class ConfigureAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
public get tooltip(): string {
|
||||
if (this.debugService.getConfigurationManager().selectedName) {
|
||||
if (this.debugService.getConfigurationManager().selectedConfiguration.name) {
|
||||
return ConfigureAction.LABEL;
|
||||
}
|
||||
|
||||
@@ -93,17 +95,17 @@ export class ConfigureAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
private updateClass(): void {
|
||||
this.class = this.debugService.getConfigurationManager().selectedName ? 'debug-action configure' : 'debug-action configure notification';
|
||||
this.class = this.debugService.getConfigurationManager().selectedConfiguration.name ? 'debug-action configure' : 'debug-action configure notification';
|
||||
}
|
||||
|
||||
public run(event?: any): TPromise<any> {
|
||||
if (!this.debugService.getConfigurationManager().selectedLaunch) {
|
||||
this.messageService.show(severity.Info, nls.localize('noFolderDebugConfig', "Please first open a folder in order to do advanced debug configuration."));
|
||||
if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
|
||||
this.notificationService.info(nls.localize('noFolderDebugConfig', "Please first open a folder in order to do advanced debug configuration."));
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
const sideBySide = !!(event && (event.ctrlKey || event.metaKey));
|
||||
return this.debugService.getConfigurationManager().selectedLaunch.openConfigFile(sideBySide);
|
||||
return this.debugService.getConfigurationManager().selectedConfiguration.launch.openConfigFile(sideBySide);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,8 +126,8 @@ export class StartAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
const launch = this.debugService.getConfigurationManager().selectedLaunch;
|
||||
return this.debugService.startDebugging(launch ? launch.workspace : undefined, undefined, this.isNoDebug());
|
||||
const launch = this.debugService.getConfigurationManager().selectedConfiguration.launch;
|
||||
return this.debugService.startDebugging(launch, undefined, this.isNoDebug());
|
||||
}
|
||||
|
||||
protected isNoDebug(): boolean {
|
||||
@@ -134,7 +136,7 @@ export class StartAction extends AbstractDebugAction {
|
||||
|
||||
public static isEnabled(debugService: IDebugService, contextService: IWorkspaceContextService, configName: string) {
|
||||
const processes = debugService.getModel().getProcesses();
|
||||
const launch = debugService.getConfigurationManager().selectedLaunch;
|
||||
const launch = debugService.getConfigurationManager().selectedConfiguration.launch;
|
||||
|
||||
if (debugService.state === State.Initializing) {
|
||||
return false;
|
||||
@@ -142,7 +144,7 @@ export class StartAction extends AbstractDebugAction {
|
||||
if (contextService && contextService.getWorkbenchState() === WorkbenchState.EMPTY && processes.length > 0) {
|
||||
return false;
|
||||
}
|
||||
if (processes.some(p => p.getName(false) === configName && (!launch || p.session.root.uri.toString() === launch.workspace.uri.toString()))) {
|
||||
if (processes.some(p => p.getName(false) === configName && (!launch || !launch.workspace || !p.session.root || p.session.root.uri.toString() === launch.workspace.uri.toString()))) {
|
||||
return false;
|
||||
}
|
||||
const compound = launch && launch.getCompound(configName);
|
||||
@@ -155,12 +157,12 @@ export class StartAction extends AbstractDebugAction {
|
||||
|
||||
// Disabled if the launch drop down shows the launch config that is already running.
|
||||
protected isEnabled(state: State): boolean {
|
||||
return StartAction.isEnabled(this.debugService, this.contextService, this.debugService.getConfigurationManager().selectedName);
|
||||
return StartAction.isEnabled(this.debugService, this.contextService, this.debugService.getConfigurationManager().selectedConfiguration.name);
|
||||
}
|
||||
}
|
||||
|
||||
export class RunAction extends StartAction {
|
||||
static ID = 'workbench.action.debug.run';
|
||||
static readonly ID = 'workbench.action.debug.run';
|
||||
static LABEL = nls.localize('startWithoutDebugging', "Start Without Debugging");
|
||||
|
||||
protected isNoDebug(): boolean {
|
||||
@@ -169,7 +171,7 @@ export class RunAction extends StartAction {
|
||||
}
|
||||
|
||||
export class SelectAndStartAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.selectandstart';
|
||||
static readonly ID = 'workbench.action.debug.selectandstart';
|
||||
static LABEL = nls.localize('selectAndStartDebugging', "Select and Start Debugging");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -190,7 +192,7 @@ export class SelectAndStartAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class RestartAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.restart';
|
||||
static readonly ID = 'workbench.action.debug.restart';
|
||||
static LABEL = nls.localize('restartDebug', "Restart");
|
||||
static RECONNECT_LABEL = nls.localize('reconnectDebug', "Reconnect");
|
||||
|
||||
@@ -224,7 +226,7 @@ export class RestartAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class StepOverAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.stepOver';
|
||||
static readonly ID = 'workbench.action.debug.stepOver';
|
||||
static LABEL = nls.localize('stepOverDebug', "Step Over");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -245,7 +247,7 @@ export class StepOverAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class StepIntoAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.stepInto';
|
||||
static readonly ID = 'workbench.action.debug.stepInto';
|
||||
static LABEL = nls.localize('stepIntoDebug', "Step Into");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -266,7 +268,7 @@ export class StepIntoAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class StepOutAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.stepOut';
|
||||
static readonly ID = 'workbench.action.debug.stepOut';
|
||||
static LABEL = nls.localize('stepOutDebug', "Step Out");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -287,7 +289,7 @@ export class StepOutAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class StopAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.stop';
|
||||
static readonly ID = 'workbench.action.debug.stop';
|
||||
static LABEL = nls.localize('stopDebug', "Stop");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -308,7 +310,7 @@ export class StopAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class DisconnectAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.disconnect';
|
||||
static readonly ID = 'workbench.action.debug.disconnect';
|
||||
static LABEL = nls.localize('disconnectDebug', "Disconnect");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -326,7 +328,7 @@ export class DisconnectAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class ContinueAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.continue';
|
||||
static readonly ID = 'workbench.action.debug.continue';
|
||||
static LABEL = nls.localize('continueDebug', "Continue");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -347,7 +349,7 @@ export class ContinueAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class PauseAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.pause';
|
||||
static readonly ID = 'workbench.action.debug.pause';
|
||||
static LABEL = nls.localize('pauseDebug', "Pause");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -368,7 +370,7 @@ export class PauseAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class RestartFrameAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.restartFrame';
|
||||
static readonly ID = 'workbench.action.debug.restartFrame';
|
||||
static LABEL = nls.localize('restartFrame', "Restart Frame");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -385,7 +387,7 @@ export class RestartFrameAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class RemoveBreakpointAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.removeBreakpoint';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.removeBreakpoint';
|
||||
static LABEL = nls.localize('removeBreakpoint', "Remove Breakpoint");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -399,7 +401,7 @@ export class RemoveBreakpointAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class RemoveAllBreakpointsAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.removeAllBreakpoints';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.removeAllBreakpoints';
|
||||
static LABEL = nls.localize('removeAllBreakpoints', "Remove All Breakpoints");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -418,7 +420,7 @@ export class RemoveAllBreakpointsAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class EnableBreakpointAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.enableBreakpoint';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.enableBreakpoint';
|
||||
static LABEL = nls.localize('enableBreakpoint', "Enable Breakpoint");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -431,7 +433,7 @@ export class EnableBreakpointAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class DisableBreakpointAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.disableBreakpoint';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.disableBreakpoint';
|
||||
static LABEL = nls.localize('disableBreakpoint', "Disable Breakpoint");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -444,7 +446,7 @@ export class DisableBreakpointAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class EnableAllBreakpointsAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.enableAllBreakpoints';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.enableAllBreakpoints';
|
||||
static LABEL = nls.localize('enableAllBreakpoints', "Enable All Breakpoints");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -463,7 +465,7 @@ export class EnableAllBreakpointsAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class DisableAllBreakpointsAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.disableAllBreakpoints';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.disableAllBreakpoints';
|
||||
static LABEL = nls.localize('disableAllBreakpoints', "Disable All Breakpoints");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -482,7 +484,7 @@ export class DisableAllBreakpointsAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class ToggleBreakpointsActivatedAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.toggleBreakpointsActivatedAction';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.toggleBreakpointsActivatedAction';
|
||||
static ACTIVATE_LABEL = nls.localize('activateBreakpoints', "Activate Breakpoints");
|
||||
static DEACTIVATE_LABEL = nls.localize('deactivateBreakpoints', "Deactivate Breakpoints");
|
||||
|
||||
@@ -506,7 +508,7 @@ export class ToggleBreakpointsActivatedAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class ReapplyBreakpointsAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.reapplyBreakpointsAction';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.reapplyBreakpointsAction';
|
||||
static LABEL = nls.localize('reapplyAllBreakpoints', "Reapply All Breakpoints");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -526,7 +528,7 @@ export class ReapplyBreakpointsAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class AddFunctionBreakpointAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.addFunctionBreakpointAction';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.addFunctionBreakpointAction';
|
||||
static LABEL = nls.localize('addFunctionBreakpoint', "Add Function Breakpoint");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -546,7 +548,7 @@ export class AddFunctionBreakpointAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class AddConditionalBreakpointAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.addConditionalBreakpointAction';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.addConditionalBreakpointAction';
|
||||
static LABEL = nls.localize('addConditionalBreakpoint', "Add Conditional Breakpoint...");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -565,7 +567,7 @@ export class AddConditionalBreakpointAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class EditConditionalBreakpointAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.editConditionalBreakpointAction';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.editConditionalBreakpointAction';
|
||||
static LABEL = nls.localize('editConditionalBreakpoint', "Edit Breakpoint...");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -584,7 +586,7 @@ export class EditConditionalBreakpointAction extends AbstractDebugAction {
|
||||
|
||||
|
||||
export class SetValueAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.setValue';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.setValue';
|
||||
static LABEL = nls.localize('setValue', "Set Value");
|
||||
|
||||
constructor(id: string, label: string, private variable: Variable, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -607,7 +609,7 @@ export class SetValueAction extends AbstractDebugAction {
|
||||
|
||||
|
||||
export class AddWatchExpressionAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.addWatchExpression';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.addWatchExpression';
|
||||
static LABEL = nls.localize('addWatchExpression', "Add Expression");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -616,7 +618,8 @@ export class AddWatchExpressionAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
return this.debugService.addWatchExpression();
|
||||
this.debugService.addWatchExpression();
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
|
||||
protected isEnabled(state: State): boolean {
|
||||
@@ -625,7 +628,7 @@ export class AddWatchExpressionAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class EditWatchExpressionAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.editWatchExpression';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.editWatchExpression';
|
||||
static LABEL = nls.localize('editWatchExpression', "Edit Expression");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -639,7 +642,7 @@ export class EditWatchExpressionAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class AddToWatchExpressionsAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.addToWatchExpressions';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.addToWatchExpressions';
|
||||
static LABEL = nls.localize('addToWatchExpressions', "Add to Watch");
|
||||
|
||||
constructor(id: string, label: string, private expression: IExpression, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -648,12 +651,14 @@ export class AddToWatchExpressionsAction extends AbstractDebugAction {
|
||||
|
||||
public run(): TPromise<any> {
|
||||
const name = this.expression instanceof Variable ? this.expression.evaluateName : this.expression.name;
|
||||
return this.debugService.addWatchExpression(name);
|
||||
this.debugService.addWatchExpression(name);
|
||||
return TPromise.as(undefined);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class RemoveWatchExpressionAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.removeWatchExpression';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.removeWatchExpression';
|
||||
static LABEL = nls.localize('removeWatchExpression', "Remove Expression");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -667,7 +672,7 @@ export class RemoveWatchExpressionAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class RemoveAllWatchExpressionsAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.viewlet.action.removeAllWatchExpressions';
|
||||
static readonly ID = 'workbench.debug.viewlet.action.removeAllWatchExpressions';
|
||||
static LABEL = nls.localize('removeAllWatchExpressions', "Remove All Expressions");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -686,7 +691,7 @@ export class RemoveAllWatchExpressionsAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class ClearReplAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.debug.panel.action.clearReplAction';
|
||||
static readonly ID = 'workbench.debug.panel.action.clearReplAction';
|
||||
static LABEL = nls.localize('clearRepl', "Clear Console");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -706,7 +711,7 @@ export class ClearReplAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class ToggleReplAction extends TogglePanelAction {
|
||||
static ID = 'workbench.debug.action.toggleRepl';
|
||||
static readonly ID = 'workbench.debug.action.toggleRepl';
|
||||
static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugConsoleAction' }, 'Debug Console');
|
||||
private toDispose: lifecycle.IDisposable[];
|
||||
|
||||
@@ -748,7 +753,7 @@ export class ToggleReplAction extends TogglePanelAction {
|
||||
|
||||
export class FocusReplAction extends Action {
|
||||
|
||||
static ID = 'workbench.debug.action.focusRepl';
|
||||
static readonly ID = 'workbench.debug.action.focusRepl';
|
||||
static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugFocusConsole' }, 'Focus Debug Console');
|
||||
|
||||
|
||||
@@ -764,7 +769,7 @@ export class FocusReplAction extends Action {
|
||||
}
|
||||
|
||||
export class FocusProcessAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.focusProcess';
|
||||
static readonly ID = 'workbench.action.debug.focusProcess';
|
||||
static LABEL = nls.localize('focusProcess', "Focus Process");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -778,19 +783,19 @@ export class FocusProcessAction extends AbstractDebugAction {
|
||||
public run(processName: string): TPromise<any> {
|
||||
const isMultiRoot = this.debugService.getConfigurationManager().getLaunches().length > 1;
|
||||
const process = this.debugService.getModel().getProcesses().filter(p => p.getName(isMultiRoot) === processName).pop();
|
||||
return this.debugService.focusStackFrameAndEvaluate(null, process, true).then(() => {
|
||||
const stackFrame = this.debugService.getViewModel().focusedStackFrame;
|
||||
if (stackFrame) {
|
||||
return stackFrame.openInEditor(this.editorService, true);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
this.debugService.focusStackFrame(undefined, undefined, process, true);
|
||||
const stackFrame = this.debugService.getViewModel().focusedStackFrame;
|
||||
if (stackFrame) {
|
||||
return stackFrame.openInEditor(this.editorService, true);
|
||||
}
|
||||
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
// Actions used by the chakra debugger
|
||||
export class StepBackAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.stepBack';
|
||||
static readonly ID = 'workbench.action.debug.stepBack';
|
||||
static LABEL = nls.localize('stepBackDebug', "Step Back");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -813,7 +818,7 @@ export class StepBackAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
export class ReverseContinueAction extends AbstractDebugAction {
|
||||
static ID = 'workbench.action.debug.reverseContinue';
|
||||
static readonly ID = 'workbench.action.debug.reverseContinue';
|
||||
static LABEL = nls.localize('reverseContinue', "Reverse");
|
||||
|
||||
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
|
||||
@@ -834,3 +839,15 @@ export class ReverseContinueAction extends AbstractDebugAction {
|
||||
process && process.session.capabilities.supportsStepBack;
|
||||
}
|
||||
}
|
||||
|
||||
export class ReplCollapseAllAction extends CollapseAction {
|
||||
constructor(viewer: ITree, private toFocus: { focus(): void; }) {
|
||||
super(viewer, true, undefined);
|
||||
}
|
||||
|
||||
public run(event?: any): TPromise<any> {
|
||||
return super.run(event).then(() => {
|
||||
this.toFocus.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!vs/workbench/parts/debug/browser/media/debugActionsWidget';
|
||||
import 'vs/css!./media/debugActionsWidget';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import severity from 'vs/base/common/severity';
|
||||
import * as builder from 'vs/base/browser/builder';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
@@ -21,7 +20,6 @@ import { AbstractDebugAction, PauseAction, ContinueAction, StepBackAction, Rever
|
||||
import { FocusProcessActionItem } from 'vs/workbench/parts/debug/browser/debugActionItems';
|
||||
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { Themable } from 'vs/workbench/common/theme';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -29,6 +27,8 @@ import { registerColor, contrastBorder, widgetShadow } from 'vs/platform/theme/c
|
||||
import { localize } from 'vs/nls';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
const $ = builder.$;
|
||||
const DEBUG_ACTIONS_WIDGET_POSITION_KEY = 'debug.actionswidgetposition';
|
||||
@@ -38,6 +38,11 @@ export const debugToolBarBackground = registerColor('debugToolBar.background', {
|
||||
light: '#F3F3F3',
|
||||
hc: '#000000'
|
||||
}, localize('debugToolBarBackground', "Debug toolbar background color."));
|
||||
export const debugToolBarBorder = registerColor('debugToolBar.border', {
|
||||
dark: null,
|
||||
light: null,
|
||||
hc: null
|
||||
}, localize('debugToolBarBorder', "Debug toolbar border color."));
|
||||
|
||||
export class DebugActionsWidget extends Themable implements IWorkbenchContribution {
|
||||
|
||||
@@ -51,7 +56,7 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
|
||||
private isBuilt: boolean;
|
||||
|
||||
constructor(
|
||||
@IMessageService private messageService: IMessageService,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IPartService private partService: IPartService,
|
||||
@@ -59,7 +64,8 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService,
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
|
||||
@IContextViewService contextViewService: IContextViewService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
@@ -75,7 +81,7 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
|
||||
orientation: ActionsOrientation.HORIZONTAL,
|
||||
actionItemProvider: (action: IAction) => {
|
||||
if (action.id === FocusProcessAction.ID) {
|
||||
return new FocusProcessActionItem(action, this.debugService, this.themeService);
|
||||
return new FocusProcessActionItem(action, this.debugService, this.themeService, contextViewService);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -97,7 +103,7 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
|
||||
this.toUnbind.push(this.actionBar.actionRunner.onDidRun((e: IRunEvent) => {
|
||||
// check for error
|
||||
if (e.error && !errors.isPromiseCanceledError(e.error)) {
|
||||
this.messageService.show(severity.Error, e.error);
|
||||
this.notificationService.error(e.error);
|
||||
}
|
||||
|
||||
// log in telemetry
|
||||
@@ -159,9 +165,16 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
|
||||
this.$el.style('box-shadow', widgetShadowColor ? `0 5px 8px ${widgetShadowColor}` : null);
|
||||
|
||||
const contrastBorderColor = this.getColor(contrastBorder);
|
||||
this.$el.style('border-style', contrastBorderColor ? 'solid' : null);
|
||||
this.$el.style('border-width', contrastBorderColor ? '1px' : null);
|
||||
this.$el.style('border-color', contrastBorderColor);
|
||||
const borderColor = this.getColor(debugToolBarBorder);
|
||||
|
||||
if (contrastBorderColor) {
|
||||
this.$el.style('border', `1px solid ${contrastBorderColor}`);
|
||||
} else {
|
||||
this.$el.style({
|
||||
'border': borderColor ? `solid ${borderColor}` : 'none',
|
||||
'border-width': '1px 0'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,4 +295,4 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
|
||||
delete this.$el;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
241
src/vs/workbench/parts/debug/browser/debugCommands.ts
Normal file
241
src/vs/workbench/parts/debug/browser/debugCommands.ts
Normal file
@@ -0,0 +1,241 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IListService } from 'vs/platform/list/browser/listService';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_NOT_IN_DEBUG_REPL, CONTEXT_EXPRESSION_SELECTED, CONTEXT_BREAKPOINT_SELECTED } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Expression, Variable, Breakpoint, FunctionBreakpoint } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { openBreakpointSource } from 'vs/workbench/parts/debug/browser/breakpointsView';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { InputFocusedContext } from 'vs/platform/workbench/common/contextkeys';
|
||||
|
||||
export function registerCommands(): void {
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.toggleBreakpoint',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(5),
|
||||
when: ContextKeyExpr.and(CONTEXT_BREAKPOINTS_FOCUSED, InputFocusedContext.toNegated()),
|
||||
primary: KeyCode.Space,
|
||||
handler: (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const focused = listService.lastFocusedList;
|
||||
|
||||
// Tree only
|
||||
if (!(focused instanceof List)) {
|
||||
const tree = focused;
|
||||
const element = <IEnablement>tree.getFocus();
|
||||
debugService.enableOrDisableBreakpoints(!element.enabled, element).done(null, errors.onUnexpectedError);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.renameWatchExpression',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(5),
|
||||
when: CONTEXT_WATCH_EXPRESSIONS_FOCUSED,
|
||||
primary: KeyCode.F2,
|
||||
mac: { primary: KeyCode.Enter },
|
||||
handler: (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const focused = listService.lastFocusedList;
|
||||
|
||||
// Tree only
|
||||
if (!(focused instanceof List)) {
|
||||
const element = focused.getFocus();
|
||||
if (element instanceof Expression) {
|
||||
debugService.getViewModel().setSelectedExpression(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.setVariable',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(5),
|
||||
when: CONTEXT_VARIABLES_FOCUSED,
|
||||
primary: KeyCode.F2,
|
||||
mac: { primary: KeyCode.Enter },
|
||||
handler: (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const focused = listService.lastFocusedList;
|
||||
|
||||
// Tree only
|
||||
if (!(focused instanceof List)) {
|
||||
const element = focused.getFocus();
|
||||
if (element instanceof Variable) {
|
||||
debugService.getViewModel().setSelectedExpression(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.removeWatchExpression',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
|
||||
when: ContextKeyExpr.and(CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_EXPRESSION_SELECTED.toNegated()),
|
||||
primary: KeyCode.Delete,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace },
|
||||
handler: (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const focused = listService.lastFocusedList;
|
||||
|
||||
// Tree only
|
||||
if (!(focused instanceof List)) {
|
||||
const element = focused.getFocus();
|
||||
if (element instanceof Expression) {
|
||||
debugService.removeWatchExpressions(element.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.removeBreakpoint',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
|
||||
when: ContextKeyExpr.and(CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_BREAKPOINT_SELECTED.toNegated()),
|
||||
primary: KeyCode.Delete,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace },
|
||||
handler: (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const focused = listService.lastFocusedList;
|
||||
|
||||
// Tree only
|
||||
if (!(focused instanceof List)) {
|
||||
const element = focused.getFocus();
|
||||
if (element instanceof Breakpoint) {
|
||||
debugService.removeBreakpoints(element.getId()).done(null, errors.onUnexpectedError);
|
||||
} else if (element instanceof FunctionBreakpoint) {
|
||||
debugService.removeFunctionBreakpoints(element.getId()).done(null, errors.onUnexpectedError);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.installAdditionalDebuggers',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: (accessor) => {
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
return viewletService.openViewlet(EXTENSIONS_VIEWLET_ID, true)
|
||||
.then(viewlet => viewlet as IExtensionsViewlet)
|
||||
.then(viewlet => {
|
||||
viewlet.search('tag:debuggers @sort:installs');
|
||||
viewlet.focus();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.addConfiguration',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: (accessor, launchUri: string) => {
|
||||
const manager = accessor.get(IDebugService).getConfigurationManager();
|
||||
if (accessor.get(IWorkspaceContextService).getWorkbenchState() === WorkbenchState.EMPTY) {
|
||||
accessor.get(INotificationService).info(nls.localize('noFolderDebugConfig', "Please first open a folder in order to do advanced debug configuration."));
|
||||
return TPromise.as(null);
|
||||
}
|
||||
const launch = manager.getLaunches().filter(l => l.uri.toString() === launchUri).pop() || manager.selectedConfiguration.launch;
|
||||
|
||||
return launch.openConfigFile(false).done(editor => {
|
||||
if (editor) {
|
||||
const codeEditor = <ICodeEditor>editor.getControl();
|
||||
if (codeEditor) {
|
||||
return codeEditor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID).addLaunchConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const COLUMN_BREAKPOINT_COMMAND_ID = 'editor.debug.action.toggleColumnBreakpoint';
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
|
||||
primary: KeyMod.Shift | KeyCode.F9,
|
||||
when: EditorContextKeys.textFocus,
|
||||
id: COLUMN_BREAKPOINT_COMMAND_ID,
|
||||
handler: (accessor) => {
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const editorService = accessor.get(IWorkbenchEditorService);
|
||||
const editor = editorService.getActiveEditor();
|
||||
const control = editor && <ICodeEditor>editor.getControl();
|
||||
if (control) {
|
||||
const position = control.getPosition();
|
||||
const modelUri = control.getModel().uri;
|
||||
const bp = debugService.getModel().getBreakpoints()
|
||||
.filter(bp => bp.lineNumber === position.lineNumber && bp.column === position.column && bp.uri.toString() === modelUri.toString()).pop();
|
||||
|
||||
if (bp) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
if (debugService.getConfigurationManager().canSetBreakpointsIn(control.getModel())) {
|
||||
return debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber, column: position.column }]);
|
||||
}
|
||||
}
|
||||
|
||||
return TPromise.as(null);
|
||||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: COLUMN_BREAKPOINT_COMMAND_ID,
|
||||
title: nls.localize('columnBreakpoint', "Column Breakpoint"),
|
||||
category: nls.localize('debug', "Debug")
|
||||
}
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorContext, {
|
||||
command: {
|
||||
id: COLUMN_BREAKPOINT_COMMAND_ID,
|
||||
title: nls.localize('addColumnBreakpoint', "Add Column Breakpoint")
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_NOT_IN_DEBUG_REPL, EditorContextKeys.writable),
|
||||
group: 'debug',
|
||||
order: 1
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.openBreakpointToSide',
|
||||
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
|
||||
when: CONTEXT_BREAKPOINTS_FOCUSED,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Enter,
|
||||
secondary: [KeyMod.Alt | KeyCode.Enter],
|
||||
handler: (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const list = listService.lastFocusedList;
|
||||
if (list instanceof List) {
|
||||
const focus = list.getFocusedElements();
|
||||
if (focus.length && focus[0] instanceof Breakpoint) {
|
||||
return openBreakpointSource(focus[0], true, false, accessor.get(IDebugService), accessor.get(IWorkbenchEditorService));
|
||||
}
|
||||
}
|
||||
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import uri from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { guessMimeTypes, MIME_TEXT } from 'vs/base/common/mime';
|
||||
import { IModel } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService';
|
||||
@@ -39,7 +39,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
|
||||
textModelResolverService.registerTextModelContentProvider(DEBUG_SCHEME, this);
|
||||
}
|
||||
|
||||
public provideTextContent(resource: uri): TPromise<IModel> {
|
||||
public provideTextContent(resource: uri): TPromise<ITextModel> {
|
||||
|
||||
let process: IProcess;
|
||||
let sourceRef: number;
|
||||
@@ -56,7 +56,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
|
||||
}
|
||||
|
||||
if (!process) {
|
||||
return TPromise.wrapError<IModel>(new Error(localize('unable', "Unable to resolve the resource without a debug session")));
|
||||
return TPromise.wrapError<ITextModel>(new Error(localize('unable', "Unable to resolve the resource without a debug session")));
|
||||
}
|
||||
const source = process.sources.get(resource.toString());
|
||||
let rawSource: DebugProtocol.Source;
|
||||
@@ -73,20 +73,24 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
|
||||
};
|
||||
}
|
||||
|
||||
const createErrModel = (message: string) => {
|
||||
this.debugService.sourceIsNotAvailable(resource);
|
||||
const modePromise = this.modeService.getOrCreateMode(MIME_TEXT);
|
||||
const model = this.modelService.createModel(message, modePromise, resource);
|
||||
|
||||
return model;
|
||||
};
|
||||
|
||||
return process.session.source({ sourceReference: sourceRef, source: rawSource }).then(response => {
|
||||
if (!response) {
|
||||
return createErrModel(localize('canNotResolveSource', "Could not resolve resource {0}, no response from debug extension.", resource.toString()));
|
||||
}
|
||||
|
||||
const mime = response.body.mimeType || guessMimeTypes(resource.path)[0];
|
||||
const modePromise = this.modeService.getOrCreateMode(mime);
|
||||
const model = this.modelService.createModel(response.body.content, modePromise, resource);
|
||||
|
||||
return model;
|
||||
}, (err: DebugProtocol.ErrorResponse) => {
|
||||
|
||||
this.debugService.sourceIsNotAvailable(resource);
|
||||
const modePromise = this.modeService.getOrCreateMode(MIME_TEXT);
|
||||
const model = this.modelService.createModel(err.message, modePromise, resource);
|
||||
|
||||
return model;
|
||||
});
|
||||
}, (err: DebugProtocol.ErrorResponse) => createErrModel(err.message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,63 +49,6 @@ class ToggleBreakpointAction extends EditorAction {
|
||||
}
|
||||
}
|
||||
|
||||
function addColumnBreakpoint(accessor: ServicesAccessor, editor: ICodeEditor, remove: boolean): TPromise<any> {
|
||||
const debugService = accessor.get(IDebugService);
|
||||
|
||||
const position = editor.getPosition();
|
||||
const modelUri = editor.getModel().uri;
|
||||
const bp = debugService.getModel().getBreakpoints()
|
||||
.filter(bp => bp.lineNumber === position.lineNumber && bp.column === position.column && bp.uri.toString() === modelUri.toString()).pop();
|
||||
|
||||
if (bp) {
|
||||
return remove ? debugService.removeBreakpoints(bp.getId()) : TPromise.as(null);
|
||||
}
|
||||
if (debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel())) {
|
||||
return debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber, column: position.column }]);
|
||||
}
|
||||
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
class ToggleColumnBreakpointAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.debug.action.toggleColumnBreakpoint',
|
||||
label: nls.localize('columnBreakpointAction', "Debug: Column Breakpoint"),
|
||||
alias: 'Debug: Column Breakpoint',
|
||||
precondition: null,
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.textFocus,
|
||||
primary: KeyMod.Shift | KeyCode.F9
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): TPromise<any> {
|
||||
return addColumnBreakpoint(accessor, editor, true);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO@Isidor merge two column breakpoints actions together
|
||||
class ToggleColumnBreakpointContextMenuAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.debug.action.toggleColumnBreakpointContextMenu',
|
||||
label: nls.localize('columnBreakpoint', "Add Column Breakpoint"),
|
||||
alias: 'Toggle Column Breakpoint',
|
||||
precondition: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_NOT_IN_DEBUG_REPL, EditorContextKeys.writable),
|
||||
menuOpts: {
|
||||
group: 'debug',
|
||||
order: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): TPromise<any> {
|
||||
return addColumnBreakpoint(accessor, editor, false);
|
||||
}
|
||||
}
|
||||
|
||||
class ConditionalBreakpointAction extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
@@ -268,12 +211,9 @@ class CloseBreakpointWidgetCommand extends EditorCommand {
|
||||
}
|
||||
|
||||
registerEditorAction(ToggleBreakpointAction);
|
||||
registerEditorAction(ToggleColumnBreakpointAction);
|
||||
registerEditorAction(ToggleColumnBreakpointContextMenuAction);
|
||||
registerEditorAction(ConditionalBreakpointAction);
|
||||
registerEditorAction(RunToCursorAction);
|
||||
registerEditorAction(SelectionToReplAction);
|
||||
registerEditorAction(SelectionToWatchExpressionsAction);
|
||||
registerEditorAction(ShowDebugHoverAction);
|
||||
|
||||
registerEditorCommand(new CloseBreakpointWidgetCommand());
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as lifecycle from 'vs/base/common/lifecycle';
|
||||
import { Constants } from 'vs/editor/common/core/uint';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IModel, TrackedRangeStickiness, IModelDeltaDecoration, IModelDecorationOptions } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel, TrackedRangeStickiness, IModelDeltaDecoration, IModelDecorationOptions } from 'vs/editor/common/model';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IDebugService, IBreakpoint, State } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { getBreakpointMessageAndClassName } from 'vs/workbench/parts/debug/browser/breakpointsView';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
|
||||
interface IBreakpointDecoration {
|
||||
decorationId: string;
|
||||
@@ -21,26 +21,24 @@ interface IBreakpointDecoration {
|
||||
}
|
||||
|
||||
interface IDebugEditorModelData {
|
||||
model: IModel;
|
||||
model: ITextModel;
|
||||
toDispose: lifecycle.IDisposable[];
|
||||
breakpointDecorations: IBreakpointDecoration[];
|
||||
currentStackDecorations: string[];
|
||||
dirty: boolean;
|
||||
topStackFrameRange: Range;
|
||||
}
|
||||
|
||||
const stickiness = TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges;
|
||||
|
||||
export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
static ID = 'breakpointManager';
|
||||
|
||||
static readonly ID = 'breakpointManager';
|
||||
static readonly STICKINESS = TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges;
|
||||
private modelDataMap: Map<string, IDebugEditorModelData>;
|
||||
private toDispose: lifecycle.IDisposable[];
|
||||
private ignoreDecorationsChangedEvent: boolean;
|
||||
|
||||
constructor(
|
||||
@IModelService private modelService: IModelService,
|
||||
@IDebugService private debugService: IDebugService
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@ITextFileService private textFileService: ITextFileService
|
||||
) {
|
||||
this.modelDataMap = new Map<string, IDebugEditorModelData>();
|
||||
this.toDispose = [];
|
||||
@@ -68,14 +66,13 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
this.toDispose.push(this.debugService.onDidChangeState(state => {
|
||||
if (state === State.Inactive) {
|
||||
this.modelDataMap.forEach(modelData => {
|
||||
modelData.dirty = false;
|
||||
modelData.topStackFrameRange = undefined;
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private onModelAdded(model: IModel): void {
|
||||
private onModelAdded(model: ITextModel): void {
|
||||
const modelUrlStr = model.uri.toString();
|
||||
const breakpoints = this.debugService.getModel().getBreakpoints().filter(bp => bp.uri.toString() === modelUrlStr);
|
||||
|
||||
@@ -89,12 +86,11 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
toDispose: toDispose,
|
||||
breakpointDecorations: breakpointDecorationIds.map((decorationId, index) => ({ decorationId, modelId: breakpoints[index].getId(), range: desiredDecorations[index].range })),
|
||||
currentStackDecorations: currentStackDecorations,
|
||||
dirty: false,
|
||||
topStackFrameRange: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private onModelRemoved(model: IModel): void {
|
||||
private onModelRemoved(model: ITextModel): void {
|
||||
const modelUriStr = model.uri.toString();
|
||||
if (this.modelDataMap.has(modelUriStr)) {
|
||||
lifecycle.dispose(this.modelDataMap.get(modelUriStr).toDispose);
|
||||
@@ -220,9 +216,8 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
}
|
||||
}
|
||||
}
|
||||
modelData.dirty = this.debugService.state !== State.Inactive;
|
||||
|
||||
this.debugService.updateBreakpoints(modelUri, data);
|
||||
this.debugService.updateBreakpoints(modelUri, data, true);
|
||||
}
|
||||
|
||||
private onBreakpointsChange(): void {
|
||||
@@ -262,121 +257,73 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
({ decorationId, modelId: newBreakpoints[index].getId(), range: desiredDecorations[index].range }));
|
||||
}
|
||||
|
||||
private createBreakpointDecorations(model: IModel, breakpoints: IBreakpoint[]): { range: Range; options: IModelDecorationOptions; }[] {
|
||||
return breakpoints.map((breakpoint) => {
|
||||
const column = model.getLineFirstNonWhitespaceColumn(breakpoint.lineNumber);
|
||||
const range = model.validateRange(
|
||||
breakpoint.column ? new Range(breakpoint.lineNumber, breakpoint.column, breakpoint.lineNumber, breakpoint.column + 1)
|
||||
: new Range(breakpoint.lineNumber, column, breakpoint.lineNumber, column + 1) // Decoration has to have a width #20688
|
||||
);
|
||||
return {
|
||||
options: this.getBreakpointDecorationOptions(breakpoint),
|
||||
range
|
||||
};
|
||||
private createBreakpointDecorations(model: ITextModel, breakpoints: IBreakpoint[]): { range: Range; options: IModelDecorationOptions; }[] {
|
||||
const result: { range: Range; options: IModelDecorationOptions; }[] = [];
|
||||
breakpoints.forEach((breakpoint) => {
|
||||
if (breakpoint.lineNumber <= model.getLineCount()) {
|
||||
const column = model.getLineFirstNonWhitespaceColumn(breakpoint.lineNumber);
|
||||
const range = model.validateRange(
|
||||
breakpoint.column ? new Range(breakpoint.lineNumber, breakpoint.column, breakpoint.lineNumber, breakpoint.column + 1)
|
||||
: new Range(breakpoint.lineNumber, column, breakpoint.lineNumber, column + 1) // Decoration has to have a width #20688
|
||||
);
|
||||
|
||||
result.push({
|
||||
options: this.getBreakpointDecorationOptions(breakpoint),
|
||||
range
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private getBreakpointDecorationOptions(breakpoint: IBreakpoint): IModelDecorationOptions {
|
||||
const activated = this.debugService.getModel().areBreakpointsActivated();
|
||||
const state = this.debugService.state;
|
||||
const debugActive = state === State.Running || state === State.Stopped;
|
||||
const modelData = this.modelDataMap.get(breakpoint.uri.toString());
|
||||
const { className, message } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, breakpoint);
|
||||
let glyphMarginHoverMessage: MarkdownString;
|
||||
|
||||
let result = (!breakpoint.enabled || !activated) ? DebugEditorModelManager.BREAKPOINT_DISABLED_DECORATION :
|
||||
debugActive && modelData && modelData.dirty && !breakpoint.verified ? DebugEditorModelManager.BREAKPOINT_DIRTY_DECORATION :
|
||||
debugActive && !breakpoint.verified ? DebugEditorModelManager.BREAKPOINT_UNVERIFIED_DECORATION :
|
||||
!breakpoint.condition && !breakpoint.hitCondition ? DebugEditorModelManager.BREAKPOINT_DECORATION : null;
|
||||
|
||||
if (result) {
|
||||
result = objects.deepClone(result);
|
||||
if (breakpoint.message) {
|
||||
result.glyphMarginHoverMessage = new MarkdownString().appendText(breakpoint.message);
|
||||
if (message) {
|
||||
if (breakpoint.condition || breakpoint.hitCondition) {
|
||||
const modelData = this.modelDataMap.get(breakpoint.uri.toString());
|
||||
const modeId = modelData ? modelData.model.getLanguageIdentifier().language : '';
|
||||
glyphMarginHoverMessage = new MarkdownString().appendCodeblock(modeId, message);
|
||||
} else {
|
||||
glyphMarginHoverMessage = new MarkdownString().appendText(message);
|
||||
}
|
||||
if (breakpoint.column) {
|
||||
result.beforeContentClassName = `debug-breakpoint-column ${result.glyphMarginClassName}-column`;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const process = this.debugService.getViewModel().focusedProcess;
|
||||
if (process && !process.session.capabilities.supportsConditionalBreakpoints) {
|
||||
return DebugEditorModelManager.BREAKPOINT_UNSUPPORTED_DECORATION;
|
||||
}
|
||||
|
||||
const modeId = modelData ? modelData.model.getLanguageIdentifier().language : '';
|
||||
let condition: string;
|
||||
if (breakpoint.condition && breakpoint.hitCondition) {
|
||||
condition = `Expression: ${breakpoint.condition}\nHitCount: ${breakpoint.hitCondition}`;
|
||||
} else {
|
||||
condition = breakpoint.condition ? breakpoint.condition : breakpoint.hitCondition;
|
||||
}
|
||||
const glyphMarginHoverMessage = new MarkdownString().appendCodeblock(modeId, condition);
|
||||
const glyphMarginClassName = 'debug-breakpoint-conditional-glyph';
|
||||
const beforeContentClassName = breakpoint.column ? `debug-breakpoint-column ${glyphMarginClassName}-column` : undefined;
|
||||
|
||||
return {
|
||||
glyphMarginClassName,
|
||||
glyphMarginClassName: className,
|
||||
glyphMarginHoverMessage,
|
||||
stickiness,
|
||||
beforeContentClassName
|
||||
stickiness: DebugEditorModelManager.STICKINESS,
|
||||
beforeContentClassName: breakpoint.column ? `debug-breakpoint-column ${className}-column` : undefined
|
||||
};
|
||||
}
|
||||
|
||||
// editor decorations
|
||||
|
||||
private static BREAKPOINT_DECORATION: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-breakpoint-glyph',
|
||||
stickiness
|
||||
};
|
||||
|
||||
private static BREAKPOINT_DISABLED_DECORATION: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-breakpoint-disabled-glyph',
|
||||
glyphMarginHoverMessage: new MarkdownString().appendText(nls.localize('breakpointDisabledHover', "Disabled Breakpoint")),
|
||||
stickiness
|
||||
};
|
||||
|
||||
private static BREAKPOINT_UNVERIFIED_DECORATION: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-breakpoint-unverified-glyph',
|
||||
glyphMarginHoverMessage: new MarkdownString().appendText(nls.localize('breakpointUnverifieddHover', "Unverified Breakpoint")),
|
||||
stickiness
|
||||
};
|
||||
|
||||
private static BREAKPOINT_DIRTY_DECORATION: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-breakpoint-unverified-glyph',
|
||||
glyphMarginHoverMessage: new MarkdownString().appendText(nls.localize('breakpointDirtydHover', "Unverified breakpoint. File is modified, please restart debug session.")),
|
||||
stickiness
|
||||
};
|
||||
|
||||
private static BREAKPOINT_UNSUPPORTED_DECORATION: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-breakpoint-unsupported-glyph',
|
||||
glyphMarginHoverMessage: new MarkdownString().appendText(nls.localize('breakpointUnsupported', "Conditional breakpoints not supported by this debug type")),
|
||||
stickiness
|
||||
};
|
||||
|
||||
// we need a separate decoration for glyph margin, since we do not want it on each line of a multi line statement.
|
||||
private static TOP_STACK_FRAME_MARGIN: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-top-stack-frame-glyph',
|
||||
stickiness
|
||||
glyphMarginClassName: 'debug-top-stack-frame',
|
||||
stickiness: DebugEditorModelManager.STICKINESS
|
||||
};
|
||||
|
||||
private static FOCUSED_STACK_FRAME_MARGIN: IModelDecorationOptions = {
|
||||
glyphMarginClassName: 'debug-focused-stack-frame-glyph',
|
||||
stickiness
|
||||
glyphMarginClassName: 'debug-focused-stack-frame',
|
||||
stickiness: DebugEditorModelManager.STICKINESS
|
||||
};
|
||||
|
||||
private static TOP_STACK_FRAME_DECORATION: IModelDecorationOptions = {
|
||||
isWholeLine: true,
|
||||
inlineClassName: 'debug-remove-token-colors',
|
||||
className: 'debug-top-stack-frame-line',
|
||||
stickiness
|
||||
stickiness: DebugEditorModelManager.STICKINESS
|
||||
};
|
||||
|
||||
private static TOP_STACK_FRAME_EXCEPTION_DECORATION: IModelDecorationOptions = {
|
||||
isWholeLine: true,
|
||||
inlineClassName: 'debug-remove-token-colors',
|
||||
className: 'debug-top-stack-frame-exception-line',
|
||||
stickiness
|
||||
stickiness: DebugEditorModelManager.STICKINESS
|
||||
};
|
||||
|
||||
private static TOP_STACK_FRAME_INLINE_DECORATION: IModelDecorationOptions = {
|
||||
@@ -387,6 +334,6 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
||||
isWholeLine: true,
|
||||
inlineClassName: 'debug-remove-token-colors',
|
||||
className: 'debug-focused-stack-frame-line',
|
||||
stickiness
|
||||
stickiness: DebugEditorModelManager.STICKINESS
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ import * as errors from 'vs/base/common/errors';
|
||||
import { QuickOpenEntry, QuickOpenEntryGroup } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { StartAction } from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { Severity } from 'vs/workbench/services/message/browser/messageList';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
class AddConfigEntry extends Model.QuickOpenEntry {
|
||||
|
||||
@@ -29,7 +28,7 @@ class AddConfigEntry extends Model.QuickOpenEntry {
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? this.launch.workspace.name : '';
|
||||
return this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? this.launch.name : '';
|
||||
}
|
||||
|
||||
public getAriaLabel(): string {
|
||||
@@ -40,7 +39,7 @@ class AddConfigEntry extends Model.QuickOpenEntry {
|
||||
if (mode === QuickOpen.Mode.PREVIEW) {
|
||||
return false;
|
||||
}
|
||||
this.commandService.executeCommand('debug.addConfiguration', this.launch.workspace.uri.toString()).done(undefined, errors.onUnexpectedError);
|
||||
this.commandService.executeCommand('debug.addConfiguration', this.launch.uri.toString()).done(undefined, errors.onUnexpectedError);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -48,7 +47,7 @@ class AddConfigEntry extends Model.QuickOpenEntry {
|
||||
|
||||
class StartDebugEntry extends Model.QuickOpenEntry {
|
||||
|
||||
constructor(private debugService: IDebugService, private contextService: IWorkspaceContextService, private messageService: IMessageService, private launch: ILaunch, private configurationName: string, highlights: Model.IHighlight[] = []) {
|
||||
constructor(private debugService: IDebugService, private contextService: IWorkspaceContextService, private notificationService: INotificationService, private launch: ILaunch, private configurationName: string, highlights: Model.IHighlight[] = []) {
|
||||
super(highlights);
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ class StartDebugEntry extends Model.QuickOpenEntry {
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? this.launch.workspace.name : '';
|
||||
return this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? this.launch.name : '';
|
||||
}
|
||||
|
||||
public getAriaLabel(): string {
|
||||
@@ -70,7 +69,7 @@ class StartDebugEntry extends Model.QuickOpenEntry {
|
||||
}
|
||||
// Run selected debug configuration
|
||||
this.debugService.getConfigurationManager().selectConfiguration(this.launch, this.configurationName);
|
||||
this.debugService.startDebugging(this.launch.workspace).done(undefined, e => this.messageService.show(Severity.Error, e));
|
||||
this.debugService.startDebugging(this.launch).done(undefined, e => this.notificationService.error(e));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -85,7 +84,7 @@ export class DebugQuickOpenHandler extends Quickopen.QuickOpenHandler {
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@ICommandService private commandService: ICommandService,
|
||||
@IMessageService private messageService: IMessageService
|
||||
@INotificationService private notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -103,14 +102,15 @@ export class DebugQuickOpenHandler extends Quickopen.QuickOpenHandler {
|
||||
launch.getConfigurationNames().map(config => ({ config: config, highlights: Filters.matchesContiguousSubString(input, config) }))
|
||||
.filter(({ highlights }) => !!highlights)
|
||||
.forEach(({ config, highlights }) => {
|
||||
if (launch === configManager.selectedLaunch && config === configManager.selectedName) {
|
||||
if (launch === configManager.selectedConfiguration.launch && config === configManager.selectedConfiguration.name) {
|
||||
this.autoFocusIndex = configurations.length;
|
||||
}
|
||||
configurations.push(new StartDebugEntry(this.debugService, this.contextService, this.messageService, launch, config, highlights));
|
||||
configurations.push(new StartDebugEntry(this.debugService, this.contextService, this.notificationService, launch, config, highlights));
|
||||
});
|
||||
}
|
||||
launches.forEach((l, index) => {
|
||||
const label = launches.length > 1 ? nls.localize("addConfigTo", "Add Config ({0})...", l.workspace.name) : nls.localize('addConfiguration', "Add Configuration...");
|
||||
launches.filter(l => !l.hidden).forEach((l, index) => {
|
||||
|
||||
const label = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? nls.localize("addConfigTo", "Add Config ({0})...", l.name) : nls.localize('addConfiguration', "Add Configuration...");
|
||||
const entry = new AddConfigEntry(label, l, this.commandService, this.contextService, Filters.matchesContiguousSubString(input, label));
|
||||
if (index === 0) {
|
||||
configurations.push(new QuickOpenEntryGroup(entry, undefined, true));
|
||||
|
||||
@@ -92,8 +92,13 @@ export class DebugStatus extends Themable implements IStatusbarItem {
|
||||
private setLabel(): void {
|
||||
if (this.label && this.statusBarItem) {
|
||||
const manager = this.debugService.getConfigurationManager();
|
||||
const name = manager.selectedName || '';
|
||||
this.label.textContent = manager.getLaunches().length > 1 ? `${name} (${manager.selectedLaunch.workspace.name})` : name;
|
||||
const name = manager.selectedConfiguration.name;
|
||||
if (name) {
|
||||
this.statusBarItem.style.display = 'block';
|
||||
this.label.textContent = manager.getLaunches().length > 1 ? `${name} (${manager.selectedConfiguration.launch.name})` : name;
|
||||
} else {
|
||||
this.statusBarItem.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,17 +15,18 @@ import { IDebugService, VIEWLET_ID, State, VARIABLES_VIEW_ID, WATCH_VIEW_ID, CAL
|
||||
import { StartAction, ToggleReplAction, ConfigureAction } from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { StartDebugActionItem } from 'vs/workbench/parts/debug/browser/debugActionItems';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IProgressService, IProgressRunner } 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';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { ViewLocation } from 'vs/workbench/browser/parts/views/viewsRegistry';
|
||||
import { ViewLocation } from 'vs/workbench/common/views';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
|
||||
export class DebugViewlet extends PersistentViewsViewlet {
|
||||
|
||||
@@ -35,6 +36,7 @@ export class DebugViewlet extends PersistentViewsViewlet {
|
||||
private panelListeners = new Map<string, IDisposable>();
|
||||
|
||||
constructor(
|
||||
@IPartService partService: IPartService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IProgressService private progressService: IProgressService,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@@ -46,7 +48,7 @@ export class DebugViewlet extends PersistentViewsViewlet {
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IExtensionService extensionService: IExtensionService
|
||||
) {
|
||||
super(VIEWLET_ID, ViewLocation.Debug, `${VIEWLET_ID}.state`, false, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService);
|
||||
super(VIEWLET_ID, ViewLocation.Debug, `${VIEWLET_ID}.state`, false, partService, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService);
|
||||
|
||||
this.progressRunner = null;
|
||||
|
||||
@@ -82,7 +84,7 @@ export class DebugViewlet extends PersistentViewsViewlet {
|
||||
}
|
||||
|
||||
public getActionItem(action: IAction): IActionItem {
|
||||
if (action.id === StartAction.ID && !!this.debugService.getConfigurationManager().selectedLaunch) {
|
||||
if (action.id === StartAction.ID) {
|
||||
this.startDebugActionItem = this.instantiationService.createInstance(StartDebugActionItem, null, action);
|
||||
return this.startDebugActionItem;
|
||||
}
|
||||
@@ -138,7 +140,7 @@ export class DebugViewlet extends PersistentViewsViewlet {
|
||||
|
||||
export class FocusVariablesViewAction extends Action {
|
||||
|
||||
static ID = 'workbench.debug.action.focusVariablesView';
|
||||
static readonly ID = 'workbench.debug.action.focusVariablesView';
|
||||
static LABEL = nls.localize('debugFocusVariablesView', 'Focus Variables');
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -156,7 +158,7 @@ export class FocusVariablesViewAction extends Action {
|
||||
|
||||
export class FocusWatchViewAction extends Action {
|
||||
|
||||
static ID = 'workbench.debug.action.focusWatchView';
|
||||
static readonly ID = 'workbench.debug.action.focusWatchView';
|
||||
static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugFocusWatchView' }, 'Focus Watch');
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -174,7 +176,7 @@ export class FocusWatchViewAction extends Action {
|
||||
|
||||
export class FocusCallStackViewAction extends Action {
|
||||
|
||||
static ID = 'workbench.debug.action.focusCallStackView';
|
||||
static readonly ID = 'workbench.debug.action.focusCallStackView';
|
||||
static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugFocusCallStackView' }, 'Focus CallStack');
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@@ -192,7 +194,7 @@ export class FocusCallStackViewAction extends Action {
|
||||
|
||||
export class FocusBreakpointsViewAction extends Action {
|
||||
|
||||
static ID = 'workbench.debug.action.focusBreakpointsView';
|
||||
static readonly ID = 'workbench.debug.action.focusBreakpointsView';
|
||||
static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugFocusBreakpointsView' }, 'Focus Breakpoints');
|
||||
|
||||
constructor(id: string, label: string,
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as nls from 'vs/nls';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
export class LinkDetector {
|
||||
private static readonly MAX_LENGTH = 500;
|
||||
private static FILE_LOCATION_PATTERNS: RegExp[] = [
|
||||
// group 0: full path with line and column
|
||||
// group 1: full path without line and column, matched by `*.*` in the end to work only on paths with extensions in the end (s.t. node:10352 would not match)
|
||||
@@ -34,8 +35,11 @@ export class LinkDetector {
|
||||
* If no links were detected, returns the original string.
|
||||
*/
|
||||
public handleLinks(text: string): HTMLElement | string {
|
||||
let linkContainer: HTMLElement;
|
||||
if (text.length > LinkDetector.MAX_LENGTH) {
|
||||
return text;
|
||||
}
|
||||
|
||||
let linkContainer: HTMLElement;
|
||||
for (let pattern of LinkDetector.FILE_LOCATION_PATTERNS) {
|
||||
pattern.lastIndex = 0; // the holy grail of software development
|
||||
let lastMatchIndex = 0;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-red{fill:#c10;}</style></defs><title>BreakpointFunction_16xMD</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.7,14H1.3L8,1.941Z"/></g><g id="iconBg"><path class="icon-vs-red" d="M13,13H3L8,4Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 482 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-disabled-grey{fill:#848484;}</style></defs><title>BreakpointFunction_disabled_16xMD</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.7,14H1.3L8,1.941Z"/></g><g id="iconBg"><path class="icon-disabled-grey" d="M13,13H3L8,4Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 508 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-disabled-grey{fill:#848484;}</style></defs><title>BreakpointFunction_disabled_16xMD</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.7,14H1.3L8,1.941Z"/></g><g id="iconBg"><path class="icon-disabled-grey" d="M13,13H3L8,4Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 508 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-red{fill:#848484;}</style></defs><title>BreakpointFunctionUnverified_16xMD</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.7,14H1.3L8,1.941Z"/></g><g id="iconBg"><path class="icon-vs-red" d="M8,4,3,13H13ZM8,6.059,11.3,12H4.7Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 516 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-red{fill:#848484;}</style></defs><title>BreakpointFunctionUnverified_16xMD</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.7,14H1.3L8,1.941Z"/></g><g id="iconBg"><path class="icon-vs-red" d="M8,4,3,13H13ZM8,6.059,11.3,12H4.7Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 516 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-red{fill:#e51400;}</style></defs><title>BreakpointFunction_16xMD</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.7,14H1.3L8,1.941Z"/></g><g id="iconBg"><path class="icon-vs-red" d="M13,13H3L8,4Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 484 B |
@@ -14,7 +14,7 @@
|
||||
}
|
||||
|
||||
.monaco-editor .debug-top-stack-frame-range {
|
||||
background: #ffeca0;
|
||||
background: rgba(255, 255, 102, 0.6);
|
||||
}
|
||||
|
||||
.monaco-editor .debug-top-stack-frame-column::before {
|
||||
@@ -29,30 +29,30 @@
|
||||
background: rgba(206, 231, 206, 1);
|
||||
}
|
||||
|
||||
.monaco-editor .debug-breakpoint-hint-glyph {
|
||||
.debug-breakpoint-hint {
|
||||
background: url('breakpoint-hint.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-breakpoint-disabled-glyph,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-disabled-glyph-column::before {
|
||||
.debug-breakpoint-disabled,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-disabled-column::before {
|
||||
background: url('breakpoint-disabled.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-breakpoint-unverified-glyph,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-unverified-glyph-column::before {
|
||||
.debug-breakpoint-unverified,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-unverified-column::before {
|
||||
background: url('breakpoint-unverified.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-top-stack-frame-glyph {
|
||||
.monaco-editor .debug-top-stack-frame {
|
||||
background: url('current-arrow.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-focused-stack-frame-glyph {
|
||||
.monaco-editor .debug-focused-stack-frame {
|
||||
background: url('stackframe-arrow.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-breakpoint-glyph,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-glyph-column::before {
|
||||
.debug-breakpoint,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-column::before {
|
||||
background: url('breakpoint.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
@@ -68,27 +68,40 @@
|
||||
background-position: initial !important;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-breakpoint-conditional-glyph,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-conditional-glyph-column::before {
|
||||
.debug-function-breakpoint {
|
||||
background: url('breakpoint-function.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.debug-function-breakpoint-unverified {
|
||||
background: url('breakpoint-function-unverified.svg') center center no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.debug-function-breakpoint-disabled {
|
||||
background: url('breakpoint-function-disabled.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.debug-breakpoint-conditional,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-conditional-column::before {
|
||||
background: url('breakpoint-conditional.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-breakpoint-unsupported-glyph,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-unsupported-glyph-column::before {
|
||||
.debug-breakpoint-unsupported,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-unsupported-column::before {
|
||||
background: url('breakpoint-unsupported.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-top-stack-frame-glyph.debug-breakpoint-glyph,
|
||||
.monaco-editor .debug-top-stack-frame-glyph.debug-breakpoint-conditional-glyph,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-glyph-column.debug-top-stack-frame-column::before,
|
||||
.monaco-editor.vs-dark .debug-top-stack-frame-glyph.debug-breakpoint-glyph,
|
||||
.monaco-editor.vs-dark .debug-top-stack-frame-glyph.debug-breakpoint-conditional-glyph,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-glyph-column.debug-top-stack-frame-column::before {
|
||||
.monaco-editor .debug-top-stack-frame.debug-breakpoint,
|
||||
.monaco-editor .debug-top-stack-frame.debug-breakpoint-conditional,
|
||||
.monaco-editor .debug-breakpoint-column.debug-breakpoint-column.debug-top-stack-frame-column::before,
|
||||
.monaco-editor.vs-dark .debug-top-stack-frame.debug-breakpoint,
|
||||
.monaco-editor.vs-dark .debug-top-stack-frame.debug-breakpoint-conditional,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-column.debug-top-stack-frame-column::before {
|
||||
background: url('current-and-breakpoint.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-focused-stack-frame-glyph.debug-breakpoint-glyph,
|
||||
.monaco-editor .debug-focused-stack-frame-glyph.debug-breakpoint-conditional-glyph {
|
||||
.monaco-editor .debug-focused-stack-frame.debug-breakpoint,
|
||||
.monaco-editor .debug-focused-stack-frame.debug-breakpoint-conditional {
|
||||
background: url('stackframe-and-breakpoint.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
@@ -233,40 +246,61 @@
|
||||
background-color: rgba(255, 255, 0, 0.3)
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-breakpoint-glyph,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-glyph-column::before {
|
||||
.vs-dark .debug-breakpoint,
|
||||
.hc-black .debug-breakpoint,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-column::before {
|
||||
background: url('breakpoint-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-breakpoint-conditional-glyph,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-conditional-glyph-column::before {
|
||||
.vs-dark .debug-breakpoint-conditional,
|
||||
.hc-black .debug-breakpoint-conditional,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-conditional-column::before {
|
||||
background: url('breakpoint-conditional-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-breakpoint-unsupported-glyph,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-unsupported-glyph-column::before {
|
||||
.vs-dark .debug-breakpoint-unsupported,
|
||||
.hc-black .debug-breakpoint-unsupported,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-unsupported-column::before {
|
||||
background: url('breakpoint-unsupported-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-breakpoint-disabled-glyph,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-disabled-glyph-column::before {
|
||||
.vs-dark .debug-breakpoint-disabled,
|
||||
.hc-black .debug-breakpoint-disabled,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-disabled-column::before {
|
||||
background: url('breakpoint-disabled-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-breakpoint-unverified-glyph,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-unverified-glyph-column::before {
|
||||
.vs-dark .debug-breakpoint-unverified,
|
||||
.hc-black .debug-breakpoint-unverified,
|
||||
.monaco-editor.vs-dark .debug-breakpoint-column.debug-breakpoint-unverified-column::before {
|
||||
background: url('breakpoint-unverified-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-focused-stack-frame-glyph {
|
||||
.monaco-editor.vs-dark .debug-focused-stack-frame {
|
||||
background: url('stackframe-arrow-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-focused-stack-frame-glyph.debug-breakpoint-glyph,
|
||||
.monaco-editor.vs-dark .debug-focused-stack-frame-glyph.debug-breakpoint-conditional-glyph {
|
||||
.monaco-editor.vs-dark .debug-focused-stack-frame.debug-breakpoint,
|
||||
.monaco-editor.vs-dark .debug-focused-stack-frame.debug-breakpoint-conditional {
|
||||
background: url('stackframe-and-breakpoint-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .debug-function-breakpoint,
|
||||
.hc-black .debug-function-breakpoint {
|
||||
background: url('breakpoint-function-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .debug-function-breakpoint-unverified,
|
||||
.hc-black .debug-function-breakpoint-unverified {
|
||||
background: url('breakpoint-function-unverified.svg') center center no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.vs-dark .debug-function-breakpoint-disabled,
|
||||
.hc-black .debug-function-breakpoint-disabled {
|
||||
background: url('breakpoint-function-disabled.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
/* High Contrast Theming */
|
||||
|
||||
.monaco-editor.hc-black .debug-focused-stack-frame-line {
|
||||
|
||||
@@ -348,7 +348,11 @@
|
||||
|
||||
/* Breakpoints */
|
||||
|
||||
.debug-viewlet .debug-breakpoints .monaco-list-row {
|
||||
.debug-viewlet .debug-breakpoints .monaco-list-row .breakpoint {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-breakpoints .breakpoint.exception {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
@@ -363,6 +367,11 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-breakpoints .breakpoint > .icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-breakpoints .breakpoint > .file-path {
|
||||
opacity: 0.7;
|
||||
font-size: 0.9em;
|
||||
|
||||
123
src/vs/workbench/parts/debug/browser/statusbarColorProvider.ts
Normal file
123
src/vs/workbench/parts/debug/browser/statusbarColorProvider.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { registerColor, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
import { IDebugService, State } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_BACKGROUND, Themable, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER, STATUS_BAR_BORDER } from 'vs/workbench/common/theme';
|
||||
import { addClass, removeClass, createStyleSheet } from 'vs/base/browser/dom';
|
||||
|
||||
// colors for theming
|
||||
|
||||
export const STATUS_BAR_DEBUGGING_BACKGROUND = registerColor('statusBar.debuggingBackground', {
|
||||
dark: '#CC6633',
|
||||
light: '#CC6633',
|
||||
hc: '#CC6633'
|
||||
}, localize('statusBarDebuggingBackground', "Status bar background color when a program is being debugged. The status bar is shown in the bottom of the window"));
|
||||
|
||||
export const STATUS_BAR_DEBUGGING_FOREGROUND = registerColor('statusBar.debuggingForeground', {
|
||||
dark: STATUS_BAR_FOREGROUND,
|
||||
light: STATUS_BAR_FOREGROUND,
|
||||
hc: STATUS_BAR_FOREGROUND
|
||||
}, localize('statusBarDebuggingForeground', "Status bar foreground color when a program is being debugged. The status bar is shown in the bottom of the window"));
|
||||
|
||||
export const STATUS_BAR_DEBUGGING_BORDER = registerColor('statusBar.debuggingBorder', {
|
||||
dark: STATUS_BAR_BORDER,
|
||||
light: STATUS_BAR_BORDER,
|
||||
hc: STATUS_BAR_BORDER
|
||||
}, localize('statusBarDebuggingBorder', "Status bar border color separating to the sidebar and editor when a program is being debugged. The status bar is shown in the bottom of the window"));
|
||||
|
||||
export class StatusBarColorProvider extends Themable implements IWorkbenchContribution {
|
||||
private styleElement: HTMLStyleElement;
|
||||
|
||||
constructor(
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IPartService private partService: IPartService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this.toUnbind.push(this.debugService.onDidChangeState(state => this.updateStyles()));
|
||||
this.toUnbind.push(this.contextService.onDidChangeWorkbenchState(state => this.updateStyles()));
|
||||
}
|
||||
|
||||
protected updateStyles(): void {
|
||||
super.updateStyles();
|
||||
|
||||
const container = this.partService.getContainer(Parts.STATUSBAR_PART);
|
||||
if (this.isDebugging()) {
|
||||
addClass(container, 'debugging');
|
||||
} else {
|
||||
removeClass(container, 'debugging');
|
||||
}
|
||||
|
||||
// Container Colors
|
||||
const backgroundColor = this.getColor(this.getColorKey(STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_DEBUGGING_BACKGROUND, STATUS_BAR_BACKGROUND));
|
||||
container.style.backgroundColor = backgroundColor;
|
||||
container.style.color = this.getColor(this.getColorKey(STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_DEBUGGING_FOREGROUND, STATUS_BAR_FOREGROUND));
|
||||
|
||||
// Border Color
|
||||
const borderColor = this.getColor(this.getColorKey(STATUS_BAR_NO_FOLDER_BORDER, STATUS_BAR_DEBUGGING_BORDER, STATUS_BAR_BORDER)) || this.getColor(contrastBorder);
|
||||
container.style.borderTopWidth = borderColor ? '1px' : null;
|
||||
container.style.borderTopStyle = borderColor ? 'solid' : null;
|
||||
container.style.borderTopColor = borderColor;
|
||||
|
||||
// Notification Beak
|
||||
if (!this.styleElement) {
|
||||
this.styleElement = createStyleSheet(container);
|
||||
}
|
||||
|
||||
this.styleElement.innerHTML = `.monaco-workbench > .part.statusbar > .statusbar-item.has-beak:before { border-bottom-color: ${backgroundColor} !important; }`;
|
||||
}
|
||||
|
||||
private getColorKey(noFolderColor: string, debuggingColor: string, normalColor: string): string {
|
||||
|
||||
// Not debugging
|
||||
if (!this.isDebugging()) {
|
||||
if (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
|
||||
return normalColor;
|
||||
}
|
||||
|
||||
return noFolderColor;
|
||||
}
|
||||
|
||||
// Debugging
|
||||
return debuggingColor;
|
||||
}
|
||||
|
||||
private isDebugging(): boolean {
|
||||
if (this.debugService.state === State.Inactive || this.debugService.state === State.Initializing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isRunningWithoutDebug()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private isRunningWithoutDebug(): boolean {
|
||||
const process = this.debugService.getViewModel().focusedProcess;
|
||||
|
||||
return process && process.configuration && process.configuration.noDebug;
|
||||
}
|
||||
}
|
||||
|
||||
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; }`);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user