Merge from vscode de81ccf04849309f843db21130c806a5783678f7 (#4738)

This commit is contained in:
Anthony Dresser
2019-03-28 13:06:16 -07:00
committed by GitHub
parent cc2951265e
commit e6785ffe95
77 changed files with 562 additions and 835 deletions

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { RunOnceScheduler, ignoreErrors } from 'vs/base/common/async';
import { RunOnceScheduler, ignoreErrors, sequence } from 'vs/base/common/async';
import * as dom from 'vs/base/browser/dom';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IDebugService, State, IStackFrame, IDebugSession, IThread, CONTEXT_CALLSTACK_ITEM_TYPE, IDebugModel } from 'vs/workbench/contrib/debug/common/debug';
@@ -28,6 +28,7 @@ import { TreeResourceNavigator2, WorkbenchAsyncDataTree } from 'vs/platform/list
import { onUnexpectedError } from 'vs/base/common/errors';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { createMatches, FuzzyScore } from 'vs/base/common/filters';
import { Event } from 'vs/base/common/event';
const $ = dom.$;
@@ -45,6 +46,7 @@ export class CallStackView extends ViewletPanel {
private dataSource: CallStackDataSource;
private tree: WorkbenchAsyncDataTree<CallStackItem | IDebugModel, CallStackItem, FuzzyScore>;
private contributedContextMenu: IMenu;
private parentSessionToExpand = new Set<IDebugSession>();
constructor(
private options: IViewletViewOptions,
@@ -80,7 +82,11 @@ export class CallStackView extends ViewletPanel {
this.needsRefresh = false;
this.dataSource.deemphasizedStackFramesToShow = [];
this.tree.updateChildren().then(() => this.updateTreeSelection());
this.tree.updateChildren().then(() => {
this.parentSessionToExpand.forEach(s => this.tree.expand(s));
this.parentSessionToExpand.clear();
this.updateTreeSelection();
});
}, 50);
}
@@ -193,7 +199,8 @@ export class CallStackView extends ViewletPanel {
this.onCallStackChangeScheduler.schedule();
}
}));
this.disposables.push(this.debugService.getViewModel().onDidFocusStackFrame(() => {
const onCallStackChange = Event.any<any>(this.debugService.getViewModel().onDidFocusStackFrame, this.debugService.getViewModel().onDidFocusSession);
this.disposables.push(onCallStackChange(() => {
if (this.ignoreFocusStackFrameEvent) {
return;
}
@@ -216,6 +223,13 @@ export class CallStackView extends ViewletPanel {
this.onCallStackChangeScheduler.schedule();
}
}));
this.disposables.push(this.debugService.onDidNewSession(s => {
if (s.parentSession) {
// Auto expand sessions that have sub sessions
this.parentSessionToExpand.add(s.parentSession);
}
}));
}
layoutBody(height: number, width: number): void {
@@ -253,11 +267,20 @@ export class CallStackView extends ViewletPanel {
updateSelectionAndReveal(session);
}
} else {
const expansionsPromise = ignoreErrors(this.tree.expand(thread.session))
.then(() => ignoreErrors(this.tree.expand(thread)));
if (stackFrame) {
expansionsPromise.then(() => updateSelectionAndReveal(stackFrame));
const expandPromises = [() => ignoreErrors(this.tree.expand(thread))];
let s: IDebugSession | undefined = thread.session;
while (s) {
const sessionToExpand = s;
expandPromises.push(() => ignoreErrors(this.tree.expand(sessionToExpand)));
s = s.parentSession;
}
sequence(expandPromises.reverse()).then(() => {
const toReveal = stackFrame || session;
if (toReveal) {
updateSelectionAndReveal(toReveal);
}
});
}
}
@@ -574,7 +597,7 @@ class CallStackDataSource implements IAsyncDataSource<IDebugModel, CallStackItem
if (sessions.length === 0) {
return Promise.resolve([]);
}
if (sessions.length > 1) {
if (sessions.length > 1 || this.debugService.getViewModel().isMultiSessionView()) {
return Promise.resolve(sessions.filter(s => !s.parentSession));
}

View File

@@ -214,6 +214,10 @@ export class FocusSessionActionItem extends SelectActionItem {
this.update();
}
protected getActionContext(_: string, index: number): any {
return this.debugService.getModel().getSessions()[index];
}
private update() {
const session = this.debugService.getViewModel().focusedSession;
const sessions = this.getSessions();

View File

@@ -8,22 +8,14 @@ import { Action } from 'vs/base/common/actions';
import * as lifecycle from 'vs/base/common/lifecycle';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IDebugService, State, IDebugSession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID }
from 'vs/workbench/contrib/debug/common/debug';
import { Variable, Expression, Thread, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IDebugService, State, IEnablement, IBreakpoint, IDebugSession } from 'vs/workbench/contrib/debug/common/debug';
import { Variable, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
import { IEditorService } 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 { first } from 'vs/base/common/arrays';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { memoize } from 'vs/base/common/decorators';
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
import { startDebugging } from 'vs/workbench/contrib/debug/common/debugUtils';
export abstract class AbstractDebugAction extends Action {
@@ -135,23 +127,8 @@ export class StartAction extends AbstractDebugAction {
this.toDispose.push(this.contextService.onDidChangeWorkbenchState(() => this.updateEnablement()));
}
// Note: When this action is executed from the process explorer, a config is passed. For all
// other cases it is run with no arguments.
public run(): Promise<any> {
const configurationManager = this.debugService.getConfigurationManager();
let launch = configurationManager.selectedConfiguration.launch;
if (!launch || launch.getConfigurationNames().length === 0) {
const rootUri = this.historyService.getLastActiveWorkspaceRoot();
launch = configurationManager.getLaunch(rootUri);
if (!launch || launch.getConfigurationNames().length === 0) {
const launches = configurationManager.getLaunches();
launch = first(launches, l => !!(l && l.getConfigurationNames().length), launch);
}
configurationManager.selectConfiguration(launch);
}
return this.debugService.startDebugging(launch, undefined, this.isNoDebug());
public run(): Promise<boolean> {
return startDebugging(this.debugService, this.historyService, this.isNoDebug());
}
protected isNoDebug(): boolean {
@@ -204,242 +181,6 @@ export class SelectAndStartAction extends AbstractDebugAction {
}
}
export class RestartAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.restart';
static LABEL = nls.localize('restartDebug', "Restart");
static RECONNECT_LABEL = nls.localize('reconnectDebug', "Reconnect");
constructor(id: string, label: string,
@IDebugService debugService: IDebugService,
@IKeybindingService keybindingService: IKeybindingService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IHistoryService private readonly historyService: IHistoryService
) {
super(id, label, 'debug-action restart', debugService, keybindingService, 70);
this.setLabel(this.debugService.getViewModel().focusedSession);
this.toDispose.push(this.debugService.getViewModel().onDidFocusSession(() => this.setLabel(this.debugService.getViewModel().focusedSession)));
}
@memoize
private get startAction(): StartAction {
return new StartAction(StartAction.ID, StartAction.LABEL, this.debugService, this.keybindingService, this.contextService, this.historyService);
}
private setLabel(session: IDebugSession | undefined): void {
if (session) {
this.updateLabel(session && session.configuration.request === 'attach' ? RestartAction.RECONNECT_LABEL : RestartAction.LABEL);
}
}
public run(session: IDebugSession | undefined): Promise<any> {
if (!session || !session.getId) {
session = this.debugService.getViewModel().focusedSession;
}
if (!session) {
return this.startAction.run();
}
session.removeReplExpressions();
return this.debugService.restartSession(session);
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && (
state === State.Running ||
state === State.Stopped ||
StartAction.isEnabled(this.debugService)
);
}
}
export class StepOverAction extends AbstractDebugAction {
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) {
super(id, label, 'debug-action step-over', debugService, keybindingService, 20);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.next() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && state === State.Stopped;
}
}
export class StepIntoAction extends AbstractDebugAction {
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) {
super(id, label, 'debug-action step-into', debugService, keybindingService, 30);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.stepIn() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && state === State.Stopped;
}
}
export class StepOutAction extends AbstractDebugAction {
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) {
super(id, label, 'debug-action step-out', debugService, keybindingService, 40);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.stepOut() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && state === State.Stopped;
}
}
export class StopAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.stop';
static LABEL = nls.localize('stopDebug', "Stop");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action stop', debugService, keybindingService, 80);
}
public run(session: IDebugSession | undefined): Promise<any> {
if (!session || !session.getId) {
session = this.debugService.getViewModel().focusedSession;
}
return this.debugService.stopSession(session);
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && (state !== State.Inactive);
}
}
export class DisconnectAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.disconnect';
static LABEL = nls.localize('disconnectDebug', "Disconnect");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action disconnect', debugService, keybindingService, 80);
}
public run(): Promise<any> {
const session = this.debugService.getViewModel().focusedSession;
return this.debugService.stopSession(session);
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && (state === State.Running || state === State.Stopped);
}
}
export class ContinueAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.continue';
static LABEL = nls.localize('continueDebug', "Continue");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action continue', debugService, keybindingService, 10);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.continue() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && state === State.Stopped;
}
}
export class PauseAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.pause';
static LABEL = nls.localize('pauseDebug', "Pause");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action pause', debugService, keybindingService, 10);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
if (!thread) {
const session = this.debugService.getViewModel().focusedSession;
const threads = session && session.getAllThreads();
thread = threads && threads.length ? threads[0] : undefined;
}
}
return thread ? thread.pause() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && state === State.Running;
}
}
export class TerminateThreadAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.terminateThread';
static LABEL = nls.localize('terminateThread', "Terminate Thread");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, '', debugService, keybindingService);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.terminate() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && (state === State.Running || state === State.Stopped);
}
}
export class RestartFrameAction extends AbstractDebugAction {
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) {
super(id, label, '', debugService, keybindingService);
}
public run(frame: IStackFrame | undefined): Promise<any> {
if (!frame) {
frame = this.debugService.getViewModel().focusedStackFrame;
}
return frame!.restart();
}
}
export class RemoveBreakpointAction extends AbstractDebugAction {
static readonly ID = 'workbench.debug.viewlet.action.removeBreakpoint';
static LABEL = nls.localize('removeBreakpoint', "Remove Breakpoint");
@@ -575,29 +316,6 @@ export class AddFunctionBreakpointAction extends AbstractDebugAction {
}
}
export class SetValueAction extends AbstractDebugAction {
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) {
super(id, label, '', debugService, keybindingService);
}
public run(): Promise<any> {
if (this.variable instanceof Variable) {
this.debugService.getViewModel().setSelectedExpression(this.variable);
}
return Promise.resolve();
}
protected isEnabled(state: State): boolean {
const session = this.debugService.getViewModel().focusedSession;
return !!(super.isEnabled(state) && state === State.Stopped && session && session.capabilities.supportsSetVariable);
}
}
export class AddWatchExpressionAction extends AbstractDebugAction {
static readonly ID = 'workbench.debug.viewlet.action.addWatchExpression';
static LABEL = nls.localize('addWatchExpression', "Add Expression");
@@ -617,53 +335,6 @@ export class AddWatchExpressionAction extends AbstractDebugAction {
}
}
export class EditWatchExpressionAction extends AbstractDebugAction {
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) {
super(id, label, '', debugService, keybindingService);
}
public run(expression: Expression): Promise<any> {
this.debugService.getViewModel().setSelectedExpression(expression);
return Promise.resolve();
}
}
export class AddToWatchExpressionsAction extends AbstractDebugAction {
static readonly ID = 'workbench.debug.viewlet.action.addToWatchExpressions';
static LABEL = nls.localize('addToWatchExpressions', "Add to Watch");
constructor(id: string, label: string, private variable: Variable, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action add-to-watch', debugService, keybindingService);
this.updateEnablement();
}
public run(): Promise<any> {
this.debugService.addWatchExpression(this.variable.evaluateName);
return Promise.resolve(undefined);
}
protected isEnabled(state: State): boolean {
return super.isEnabled(state) && this.variable && !!this.variable.evaluateName;
}
}
export class RemoveWatchExpressionAction extends AbstractDebugAction {
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) {
super(id, label, '', debugService, keybindingService);
}
public run(expression: Expression): Promise<any> {
this.debugService.removeWatchExpressions(expression.getId());
return Promise.resolve();
}
}
export class RemoveAllWatchExpressionsAction extends AbstractDebugAction {
static readonly ID = 'workbench.debug.viewlet.action.removeAllWatchExpressions';
static LABEL = nls.localize('removeAllWatchExpressions', "Remove All Expressions");
@@ -683,53 +354,6 @@ export class RemoveAllWatchExpressionsAction extends AbstractDebugAction {
}
}
export class ToggleReplAction extends TogglePanelAction {
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[];
constructor(id: string, label: string,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@IPanelService panelService: IPanelService
) {
super(id, label, REPL_ID, panelService, layoutService, 'debug-action toggle-repl');
this.toDispose = [];
this.registerListeners();
}
private registerListeners(): void {
this.toDispose.push(this.panelService.onDidPanelOpen(({ panel }) => {
if (panel.getId() === REPL_ID) {
this.class = 'debug-action toggle-repl';
this.tooltip = ToggleReplAction.LABEL;
}
}));
}
public dispose(): void {
super.dispose();
this.toDispose = lifecycle.dispose(this.toDispose);
}
}
export class FocusReplAction extends Action {
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 on Debug Console View');
constructor(id: string, label: string,
@IPanelService private readonly panelService: IPanelService
) {
super(id, label);
}
public run(): Promise<any> {
this.panelService.openPanel(REPL_ID, true);
return Promise.resolve();
}
}
export class FocusSessionAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.focusProcess';
static LABEL = nls.localize('focusSession', "Focus Session");
@@ -742,8 +366,7 @@ export class FocusSessionAction extends AbstractDebugAction {
super(id, label, '', debugService, keybindingService, 100);
}
public run(sessionName: string): Promise<any> {
const session = this.debugService.getModel().getSessions().filter(p => p.getLabel() === sessionName).pop();
public run(session: IDebugSession): Promise<any> {
this.debugService.focusStackFrame(undefined, undefined, session, true);
const stackFrame = this.debugService.getViewModel().focusedStackFrame;
if (stackFrame) {
@@ -754,65 +377,6 @@ export class FocusSessionAction extends AbstractDebugAction {
}
}
// Actions used by the chakra debugger
export class StepBackAction extends AbstractDebugAction {
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) {
super(id, label, 'debug-action step-back', debugService, keybindingService, 50);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.stepBack() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
const session = this.debugService.getViewModel().focusedSession;
return !!(super.isEnabled(state) && state === State.Stopped &&
session && session.capabilities.supportsStepBack);
}
}
export class ReverseContinueAction extends AbstractDebugAction {
static readonly ID = 'workbench.action.debug.reverseContinue';
static LABEL = nls.localize('reverseContinue', "Reverse");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action reverse-continue', debugService, keybindingService, 60);
}
public run(thread: IThread | undefined): Promise<any> {
if (!(thread instanceof Thread)) {
thread = this.debugService.getViewModel().focusedThread;
}
return thread ? thread.reverseContinue() : Promise.resolve();
}
protected isEnabled(state: State): boolean {
const session = this.debugService.getViewModel().focusedSession;
return !!(super.isEnabled(state) && state === State.Stopped &&
session && session.capabilities.supportsStepBack);
}
}
export class ReplCollapseAllAction extends CollapseAction {
constructor(tree: AsyncDataTree<any, any, any>, private toFocus: { focus(): void; }) {
super(tree, true, undefined);
}
public run(event?: any): Promise<any> {
return super.run(event).then(() => {
this.toFocus.focus();
});
}
}
export class CopyValueAction extends Action {
static readonly ID = 'workbench.debug.viewlet.action.copyValue';
static LABEL = nls.localize('copyValue', "Copy Value");
@@ -840,57 +404,3 @@ export class CopyValueAction extends Action {
return Promise.resolve(undefined);
}
}
export class CopyEvaluatePathAction extends Action {
static readonly ID = 'workbench.debug.viewlet.action.copyEvaluatePath';
static LABEL = nls.localize('copyAsExpression', "Copy as Expression");
constructor(
id: string, label: string, private value: Variable,
@IClipboardService private readonly clipboardService: IClipboardService
) {
super(id, label);
this._enabled = this.value && !!this.value.evaluateName;
}
public run(): Promise<any> {
this.clipboardService.writeText(this.value.evaluateName!);
return Promise.resolve(undefined);
}
}
export class CopyAction extends Action {
static readonly ID = 'workbench.debug.action.copy';
static LABEL = nls.localize('copy', "Copy");
constructor(
id: string, label: string,
@IClipboardService private readonly clipboardService: IClipboardService
) {
super(id, label);
}
public run(): Promise<any> {
this.clipboardService.writeText(window.getSelection().toString());
return Promise.resolve(undefined);
}
}
export class CopyStackTraceAction extends Action {
static readonly ID = 'workbench.action.debug.copyStackTrace';
static LABEL = nls.localize('copyStackTrace', "Copy Call Stack");
constructor(
id: string, label: string,
@IClipboardService private readonly clipboardService: IClipboardService,
@ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService
) {
super(id, label);
}
public run(frame: IStackFrame): Promise<any> {
const eol = this.textResourcePropertiesService.getEOL(frame.source.uri);
this.clipboardService.writeText(frame.thread.getCallStack().map(sf => sf.toString()).join(eol));
return Promise.resolve(undefined);
}
}

View File

@@ -149,7 +149,19 @@ export function registerCommands(): void {
primary: KeyCode.F6,
when: CONTEXT_DEBUG_STATE.isEqualTo('running'),
handler: (accessor: ServicesAccessor, _: string, thread: IThread | undefined) => {
getThreadAndRun(accessor, thread, thread => thread.pause());
const debugService = accessor.get(IDebugService);
if (!(thread instanceof Thread)) {
thread = debugService.getViewModel().focusedThread;
if (!thread) {
const session = debugService.getViewModel().focusedSession;
const threads = session && session.getAllThreads();
thread = threads && threads.length ? threads[0] : undefined;
}
}
if (thread) {
thread.pause().then(undefined, onUnexpectedError);
}
}
});