Merge from vscode 777931080477e28b7c27e8f7d4b0d69897945946 (#9220)

This commit is contained in:
Anthony Dresser
2020-02-19 22:27:53 -08:00
committed by GitHub
parent ab6fb810f8
commit 0cec223301
115 changed files with 1431 additions and 1133 deletions

View File

@@ -915,14 +915,13 @@ export class DebugSession implements IDebugSession {
// Disconnects and clears state. Session can be initialized again for a new connection.
private shutdown(): void {
dispose(this.rawListeners);
if (this.raw) {
this.raw.disconnect();
this.raw.dispose();
this.raw = undefined;
}
this.fetchThreadsScheduler = undefined;
this.model.clearThreads(this.getId(), true);
if (this.raw) {
const raw = this.raw;
this.raw = undefined;
raw.disconnect();
raw.dispose();
}
this._onDidChangeState.fire();
}

View File

@@ -13,31 +13,6 @@
height: 100%;
}
.debug-pane .debug-start-view {
padding: 0 20px 0 20px;
}
.debug-pane .debug-start-view .monaco-button,
.debug-pane .debug-start-view .section {
margin-top: 20px;
}
.debug-pane .debug-start-view .top-section {
margin-top: 10px;
}
.debug-pane .debug-start-view .monaco-button {
max-width: 260px;
margin-left: auto;
margin-right: auto;
display: block;
}
.debug-pane .debug-start-view .click {
cursor: pointer;
color: #007ACC;
}
.monaco-workbench .debug-action.notification:after {
content: '';
width: 6px;

View File

@@ -3,64 +3,33 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as dom from 'vs/base/browser/dom';
import { Button } from 'vs/base/browser/ui/button/button';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { localize } from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { StartAction, ConfigureAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { IDebugService } from 'vs/workbench/contrib/debug/common/debug';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { equals } from 'vs/base/common/arrays';
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IViewDescriptorService, IViewsRegistry, Extensions } from 'vs/workbench/common/views';
import { Registry } from 'vs/platform/registry/common/platform';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const $ = dom.$;
import { WorkbenchStateContext } from 'vs/workbench/browser/contextkeys';
import { OpenFolderAction, OpenFileAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import { isMacintosh } from 'vs/base/common/platform';
interface DebugStartMetrics {
debuggers?: string[];
}
type DebugStartMetricsClassification = {
debuggers?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
function createClickElement(textContent: string, action: () => any): HTMLSpanElement {
const clickElement = $('span.click');
clickElement.textContent = textContent;
clickElement.onclick = action;
clickElement.tabIndex = 0;
clickElement.onkeyup = (e) => {
const keyboardEvent = new StandardKeyboardEvent(e);
if (keyboardEvent.keyCode === KeyCode.Enter || (keyboardEvent.keyCode === KeyCode.Space)) {
action();
}
};
return clickElement;
}
const CONTEXT_DEBUGGER_INTERESTED = new RawContextKey<boolean>('debuggerInterested', false);
export class StartView extends ViewPane {
static ID = 'workbench.debug.startView';
static LABEL = localize('start', "Start");
private debugButton!: Button;
private firstMessageContainer!: HTMLElement;
private secondMessageContainer!: HTMLElement;
private clickElement: HTMLElement | undefined;
private debuggerLabels: string[] | undefined = undefined;
private debuggerInterestedContext: IContextKey<boolean>;
constructor(
options: IViewletViewOptions,
@@ -69,125 +38,45 @@ export class StartView extends ViewPane {
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
@ICommandService private readonly commandService: ICommandService,
@IDebugService private readonly debugService: IDebugService,
@IEditorService private readonly editorService: IEditorService,
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
@IFileDialogService private readonly dialogService: IFileDialogService,
@IInstantiationService instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IOpenerService openerService: IOpenerService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Start Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this._register(editorService.onDidActiveEditorChange(() => this.updateView()));
this._register(this.debugService.getConfigurationManager().onDidRegisterDebugger(() => this.updateView()));
this.debuggerInterestedContext = CONTEXT_DEBUGGER_INTERESTED.bindTo(contextKeyService);
const setContextKey = () => {
const activeEditor = this.editorService.activeTextEditorWidget;
const debuggerLabels = this.debugService.getConfigurationManager().getDebuggerLabelsForEditor(activeEditor);
this.debuggerInterestedContext.set(debuggerLabels.length > 0);
};
this._register(editorService.onDidActiveEditorChange(setContextKey));
this._register(this.debugService.getConfigurationManager().onDidRegisterDebugger(setContextKey));
}
private updateView(): void {
const activeEditor = this.editorService.activeTextEditorWidget;
const debuggerLabels = this.debugService.getConfigurationManager().getDebuggerLabelsForEditor(activeEditor);
if (!equals(this.debuggerLabels, debuggerLabels)) {
this.debuggerLabels = debuggerLabels;
const enabled = this.debuggerLabels.length > 0;
this.debugButton.enabled = enabled;
const debugKeybinding = this.keybindingService.lookupKeybinding(StartAction.ID);
let debugLabel = this.debuggerLabels.length !== 1 ? localize('debug', "Run and Debug") : localize('debugWith', "Run and Debug {0}", this.debuggerLabels[0]);
if (debugKeybinding) {
debugLabel += ` (${debugKeybinding.getLabel()})`;
}
this.debugButton.label = debugLabel;
const emptyWorkbench = this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY;
this.firstMessageContainer.innerHTML = '';
this.secondMessageContainer.innerHTML = '';
const secondMessageElement = $('span');
this.secondMessageContainer.appendChild(secondMessageElement);
const setSecondMessage = () => {
secondMessageElement.textContent = localize('specifyHowToRun', "To customize Run and Debug");
this.clickElement = createClickElement(localize('configure', " create a launch.json file."), () => {
this.telemetryService.publicLog2<DebugStartMetrics, DebugStartMetricsClassification>('debugStart.configure', { debuggers: this.debuggerLabels });
this.commandService.executeCommand(ConfigureAction.ID);
});
this.secondMessageContainer.appendChild(this.clickElement);
};
const setSecondMessageWithFolder = () => {
secondMessageElement.textContent = localize('noLaunchConfiguration', "To customize Run and Debug, ");
this.clickElement = createClickElement(localize('openFolder', " open a folder"), () => {
this.telemetryService.publicLog2<DebugStartMetrics, DebugStartMetricsClassification>('debugStart.openFolder', { debuggers: this.debuggerLabels });
this.dialogService.pickFolderAndOpen({ forceNewWindow: false });
});
this.secondMessageContainer.appendChild(this.clickElement);
const moreText = $('span.moreText');
moreText.textContent = localize('andconfigure', " and create a launch.json file.");
this.secondMessageContainer.appendChild(moreText);
};
if (enabled && !emptyWorkbench) {
setSecondMessage();
}
if (enabled && emptyWorkbench) {
setSecondMessageWithFolder();
}
if (!enabled && !emptyWorkbench) {
const firstMessageElement = $('span');
this.firstMessageContainer.appendChild(firstMessageElement);
firstMessageElement.textContent = localize('simplyDebugAndRun', "Open a file which can be debugged or run.");
setSecondMessage();
}
if (!enabled && emptyWorkbench) {
this.clickElement = createClickElement(localize('openFile', "Open a file"), () => {
this.telemetryService.publicLog2<DebugStartMetrics, DebugStartMetricsClassification>('debugStart.openFile');
this.dialogService.pickFileAndOpen({ forceNewWindow: false });
});
this.firstMessageContainer.appendChild(this.clickElement);
const firstMessageElement = $('span');
this.firstMessageContainer.appendChild(firstMessageElement);
firstMessageElement.textContent = localize('canBeDebuggedOrRun', " which can be debugged or run.");
setSecondMessageWithFolder();
}
}
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
this.firstMessageContainer = $('.top-section');
container.appendChild(this.firstMessageContainer);
this.debugButton = new Button(container);
this._register(this.debugButton.onDidClick(() => {
this.commandService.executeCommand(StartAction.ID);
this.telemetryService.publicLog2<DebugStartMetrics, DebugStartMetricsClassification>('debugStart.runAndDebug', { debuggers: this.debuggerLabels });
}));
attachButtonStyler(this.debugButton, this.themeService);
dom.addClass(this.element, 'debug-pane');
dom.addClass(container, 'debug-start-view');
this.secondMessageContainer = $('.section');
container.appendChild(this.secondMessageContainer);
this.updateView();
}
protected layoutBody(_: number, __: number): void {
// no-op
}
focus(): void {
if (this.debugButton.enabled) {
this.debugButton.focus();
} else if (this.clickElement) {
this.clickElement.focus();
}
shouldShowWelcome(): boolean {
return true;
}
}
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
viewsRegistry.registerViewWelcomeContent(StartView.ID, {
content: localize('openAFileWhichCanBeDebugged', "[Open a file](command:{0}) which can be debugged or run.", isMacintosh ? OpenFileFolderAction.ID : OpenFileAction.ID),
when: CONTEXT_DEBUGGER_INTERESTED.toNegated()
});
viewsRegistry.registerViewWelcomeContent(StartView.ID, {
content: localize('runAndDebugAction', "[Run and Debug](command:{0})", StartAction.ID)
});
viewsRegistry.registerViewWelcomeContent(StartView.ID, {
content: localize('customizeRunAndDebug', "To customize Run and Debug [create a launch.json file](command:{0}).", ConfigureAction.ID),
when: WorkbenchStateContext.notEqualsTo('empty')
});
viewsRegistry.registerViewWelcomeContent(StartView.ID, {
content: localize('customizeRunAndDebugOpenFolder', "To customize Run and Debug, [open a folder](command:{0}) and create a launch.json file.", isMacintosh ? OpenFileFolderAction.ID : OpenFolderAction.ID),
when: WorkbenchStateContext.isEqualTo('empty')
});

View File

@@ -1773,6 +1773,16 @@ declare module DebugProtocol {
If missing the value 0 is assumed which results in the completion text being inserted.
*/
length?: number;
/** Determines the start of the new selection after the text has been inserted (or replaced).
The start position must in the range 0 and length of the completion text.
If omitted the selection starts at the end of the completion text.
*/
selectionStart?: number;
/** Determines the length of the new selection after the text has been inserted (or replaced).
The selection can not extend beyond the bounds of the completion text.
If omitted the length is assumed to be 0.
*/
selectionLength?: number;
}
/** Some predefined types for the CompletionItem. Please note that not all clients have specific icons for all of them. */