Change:
Testing As already pointed out The "Open Disassembly View" command is now only visible when the active stackframe has a instructionPointerReference property. This makes it hard to discover. I suggest to have the context menu's "Open Disassembly View" command always visible if a debug adapter has the supportsDisassembleRequest capability. But the command should only be enabled if the active stackframe has a instructionPointerReference property. That results in a more stable user experience. Apart from that we should have the Open Disassembly View command in the command palette.
That's a fair suggestion. However, we are not sure how to disable a command...
commands have clauses and . clause determines if the command is present at all and if it is disabled. So please use the when registering the editor command for disablement.
Also we should consider to introduce a call stack context menu action for the Open Disassembly View.
will fix this.

Discussion:
registerDebugViewMenuItem(MenuId.DebugCallStackContext, STEP_OUT_ID, STEP_OUT_LABEL, 40, CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('thread'), CONTEXT_DEBUG_STATE.isEqualTo('stopped')); registerDebugViewMenuItem(MenuId.DebugCallStackContext, TERMINATE_THREAD_ID, nls.localize('terminateThread', "Terminate Thread"), 10, CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('thread'), undefined, 'termination'); registerDebugViewMenuItem(MenuId.DebugCallStackContext, RESTART_FRAME_ID, nls.localize('restartFrame', "Restart Frame"), 10, ContextKeyExpr.and(CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('stackFrame'), CONTEXT_RESTART_FRAME_SUPPORTED), CONTEXT_STACK_FRAME_SUPPORTS_RESTART); <del> registerDebugViewMenuItem(MenuId.DebugCallStackContext, COPY_STACK_TRACE_ID, nls.localize('copyStackTrace', "Copy Call Stack"), 20, CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('stackFrame')); </del> <ins> registerDebugViewMenuItem(MenuId.DebugCallStackContext, COPY_STACK_TRACE_ID, nls.localize('copyStackTrace', "Copy Call Stack"), 20, CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('stackFrame'), undefined, '3_modification'); </ins> registerDebugViewMenuItem(MenuId.DebugVariablesContext, SET_VARIABLE_ID, nls.localize('setValue', "Set Value"), 10, CONTEXT_SET_VARIABLE_SUPPORTED, undefined, '3_modification'); registerDebugViewMenuItem(MenuId.DebugVariablesContext, COPY_VALUE_ID, nls.localize('copyValue', "Copy Value"), 10, undefined, undefined, '5_cutcopypaste');

import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { registerEditorAction, EditorAction, IActionOptions, EditorAction2 } from 'vs/editor/browser/editorExtensions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; <del> import { IDebugService, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE, State, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, BreakpointWidgetContext, IBreakpoint, BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, REPL_VIEW_ID, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, WATCH_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_EXCEPTION_WIDGET_VISIBLE, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST } from 'vs/workbench/contrib/debug/common/debug'; </del> <ins> import { IDebugService, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE, State, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, BreakpointWidgetContext, IBreakpoint, BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, REPL_VIEW_ID, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, WATCH_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_EXCEPTION_WIDGET_VISIBLE, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST, CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE, CONTEXT_CALLSTACK_ITEM_TYPE } from 'vs/workbench/contrib/debug/common/debug'; </ins> import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { openBreakpointSource } from 'vs/workbench/contrib/debug/browser/breakpointsView';

} } <del> class OpenDisassemblyViewAction extends EditorAction { </del> <ins> class OpenDisassemblyViewAction extends EditorAction2 { </ins> public static readonly ID = 'editor.debug.action.openDisassemblyView'; <del> public static readonly LABEL = nls.localize('openDisassemblyView', "Open Disassembly View"); </del> constructor() { super({ id: OpenDisassemblyViewAction.ID, <del> label: OpenDisassemblyViewAction.LABEL, alias: 'Debug: Go to Disassembly', precondition: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, PanelFocusContext.toNegated(), CONTEXT_DEBUG_STATE.isEqualTo('stopped'), EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST), contextMenuOpts: { group: 'debug', order: 5 } </del> <ins> title: { value: nls.localize('openDisassemblyView', "Open Disassembly View"), original: 'Open Disassembly View', mnemonicTitle: nls.localize({ key: 'miDisassemblyView', comment: ['&& denotes a mnemonic'] }, "&&DisassemblyView") }, precondition: CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE, menu: [ { id: MenuId.EditorContext, group: 'debug', order: 5, when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, PanelFocusContext.toNegated(), CONTEXT_DEBUG_STATE.isEqualTo('stopped'), EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST) }, { id: MenuId.DebugCallStackContext, group: 'z_commands', order: 50, when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('stackFrame'), CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED) }, { id: MenuId.CommandPalette, when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED) } ] </ins> }); } <del> async run(accessor: ServicesAccessor, editor: ICodeEditor, ...args: any[]): Promise<void> { </del> <ins> runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: any[]): void { </ins> if (editor.hasModel()) { const editorService = accessor.get(IEditorService); editorService.openEditor(DisassemblyViewInput.instance, { pinned: true });

registerAction2(ToggleBreakpointAction); registerAction2(ConditionalBreakpointAction); registerAction2(LogPointAction); <del> registerEditorAction(OpenDisassemblyViewAction); </del> <ins> registerAction2(OpenDisassemblyViewAction); </ins> registerEditorAction(RunToCursorAction); registerEditorAction(StepIntoTargetsAction); registerEditorAction(SelectionToReplAction);

export const CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED = new RawContextKey<boolean>('disassembleRequestSupported', false, { type: 'boolean', description: nls.localize('disassembleRequestSupported', "True when the focused sessions supports disassemble request.") }); export const CONTEXT_DISASSEMBLY_VIEW_FOCUS = new RawContextKey<boolean>('disassemblyViewFocus', false, { type: 'boolean', description: nls.localize('disassemblyViewFocus', "True when the Disassembly View is focused.") }); export const CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST = new RawContextKey<boolean>('languageSupportsDisassembleRequest', false, { type: 'boolean', description: nls.localize('languageSupportsDisassembleRequest', "True when the language in the current editor supports disassemble request.") }); <ins> export const CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE = new RawContextKey<boolean>('focusedStackFrameHasInstructionReference', false, { type: 'boolean', description: nls.localize('focusedStackFrameHasInstructionReference', "True when the focused stack frame has instruction pointer reference.") }); </ins> export const EDITOR_CONTRIBUTION_ID = 'editor.contrib.debug'; export const BREAKPOINT_EDITOR_CONTRIBUTION_ID = 'editor.contrib.breakpoint';

*--------------------------------------------------------------------------------------------*/ import { Event, Emitter } from 'vs/base/common/event'; <del> import { CONTEXT_EXPRESSION_SELECTED, IViewModel, IStackFrame, IDebugSession, IThread, IExpression, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_SET_VARIABLE_SUPPORTED, CONTEXT_MULTI_SESSION_DEBUG, CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED } from 'vs/workbench/contrib/debug/common/debug'; </del> <ins> import { CONTEXT_EXPRESSION_SELECTED, IViewModel, IStackFrame, IDebugSession, IThread, IExpression, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_SET_VARIABLE_SUPPORTED, CONTEXT_MULTI_SESSION_DEBUG, CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE } from 'vs/workbench/contrib/debug/common/debug'; </ins> import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { isSessionAttach } from 'vs/workbench/contrib/debug/common/debugUtils';

private multiSessionDebug!: IContextKey<boolean>; private terminateDebuggeeSuported!: IContextKey<boolean>; private disassembleRequestSupported!: IContextKey<boolean>; <ins> private focusedStackFrameHasInstructionPointerReference!: IContextKey<Boolean>; </ins> constructor(private contextKeyService: IContextKeyService) { contextKeyService.bufferChangeEvents(() => {

this.multiSessionDebug = CONTEXT_MULTI_SESSION_DEBUG.bindTo(contextKeyService); this.terminateDebuggeeSuported = CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED.bindTo(contextKeyService); this.disassembleRequestSupported = CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED.bindTo(contextKeyService); <ins> this.focusedStackFrameHasInstructionPointerReference = CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE.bindTo(contextKeyService); </ins> }); }

this.jumpToCursorSupported.set(session ? !!session.capabilities.supportsGotoTargetsRequest : false); this.setVariableSupported.set(session ? !!session.capabilities.supportsSetVariable : false); this.terminateDebuggeeSuported.set(session ? !!session.capabilities.supportTerminateDebuggee : false); <del> this.disassembleRequestSupported.set(!!stackFrame?.instructionPointerReference && !!session?.capabilities.supportsDisassembleRequest); </del> <ins> this.disassembleRequestSupported.set(!!session?.capabilities.supportsDisassembleRequest); this.focusedStackFrameHasInstructionPointerReference.set(!!stackFrame?.instructionPointerReference); </ins> const attach = !!session && isSessionAttach(session); this.focusedSessionIsAttach.set(attach); });