mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 13:46:13 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
121a3425a4
|
@ -81,6 +81,7 @@ const vscodeResources = [
|
|||
'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js',
|
||||
'out-build/vs/code/electron-browser/issue/issueReporter.js',
|
||||
'out-build/vs/code/electron-browser/processExplorer/processExplorer.js',
|
||||
'out-build/vs/platform/auth/common/auth.css',
|
||||
'!**/test/**'
|
||||
];
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
},
|
||||
"description": "Remote environment variables."
|
||||
},
|
||||
"remoteUser": {
|
||||
"type": "string",
|
||||
"description": "The user VS Code Server will be started with. The default is the same user as the container."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "array",
|
||||
"description": "An array of extensions that should be installed into the container.",
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
},
|
||||
"description": "Remote environment variables."
|
||||
},
|
||||
"remoteUser": {
|
||||
"type": "string",
|
||||
"description": "The user VS Code Server will be started with. The default is the same user as the container."
|
||||
},
|
||||
"postCreateCommand": {
|
||||
"type": [
|
||||
"string",
|
||||
|
@ -72,6 +76,14 @@
|
|||
},
|
||||
"description": "Container environment variables."
|
||||
},
|
||||
"containerUser": {
|
||||
"type": "string",
|
||||
"description": "The user the container will be started with. The default is the user on the Docker image."
|
||||
},
|
||||
"updateRemoteUserUID": {
|
||||
"type": "boolean",
|
||||
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default."
|
||||
},
|
||||
"runArgs": {
|
||||
"type": "array",
|
||||
"description": "The arguments required when starting in the container.",
|
||||
|
|
|
@ -22,8 +22,6 @@ export interface MarkdownRenderOptions extends FormattedTextRenderOptions {
|
|||
codeBlockRenderCallback?: () => void;
|
||||
}
|
||||
|
||||
const codiconsRegex = /^icon:\/\/vscode\.codicons\/(.*)$/;
|
||||
|
||||
/**
|
||||
* Create html nodes for the given content element.
|
||||
*/
|
||||
|
@ -75,11 +73,8 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
|||
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.image = (href: string, title: string, text: string) => {
|
||||
if (href) {
|
||||
const match = codiconsRegex.exec(href);
|
||||
if (match !== null) {
|
||||
return renderCodicons(`$(${match[1]})`);
|
||||
}
|
||||
if (href && href.indexOf('vscode-icon://codicon/') === 0) {
|
||||
return renderCodicons(`$(${URI.parse(href).path.substr(1)})`);
|
||||
}
|
||||
|
||||
let dimensions: string[] = [];
|
||||
|
|
|
@ -42,7 +42,7 @@ function toSplitViewView(view: IView, getHeight: () => number): ISplitViewView {
|
|||
get maximumSize() { return view.maximumWidth; },
|
||||
get minimumSize() { return view.minimumWidth; },
|
||||
onDidChange: Event.map(view.onDidChange, e => e && e.width),
|
||||
layout: size => view.layout(size, getHeight(), Orientation.HORIZONTAL)
|
||||
layout: (size, offset) => view.layout(size, getHeight(), 0, offset)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ export class CenteredViewLayout implements IDisposable {
|
|||
this.resizeMargins();
|
||||
}
|
||||
} else {
|
||||
this.view.layout(width, height, Orientation.HORIZONTAL);
|
||||
this.view.layout(width, height, 0, 0);
|
||||
}
|
||||
this.didLayout = true;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export interface IView {
|
|||
readonly onDidChange: Event<IViewSize | undefined>;
|
||||
readonly priority?: LayoutPriority;
|
||||
readonly snap?: boolean;
|
||||
layout(width: number, height: number, orientation: Orientation): void;
|
||||
layout(width: number, height: number, top: number, left: number): void;
|
||||
setVisible?(visible: boolean): void;
|
||||
}
|
||||
|
||||
|
@ -69,10 +69,10 @@ export function orthogonal(orientation: Orientation): Orientation {
|
|||
}
|
||||
|
||||
export interface Box {
|
||||
top: number;
|
||||
left: number;
|
||||
width: number;
|
||||
height: number;
|
||||
readonly top: number;
|
||||
readonly left: number;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
}
|
||||
|
||||
export interface GridLeafNode {
|
||||
|
@ -117,11 +117,19 @@ export interface IGridViewOptions {
|
|||
readonly layoutController?: ILayoutController;
|
||||
}
|
||||
|
||||
class BranchNode implements ISplitView, IDisposable {
|
||||
interface ILayoutContext {
|
||||
readonly orthogonalSize: number;
|
||||
readonly absoluteOffset: number;
|
||||
readonly absoluteOrthogonalOffset: number;
|
||||
readonly absoluteSize: number;
|
||||
readonly absoluteOrthogonalSize: number;
|
||||
}
|
||||
|
||||
class BranchNode implements ISplitView<ILayoutContext>, IDisposable {
|
||||
|
||||
readonly element: HTMLElement;
|
||||
readonly children: Node[] = [];
|
||||
private splitview: SplitView;
|
||||
private splitview: SplitView<ILayoutContext>;
|
||||
|
||||
private _size: number;
|
||||
get size(): number { return this._size; }
|
||||
|
@ -129,6 +137,9 @@ class BranchNode implements ISplitView, IDisposable {
|
|||
private _orthogonalSize: number;
|
||||
get orthogonalSize(): number { return this._orthogonalSize; }
|
||||
|
||||
private absoluteOffset: number = 0;
|
||||
private absoluteOrthogonalOffset: number = 0;
|
||||
|
||||
private _styles: IGridViewStyles;
|
||||
get styles(): IGridViewStyles { return this._styles; }
|
||||
|
||||
|
@ -140,6 +151,14 @@ class BranchNode implements ISplitView, IDisposable {
|
|||
return this.orientation === Orientation.HORIZONTAL ? this.orthogonalSize : this.size;
|
||||
}
|
||||
|
||||
get top(): number {
|
||||
return this.orientation === Orientation.HORIZONTAL ? this.absoluteOffset : this.absoluteOrthogonalOffset;
|
||||
}
|
||||
|
||||
get left(): number {
|
||||
return this.orientation === Orientation.HORIZONTAL ? this.absoluteOrthogonalOffset : this.absoluteOffset;
|
||||
}
|
||||
|
||||
get minimumSize(): number {
|
||||
return this.children.length === 0 ? 0 : Math.max(...this.children.map(c => c.minimumOrthogonalSize));
|
||||
}
|
||||
|
@ -221,7 +240,7 @@ class BranchNode implements ISplitView, IDisposable {
|
|||
if (!childDescriptors) {
|
||||
// Normal behavior, we have no children yet, just set up the splitview
|
||||
this.splitview = new SplitView(this.element, { orientation, styles, proportionalLayout });
|
||||
this.splitview.layout(size, orthogonalSize);
|
||||
this.splitview.layout(size, { orthogonalSize, absoluteOffset: 0, absoluteOrthogonalOffset: 0, absoluteSize: size, absoluteOrthogonalSize: orthogonalSize });
|
||||
} else {
|
||||
// Reconstruction behavior, we want to reconstruct a splitview
|
||||
const descriptor = {
|
||||
|
@ -268,20 +287,32 @@ class BranchNode implements ISplitView, IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
layout(size: number, orthogonalSize: number | undefined): void {
|
||||
layout(size: number, offset: number, ctx: ILayoutContext | undefined): void {
|
||||
if (!this.layoutController.isLayoutEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof orthogonalSize !== 'number') {
|
||||
if (typeof ctx === 'undefined') {
|
||||
throw new Error('Invalid state');
|
||||
}
|
||||
|
||||
// branch nodes should flip the normal/orthogonal directions
|
||||
this._size = orthogonalSize;
|
||||
this._size = ctx.orthogonalSize;
|
||||
this._orthogonalSize = size;
|
||||
this.absoluteOffset = ctx.absoluteOffset + offset;
|
||||
this.absoluteOrthogonalOffset = ctx.absoluteOrthogonalOffset;
|
||||
|
||||
this.splitview.layout(orthogonalSize, size);
|
||||
this.splitview.layout(ctx.orthogonalSize, {
|
||||
orthogonalSize: size,
|
||||
absoluteOffset: this.absoluteOrthogonalOffset,
|
||||
absoluteOrthogonalOffset: this.absoluteOffset,
|
||||
absoluteSize: ctx.absoluteOrthogonalSize,
|
||||
absoluteOrthogonalSize: ctx.absoluteSize
|
||||
});
|
||||
|
||||
// Disable snapping on views which sit on the edges of the grid
|
||||
this.splitview.startSnappingEnabled = this.absoluteOrthogonalOffset > 0;
|
||||
this.splitview.endSnappingEnabled = this.absoluteOrthogonalOffset + ctx.orthogonalSize < ctx.absoluteOrthogonalSize;
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
|
@ -511,7 +542,7 @@ class BranchNode implements ISplitView, IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
class LeafNode implements ISplitView, IDisposable {
|
||||
class LeafNode implements ISplitView<ILayoutContext>, IDisposable {
|
||||
|
||||
private _size: number = 0;
|
||||
get size(): number { return this._size; }
|
||||
|
@ -519,6 +550,9 @@ class LeafNode implements ISplitView, IDisposable {
|
|||
private _orthogonalSize: number;
|
||||
get orthogonalSize(): number { return this._orthogonalSize; }
|
||||
|
||||
private absoluteOffset: number = 0;
|
||||
private absoluteOrthogonalOffset: number = 0;
|
||||
|
||||
readonly onDidSashReset: Event<number[]> = Event.None;
|
||||
|
||||
private _onDidLinkedWidthNodeChange = new Relay<number | undefined>();
|
||||
|
@ -565,6 +599,14 @@ class LeafNode implements ISplitView, IDisposable {
|
|||
return this.orientation === Orientation.HORIZONTAL ? this.size : this.orthogonalSize;
|
||||
}
|
||||
|
||||
get top(): number {
|
||||
return this.orientation === Orientation.HORIZONTAL ? this.absoluteOffset : this.absoluteOrthogonalOffset;
|
||||
}
|
||||
|
||||
get left(): number {
|
||||
return this.orientation === Orientation.HORIZONTAL ? this.absoluteOrthogonalOffset : this.absoluteOffset;
|
||||
}
|
||||
|
||||
get element(): HTMLElement {
|
||||
return this.view.element;
|
||||
}
|
||||
|
@ -617,18 +659,20 @@ class LeafNode implements ISplitView, IDisposable {
|
|||
// noop
|
||||
}
|
||||
|
||||
layout(size: number, orthogonalSize: number | undefined): void {
|
||||
layout(size: number, offset: number, ctx: ILayoutContext | undefined): void {
|
||||
if (!this.layoutController.isLayoutEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof orthogonalSize !== 'number') {
|
||||
if (typeof ctx === 'undefined') {
|
||||
throw new Error('Invalid state');
|
||||
}
|
||||
|
||||
this._size = size;
|
||||
this._orthogonalSize = orthogonalSize;
|
||||
this.view.layout(this.width, this.height, orthogonal(this.orientation));
|
||||
this._orthogonalSize = ctx.orthogonalSize;
|
||||
this.absoluteOffset = ctx.absoluteOffset + offset;
|
||||
this.absoluteOrthogonalOffset = ctx.absoluteOrthogonalOffset;
|
||||
this.view.layout(this.width, this.height, this.top, this.left);
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
|
@ -715,7 +759,7 @@ export class GridView implements IDisposable {
|
|||
|
||||
const { size, orthogonalSize } = this._root;
|
||||
this.root = flipNode(this._root, orthogonalSize, size);
|
||||
this.root.layout(size, orthogonalSize);
|
||||
this.root.layout(size, 0, { orthogonalSize, absoluteOffset: 0, absoluteOrthogonalOffset: 0, absoluteSize: size, absoluteOrthogonalSize: orthogonalSize });
|
||||
}
|
||||
|
||||
get width(): number { return this.root.width; }
|
||||
|
@ -771,7 +815,7 @@ export class GridView implements IDisposable {
|
|||
this.firstLayoutController.isLayoutEnabled = true;
|
||||
|
||||
const [size, orthogonalSize] = this.root.orientation === Orientation.HORIZONTAL ? [height, width] : [width, height];
|
||||
this.root.layout(size, orthogonalSize);
|
||||
this.root.layout(size, 0, { orthogonalSize, absoluteOffset: 0, absoluteOrthogonalOffset: 0, absoluteSize: size, absoluteOrthogonalSize: orthogonalSize });
|
||||
}
|
||||
|
||||
addView(view: IView, size: number | Sizing, location: number[]): void {
|
||||
|
@ -1032,7 +1076,7 @@ export class GridView implements IDisposable {
|
|||
getView(location?: number[]): GridNode;
|
||||
getView(location?: number[]): GridNode {
|
||||
const node = location ? this.getNode(location)[1] : this._root;
|
||||
return this._getViews(node, this.orientation, { top: 0, left: 0, width: this.width, height: this.height });
|
||||
return this._getViews(node, this.orientation);
|
||||
}
|
||||
|
||||
static deserialize<T extends ISerializableView>(json: ISerializedGridView, deserializer: IViewDeserializer<T>, options: IGridViewOptions = {}): GridView {
|
||||
|
@ -1076,24 +1120,20 @@ export class GridView implements IDisposable {
|
|||
return result;
|
||||
}
|
||||
|
||||
private _getViews(node: Node, orientation: Orientation, box: Box, cachedVisibleSize?: number): GridNode {
|
||||
private _getViews(node: Node, orientation: Orientation, cachedVisibleSize?: number): GridNode {
|
||||
const box = { top: node.top, left: node.left, width: node.width, height: node.height };
|
||||
|
||||
if (node instanceof LeafNode) {
|
||||
return { view: node.view, box, cachedVisibleSize };
|
||||
}
|
||||
|
||||
const children: GridNode[] = [];
|
||||
let i = 0;
|
||||
let offset = 0;
|
||||
|
||||
for (const child of node.children) {
|
||||
const childOrientation = orthogonal(orientation);
|
||||
const childBox: Box = orientation === Orientation.HORIZONTAL
|
||||
? { top: box.top, left: box.left + offset, width: child.width, height: box.height }
|
||||
: { top: box.top + offset, left: box.left, width: box.width, height: child.height };
|
||||
const cachedVisibleSize = node.getChildCachedVisibleSize(i++);
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
const child = node.children[i];
|
||||
const cachedVisibleSize = node.getChildCachedVisibleSize(i);
|
||||
|
||||
children.push(this._getViews(child, childOrientation, childBox, cachedVisibleSize));
|
||||
offset += orientation === Orientation.HORIZONTAL ? child.width : child.height;
|
||||
children.push(this._getViews(child, orthogonal(orientation), cachedVisibleSize));
|
||||
}
|
||||
|
||||
return { children, box };
|
||||
|
|
|
@ -23,14 +23,14 @@ const defaultStyles: ISplitViewStyles = {
|
|||
separatorBorder: Color.transparent
|
||||
};
|
||||
|
||||
export interface ISplitViewOptions {
|
||||
export interface ISplitViewOptions<TLayoutContext = undefined> {
|
||||
readonly orientation?: Orientation; // default Orientation.VERTICAL
|
||||
readonly styles?: ISplitViewStyles;
|
||||
readonly orthogonalStartSash?: Sash;
|
||||
readonly orthogonalEndSash?: Sash;
|
||||
readonly inverseAltBehavior?: boolean;
|
||||
readonly proportionalLayout?: boolean; // default true,
|
||||
readonly descriptor?: ISplitViewDescriptor;
|
||||
readonly descriptor?: ISplitViewDescriptor<TLayoutContext>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,14 +42,14 @@ export const enum LayoutPriority {
|
|||
High
|
||||
}
|
||||
|
||||
export interface IView {
|
||||
export interface IView<TLayoutContext = undefined> {
|
||||
readonly element: HTMLElement;
|
||||
readonly minimumSize: number;
|
||||
readonly maximumSize: number;
|
||||
readonly onDidChange: Event<number | undefined>;
|
||||
readonly priority?: LayoutPriority;
|
||||
readonly snap?: boolean;
|
||||
layout(size: number, orthogonalSize: number | undefined): void;
|
||||
layout(size: number, offset: number, context: TLayoutContext | undefined): void;
|
||||
setVisible?(visible: boolean): void;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ interface ISashEvent {
|
|||
|
||||
type ViewItemSize = number | { cachedVisibleSize: number };
|
||||
|
||||
abstract class ViewItem {
|
||||
abstract class ViewItem<TLayoutContext> {
|
||||
|
||||
private _size: number;
|
||||
set size(size: number) {
|
||||
|
@ -115,7 +115,7 @@ abstract class ViewItem {
|
|||
|
||||
constructor(
|
||||
protected container: HTMLElement,
|
||||
private view: IView,
|
||||
private view: IView<TLayoutContext>,
|
||||
size: ViewItemSize,
|
||||
private disposable: IDisposable
|
||||
) {
|
||||
|
@ -129,31 +129,31 @@ abstract class ViewItem {
|
|||
}
|
||||
}
|
||||
|
||||
layout(position: number, orthogonalSize: number | undefined): void {
|
||||
this.layoutContainer(position);
|
||||
this.view.layout(this.size, orthogonalSize);
|
||||
layout(offset: number, layoutContext: TLayoutContext | undefined): void {
|
||||
this.layoutContainer(offset);
|
||||
this.view.layout(this.size, offset, layoutContext);
|
||||
}
|
||||
|
||||
abstract layoutContainer(position: number): void;
|
||||
abstract layoutContainer(offset: number): void;
|
||||
|
||||
dispose(): IView {
|
||||
dispose(): IView<TLayoutContext> {
|
||||
this.disposable.dispose();
|
||||
return this.view;
|
||||
}
|
||||
}
|
||||
|
||||
class VerticalViewItem extends ViewItem {
|
||||
class VerticalViewItem<TLayoutContext> extends ViewItem<TLayoutContext> {
|
||||
|
||||
layoutContainer(position: number): void {
|
||||
this.container.style.top = `${position}px`;
|
||||
layoutContainer(offset: number): void {
|
||||
this.container.style.top = `${offset}px`;
|
||||
this.container.style.height = `${this.size}px`;
|
||||
}
|
||||
}
|
||||
|
||||
class HorizontalViewItem extends ViewItem {
|
||||
class HorizontalViewItem<TLayoutContext> extends ViewItem<TLayoutContext> {
|
||||
|
||||
layoutContainer(position: number): void {
|
||||
this.container.style.left = `${position}px`;
|
||||
layoutContainer(offset: number): void {
|
||||
this.container.style.left = `${offset}px`;
|
||||
this.container.style.width = `${this.size}px`;
|
||||
}
|
||||
}
|
||||
|
@ -198,26 +198,26 @@ export namespace Sizing {
|
|||
export function Invisible(cachedVisibleSize: number): InvisibleSizing { return { type: 'invisible', cachedVisibleSize }; }
|
||||
}
|
||||
|
||||
export interface ISplitViewDescriptor {
|
||||
export interface ISplitViewDescriptor<TLayoutContext> {
|
||||
size: number;
|
||||
views: {
|
||||
visible?: boolean;
|
||||
size: number;
|
||||
view: IView;
|
||||
view: IView<TLayoutContext>;
|
||||
}[];
|
||||
}
|
||||
|
||||
export class SplitView extends Disposable {
|
||||
export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
|
||||
readonly orientation: Orientation;
|
||||
readonly el: HTMLElement;
|
||||
private sashContainer: HTMLElement;
|
||||
private viewContainer: HTMLElement;
|
||||
private size = 0;
|
||||
private orthogonalSize: number | undefined;
|
||||
private layoutContext: TLayoutContext | undefined;
|
||||
private contentSize = 0;
|
||||
private proportions: undefined | number[] = undefined;
|
||||
private viewItems: ViewItem[] = [];
|
||||
private viewItems: ViewItem<TLayoutContext>[] = [];
|
||||
private sashItems: ISashItem[] = [];
|
||||
private sashDragState: ISashDragState | undefined;
|
||||
private state: State = State.Idle;
|
||||
|
@ -266,7 +266,29 @@ export class SplitView extends Disposable {
|
|||
return this.sashItems.map(s => s.sash);
|
||||
}
|
||||
|
||||
constructor(container: HTMLElement, options: ISplitViewOptions = {}) {
|
||||
private _startSnappingEnabled = true;
|
||||
get startSnappingEnabled(): boolean { return this._startSnappingEnabled; }
|
||||
set startSnappingEnabled(startSnappingEnabled: boolean) {
|
||||
if (this._startSnappingEnabled === startSnappingEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._startSnappingEnabled = startSnappingEnabled;
|
||||
this.updateSashEnablement();
|
||||
}
|
||||
|
||||
private _endSnappingEnabled = true;
|
||||
get endSnappingEnabled(): boolean { return this._endSnappingEnabled; }
|
||||
set endSnappingEnabled(endSnappingEnabled: boolean) {
|
||||
if (this._endSnappingEnabled === endSnappingEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._endSnappingEnabled = endSnappingEnabled;
|
||||
this.updateSashEnablement();
|
||||
}
|
||||
|
||||
constructor(container: HTMLElement, options: ISplitViewOptions<TLayoutContext> = {}) {
|
||||
super();
|
||||
|
||||
this.orientation = types.isUndefined(options.orientation) ? Orientation.VERTICAL : options.orientation;
|
||||
|
@ -309,11 +331,11 @@ export class SplitView extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
addView(view: IView, size: number | Sizing, index = this.viewItems.length): void {
|
||||
addView(view: IView<TLayoutContext>, size: number | Sizing, index = this.viewItems.length): void {
|
||||
this.doAddView(view, size, index, false);
|
||||
}
|
||||
|
||||
removeView(index: number, sizing?: Sizing): IView {
|
||||
removeView(index: number, sizing?: Sizing): IView<TLayoutContext> {
|
||||
if (this.state !== State.Idle) {
|
||||
throw new Error('Cant modify splitview');
|
||||
}
|
||||
|
@ -405,10 +427,10 @@ export class SplitView extends Disposable {
|
|||
return viewItem.cachedVisibleSize;
|
||||
}
|
||||
|
||||
layout(size: number, orthogonalSize?: number): void {
|
||||
layout(size: number, layoutContext?: TLayoutContext): void {
|
||||
const previousSize = Math.max(this.size, this.contentSize);
|
||||
this.size = size;
|
||||
this.orthogonalSize = orthogonalSize;
|
||||
this.layoutContext = layoutContext;
|
||||
|
||||
if (!this.proportions) {
|
||||
const indexes = range(this.viewItems.length);
|
||||
|
@ -549,7 +571,7 @@ export class SplitView extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
private onViewChange(item: ViewItem, size: number | undefined): void {
|
||||
private onViewChange(item: ViewItem<TLayoutContext>, size: number | undefined): void {
|
||||
const index = this.viewItems.indexOf(item);
|
||||
|
||||
if (index < 0 || index >= this.viewItems.length) {
|
||||
|
@ -596,7 +618,7 @@ export class SplitView extends Disposable {
|
|||
}
|
||||
|
||||
distributeViewSizes(): void {
|
||||
const flexibleViewItems: ViewItem[] = [];
|
||||
const flexibleViewItems: ViewItem<TLayoutContext>[] = [];
|
||||
let flexibleSize = 0;
|
||||
|
||||
for (const item of this.viewItems) {
|
||||
|
@ -627,7 +649,7 @@ export class SplitView extends Disposable {
|
|||
return this.viewItems[index].size;
|
||||
}
|
||||
|
||||
private doAddView(view: IView, size: number | Sizing, index = this.viewItems.length, skipLayout?: boolean): void {
|
||||
private doAddView(view: IView<TLayoutContext>, size: number | Sizing, index = this.viewItems.length, skipLayout?: boolean): void {
|
||||
if (this.state !== State.Idle) {
|
||||
throw new Error('Cant modify splitview');
|
||||
}
|
||||
|
@ -861,17 +883,19 @@ export class SplitView extends Disposable {
|
|||
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
|
||||
// Layout views
|
||||
let position = 0;
|
||||
let offset = 0;
|
||||
|
||||
for (const viewItem of this.viewItems) {
|
||||
viewItem.layout(position, this.orthogonalSize);
|
||||
position += viewItem.size;
|
||||
viewItem.layout(offset, this.layoutContext);
|
||||
offset += viewItem.size;
|
||||
}
|
||||
|
||||
// Layout sashes
|
||||
this.sashItems.forEach(item => item.sash.layout());
|
||||
this.updateSashEnablement();
|
||||
}
|
||||
|
||||
// Update sashes enablement
|
||||
private updateSashEnablement(): void {
|
||||
let previous = false;
|
||||
const collapsesDown = this.viewItems.map(i => previous = (i.size - i.minimumSize > 0) || previous);
|
||||
|
||||
|
@ -885,7 +909,12 @@ export class SplitView extends Disposable {
|
|||
previous = false;
|
||||
const expandsUp = reverseViews.map(i => previous = (i.maximumSize - i.size > 0) || previous).reverse();
|
||||
|
||||
this.sashItems.forEach(({ sash }, index) => {
|
||||
let position = 0;
|
||||
for (let index = 0; index < this.sashItems.length; index++) {
|
||||
const { sash } = this.sashItems[index];
|
||||
const viewItem = this.viewItems[index];
|
||||
position += viewItem.size;
|
||||
|
||||
const min = !(collapsesDown[index] && expandsUp[index + 1]);
|
||||
const max = !(expandsDown[index] && collapsesUp[index + 1]);
|
||||
|
||||
|
@ -898,9 +927,9 @@ export class SplitView extends Disposable {
|
|||
const snappedBefore = typeof snapBeforeIndex === 'number' && !this.viewItems[snapBeforeIndex].visible;
|
||||
const snappedAfter = typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible;
|
||||
|
||||
if (snappedBefore && collapsesUp[index]) {
|
||||
if (snappedBefore && collapsesUp[index] && (position > 0 || this.startSnappingEnabled)) {
|
||||
sash.state = SashState.Minimum;
|
||||
} else if (snappedAfter && collapsesDown[index]) {
|
||||
} else if (snappedAfter && collapsesDown[index] && (position < this.contentSize || this.endSnappingEnabled)) {
|
||||
sash.state = SashState.Maximum;
|
||||
} else {
|
||||
sash.state = SashState.Disabled;
|
||||
|
@ -912,8 +941,7 @@ export class SplitView extends Disposable {
|
|||
} else {
|
||||
sash.state = SashState.Enabled;
|
||||
}
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private getSashPosition(sash: Sash): number {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -8,7 +8,7 @@ import { Emitter } from 'vs/base/common/event';
|
|||
import { SplitView, IView, Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview';
|
||||
import { Sash, SashState } from 'vs/base/browser/ui/sash/sash';
|
||||
|
||||
class TestView implements IView {
|
||||
class TestView implements IView<number> {
|
||||
|
||||
private readonly _onDidChange = new Emitter<number | undefined>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
@ -43,7 +43,7 @@ class TestView implements IView {
|
|||
assert(_minimumSize <= _maximumSize, 'splitview view minimum size must be <= maximum size');
|
||||
}
|
||||
|
||||
layout(size: number, orthogonalSize: number | undefined): void {
|
||||
layout(size: number, _offset: number, orthogonalSize: number | undefined): void {
|
||||
this._size = size;
|
||||
this._orthogonalSize = orthogonalSize;
|
||||
this._onDidLayout.fire({ size, orthogonalSize });
|
||||
|
@ -527,11 +527,11 @@ suite('Splitview', () => {
|
|||
view1.dispose();
|
||||
});
|
||||
|
||||
test('orthogonal size propagates to views', () => {
|
||||
test('context propagates to views', () => {
|
||||
const view1 = new TestView(20, Number.POSITIVE_INFINITY);
|
||||
const view2 = new TestView(20, Number.POSITIVE_INFINITY);
|
||||
const view3 = new TestView(20, Number.POSITIVE_INFINITY, LayoutPriority.Low);
|
||||
const splitview = new SplitView(container, { proportionalLayout: false });
|
||||
const splitview = new SplitView<number>(container, { proportionalLayout: false });
|
||||
splitview.layout(200);
|
||||
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
|
|
|
@ -492,4 +492,8 @@ suite('Strings', () => {
|
|||
assertEncodeDecodeUTF8('🧝', [240, 159, 167, 157]);
|
||||
|
||||
});
|
||||
|
||||
test('getGraphemeBreakType', () => {
|
||||
assert.equal(strings.getGraphemeBreakType(0xBC1), strings.GraphemeBreakType.SpacingMark);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -523,12 +523,15 @@ export class CursorColumns {
|
|||
if (codePoint === CharCode.Tab) {
|
||||
result = CursorColumns.nextRenderTabStop(result, tabSize);
|
||||
} else {
|
||||
let graphemeBreakType = strings.getGraphemeBreakType(codePoint);
|
||||
while (i < endOffset) {
|
||||
const nextCodePoint = strings.getNextCodePoint(lineContent, endOffset, i);
|
||||
if (!strings.isUnicodeMark(nextCodePoint)) {
|
||||
const nextGraphemeBreakType = strings.getGraphemeBreakType(nextCodePoint);
|
||||
if (strings.breakBetweenGraphemeBreakType(graphemeBreakType, nextGraphemeBreakType)) {
|
||||
break;
|
||||
}
|
||||
i += (nextCodePoint >= Constants.UNICODE_SUPPLEMENTARY_PLANE_BEGIN ? 2 : 1);
|
||||
graphemeBreakType = nextGraphemeBreakType;
|
||||
}
|
||||
if (strings.isFullWidthCharacter(codePoint) || strings.isEmojiImprecise(codePoint)) {
|
||||
result = result + 2;
|
||||
|
@ -582,12 +585,15 @@ export class CursorColumns {
|
|||
if (codePoint === CharCode.Tab) {
|
||||
afterVisibleColumn = CursorColumns.nextRenderTabStop(beforeVisibleColumn, tabSize);
|
||||
} else {
|
||||
let graphemeBreakType = strings.getGraphemeBreakType(codePoint);
|
||||
while (i < lineLength) {
|
||||
const nextCodePoint = strings.getNextCodePoint(lineContent, lineLength, i);
|
||||
if (!strings.isUnicodeMark(nextCodePoint)) {
|
||||
const nextGraphemeBreakType = strings.getGraphemeBreakType(nextCodePoint);
|
||||
if (strings.breakBetweenGraphemeBreakType(graphemeBreakType, nextGraphemeBreakType)) {
|
||||
break;
|
||||
}
|
||||
i += (nextCodePoint >= Constants.UNICODE_SUPPLEMENTARY_PLANE_BEGIN ? 2 : 1);
|
||||
graphemeBreakType = nextGraphemeBreakType;
|
||||
}
|
||||
if (strings.isFullWidthCharacter(codePoint) || strings.isEmojiImprecise(codePoint)) {
|
||||
afterVisibleColumn = beforeVisibleColumn + 2;
|
||||
|
|
|
@ -289,17 +289,26 @@ export class WordOperations {
|
|||
column = model.getLineMaxColumn(lineNumber);
|
||||
}
|
||||
} else if (wordNavigationType === WordNavigationType.WordAccessibility) {
|
||||
if (movedDown) {
|
||||
// If we move to the next line, pretend that the cursor is right before the first character.
|
||||
// This is needed when the first word starts right at the first character - and in order not to miss it,
|
||||
// we need to start before.
|
||||
column = 0;
|
||||
}
|
||||
|
||||
while (
|
||||
nextWordOnLine
|
||||
&& nextWordOnLine.wordType === WordType.Separator
|
||||
&& (nextWordOnLine.wordType === WordType.Separator
|
||||
|| nextWordOnLine.start + 1 <= column
|
||||
)
|
||||
) {
|
||||
// Skip over a word made up of one single separator
|
||||
// Also skip over word if it begins before current cursor position to ascertain we're moving forward at least 1 character.
|
||||
nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
|
||||
}
|
||||
|
||||
if (nextWordOnLine) {
|
||||
column = nextWordOnLine.end + 1;
|
||||
column = nextWordOnLine.start + 1;
|
||||
} else {
|
||||
column = model.getLineMaxColumn(lineNumber);
|
||||
}
|
||||
|
|
|
@ -351,7 +351,7 @@ suite('WordOperations', () => {
|
|||
});
|
||||
|
||||
test('cursorWordAccessibilityRight', () => {
|
||||
const EXPECTED = [' /* Just| some| more| text| a|+= 3| +5|-3| + 7| */ |'].join('\n');
|
||||
const EXPECTED = [' /* |Just |some |more |text |a+= |3 +|5-|3 + |7 */ |'].join('\n');
|
||||
const [text,] = deserializePipePositions(EXPECTED);
|
||||
const actualStops = testRepeatedActionAndExtractPositions(
|
||||
text,
|
||||
|
|
|
@ -726,7 +726,7 @@ suite('Editor Controller - Cursor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('combining marks', () => {
|
||||
test('grapheme breaking', () => {
|
||||
withTestCodeEditor([
|
||||
'abcabc',
|
||||
'ãããããã',
|
||||
|
|
|
@ -755,7 +755,7 @@ suite('Editor Model - TextModel', () => {
|
|||
assert.deepEqual(actual, expected, `validateRange for ${input}, got ${actual}, expected ${expected}`);
|
||||
}
|
||||
|
||||
test('combining marks', () => {
|
||||
test('grapheme breaking', () => {
|
||||
const m = TextModel.createFromString([
|
||||
'abcabc',
|
||||
'ãããããã',
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IMenu, IMenuActionOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuRegistry, SubmenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { IMenu, IMenuActionOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuRegistry, SubmenuItemAction, ILocalizedString } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ContextKeyExpr, IContextKeyService, IContextKeyChangeEvent } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
|
@ -133,7 +133,7 @@ class Menu implements IMenu {
|
|||
}
|
||||
}
|
||||
|
||||
private static _compareMenuItems(a: IMenuItem, b: IMenuItem): number {
|
||||
private static _compareMenuItems(a: IMenuItem | ISubmenuItem, b: IMenuItem | ISubmenuItem): number {
|
||||
|
||||
let aGroup = a.group;
|
||||
let bGroup = b.group;
|
||||
|
@ -171,8 +171,15 @@ class Menu implements IMenu {
|
|||
}
|
||||
|
||||
// sort on titles
|
||||
const aTitle = typeof a.command.title === 'string' ? a.command.title : a.command.title.value;
|
||||
const bTitle = typeof b.command.title === 'string' ? b.command.title : b.command.title.value;
|
||||
return aTitle.localeCompare(bTitle);
|
||||
return Menu._compareTitles(
|
||||
isIMenuItem(a) ? a.command.title : a.title,
|
||||
isIMenuItem(b) ? b.command.title : b.title
|
||||
);
|
||||
}
|
||||
|
||||
private static _compareTitles(a: string | ILocalizedString, b: string | ILocalizedString) {
|
||||
const aStr = typeof a === 'string' ? a : a.value;
|
||||
const bStr = typeof b === 'string' ? b : b.value;
|
||||
return aStr.localeCompare(bStr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ function sendFile(res: http.ServerResponse, filepath: string, contentType: strin
|
|||
fs.readFile(filepath, (err, body) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
} else {
|
||||
res.writeHead(200, {
|
||||
'Content-Length': body.length,
|
||||
|
|
|
@ -171,7 +171,7 @@ export class UserDataAutoSync extends Disposable {
|
|||
this.logService.error(e);
|
||||
}
|
||||
if (loop) {
|
||||
await timeout(1000 * 5); // Loop sync for every 5s.
|
||||
await timeout(1000 * 30); // Loop sync for every 30s.
|
||||
this.sync(loop);
|
||||
}
|
||||
}
|
||||
|
|
10
src/vs/vscode.proposed.d.ts
vendored
10
src/vs/vscode.proposed.d.ts
vendored
|
@ -130,7 +130,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
// #region Joh - code insets
|
||||
// #region Joh - code insets, https://github.com/microsoft/vscode/issues/85682
|
||||
|
||||
export interface WebviewEditorInset {
|
||||
readonly editor: TextEditor;
|
||||
|
@ -147,7 +147,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
//#region Joh - read/write in chunks
|
||||
//#region Joh - read/write in chunks, https://github.com/microsoft/vscode/issues/84515
|
||||
|
||||
export interface FileSystemProvider {
|
||||
open?(resource: Uri, options: { create: boolean }): number | Thenable<number>;
|
||||
|
@ -528,7 +528,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
//#region Joao: diff command
|
||||
//#region Joao: diff command, https://github.com/microsoft/vscode/issues/84899
|
||||
|
||||
/**
|
||||
* The contiguous set of modified lines in a diff.
|
||||
|
@ -561,7 +561,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
//#region Joh: decorations
|
||||
//#region Joh: decorations, https://github.com/microsoft/vscode/issues/54938
|
||||
|
||||
export class Decoration {
|
||||
letter?: string;
|
||||
|
@ -1206,7 +1206,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
//#region Custom editors, mjbvz
|
||||
//#region Custom editors, mjbvz, https://github.com/microsoft/vscode/issues/77131
|
||||
|
||||
/**
|
||||
* Defines how a webview editor interacts with VS Code.
|
||||
|
|
|
@ -40,7 +40,7 @@ import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list
|
|||
import { ITreeRenderer, ITreeNode, IAsyncDataSource, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
|
||||
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
|
||||
import { escape, isFalsyOrWhitespace } from 'vs/base/common/strings';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
|
||||
export class CustomTreeViewPane extends ViewletPane {
|
||||
|
@ -796,9 +796,26 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
|
|||
templateData.resourceLabel.setResource({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches: matches ? matches : createMatches(element.filterData) });
|
||||
}
|
||||
|
||||
templateData.icon.style.backgroundImage = iconUrl ? DOM.asCSSUrl(iconUrl) : '';
|
||||
templateData.icon.title = title ? title : '';
|
||||
DOM.toggleClass(templateData.icon, 'custom-view-tree-node-item-icon', !!iconUrl);
|
||||
|
||||
let codicon: string | undefined;
|
||||
if (iconUrl?.scheme === 'vscode-icon' && iconUrl?.authority === 'codicon') {
|
||||
codicon = `codicon-${escape(iconUrl.path.substr(1))}`;
|
||||
}
|
||||
|
||||
DOM.toggleClass(templateData.icon, 'codicon', !!codicon);
|
||||
templateData.icon.classList.forEach((cls, i, list) => {
|
||||
if (cls !== codicon && cls.indexOf('codicon-') === 0) {
|
||||
list.remove(cls);
|
||||
}
|
||||
});
|
||||
if (codicon) {
|
||||
DOM.addClass(templateData.icon, codicon);
|
||||
}
|
||||
|
||||
templateData.icon.style.backgroundImage = iconUrl && !codicon ? DOM.asCSSUrl(iconUrl) : '';
|
||||
|
||||
templateData.actionBar.context = <TreeViewItemHandleArg>{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle };
|
||||
templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false });
|
||||
if (this._actionRunner) {
|
||||
|
|
|
@ -112,6 +112,10 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.codicon {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel .monaco-icon-label-description-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
|
|
@ -107,25 +107,29 @@ async function createCandidateDecorations(model: ITextModel, breakpointDecoratio
|
|||
const session = debugService.getViewModel().focusedSession;
|
||||
if (session && session.capabilities.supportsBreakpointLocationsRequest) {
|
||||
await Promise.all(lineNumbers.map(async lineNumber => {
|
||||
const positions = await session.breakpointsLocations(model.uri, lineNumber);
|
||||
if (positions.length > 1) {
|
||||
// Do not render candidates if there is only one, since it is already covered by the line breakpoint
|
||||
positions.forEach(p => {
|
||||
const range = new Range(p.lineNumber, p.column, p.lineNumber, p.column + 1);
|
||||
const breakpointAtPosition = breakpointDecorations.filter(bpd => bpd.range.equalsRange(range)).pop();
|
||||
if (breakpointAtPosition && breakpointAtPosition.inlineWidget) {
|
||||
// Space already occupied, do not render candidate.
|
||||
return;
|
||||
}
|
||||
result.push({
|
||||
range,
|
||||
options: {
|
||||
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
beforeContentClassName: `debug-breakpoint-placeholder`
|
||||
},
|
||||
breakpoint: breakpointAtPosition ? breakpointAtPosition.breakpoint : undefined
|
||||
try {
|
||||
const positions = await session.breakpointsLocations(model.uri, lineNumber);
|
||||
if (positions.length > 1) {
|
||||
// Do not render candidates if there is only one, since it is already covered by the line breakpoint
|
||||
positions.forEach(p => {
|
||||
const range = new Range(p.lineNumber, p.column, p.lineNumber, p.column + 1);
|
||||
const breakpointAtPosition = breakpointDecorations.filter(bpd => bpd.range.equalsRange(range)).pop();
|
||||
if (breakpointAtPosition && breakpointAtPosition.inlineWidget) {
|
||||
// Space already occupied, do not render candidate.
|
||||
return;
|
||||
}
|
||||
result.push({
|
||||
range,
|
||||
options: {
|
||||
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
beforeContentClassName: `debug-breakpoint-placeholder`
|
||||
},
|
||||
breakpoint: breakpointAtPosition ? breakpointAtPosition.breakpoint : undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// If there is an error when fetching breakpoint locations just do not render them
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -133,7 +137,6 @@ async function createCandidateDecorations(model: ITextModel, breakpointDecoratio
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
class BreakpointEditorContribution implements IBreakpointEditorContribution {
|
||||
|
||||
private breakpointHintDecoration: string[] = [];
|
||||
|
|
|
@ -20,7 +20,7 @@ import { CallStackView } from 'vs/workbench/contrib/debug/browser/callStackView'
|
|||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import {
|
||||
IDebugService, VIEWLET_ID, REPL_ID, CONTEXT_IN_DEBUG_MODE, INTERNAL_CONSOLE_OPTIONS_SCHEMA,
|
||||
CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, VIEW_CONTAINER, LOADED_SCRIPTS_VIEW_ID, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED,
|
||||
CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, VIEW_CONTAINER, LOADED_SCRIPTS_VIEW_ID, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_DEBUG_UX,
|
||||
} from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
|
@ -48,6 +48,7 @@ import { VariablesView } from 'vs/workbench/contrib/debug/browser/variablesView'
|
|||
import { ClearReplAction, Repl } from 'vs/workbench/contrib/debug/browser/repl';
|
||||
import { DebugContentProvider } from 'vs/workbench/contrib/debug/common/debugContentProvider';
|
||||
import { DebugCallStackContribution } from 'vs/workbench/contrib/debug/browser/debugCallStackContribution';
|
||||
import { StartView } from 'vs/workbench/contrib/debug/browser/startView';
|
||||
|
||||
class OpenDebugViewletAction extends ShowViewletAction {
|
||||
public static readonly ID = VIEWLET_ID;
|
||||
|
@ -82,7 +83,7 @@ class OpenDebugPanelAction extends TogglePanelAction {
|
|||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(ViewletDescriptor.create(
|
||||
DebugViewlet,
|
||||
VIEWLET_ID,
|
||||
nls.localize('debug', "Debug"),
|
||||
nls.localize('debugAndRun', "Debug And Run"),
|
||||
'codicon-debug-alt',
|
||||
3
|
||||
));
|
||||
|
@ -106,11 +107,12 @@ Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(PanelDescriptor
|
|||
|
||||
// Register default debug views
|
||||
const viewsRegistry = Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry);
|
||||
viewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctorDescriptor: { ctor: VariablesView }, order: 10, weight: 40, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusVariablesView' } }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctorDescriptor: { ctor: WatchExpressionsView }, order: 20, weight: 10, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusWatchView' } }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctorDescriptor: { ctor: CallStackView }, order: 30, weight: 30, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusCallStackView' } }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctorDescriptor: { ctor: BreakpointsView }, order: 40, weight: 20, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' } }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctorDescriptor: { ctor: LoadedScriptsView }, order: 35, weight: 5, canToggleVisibility: true, collapsed: true, when: CONTEXT_LOADED_SCRIPTS_SUPPORTED }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctorDescriptor: { ctor: VariablesView }, order: 10, weight: 40, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusVariablesView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctorDescriptor: { ctor: WatchExpressionsView }, order: 20, weight: 10, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusWatchView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctorDescriptor: { ctor: CallStackView }, order: 30, weight: 30, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusCallStackView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctorDescriptor: { ctor: BreakpointsView }, order: 40, weight: 20, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: StartView.ID, name: StartView.LABEL, ctorDescriptor: { ctor: StartView }, order: 10, weight: 40, canToggleVisibility: true, when: CONTEXT_DEBUG_UX.isEqualTo('simple') }], VIEW_CONTAINER);
|
||||
viewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctorDescriptor: { ctor: LoadedScriptsView }, order: 35, weight: 5, canToggleVisibility: true, collapsed: true, when: ContextKeyExpr.and(CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_DEBUG_UX.isEqualTo('default')) }], VIEW_CONTAINER);
|
||||
|
||||
registerCommands();
|
||||
|
||||
|
@ -365,7 +367,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, {
|
|||
group: '1_debug',
|
||||
command: {
|
||||
id: RunAction.ID,
|
||||
title: nls.localize({ key: 'miStartWithoutDebugging', comment: ['&& denotes a mnemonic'] }, "Start &&Without Debugging")
|
||||
title: nls.localize({ key: 'miRun', comment: ['&& denotes a mnemonic'] }, "R&&un")
|
||||
},
|
||||
order: 2
|
||||
});
|
||||
|
|
|
@ -143,7 +143,7 @@ export class StartAction extends AbstractDebugAction {
|
|||
|
||||
export class RunAction extends StartAction {
|
||||
static readonly ID = 'workbench.action.debug.run';
|
||||
static LABEL = nls.localize('startWithoutDebugging', "Start Without Debugging");
|
||||
static LABEL = nls.localize('startWithoutDebugging', "Run (Start Without Debugging)");
|
||||
|
||||
protected isNoDebug(): boolean {
|
||||
return true;
|
||||
|
|
|
@ -239,7 +239,7 @@ export function registerCommands(): void {
|
|||
id: STEP_INTO_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + 10, // Have a stronger weight to have priority over full screen when debugging
|
||||
primary: KeyCode.F11,
|
||||
when: CONTEXT_IN_DEBUG_MODE,
|
||||
when: CONTEXT_DEBUG_STATE.isEqualTo('stopped'),
|
||||
handler: (accessor: ServicesAccessor, context: CallStackContext | unknown) => {
|
||||
getThreadAndRun(accessor, context, (thread: IThread) => thread.stepIn());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import * as objects from 'vs/base/common/objects';
|
|||
import { URI as uri } from 'vs/base/common/uri';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IEditor } from 'vs/workbench/common/editor';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
|
@ -56,6 +57,7 @@ export class ConfigurationManager implements IConfigurationManager {
|
|||
private adapterDescriptorFactories: IDebugAdapterDescriptorFactory[];
|
||||
private debugAdapterFactories = new Map<string, IDebugAdapterFactory>();
|
||||
private debugConfigurationTypeContext: IContextKey<string>;
|
||||
private readonly _onDidRegisterDebugger = new Emitter<void>();
|
||||
|
||||
constructor(
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
|
@ -166,6 +168,10 @@ export class ConfigurationManager implements IConfigurationManager {
|
|||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
get onDidRegisterDebugger(): Event<void> {
|
||||
return this._onDidRegisterDebugger.event;
|
||||
}
|
||||
|
||||
// debug configurations
|
||||
|
||||
registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable {
|
||||
|
@ -266,6 +272,7 @@ export class ConfigurationManager implements IConfigurationManager {
|
|||
});
|
||||
|
||||
this.setCompoundSchemaValues();
|
||||
this._onDidRegisterDebugger.fire();
|
||||
});
|
||||
|
||||
breakpointsExtPoint.setHandler((extensions, delta) => {
|
||||
|
@ -388,6 +395,17 @@ export class ConfigurationManager implements IConfigurationManager {
|
|||
return this.debuggers.filter(dbg => strings.equalsIgnoreCase(dbg.type, type)).pop();
|
||||
}
|
||||
|
||||
getDebuggerLabelsForEditor(editor: editorCommon.IEditor | undefined): string[] {
|
||||
if (isCodeEditor(editor)) {
|
||||
const model = editor.getModel();
|
||||
const language = model ? model.getLanguageIdentifier().language : undefined;
|
||||
|
||||
return this.debuggers.filter(a => language && a.languages && a.languages.indexOf(language) >= 0).map(d => d.label);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
async guessDebugger(type?: string): Promise<Debugger | undefined> {
|
||||
if (type) {
|
||||
const adapter = this.getDebugger(type);
|
||||
|
|
|
@ -40,7 +40,7 @@ import { IAction } from 'vs/base/common/actions';
|
|||
import { deepClone, equals } from 'vs/base/common/objects';
|
||||
import { DebugSession } from 'vs/workbench/contrib/debug/browser/debugSession';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDebugService, State, IDebugSession, CONTEXT_DEBUG_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_MODE, IThread, IDebugConfiguration, VIEWLET_ID, REPL_ID, IConfig, ILaunch, IViewModel, IConfigurationManager, IDebugModel, IEnablement, IBreakpoint, IBreakpointData, ICompound, IGlobalConfig, IStackFrame, AdapterEndEvent, getStateLabel, IDebugSessionOptions } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugService, State, IDebugSession, CONTEXT_DEBUG_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_MODE, IThread, IDebugConfiguration, VIEWLET_ID, REPL_ID, IConfig, ILaunch, IViewModel, IConfigurationManager, IDebugModel, IEnablement, IBreakpoint, IBreakpointData, ICompound, IGlobalConfig, IStackFrame, AdapterEndEvent, getStateLabel, IDebugSessionOptions, CONTEXT_DEBUG_UX } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { isExtensionHostDebugging } from 'vs/workbench/contrib/debug/common/debugUtils';
|
||||
import { isErrorWithActions, createErrorWithActions } from 'vs/base/common/errorsWithActions';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
|
@ -86,6 +86,7 @@ export class DebugService implements IDebugService {
|
|||
private debugType: IContextKey<string>;
|
||||
private debugState: IContextKey<string>;
|
||||
private inDebugMode: IContextKey<boolean>;
|
||||
private debugUx: IContextKey<string>;
|
||||
private breakpointsToSendOnResourceSaved: Set<string>;
|
||||
private initializing = false;
|
||||
private previousState: State | undefined;
|
||||
|
@ -127,6 +128,8 @@ export class DebugService implements IDebugService {
|
|||
this.debugType = CONTEXT_DEBUG_TYPE.bindTo(contextKeyService);
|
||||
this.debugState = CONTEXT_DEBUG_STATE.bindTo(contextKeyService);
|
||||
this.inDebugMode = CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService);
|
||||
this.debugUx = CONTEXT_DEBUG_UX.bindTo(contextKeyService);
|
||||
this.debugUx.set(!!this.configurationManager.selectedConfiguration.name ? 'default' : 'simple');
|
||||
|
||||
this.model = new DebugModel(this.loadBreakpoints(), this.loadFunctionBreakpoints(),
|
||||
this.loadExceptionBreakpoints(), this.loadDataBreakpoints(), this.loadWatchExpressions(), this.textFileService);
|
||||
|
@ -170,6 +173,9 @@ export class DebugService implements IDebugService {
|
|||
this.toDispose.push(this.viewModel.onDidFocusSession(() => {
|
||||
this.onStateChange();
|
||||
}));
|
||||
this.toDispose.push(this.configurationManager.onDidSelectConfiguration(() => {
|
||||
this.debugUx.set(!!(this.state !== State.Inactive || this.configurationManager.selectedConfiguration.name) ? 'default' : 'simple');
|
||||
}));
|
||||
}
|
||||
|
||||
getModel(): IDebugModel {
|
||||
|
@ -226,6 +232,7 @@ export class DebugService implements IDebugService {
|
|||
if (this.previousState !== state) {
|
||||
this.debugState.set(getStateLabel(state));
|
||||
this.inDebugMode.set(state !== State.Inactive);
|
||||
this.debugUx.set(!!(state !== State.Inactive || this.configurationManager.selectedConfiguration.name) ? 'default' : 'simple');
|
||||
this.previousState = state;
|
||||
this._onDidChangeState.fire(state);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { IAction } from 'vs/base/common/actions';
|
|||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IDebugService, VIEWLET_ID, State, BREAKPOINTS_VIEW_ID, IDebugConfiguration, REPL_ID } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugService, VIEWLET_ID, State, BREAKPOINTS_VIEW_ID, IDebugConfiguration, REPL_ID, CONTEXT_DEBUG_UX, CONTEXT_DEBUG_UX_KEY } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { StartAction, ConfigureAction, SelectAndStartAction, FocusSessionAction } from 'vs/workbench/contrib/debug/browser/debugActions';
|
||||
import { StartDebugActionViewItem, FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/debugActionViewItems';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -33,6 +33,7 @@ import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryAc
|
|||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { TogglePanelAction } from 'vs/workbench/browser/panel';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { StartView } from 'vs/workbench/contrib/debug/browser/startView';
|
||||
|
||||
export class DebugViewlet extends ViewContainerViewlet {
|
||||
|
||||
|
@ -61,10 +62,16 @@ export class DebugViewlet extends ViewContainerViewlet {
|
|||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
super(VIEWLET_ID, `${VIEWLET_ID}.state`, false, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
super(VIEWLET_ID, `${VIEWLET_ID}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
|
||||
this._register(this.debugService.onDidChangeState(state => this.onDebugServiceStateChange(state)));
|
||||
this._register(this.debugService.onDidNewSession(() => this.updateToolBar()));
|
||||
this._register(this.contextKeyService.onDidChangeContext(e => {
|
||||
if (e.affectsSome(new Set(CONTEXT_DEBUG_UX_KEY))) {
|
||||
this.updateTitleArea();
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateTitleArea()));
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('debug.toolBarLocation')) {
|
||||
|
@ -83,6 +90,8 @@ export class DebugViewlet extends ViewContainerViewlet {
|
|||
|
||||
if (this.startDebugActionViewItem) {
|
||||
this.startDebugActionViewItem.focus();
|
||||
} else {
|
||||
this.focusView(StartView.ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +116,9 @@ export class DebugViewlet extends ViewContainerViewlet {
|
|||
}
|
||||
|
||||
getActions(): IAction[] {
|
||||
if (CONTEXT_DEBUG_UX.getValue(this.contextKeyService) === 'simple') {
|
||||
return [];
|
||||
}
|
||||
if (this.showInitialDebugActions) {
|
||||
return [this.startAction, this.configureAction, this.toggleReplAction];
|
||||
}
|
||||
|
|
|
@ -13,6 +13,24 @@
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-start-view {
|
||||
padding: 0 20px 0 20px;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-start-view .monaco-button,
|
||||
.debug-viewlet .debug-start-view .section {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-start-view .top-section {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-start-view .configure {
|
||||
cursor: pointer;
|
||||
color: #007ACC;
|
||||
}
|
||||
|
||||
.monaco-workbench .debug-action.notification:after {
|
||||
content: '';
|
||||
width: 6px;
|
||||
|
|
150
src/vs/workbench/contrib/debug/browser/startView.ts
Normal file
150
src/vs/workbench/contrib/debug/browser/startView.ts
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. 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 { ViewletPane, IViewletPaneOptions } from 'vs/workbench/browser/parts/views/paneViewlet';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { StartAction, RunAction, 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';
|
||||
const $ = dom.$;
|
||||
|
||||
|
||||
export class StartView extends ViewletPane {
|
||||
|
||||
static ID = 'workbench.debug.startView';
|
||||
static LABEL = localize('start', "Start");
|
||||
|
||||
private debugButton!: Button;
|
||||
private runButton!: Button;
|
||||
private firstMessageContainer!: HTMLElement;
|
||||
private secondMessageContainer!: HTMLElement;
|
||||
private debuggerLabels: string[] | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
options: IViewletViewOptions,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@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
|
||||
) {
|
||||
super({ ...(options as IViewletPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Start Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
|
||||
this._register(editorService.onDidActiveEditorChange(() => this.updateView()));
|
||||
this._register(this.debugService.getConfigurationManager().onDidRegisterDebugger(() => this.updateView()));
|
||||
}
|
||||
|
||||
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;
|
||||
this.runButton.enabled = enabled;
|
||||
this.debugButton.label = this.debuggerLabels.length !== 1 ? localize('debug', "Debug") : localize('debugWith', "Debug with {0}", this.debuggerLabels[0]);
|
||||
this.runButton.label = this.debuggerLabels.length !== 1 ? localize('run', "Run") : localize('runWith', "Run with {0}", this.debuggerLabels[0]);
|
||||
|
||||
const emptyWorkbench = this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY;
|
||||
this.firstMessageContainer.innerHTML = '';
|
||||
this.secondMessageContainer.innerHTML = '';
|
||||
const secondMessageElement = $('span');
|
||||
this.secondMessageContainer.appendChild(secondMessageElement);
|
||||
|
||||
const setFirstMessage = () => {
|
||||
const firstMessageElement = $('span');
|
||||
this.firstMessageContainer.appendChild(firstMessageElement);
|
||||
firstMessageElement.textContent = localize('simplyDebugAndRun', "Open a file which can be debugged or run.");
|
||||
};
|
||||
const setSecondMessage = () => {
|
||||
secondMessageElement.textContent = localize('specifyHowToRun', "To futher configure the Debug and Run experience");
|
||||
const clickElement = $('span.configure');
|
||||
clickElement.textContent = localize('configure', " create a launch.json file.");
|
||||
clickElement.onclick = () => this.commandService.executeCommand(ConfigureAction.ID);
|
||||
this.secondMessageContainer.appendChild(clickElement);
|
||||
};
|
||||
const setSecondMessageWithFolder = () => {
|
||||
secondMessageElement.textContent = localize('noLaunchConfiguration', "To futher configure the Debug and Run experience, ");
|
||||
const clickElement = $('span.configure');
|
||||
clickElement.textContent = localize('openFolder', " open a folder");
|
||||
clickElement.onclick = () => this.dialogService.pickFolderAndOpen({ forceNewWindow: false });
|
||||
this.secondMessageContainer.appendChild(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) {
|
||||
setFirstMessage();
|
||||
setSecondMessage();
|
||||
}
|
||||
|
||||
if (!enabled && emptyWorkbench) {
|
||||
setFirstMessage();
|
||||
setSecondMessageWithFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
this.firstMessageContainer = $('.top-section');
|
||||
container.appendChild(this.firstMessageContainer);
|
||||
|
||||
this.debugButton = new Button(container);
|
||||
this._register(this.debugButton.onDidClick(() => {
|
||||
this.commandService.executeCommand(StartAction.ID);
|
||||
}));
|
||||
attachButtonStyler(this.debugButton, this.themeService);
|
||||
|
||||
this.runButton = new Button(container);
|
||||
this.runButton.label = localize('run', "Run");
|
||||
|
||||
dom.addClass(container, 'debug-start-view');
|
||||
this._register(this.runButton.onDidClick(() => {
|
||||
this.commandService.executeCommand(RunAction.ID);
|
||||
}));
|
||||
attachButtonStyler(this.runButton, this.themeService);
|
||||
|
||||
this.secondMessageContainer = $('.section');
|
||||
container.appendChild(this.secondMessageContainer);
|
||||
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
protected layoutBody(_: number, __: number): void {
|
||||
// no-op
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
this.runButton.focus();
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ import severity from 'vs/base/common/severity';
|
|||
import { Event } from 'vs/base/common/event';
|
||||
import { IJSONSchemaSnippet } from 'vs/base/common/jsonSchema';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel as EditorIModel } from 'vs/editor/common/model';
|
||||
import { IEditor, ITextEditor } from 'vs/workbench/common/editor';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
|
@ -40,6 +40,8 @@ export const DEBUG_SERVICE_ID = 'debugService';
|
|||
export const CONTEXT_DEBUG_TYPE = new RawContextKey<string>('debugType', undefined);
|
||||
export const CONTEXT_DEBUG_CONFIGURATION_TYPE = new RawContextKey<string>('debugConfigurationType', undefined);
|
||||
export const CONTEXT_DEBUG_STATE = new RawContextKey<string>('debugState', 'inactive');
|
||||
export const CONTEXT_DEBUG_UX_KEY = 'debugUx';
|
||||
export const CONTEXT_DEBUG_UX = new RawContextKey<string>(CONTEXT_DEBUG_UX_KEY, 'default');
|
||||
export const CONTEXT_IN_DEBUG_MODE = new RawContextKey<boolean>('inDebugMode', false);
|
||||
export const CONTEXT_IN_DEBUG_REPL = new RawContextKey<boolean>('inDebugRepl', false);
|
||||
export const CONTEXT_BREAKPOINT_WIDGET_VISIBLE = new RawContextKey<boolean>('breakpointWidgetVisible', false);
|
||||
|
@ -628,8 +630,11 @@ export interface IConfigurationManager {
|
|||
*/
|
||||
onDidSelectConfiguration: Event<void>;
|
||||
|
||||
onDidRegisterDebugger: Event<void>;
|
||||
|
||||
activateDebuggers(activationEvent: string, debugType?: string): Promise<void>;
|
||||
|
||||
getDebuggerLabelsForEditor(editor: editorCommon.IEditor | undefined): string[];
|
||||
hasDebugConfigurationProvider(debugType: string): boolean;
|
||||
|
||||
registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable;
|
||||
|
@ -861,12 +866,12 @@ export const enum BreakpointWidgetContext {
|
|||
LOG_MESSAGE = 2
|
||||
}
|
||||
|
||||
export interface IDebugEditorContribution extends IEditorContribution {
|
||||
export interface IDebugEditorContribution extends editorCommon.IEditorContribution {
|
||||
showHover(range: Range, focus: boolean): Promise<void>;
|
||||
addLaunchConfiguration(): Promise<any>;
|
||||
}
|
||||
|
||||
export interface IBreakpointEditorContribution extends IEditorContribution {
|
||||
export interface IBreakpointEditorContribution extends editorCommon.IEditorContribution {
|
||||
showBreakpointWidget(lineNumber: number, column: number | undefined, context?: BreakpointWidgetContext): void;
|
||||
closeBreakpointWidget(): void;
|
||||
}
|
||||
|
|
|
@ -1074,7 +1074,7 @@ export class DebugModel implements IDebugModel {
|
|||
if (first.column && second.column) {
|
||||
return first.column - second.column;
|
||||
}
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return first.lineNumber - second.lineNumber;
|
||||
|
|
|
@ -230,10 +230,6 @@ export class ExplorerViewlet extends ViewContainerViewlet {
|
|||
return <OpenEditorsView>this.getView(OpenEditorsView.ID);
|
||||
}
|
||||
|
||||
public getEmptyView(): EmptyView {
|
||||
return <EmptyView>this.getView(EmptyView.ID);
|
||||
}
|
||||
|
||||
public setVisible(visible: boolean): void {
|
||||
this.viewletVisibleContextKey.set(visible);
|
||||
super.setVisible(visible);
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
color: white;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 30px;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
@ -65,9 +68,8 @@
|
|||
this.setVisible(true);
|
||||
}
|
||||
|
||||
layout(width, height, orientation) {
|
||||
console.log(`layout@${this.label}`);
|
||||
this.element.style.lineHeight = `${height}px`;
|
||||
layout(width, height, top, left) {
|
||||
this.element.innerHTML = `(${top}, ${left})<br />(${width}, ${height})`;
|
||||
}
|
||||
|
||||
setVisible(visible) {
|
||||
|
|
Loading…
Reference in a new issue