Archived
Merge from vscode 011858832762aaff245b2336fb1c38166e7a10fb (#4663)
This commit is contained in:
@@ -80,10 +80,6 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSecondaryActions(tree: ITree, element: any): IAction[] {
|
|
||||||
return super.getSecondaryActions(tree, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return actions for connection elements
|
* Return actions for connection elements
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ export class TaskHistoryActionProvider extends ContributableActionProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSecondaryActions(tree: ITree, element: any): IAction[] {
|
|
||||||
return super.getSecondaryActions(tree, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return actions for history task
|
* Return actions for history task
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------------------------
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// Defined a subset of ES6 built ins that run in IE11
|
// Defined a subset of ES6 built ins that run in IE11
|
||||||
|
|||||||
Vendored
+9
-9
@@ -6,7 +6,7 @@
|
|||||||
declare module 'spdlog' {
|
declare module 'spdlog' {
|
||||||
|
|
||||||
export const version: string;
|
export const version: string;
|
||||||
export function setAsyncMode(bufferSize: number, flushInterval: number);
|
export function setAsyncMode(bufferSize: number, flushInterval: number): void;
|
||||||
|
|
||||||
export enum LogLevel {
|
export enum LogLevel {
|
||||||
CRITICAL,
|
CRITICAL,
|
||||||
@@ -21,14 +21,14 @@ declare module 'spdlog' {
|
|||||||
export class RotatingLogger {
|
export class RotatingLogger {
|
||||||
constructor(name: string, filename: string, filesize: number, filecount: number);
|
constructor(name: string, filename: string, filesize: number, filecount: number);
|
||||||
|
|
||||||
trace(message: string);
|
trace(message: string): void;
|
||||||
debug(message: string);
|
debug(message: string): void;
|
||||||
info(message: string);
|
info(message: string): void;
|
||||||
warn(message: string);
|
warn(message: string): void;
|
||||||
error(message: string);
|
error(message: string): void;
|
||||||
critical(message: string);
|
critical(message: string): void;
|
||||||
setLevel(level: number);
|
setLevel(level: number): void;
|
||||||
clearFormatters();
|
clearFormatters(): void;
|
||||||
/**
|
/**
|
||||||
* A synchronous operation to flush the contents into file
|
* A synchronous operation to flush the contents into file
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,5 +5,5 @@
|
|||||||
|
|
||||||
declare module 'sudo-prompt' {
|
declare module 'sudo-prompt' {
|
||||||
|
|
||||||
export function exec(cmd: string, options: { name?: string, icns?: string }, callback: (error: string, stdout: string, stderr: string) => void);
|
export function exec(cmd: string, options: { name?: string, icns?: string }, callback: (error: string, stdout: string, stderr: string) => void): void;
|
||||||
}
|
}
|
||||||
Vendored
+3
-3
@@ -31,9 +31,9 @@ declare module 'yauzl' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ZipFile extends EventEmitter {
|
export class ZipFile extends EventEmitter {
|
||||||
readEntry();
|
readEntry(): void;
|
||||||
openReadStream(entry: Entry, callback: (err?: Error, stream?: Readable) => void);
|
openReadStream(entry: Entry, callback: (err?: Error, stream?: Readable) => void): void;
|
||||||
close();
|
close(): void;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
entryCount: number;
|
entryCount: number;
|
||||||
comment: string;
|
comment: string;
|
||||||
|
|||||||
Vendored
+3
-3
@@ -8,8 +8,8 @@ declare module 'yazl' {
|
|||||||
|
|
||||||
class ZipFile {
|
class ZipFile {
|
||||||
outputStream: stream.Stream;
|
outputStream: stream.Stream;
|
||||||
addBuffer(buffer: Buffer, path: string);
|
addBuffer(buffer: Buffer, path: string): void;
|
||||||
addFile(localPath: string, path: string);
|
addFile(localPath: string, path: string): void;
|
||||||
end();
|
end(): void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ export class ContextSubMenu extends SubmenuAction {
|
|||||||
export interface IContextMenuDelegate {
|
export interface IContextMenuDelegate {
|
||||||
getAnchor(): HTMLElement | { x: number; y: number; width?: number; height?: number; };
|
getAnchor(): HTMLElement | { x: number; y: number; width?: number; height?: number; };
|
||||||
getActions(): Array<IAction | ContextSubMenu>;
|
getActions(): Array<IAction | ContextSubMenu>;
|
||||||
getActionItem?(action: IAction): IActionItem | null;
|
getActionItem?(action: IAction): IActionItem | undefined;
|
||||||
getActionsContext?(event?: IContextMenuEvent): any;
|
getActionsContext?(event?: IContextMenuEvent): any;
|
||||||
getKeyBinding?(action: IAction): ResolvedKeybinding | undefined;
|
getKeyBinding?(action: IAction): ResolvedKeybinding | undefined;
|
||||||
getMenuClassName?(): string;
|
getMenuClassName?(): string;
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ export interface ActionTrigger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IActionItemProvider {
|
export interface IActionItemProvider {
|
||||||
(action: IAction): IActionItem | null;
|
(action: IAction): IActionItem | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IActionBarOptions {
|
export interface IActionBarOptions {
|
||||||
@@ -609,7 +609,7 @@ export class ActionBar extends Disposable implements IActionRunner {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let item: IActionItem | null = null;
|
let item: IActionItem | undefined;
|
||||||
|
|
||||||
if (this.options.actionItemProvider) {
|
if (this.options.actionItemProvider) {
|
||||||
item = this.options.actionItemProvider(action);
|
item = this.options.actionItemProvider(action);
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export class ContextView extends Disposable {
|
|||||||
this._register(toDisposable(() => this.setContainer(null)));
|
this._register(toDisposable(() => this.setContainer(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public setContainer(container: HTMLElement | null): void {
|
setContainer(container: HTMLElement | null): void {
|
||||||
if (this.container) {
|
if (this.container) {
|
||||||
this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer);
|
this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer);
|
||||||
this.container.removeChild(this.view);
|
this.container.removeChild(this.view);
|
||||||
@@ -146,7 +146,7 @@ export class ContextView extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public show(delegate: IDelegate): void {
|
show(delegate: IDelegate): void {
|
||||||
if (this.isVisible()) {
|
if (this.isVisible()) {
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ export class ContextView extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(): void {
|
layout(): void {
|
||||||
if (!this.isVisible()) {
|
if (!this.isVisible()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ export class ContextView extends Disposable {
|
|||||||
this.view.style.width = 'initial';
|
this.view.style.width = 'initial';
|
||||||
}
|
}
|
||||||
|
|
||||||
public hide(data?: any): void {
|
hide(data?: any): void {
|
||||||
if (this.delegate && this.delegate.onHide) {
|
if (this.delegate && this.delegate.onHide) {
|
||||||
this.delegate.onHide(data);
|
this.delegate.onHide(data);
|
||||||
}
|
}
|
||||||
@@ -288,7 +288,7 @@ export class ContextView extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
dispose(): void {
|
||||||
this.hide();
|
this.hide();
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ export class DropdownMenu extends BaseDropdown {
|
|||||||
getAnchor: () => this.element,
|
getAnchor: () => this.element,
|
||||||
getActions: () => this.actions,
|
getActions: () => this.actions,
|
||||||
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
|
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
|
||||||
getActionItem: action => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null,
|
getActionItem: action => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : undefined,
|
||||||
getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : undefined,
|
getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : undefined,
|
||||||
getMenuClassName: () => this.menuClassName,
|
getMenuClassName: () => this.menuClassName,
|
||||||
onHide: () => this.onHide(),
|
onHide: () => this.onHide(),
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const DefaultOptions = {
|
|||||||
setRowLineHeight: true,
|
setRowLineHeight: true,
|
||||||
supportDynamicHeights: false,
|
supportDynamicHeights: false,
|
||||||
dnd: {
|
dnd: {
|
||||||
getDragElements(e) { return [e]; },
|
getDragElements<T>(e: T) { return [e]; },
|
||||||
getDragURI() { return null; },
|
getDragURI() { return null; },
|
||||||
onDragStart(): void { },
|
onDragStart(): void { },
|
||||||
onDragOver() { return false; },
|
onDragOver() { return false; },
|
||||||
|
|||||||
@@ -860,8 +860,8 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
|
|||||||
|
|
||||||
this.selectionDetailsPane.innerText = '';
|
this.selectionDetailsPane.innerText = '';
|
||||||
const selectedIndex = e.indexes[0];
|
const selectedIndex = e.indexes[0];
|
||||||
const description = this.options[selectedIndex].description || null;
|
const description = this.options[selectedIndex].description;
|
||||||
const descriptionIsMarkdown = this.options[selectedIndex].descriptionIsMarkdown || null;
|
const descriptionIsMarkdown = this.options[selectedIndex].descriptionIsMarkdown;
|
||||||
|
|
||||||
if (description) {
|
if (description) {
|
||||||
if (descriptionIsMarkdown) {
|
if (descriptionIsMarkdown) {
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ export class ToolBar extends Disposable {
|
|||||||
);
|
);
|
||||||
this.toggleMenuActionItem!.setActionContext(this.actionBar.context);
|
this.toggleMenuActionItem!.setActionContext(this.actionBar.context);
|
||||||
|
|
||||||
return this.toggleMenuActionItem || null;
|
return this.toggleMenuActionItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return options.actionItemProvider ? options.actionItemProvider(action) : null;
|
return options.actionItemProvider ? options.actionItemProvider(action) : undefined;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -805,7 +805,7 @@ class Trait<T> {
|
|||||||
onDidModelSplice({ insertedNodes, deletedNodes }: ITreeModelSpliceEvent<T, any>): void {
|
onDidModelSplice({ insertedNodes, deletedNodes }: ITreeModelSpliceEvent<T, any>): void {
|
||||||
if (!this.identityProvider) {
|
if (!this.identityProvider) {
|
||||||
const set = this.createNodeSet();
|
const set = this.createNodeSet();
|
||||||
const visit = node => set.delete(node);
|
const visit = (node: ITreeNode<T, any>) => set.delete(node);
|
||||||
deletedNodes.forEach(node => dfs(node, visit));
|
deletedNodes.forEach(node => dfs(node, visit));
|
||||||
this.set(values(set));
|
this.set(values(set));
|
||||||
return;
|
return;
|
||||||
@@ -816,8 +816,8 @@ class Trait<T> {
|
|||||||
this.nodes.forEach(node => nodesByIdentity.set(identityProvider.getId(node.element).toString(), node));
|
this.nodes.forEach(node => nodesByIdentity.set(identityProvider.getId(node.element).toString(), node));
|
||||||
|
|
||||||
const toDeleteByIdentity = new Map<string, ITreeNode<T, any>>();
|
const toDeleteByIdentity = new Map<string, ITreeNode<T, any>>();
|
||||||
const toRemoveSetter = node => toDeleteByIdentity.set(identityProvider.getId(node.element).toString(), node);
|
const toRemoveSetter = (node: ITreeNode<T, any>) => toDeleteByIdentity.set(identityProvider.getId(node.element).toString(), node);
|
||||||
const toRemoveDeleter = node => toDeleteByIdentity.delete(identityProvider.getId(node.element).toString());
|
const toRemoveDeleter = (node: { element: T; }) => toDeleteByIdentity.delete(identityProvider.getId(node.element).toString());
|
||||||
deletedNodes.forEach(node => dfs(node, toRemoveSetter));
|
deletedNodes.forEach(node => dfs(node, toRemoveSetter));
|
||||||
insertedNodes.forEach(node => dfs(node, toRemoveDeleter));
|
insertedNodes.forEach(node => dfs(node, toRemoveDeleter));
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { IDragAndDropData } from 'vs/base/browser/dnd';
|
|||||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||||
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
|
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
|
||||||
import { toggleClass } from 'vs/base/browser/dom';
|
import { toggleClass } from 'vs/base/browser/dom';
|
||||||
|
import { values } from 'vs/base/common/map';
|
||||||
|
|
||||||
interface IAsyncDataTreeNode<TInput, T> {
|
interface IAsyncDataTreeNode<TInput, T> {
|
||||||
element: TInput | T;
|
element: TInput | T;
|
||||||
@@ -26,7 +27,6 @@ interface IAsyncDataTreeNode<TInput, T> {
|
|||||||
hasChildren: boolean;
|
hasChildren: boolean;
|
||||||
stale: boolean;
|
stale: boolean;
|
||||||
slow: boolean;
|
slow: boolean;
|
||||||
disposed: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IAsyncDataTreeNodeRequiredProps<TInput, T> extends Partial<IAsyncDataTreeNode<TInput, T>> {
|
interface IAsyncDataTreeNodeRequiredProps<TInput, T> extends Partial<IAsyncDataTreeNode<TInput, T>> {
|
||||||
@@ -41,7 +41,6 @@ function createAsyncDataTreeNode<TInput, T>(props: IAsyncDataTreeNodeRequiredPro
|
|||||||
children: [],
|
children: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
stale: true,
|
stale: true,
|
||||||
disposed: false,
|
|
||||||
slow: false
|
slow: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -274,6 +273,11 @@ interface IAsyncDataTreeViewStateContext<TInput, T> {
|
|||||||
readonly focus: IAsyncDataTreeNode<TInput, T>[];
|
readonly focus: IAsyncDataTreeNode<TInput, T>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dfs<TInput, T>(node: IAsyncDataTreeNode<TInput, T>, fn: (node: IAsyncDataTreeNode<TInput, T>) => void): void {
|
||||||
|
fn(node);
|
||||||
|
node.children.forEach(child => dfs(child, fn));
|
||||||
|
}
|
||||||
|
|
||||||
export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable {
|
export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable {
|
||||||
|
|
||||||
private readonly tree: ObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
|
private readonly tree: ObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
|
||||||
@@ -629,11 +633,6 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async refreshNode(node: IAsyncDataTreeNode<TInput, T>, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
|
private async refreshNode(node: IAsyncDataTreeNode<TInput, T>, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
|
||||||
if (node.disposed) {
|
|
||||||
console.error('Async data tree node is disposed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result: Promise<void> | undefined;
|
let result: Promise<void> | undefined;
|
||||||
|
|
||||||
this.subTreeRefreshPromises.forEach((refreshPromise, refreshNode) => {
|
this.subTreeRefreshPromises.forEach((refreshPromise, refreshNode) => {
|
||||||
@@ -748,38 +747,48 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodeChildren: Map<string, IAsyncDataTreeNode<TInput, T>> | undefined;
|
const nodesToForget = new Map<T, IAsyncDataTreeNode<TInput, T>>();
|
||||||
|
const childrenTreeNodesById = new Map<string, ITreeNode<IAsyncDataTreeNode<TInput, T> | null, TFilterData>>();
|
||||||
if (this.identityProvider) {
|
|
||||||
nodeChildren = new Map();
|
|
||||||
|
|
||||||
for (const child of node.children) {
|
for (const child of node.children) {
|
||||||
nodeChildren.set(child.id!, child);
|
nodesToForget.set(child.element as T, child);
|
||||||
|
|
||||||
|
if (this.identityProvider) {
|
||||||
|
childrenTreeNodesById.set(child.id!, this.tree.getNode(child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let childrenToRefresh: IAsyncDataTreeNode<TInput, T>[] = [];
|
const childrenToRefresh: IAsyncDataTreeNode<TInput, T>[] = [];
|
||||||
|
|
||||||
const children = childrenElements.map<IAsyncDataTreeNode<TInput, T>>(element => {
|
const children = childrenElements.map<IAsyncDataTreeNode<TInput, T>>(element => {
|
||||||
if (!this.identityProvider) {
|
if (!this.identityProvider) {
|
||||||
return createAsyncDataTreeNode({
|
return createAsyncDataTreeNode({
|
||||||
element,
|
element,
|
||||||
parent: node,
|
parent: node,
|
||||||
hasChildren: !!this.dataSource.hasChildren(element),
|
hasChildren: !!this.dataSource.hasChildren(element)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = this.identityProvider.getId(element).toString();
|
const id = this.identityProvider.getId(element).toString();
|
||||||
const asyncDataTreeNode = nodeChildren!.get(id);
|
const childNode = childrenTreeNodesById.get(id);
|
||||||
|
|
||||||
|
if (childNode) {
|
||||||
|
const asyncDataTreeNode = childNode.element!;
|
||||||
|
|
||||||
|
nodesToForget.delete(asyncDataTreeNode.element as T);
|
||||||
|
this.nodes.delete(asyncDataTreeNode.element as T);
|
||||||
|
this.nodes.set(element, asyncDataTreeNode);
|
||||||
|
|
||||||
if (asyncDataTreeNode) {
|
|
||||||
asyncDataTreeNode.element = element;
|
asyncDataTreeNode.element = element;
|
||||||
asyncDataTreeNode.stale = asyncDataTreeNode.stale || recursive;
|
|
||||||
asyncDataTreeNode.hasChildren = !!this.dataSource.hasChildren(element);
|
asyncDataTreeNode.hasChildren = !!this.dataSource.hasChildren(element);
|
||||||
|
|
||||||
if (recursive && !this.tree.isCollapsed(asyncDataTreeNode)) {
|
if (recursive) {
|
||||||
|
if (childNode.collapsed) {
|
||||||
|
dfs(asyncDataTreeNode, node => node.stale = true);
|
||||||
|
} else {
|
||||||
childrenToRefresh.push(asyncDataTreeNode);
|
childrenToRefresh.push(asyncDataTreeNode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return asyncDataTreeNode;
|
return asyncDataTreeNode;
|
||||||
}
|
}
|
||||||
@@ -806,33 +815,22 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
|||||||
return childAsyncDataTreeNode;
|
return childAsyncDataTreeNode;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const node of values(nodesToForget)) {
|
||||||
|
dfs(node, node => this.nodes.delete(node.element as T));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const child of children) {
|
||||||
|
this.nodes.set(child.element as T, child);
|
||||||
|
}
|
||||||
|
|
||||||
node.children.splice(0, node.children.length, ...children);
|
node.children.splice(0, node.children.length, ...children);
|
||||||
|
|
||||||
return childrenToRefresh;
|
return childrenToRefresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
private render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
|
private render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
|
||||||
const insertedElements = new Set<T>();
|
|
||||||
|
|
||||||
const onDidCreateNode = (treeNode: ITreeNode<IAsyncDataTreeNode<TInput, T>, TFilterData>) => {
|
|
||||||
if (treeNode.element.element) {
|
|
||||||
insertedElements.add(treeNode.element.element as T);
|
|
||||||
this.nodes.set(treeNode.element.element as T, treeNode.element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDidDeleteNode = (treeNode: ITreeNode<IAsyncDataTreeNode<TInput, T>, TFilterData>) => {
|
|
||||||
if (treeNode.element.element) {
|
|
||||||
if (!insertedElements.has(treeNode.element.element as T)) {
|
|
||||||
treeNode.element.disposed = true;
|
|
||||||
this.nodes.delete(treeNode.element.element as T);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const children = node.children.map(c => asTreeElement(c, viewStateContext));
|
const children = node.children.map(c => asTreeElement(c, viewStateContext));
|
||||||
this.tree.setChildren(node === this.root ? null : node, children, onDidCreateNode, onDidDeleteNode);
|
this.tree.setChildren(node === this.root ? null : node, children);
|
||||||
|
|
||||||
this._onDidRender.fire();
|
this._onDidRender.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -198,8 +198,17 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNode(element: T | null = null): ITreeNode<T | null, TFilterData> {
|
getNode(element: T | null = null): ITreeNode<T | null, TFilterData> {
|
||||||
const location = this.getElementLocation(element);
|
if (element === null) {
|
||||||
return this.model.getNode(location);
|
return this.model.getNode(this.model.rootRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = this.nodes.get(element);
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
throw new Error(`Tree element not found: ${element}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNodeLocation(node: ITreeNode<T, TFilterData>): T {
|
getNodeLocation(node: ITreeNode<T, TFilterData>): T {
|
||||||
|
|||||||
@@ -404,9 +404,8 @@ export function firstIndex<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean)
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T): T;
|
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T): T;
|
||||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean): T | null;
|
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean): T | undefined;
|
||||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T | null): T | null;
|
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T | undefined = undefined): T | undefined {
|
||||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T | null = null): T | null {
|
|
||||||
const index = firstIndex(array, fn);
|
const index = firstIndex(array, fn);
|
||||||
return index < 0 ? notFoundValue : array[index];
|
return index < 0 ? notFoundValue : array[index];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ export class Delayer<T> implements IDisposable {
|
|||||||
private timeout: any;
|
private timeout: any;
|
||||||
private completionPromise: Promise<any> | null;
|
private completionPromise: Promise<any> | null;
|
||||||
private doResolve: ((value?: any | Promise<any>) => void) | null;
|
private doResolve: ((value?: any | Promise<any>) => void) | null;
|
||||||
private doReject: (err: any) => void;
|
private doReject?: (err: any) => void;
|
||||||
private task: ITask<T | Promise<T>> | null;
|
private task: ITask<T | Promise<T>> | null;
|
||||||
|
|
||||||
constructor(public defaultDelay: number) {
|
constructor(public defaultDelay: number) {
|
||||||
@@ -222,7 +222,7 @@ export class Delayer<T> implements IDisposable {
|
|||||||
this.cancelTimeout();
|
this.cancelTimeout();
|
||||||
|
|
||||||
if (this.completionPromise) {
|
if (this.completionPromise) {
|
||||||
this.doReject(errors.canceled());
|
this.doReject!(errors.canceled());
|
||||||
this.completionPromise = null;
|
this.completionPromise = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ export class Barrier {
|
|||||||
|
|
||||||
private _isOpen: boolean;
|
private _isOpen: boolean;
|
||||||
private _promise: Promise<boolean>;
|
private _promise: Promise<boolean>;
|
||||||
private _completePromise: (v: boolean) => void;
|
private _completePromise!: (v: boolean) => void;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._isOpen = false;
|
this._isOpen = false;
|
||||||
@@ -731,8 +731,8 @@ export class IdleValue<T> {
|
|||||||
private readonly _executor: () => void;
|
private readonly _executor: () => void;
|
||||||
private readonly _handle: IDisposable;
|
private readonly _handle: IDisposable;
|
||||||
|
|
||||||
private _didRun: boolean;
|
private _didRun: boolean = false;
|
||||||
private _value: T;
|
private _value?: T;
|
||||||
private _error: any;
|
private _error: any;
|
||||||
|
|
||||||
constructor(executor: () => T) {
|
constructor(executor: () => T) {
|
||||||
@@ -760,7 +760,7 @@ export class IdleValue<T> {
|
|||||||
if (this._error) {
|
if (this._error) {
|
||||||
throw this._error;
|
throw this._error;
|
||||||
}
|
}
|
||||||
return this._value;
|
return this._value!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class MutableToken implements CancellationToken {
|
|||||||
|
|
||||||
export class CancellationTokenSource {
|
export class CancellationTokenSource {
|
||||||
|
|
||||||
private _token: CancellationToken;
|
private _token?: CancellationToken;
|
||||||
|
|
||||||
get token(): CancellationToken {
|
get token(): CancellationToken {
|
||||||
if (!this._token) {
|
if (!this._token) {
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ export class Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly rgba: RGBA;
|
readonly rgba: RGBA;
|
||||||
private _hsla: HSLA;
|
private _hsla?: HSLA;
|
||||||
get hsla(): HSLA {
|
get hsla(): HSLA {
|
||||||
if (this._hsla) {
|
if (this._hsla) {
|
||||||
return this._hsla;
|
return this._hsla;
|
||||||
@@ -269,7 +269,7 @@ export class Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _hsva: HSVA;
|
private _hsva?: HSVA;
|
||||||
get hsva(): HSVA {
|
get hsva(): HSVA {
|
||||||
if (this._hsva) {
|
if (this._hsva) {
|
||||||
return this._hsva;
|
return this._hsva;
|
||||||
|
|||||||
@@ -119,6 +119,15 @@ function isWhitespace(code: number): boolean {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wordSeparators = new Set<number>();
|
||||||
|
'`~!@#$%^&*()-=+[{]}\\|;:\'",.<>/?'
|
||||||
|
.split('')
|
||||||
|
.forEach(s => wordSeparators.add(s.charCodeAt(0)));
|
||||||
|
|
||||||
|
function isWordSeparator(code: number): boolean {
|
||||||
|
return wordSeparators.has(code);
|
||||||
|
}
|
||||||
|
|
||||||
function isAlphanumeric(code: number): boolean {
|
function isAlphanumeric(code: number): boolean {
|
||||||
return isLower(code) || isUpper(code) || isNumber(code);
|
return isLower(code) || isUpper(code) || isNumber(code);
|
||||||
}
|
}
|
||||||
@@ -308,7 +317,8 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti
|
|||||||
function nextWord(word: string, start: number): number {
|
function nextWord(word: string, start: number): number {
|
||||||
for (let i = start; i < word.length; i++) {
|
for (let i = start; i < word.length; i++) {
|
||||||
const c = word.charCodeAt(i);
|
const c = word.charCodeAt(i);
|
||||||
if (isWhitespace(c) || (i > 0 && isWhitespace(word.charCodeAt(i - 1)))) {
|
if (isWhitespace(c) || (i > 0 && isWhitespace(word.charCodeAt(i - 1))) ||
|
||||||
|
isWordSeparator(c) || (i > 0 && isWordSeparator(word.charCodeAt(i - 1)))) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-12
@@ -43,7 +43,7 @@ const CHAR_QUESTION_MARK = 63; /* ? */
|
|||||||
|
|
||||||
class ErrorInvalidArgType extends Error {
|
class ErrorInvalidArgType extends Error {
|
||||||
code: 'ERR_INVALID_ARG_TYPE';
|
code: 'ERR_INVALID_ARG_TYPE';
|
||||||
constructor(name: string, expected: string, actual: string) {
|
constructor(name: string, expected: string, actual: any) {
|
||||||
// determiner: 'must be' or 'must not be'
|
// determiner: 'must be' or 'must not be'
|
||||||
let determiner;
|
let determiner;
|
||||||
if (typeof expected === 'string' && expected.indexOf('not ') === 0) {
|
if (typeof expected === 'string' && expected.indexOf('not ') === 0) {
|
||||||
@@ -53,36 +53,35 @@ class ErrorInvalidArgType extends Error {
|
|||||||
determiner = 'must be';
|
determiner = 'must be';
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg;
|
|
||||||
const type = name.indexOf('.') !== -1 ? 'property' : 'argument';
|
const type = name.indexOf('.') !== -1 ? 'property' : 'argument';
|
||||||
msg = `The "${name}" ${type} ${determiner} of type ${expected}`;
|
let msg = `The "${name}" ${type} ${determiner} of type ${expected}`;
|
||||||
|
|
||||||
msg += `. Received type ${typeof actual}`;
|
msg += `. Received type ${typeof actual}`;
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateString(value: string, name) {
|
function validateString(value: string, name: string) {
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
throw new ErrorInvalidArgType(name, 'string', value);
|
throw new ErrorInvalidArgType(name, 'string', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPathSeparator(code) {
|
function isPathSeparator(code: number) {
|
||||||
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
|
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPosixPathSeparator(code) {
|
function isPosixPathSeparator(code: number) {
|
||||||
return code === CHAR_FORWARD_SLASH;
|
return code === CHAR_FORWARD_SLASH;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isWindowsDeviceRoot(code) {
|
function isWindowsDeviceRoot(code: number) {
|
||||||
return code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z ||
|
return code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z ||
|
||||||
code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z;
|
code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolves . and .. elements in a path with directory names
|
// Resolves . and .. elements in a path with directory names
|
||||||
function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
|
function normalizeString(path: string, allowAboveRoot: boolean, separator: string, isPathSeparator: (code?: number) => boolean) {
|
||||||
let res = '';
|
let res = '';
|
||||||
let lastSegmentLength = 0;
|
let lastSegmentLength = 0;
|
||||||
let lastSlash = -1;
|
let lastSlash = -1;
|
||||||
@@ -155,7 +154,7 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _format(sep, pathObject) {
|
function _format(sep: string, pathObject: ParsedPath) {
|
||||||
const dir = pathObject.dir || pathObject.root;
|
const dir = pathObject.dir || pathObject.root;
|
||||||
const base = pathObject.base ||
|
const base = pathObject.base ||
|
||||||
((pathObject.name || '') + (pathObject.ext || ''));
|
((pathObject.name || '') + (pathObject.ext || ''));
|
||||||
@@ -185,7 +184,7 @@ interface IPath {
|
|||||||
dirname(path: string): string;
|
dirname(path: string): string;
|
||||||
basename(path: string, ext?: string): string;
|
basename(path: string, ext?: string): string;
|
||||||
extname(path: string): string;
|
extname(path: string): string;
|
||||||
format(pathObject): string;
|
format(pathObject: ParsedPath): string;
|
||||||
parse(path: string): ParsedPath;
|
parse(path: string): ParsedPath;
|
||||||
toNamespacedPath(path: string): string;
|
toNamespacedPath(path: string): string;
|
||||||
sep: '\\' | '/';
|
sep: '\\' | '/';
|
||||||
@@ -501,7 +500,7 @@ export const win32: IPath = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let joined;
|
let joined;
|
||||||
let firstPart;
|
let firstPart: string | undefined;
|
||||||
for (let i = 0; i < paths.length; ++i) {
|
for (let i = 0; i < paths.length; ++i) {
|
||||||
const arg = paths[i];
|
const arg = paths[i];
|
||||||
validateString(arg, 'path');
|
validateString(arg, 'path');
|
||||||
@@ -534,7 +533,7 @@ export const win32: IPath = {
|
|||||||
// path.join('//server', 'share') -> '\\\\server\\share\\')
|
// path.join('//server', 'share') -> '\\\\server\\share\\')
|
||||||
let needsReplace = true;
|
let needsReplace = true;
|
||||||
let slashCount = 0;
|
let slashCount = 0;
|
||||||
if (isPathSeparator(firstPart.charCodeAt(0))) {
|
if (typeof firstPart === 'string' && isPathSeparator(firstPart.charCodeAt(0))) {
|
||||||
++slashCount;
|
++slashCount;
|
||||||
const firstLen = firstPart.length;
|
const firstLen = firstPart.length;
|
||||||
if (firstLen > 1) {
|
if (firstLen > 1) {
|
||||||
|
|||||||
@@ -377,8 +377,8 @@ export class SmoothScrollingOperation {
|
|||||||
private readonly _startTime: number;
|
private readonly _startTime: number;
|
||||||
public animationFrameDisposable: IDisposable | null;
|
public animationFrameDisposable: IDisposable | null;
|
||||||
|
|
||||||
private scrollLeft: IAnimation;
|
private scrollLeft!: IAnimation;
|
||||||
private scrollTop: IAnimation;
|
private scrollTop!: IAnimation;
|
||||||
|
|
||||||
protected constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {
|
protected constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {
|
||||||
this.from = from;
|
this.from = from;
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ export function create(ctor: Function, ...args: any[]): any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/32235645/1499159
|
// https://stackoverflow.com/a/32235645/1499159
|
||||||
function isNativeClass(thing): boolean {
|
function isNativeClass(thing: any): boolean {
|
||||||
return typeof thing === 'function'
|
return typeof thing === 'function'
|
||||||
&& thing.hasOwnProperty('prototype')
|
&& thing.hasOwnProperty('prototype')
|
||||||
&& !thing.hasOwnProperty('arguments');
|
&& !thing.hasOwnProperty('arguments');
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import { TernarySearchTree } from 'vs/base/common/map';
|
|||||||
// Sun xVM VirtualBox 08-00-27
|
// Sun xVM VirtualBox 08-00-27
|
||||||
export const virtualMachineHint: { value(): number } = new class {
|
export const virtualMachineHint: { value(): number } = new class {
|
||||||
|
|
||||||
private _virtualMachineOUIs: TernarySearchTree<boolean>;
|
private _virtualMachineOUIs?: TernarySearchTree<boolean>;
|
||||||
private _value: number;
|
private _value?: number;
|
||||||
|
|
||||||
private _isVirtualMachineMacAdress(mac: string): boolean {
|
private _isVirtualMachineMacAdress(mac: string): boolean {
|
||||||
if (!this._virtualMachineOUIs) {
|
if (!this._virtualMachineOUIs) {
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ export function lstat(path: string): Promise<fs.Stats> {
|
|||||||
return nfcall(fs.lstat, path);
|
return nfcall(fs.lstat, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function move(oldPath: string, newPath: string): Promise<void> {
|
||||||
|
return nfcall(extfs.mv, oldPath, newPath);
|
||||||
|
}
|
||||||
|
|
||||||
export function rename(oldPath: string, newPath: string): Promise<void> {
|
export function rename(oldPath: string, newPath: string): Promise<void> {
|
||||||
return nfcall(fs.rename, oldPath, newPath);
|
return nfcall(fs.rename, oldPath, newPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
|
|||||||
import { ITree, IActionProvider } from 'vs/base/parts/tree/browser/tree';
|
import { ITree, IActionProvider } from 'vs/base/parts/tree/browser/tree';
|
||||||
import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
||||||
import { IQuickNavigateConfiguration, IModel, IDataSource, IFilter, IAccessiblityProvider, IRenderer, IRunner, Mode, IEntryRunContext } from 'vs/base/parts/quickopen/common/quickOpen';
|
import { IQuickNavigateConfiguration, IModel, IDataSource, IFilter, IAccessiblityProvider, IRenderer, IRunner, Mode, IEntryRunContext } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||||
import { Action, IAction, IActionRunner, IActionItem } from 'vs/base/common/actions';
|
import { IAction, IActionRunner } from 'vs/base/common/actions';
|
||||||
import { compareAnything } from 'vs/base/common/comparers';
|
import { compareAnything } from 'vs/base/common/comparers';
|
||||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||||
@@ -291,18 +291,6 @@ class NoActionProvider implements IActionProvider {
|
|||||||
getActions(tree: ITree, element: any): IAction[] | null {
|
getActions(tree: ITree, element: any): IAction[] | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasSecondaryActions(tree: ITree, element: any): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSecondaryActions(tree: ITree, element: any): IAction[] | null {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getActionItem(tree: ITree, element: any, action: Action): IActionItem | null {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IQuickOpenEntryTemplateData {
|
export interface IQuickOpenEntryTemplateData {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import * as Keyboard from 'vs/base/browser/keyboardEvent';
|
|||||||
import { INavigator } from 'vs/base/common/iterator';
|
import { INavigator } from 'vs/base/common/iterator';
|
||||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { IAction, IActionItem } from 'vs/base/common/actions';
|
import { IAction } from 'vs/base/common/actions';
|
||||||
import { Color } from 'vs/base/common/color';
|
import { Color } from 'vs/base/common/color';
|
||||||
import { IItemCollapseEvent, IItemExpandEvent } from 'vs/base/parts/tree/browser/treeModel';
|
import { IItemCollapseEvent, IItemExpandEvent } from 'vs/base/parts/tree/browser/treeModel';
|
||||||
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
||||||
@@ -169,81 +169,21 @@ export interface ITree {
|
|||||||
*/
|
*/
|
||||||
getHighlight(includeHidden?: boolean): any;
|
getHighlight(includeHidden?: boolean): any;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether an element is highlighted or not.
|
|
||||||
*/
|
|
||||||
isHighlighted(element: any): boolean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the highlight.
|
* Clears the highlight.
|
||||||
*/
|
*/
|
||||||
clearHighlight(eventPayload?: any): void;
|
clearHighlight(eventPayload?: any): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects an element.
|
|
||||||
*/
|
|
||||||
select(element: any, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects a range of elements.
|
|
||||||
*/
|
|
||||||
selectRange(fromElement: any, toElement: any, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deselects a range of elements.
|
|
||||||
*/
|
|
||||||
deselectRange(fromElement: any, toElement: any, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects several elements.
|
|
||||||
*/
|
|
||||||
selectAll(elements: any[], eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deselects an element.
|
|
||||||
*/
|
|
||||||
deselect(element: any, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deselects several elements.
|
|
||||||
*/
|
|
||||||
deselectAll(elements: any[], eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces the current selection with the given elements.
|
* Replaces the current selection with the given elements.
|
||||||
*/
|
*/
|
||||||
setSelection(elements: any[], eventPayload?: any): void;
|
setSelection(elements: any[], eventPayload?: any): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles the element's selection.
|
|
||||||
*/
|
|
||||||
toggleSelection(element: any, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently selected elements.
|
* Returns the currently selected elements.
|
||||||
*/
|
*/
|
||||||
getSelection(includeHidden?: boolean): any[];
|
getSelection(includeHidden?: boolean): any[];
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether an element is selected or not.
|
|
||||||
*/
|
|
||||||
isSelected(element: any): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects the next `count`-nth element, in visible order.
|
|
||||||
*/
|
|
||||||
selectNext(count?: number, clearSelection?: boolean, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects the previous `count`-nth element, in visible order.
|
|
||||||
*/
|
|
||||||
selectPrevious(count?: number, clearSelection?: boolean, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects the currently selected element's parent.
|
|
||||||
*/
|
|
||||||
selectParent(clearSelection?: boolean, eventPayload?: any): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the selection.
|
* Clears the selection.
|
||||||
*/
|
*/
|
||||||
@@ -254,11 +194,6 @@ export interface ITree {
|
|||||||
*/
|
*/
|
||||||
setFocus(element?: any, eventPayload?: any): void;
|
setFocus(element?: any, eventPayload?: any): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether an element is focused or not.
|
|
||||||
*/
|
|
||||||
isFocused(element: any): boolean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns focused element.
|
* Returns focused element.
|
||||||
*/
|
*/
|
||||||
@@ -316,6 +251,7 @@ export interface ITree {
|
|||||||
*/
|
*/
|
||||||
clearFocus(eventPayload?: any): void;
|
clearFocus(eventPayload?: any): void;
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}} @todo anthonydresser we need to refactor our code to not need these methods
|
||||||
/**
|
/**
|
||||||
* Adds the trait to elements.
|
* Adds the trait to elements.
|
||||||
*/
|
*/
|
||||||
@@ -327,14 +263,15 @@ export interface ITree {
|
|||||||
removeTraits(trait: string, elements: any[]): void;
|
removeTraits(trait: string, elements: any[]): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the element's trait.
|
* Selects an element.
|
||||||
*/
|
*/
|
||||||
toggleTrait(trait: string, element: any): void;
|
select(element: any, eventPayload?: any): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the element has the trait or not.
|
* Deselects an element.
|
||||||
*/
|
*/
|
||||||
hasTrait(trait: string, element: any): boolean;
|
deselect(element: any, eventPayload?: any): void;
|
||||||
|
// {{SQL CARBON EDIT}} END
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a navigator which allows to discover the visible and
|
* Returns a navigator which allows to discover the visible and
|
||||||
@@ -582,12 +519,14 @@ export interface IDragOverReaction {
|
|||||||
autoExpand?: boolean;
|
autoExpand?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}} @todo anthonydresser refactor to not need this
|
||||||
export const DRAG_OVER_REJECT: IDragOverReaction = { accept: false };
|
export const DRAG_OVER_REJECT: IDragOverReaction = { accept: false };
|
||||||
export const DRAG_OVER_ACCEPT: IDragOverReaction = { accept: true };
|
export const DRAG_OVER_ACCEPT: IDragOverReaction = { accept: true };
|
||||||
export const DRAG_OVER_ACCEPT_BUBBLE_UP: IDragOverReaction = { accept: true, bubble: DragOverBubble.BUBBLE_UP };
|
export const DRAG_OVER_ACCEPT_BUBBLE_UP: IDragOverReaction = { accept: true, bubble: DragOverBubble.BUBBLE_UP };
|
||||||
export const DRAG_OVER_ACCEPT_BUBBLE_DOWN = (autoExpand = false) => ({ accept: true, bubble: DragOverBubble.BUBBLE_DOWN, autoExpand });
|
export const DRAG_OVER_ACCEPT_BUBBLE_DOWN = (autoExpand = false) => ({ accept: true, bubble: DragOverBubble.BUBBLE_DOWN, autoExpand });
|
||||||
export const DRAG_OVER_ACCEPT_BUBBLE_UP_COPY: IDragOverReaction = { accept: true, bubble: DragOverBubble.BUBBLE_UP, effect: DragOverEffect.COPY };
|
export const DRAG_OVER_ACCEPT_BUBBLE_UP_COPY: IDragOverReaction = { accept: true, bubble: DragOverBubble.BUBBLE_UP, effect: DragOverEffect.COPY };
|
||||||
export const DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY = (autoExpand = false) => ({ accept: true, bubble: DragOverBubble.BUBBLE_DOWN, effect: DragOverEffect.COPY, autoExpand });
|
export const DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY = (autoExpand = false) => ({ accept: true, bubble: DragOverBubble.BUBBLE_DOWN, effect: DragOverEffect.COPY, autoExpand });
|
||||||
|
// {{SQL CARBON EDIT}} END
|
||||||
|
|
||||||
export interface IDragAndDrop {
|
export interface IDragAndDrop {
|
||||||
|
|
||||||
@@ -635,12 +574,6 @@ export interface IFilter {
|
|||||||
isVisible(tree: ITree, element: any): boolean;
|
isVisible(tree: ITree, element: any): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IElementCallback {
|
|
||||||
(tree: ITree, element: any): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ICallback = () => void;
|
|
||||||
|
|
||||||
export interface ISorter {
|
export interface ISorter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -730,19 +663,4 @@ export interface IActionProvider {
|
|||||||
* Returns a promise of an array with the actions of the element that should show up in place right to the element in the tree.
|
* Returns a promise of an array with the actions of the element that should show up in place right to the element in the tree.
|
||||||
*/
|
*/
|
||||||
getActions(tree: ITree | null, element: any): IAction[] | null;
|
getActions(tree: ITree | null, element: any): IAction[] | null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not the element has secondary actions. These show up once the user has expanded the element's action bar.
|
|
||||||
*/
|
|
||||||
hasSecondaryActions(tree: ITree, element: any): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a promise of an array with the secondary actions of the element that should show up once the user has expanded the element's action bar.
|
|
||||||
*/
|
|
||||||
getSecondaryActions(tree: ITree, element: any): IAction[] | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an action item to render an action.
|
|
||||||
*/
|
|
||||||
getActionItem(tree: ITree, element: any, action: IAction): IActionItem | null;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,50 +230,14 @@ export class Tree implements _.ITree {
|
|||||||
return this.model.getHighlight();
|
return this.model.getHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
public isHighlighted(element: any): boolean {
|
|
||||||
return this.model.isFocused(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public clearHighlight(eventPayload?: any): void {
|
public clearHighlight(eventPayload?: any): void {
|
||||||
this.model.setHighlight(null, eventPayload);
|
this.model.setHighlight(null, eventPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public select(element: any, eventPayload?: any): void {
|
|
||||||
this.model.select(element, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public selectRange(fromElement: any, toElement: any, eventPayload?: any): void {
|
|
||||||
this.model.selectRange(fromElement, toElement, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deselectRange(fromElement: any, toElement: any, eventPayload?: any): void {
|
|
||||||
this.model.deselectRange(fromElement, toElement, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public selectAll(elements: any[], eventPayload?: any): void {
|
|
||||||
this.model.selectAll(elements, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deselect(element: any, eventPayload?: any): void {
|
|
||||||
this.model.deselect(element, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deselectAll(elements: any[], eventPayload?: any): void {
|
|
||||||
this.model.deselectAll(elements, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public setSelection(elements: any[], eventPayload?: any): void {
|
public setSelection(elements: any[], eventPayload?: any): void {
|
||||||
this.model.setSelection(elements, eventPayload);
|
this.model.setSelection(elements, eventPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleSelection(element: any, eventPayload?: any): void {
|
|
||||||
this.model.toggleSelection(element, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public isSelected(element: any): boolean {
|
|
||||||
return this.model.isSelected(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getSelection(): any[] {
|
public getSelection(): any[] {
|
||||||
return this.model.getSelection();
|
return this.model.getSelection();
|
||||||
}
|
}
|
||||||
@@ -282,26 +246,10 @@ export class Tree implements _.ITree {
|
|||||||
this.model.setSelection([], eventPayload);
|
this.model.setSelection([], eventPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectNext(count?: number, clearSelection?: boolean, eventPayload?: any): void {
|
|
||||||
this.model.selectNext(count, clearSelection, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public selectPrevious(count?: number, clearSelection?: boolean, eventPayload?: any): void {
|
|
||||||
this.model.selectPrevious(count, clearSelection, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public selectParent(clearSelection?: boolean, eventPayload?: any): void {
|
|
||||||
this.model.selectParent(clearSelection, eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public setFocus(element?: any, eventPayload?: any): void {
|
public setFocus(element?: any, eventPayload?: any): void {
|
||||||
this.model.setFocus(element, eventPayload);
|
this.model.setFocus(element, eventPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isFocused(element: any): boolean {
|
|
||||||
return this.model.isFocused(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getFocus(): any {
|
public getFocus(): any {
|
||||||
return this.model.getFocus();
|
return this.model.getFocus();
|
||||||
}
|
}
|
||||||
@@ -346,6 +294,7 @@ export class Tree implements _.ITree {
|
|||||||
this.model.setFocus(null, eventPayload);
|
this.model.setFocus(null, eventPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}} @todo anthonydresser we need to refactor our code to not need these methods
|
||||||
public addTraits(trait: string, elements: any[]): void {
|
public addTraits(trait: string, elements: any[]): void {
|
||||||
this.model.addTraits(trait, elements);
|
this.model.addTraits(trait, elements);
|
||||||
}
|
}
|
||||||
@@ -354,14 +303,14 @@ export class Tree implements _.ITree {
|
|||||||
this.model.removeTraits(trait, elements);
|
this.model.removeTraits(trait, elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleTrait(trait: string, element: any): void {
|
public select(element: any, eventPayload?: any): void {
|
||||||
this.model.hasTrait(trait, element) ? this.model.removeTraits(trait, [element])
|
this.model.select(element, eventPayload);
|
||||||
: this.model.addTraits(trait, [element]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasTrait(trait: string, element: any): boolean {
|
public deselect(element: any, eventPayload?: any): void {
|
||||||
return this.model.hasTrait(trait, element);
|
this.model.deselect(element, eventPayload);
|
||||||
}
|
}
|
||||||
|
// {{SQL CARBON EDIT}} end
|
||||||
|
|
||||||
getNavigator(fromElement?: any, subTreeOnly?: boolean): INavigator<any> {
|
getNavigator(fromElement?: any, subTreeOnly?: boolean): INavigator<any> {
|
||||||
return new MappedNavigator(this.model.getNavigator(fromElement, subTreeOnly), i => i && i.getElement());
|
return new MappedNavigator(this.model.getNavigator(fromElement, subTreeOnly), i => i && i.getElement());
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
import * as Assert from 'vs/base/common/assert';
|
import * as Assert from 'vs/base/common/assert';
|
||||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||||
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||||
import * as arrays from 'vs/base/common/arrays';
|
|
||||||
import { INavigator } from 'vs/base/common/iterator';
|
import { INavigator } from 'vs/base/common/iterator';
|
||||||
import * as _ from './tree';
|
import * as _ from './tree';
|
||||||
import { Event, Emitter, EventMultiplexer, Relay } from 'vs/base/common/event';
|
import { Event, Emitter, EventMultiplexer, Relay } from 'vs/base/common/event';
|
||||||
@@ -872,42 +871,6 @@ export class TreeNavigator implements INavigator<Item> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRange(one: Item, other: Item): Item[] {
|
|
||||||
let oneHierarchy = one.getHierarchy();
|
|
||||||
let otherHierarchy = other.getHierarchy();
|
|
||||||
let length = arrays.commonPrefixLength(oneHierarchy, otherHierarchy);
|
|
||||||
let item: Item | null = oneHierarchy[length - 1];
|
|
||||||
let nav = item.getNavigator();
|
|
||||||
|
|
||||||
let oneIndex: number | null = null;
|
|
||||||
let otherIndex: number | null = null;
|
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
let result: Item[] = [];
|
|
||||||
|
|
||||||
while (item && (oneIndex === null || otherIndex === null)) {
|
|
||||||
result.push(item);
|
|
||||||
|
|
||||||
if (item === one) {
|
|
||||||
oneIndex = index;
|
|
||||||
}
|
|
||||||
if (item === other) {
|
|
||||||
otherIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
item = nav.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oneIndex === null || otherIndex === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let min = Math.min(oneIndex, otherIndex);
|
|
||||||
let max = Math.max(oneIndex, otherIndex);
|
|
||||||
return result.slice(min, max + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IBaseEvent {
|
export interface IBaseEvent {
|
||||||
item: Item | null;
|
item: Item | null;
|
||||||
}
|
}
|
||||||
@@ -1205,28 +1168,6 @@ export class TreeModel {
|
|||||||
this.selectAll([element], eventPayload);
|
this.selectAll([element], eventPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectRange(fromElement: any, toElement: any, eventPayload?: any): void {
|
|
||||||
let fromItem = this.getItem(fromElement);
|
|
||||||
let toItem = this.getItem(toElement);
|
|
||||||
|
|
||||||
if (!fromItem || !toItem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectAll(getRange(fromItem, toItem), eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deselectRange(fromElement: any, toElement: any, eventPayload?: any): void {
|
|
||||||
let fromItem = this.getItem(fromElement);
|
|
||||||
let toItem = this.getItem(toElement);
|
|
||||||
|
|
||||||
if (!fromItem || !toItem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.deselectAll(getRange(fromItem, toItem), eventPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public selectAll(elements: any[], eventPayload?: any): void {
|
public selectAll(elements: any[], eventPayload?: any): void {
|
||||||
this.addTraits('selected', elements);
|
this.addTraits('selected', elements);
|
||||||
let eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
|
let eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
|
||||||
@@ -1249,12 +1190,6 @@ export class TreeModel {
|
|||||||
this._onDidSelect.fire(eventData);
|
this._onDidSelect.fire(eventData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleSelection(element: any, eventPayload?: any): void {
|
|
||||||
this.toggleTrait('selected', element);
|
|
||||||
let eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
|
|
||||||
this._onDidSelect.fire(eventData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public isSelected(element: any): boolean {
|
public isSelected(element: any): boolean {
|
||||||
let item = this.getItem(element);
|
let item = this.getItem(element);
|
||||||
|
|
||||||
@@ -1324,21 +1259,6 @@ export class TreeModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectParent(eventPayload?: any, clearSelection: boolean = true): void {
|
|
||||||
let selection = this.getSelection();
|
|
||||||
let item: Item = selection.length > 0 ? selection[0] : this.input;
|
|
||||||
let nav = this.getNavigator(item, false);
|
|
||||||
let parent = nav.parent();
|
|
||||||
|
|
||||||
if (parent) {
|
|
||||||
if (clearSelection) {
|
|
||||||
this.setSelection([parent], eventPayload);
|
|
||||||
} else {
|
|
||||||
this.select(parent, eventPayload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setFocus(element?: any, eventPayload?: any): void {
|
public setFocus(element?: any, eventPayload?: any): void {
|
||||||
this.setTraits('focused', element ? [element] : []);
|
this.setTraits('focused', element ? [element] : []);
|
||||||
let eventData: _.IFocusEvent = { focus: this.getFocus(), payload: eventPayload };
|
let eventData: _.IFocusEvent = { focus: this.getFocus(), payload: eventPayload };
|
||||||
@@ -1513,25 +1433,6 @@ export class TreeModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasTrait(trait: string, element: any): boolean {
|
|
||||||
const item = this.getItem(element);
|
|
||||||
return !!(item && item.hasTrait(trait));
|
|
||||||
}
|
|
||||||
|
|
||||||
private toggleTrait(trait: string, element: any): void {
|
|
||||||
let item = this.getItem(element);
|
|
||||||
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.hasTrait(trait)) {
|
|
||||||
this.removeTraits(trait, [element]);
|
|
||||||
} else {
|
|
||||||
this.addTraits(trait, [element]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setTraits(trait: string, elements: any[]): void {
|
private setTraits(trait: string, elements: any[]): void {
|
||||||
if (elements.length === 0) {
|
if (elements.length === 0) {
|
||||||
this.removeTraits(trait, elements);
|
this.removeTraits(trait, elements);
|
||||||
|
|||||||
@@ -161,19 +161,19 @@ const SAMPLE: any = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class TestDataSource implements _.IDataSource {
|
class TestDataSource implements _.IDataSource {
|
||||||
public getId(tree, element): string {
|
public getId(tree: _.ITree, element: any): string {
|
||||||
return element.id;
|
return element.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasChildren(tree, element): boolean {
|
public hasChildren(tree: _.ITree, element: any): boolean {
|
||||||
return !!element.children;
|
return !!element.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChildren(tree, element): Promise<any> {
|
public getChildren(tree: _.ITree, element: any): Promise<any> {
|
||||||
return Promise.resolve(element.children);
|
return Promise.resolve(element.children);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getParent(tree, element): Promise<any> {
|
public getParent(tree: _.ITree, element: any): Promise<any> {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -700,13 +700,13 @@ suite('TreeModel - Expansion', () => {
|
|||||||
|
|
||||||
class TestFilter implements _.IFilter {
|
class TestFilter implements _.IFilter {
|
||||||
|
|
||||||
public fn: (any) => boolean;
|
public fn: (element: any) => boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.fn = () => true;
|
this.fn = () => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isVisible(tree, element): boolean {
|
public isVisible(tree: _.ITree, element: any): boolean {
|
||||||
return this.fn(element);
|
return this.fn(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1092,39 +1092,39 @@ class DynamicModel implements _.IDataSource {
|
|||||||
this.promiseFactory = null;
|
this.promiseFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public addChild(parent, child): void {
|
public addChild(parent: string, child: string): void {
|
||||||
if (!this.data[parent]) {
|
if (!this.data[parent]) {
|
||||||
this.data[parent] = [];
|
this.data[parent] = [];
|
||||||
}
|
}
|
||||||
this.data[parent].push(child);
|
this.data[parent].push(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeChild(parent, child): void {
|
public removeChild(parent: string, child: string): void {
|
||||||
this.data[parent].splice(this.data[parent].indexOf(child), 1);
|
this.data[parent].splice(this.data[parent].indexOf(child), 1);
|
||||||
if (this.data[parent].length === 0) {
|
if (this.data[parent].length === 0) {
|
||||||
delete this.data[parent];
|
delete this.data[parent];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public move(element, oldParent, newParent): void {
|
public move(element: string, oldParent: string, newParent: string): void {
|
||||||
this.removeChild(oldParent, element);
|
this.removeChild(oldParent, element);
|
||||||
this.addChild(newParent, element);
|
this.addChild(newParent, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public rename(parent, oldName, newName): void {
|
public rename(parent: string, oldName: string, newName: string): void {
|
||||||
this.removeChild(parent, oldName);
|
this.removeChild(parent, oldName);
|
||||||
this.addChild(parent, newName);
|
this.addChild(parent, newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getId(tree, element): string {
|
public getId(tree: _.ITree, element: any): string {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasChildren(tree, element): boolean {
|
public hasChildren(tree: _.ITree, element: any): boolean {
|
||||||
return !!this.data[element];
|
return !!this.data[element];
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChildren(tree, element): Promise<any> {
|
public getChildren(tree: _.ITree, element: any): Promise<any> {
|
||||||
this._onGetChildren.fire(element);
|
this._onGetChildren.fire(element);
|
||||||
const result = this.promiseFactory ? this.promiseFactory() : Promise.resolve(null);
|
const result = this.promiseFactory ? this.promiseFactory() : Promise.resolve(null);
|
||||||
return result.then(() => {
|
return result.then(() => {
|
||||||
@@ -1133,7 +1133,7 @@ class DynamicModel implements _.IDataSource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getParent(tree, element): Promise<any> {
|
public getParent(tree: _.ITree, element: any): Promise<any> {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1395,7 +1395,7 @@ suite('TreeModel - Dynamic data model', () => {
|
|||||||
assert.equal(getTimes, 2);
|
assert.equal(getTimes, 2);
|
||||||
assert.equal(gotTimes, 1);
|
assert.equal(gotTimes, 1);
|
||||||
|
|
||||||
let p2Complete;
|
let p2Complete: () => void;
|
||||||
dataModel.promiseFactory = () => { return new Promise((c) => { p2Complete = c; }); };
|
dataModel.promiseFactory = () => { return new Promise((c) => { p2Complete = c; }); };
|
||||||
const p2 = model.refresh('father');
|
const p2 = model.refresh('father');
|
||||||
|
|
||||||
@@ -1412,7 +1412,7 @@ suite('TreeModel - Dynamic data model', () => {
|
|||||||
assert.equal(getTimes, 3);
|
assert.equal(getTimes, 3);
|
||||||
assert.equal(gotTimes, 2);
|
assert.equal(gotTimes, 2);
|
||||||
|
|
||||||
p2Complete();
|
p2Complete!();
|
||||||
|
|
||||||
// all good
|
// all good
|
||||||
assert.equal(refreshTimes, 5); // (+1) second son request
|
assert.equal(refreshTimes, 5); // (+1) second son request
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import * as assert from 'assert';
|
|||||||
import { ArrayIterator } from 'vs/base/common/iterator';
|
import { ArrayIterator } from 'vs/base/common/iterator';
|
||||||
import { HeightMap, IViewItem } from 'vs/base/parts/tree/browser/treeViewModel';
|
import { HeightMap, IViewItem } from 'vs/base/parts/tree/browser/treeViewModel';
|
||||||
|
|
||||||
function makeItem(id, height): any {
|
function makeItem(id: any, height: any): any {
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: id,
|
||||||
getHeight: function () { return height; },
|
getHeight: function () { return height; },
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class TestView implements IView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSashes(splitview: SplitView): Sash[] {
|
function getSashes(splitview: SplitView): Sash[] {
|
||||||
return (splitview as any).sashItems.map(i => i.sash) as Sash[];
|
return (splitview as any).sashItems.map((i: any) => i.sash) as Sash[];
|
||||||
}
|
}
|
||||||
|
|
||||||
suite('Splitview', () => {
|
suite('Splitview', () => {
|
||||||
|
|||||||
@@ -143,12 +143,12 @@ suite('Paths (Node Implementation)', () => {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
joinTests.forEach((test) => {
|
joinTests.forEach((test: any[]) => {
|
||||||
if (!Array.isArray(test[0])) {
|
if (!Array.isArray(test[0])) {
|
||||||
test[0] = [test[0]];
|
test[0] = [test[0]];
|
||||||
}
|
}
|
||||||
test[0].forEach((join) => {
|
test[0].forEach((join: any) => {
|
||||||
test[1].forEach((test) => {
|
test[1].forEach((test: any) => {
|
||||||
const actual = join.apply(null, test[0]);
|
const actual = join.apply(null, test[0]);
|
||||||
const expected = test[1];
|
const expected = test[1];
|
||||||
// For non-Windows specific tests with the Windows join(), we need to try
|
// For non-Windows specific tests with the Windows join(), we need to try
|
||||||
|
|||||||
@@ -176,14 +176,14 @@ suite('Types', () => {
|
|||||||
types.validateConstraints([undefined], [types.isUndefined]);
|
types.validateConstraints([undefined], [types.isUndefined]);
|
||||||
types.validateConstraints([1], [types.isNumber]);
|
types.validateConstraints([1], [types.isNumber]);
|
||||||
|
|
||||||
function foo() { }
|
class Foo { }
|
||||||
types.validateConstraints([new foo()], [foo]);
|
types.validateConstraints([new Foo()], [Foo]);
|
||||||
|
|
||||||
function isFoo(f) { }
|
function isFoo(f: any) { }
|
||||||
assert.throws(() => types.validateConstraints([new foo()], [isFoo]));
|
assert.throws(() => types.validateConstraints([new Foo()], [isFoo]));
|
||||||
|
|
||||||
function isFoo2(f) { return true; }
|
function isFoo2(f: any) { return true; }
|
||||||
types.validateConstraints([new foo()], [isFoo2]);
|
types.validateConstraints([new Foo()], [isFoo2]);
|
||||||
|
|
||||||
assert.throws(() => types.validateConstraints([1, true], [types.isNumber, types.isString]));
|
assert.throws(() => types.validateConstraints([1, true], [types.isNumber, types.isString]));
|
||||||
assert.throws(() => types.validateConstraints(['2'], [types.isNumber]));
|
assert.throws(() => types.validateConstraints(['2'], [types.isNumber]));
|
||||||
@@ -196,7 +196,7 @@ suite('Types', () => {
|
|||||||
assert(types.create(zeroConstructor) instanceof zeroConstructor);
|
assert(types.create(zeroConstructor) instanceof zeroConstructor);
|
||||||
assert(types.isObject(types.create(zeroConstructor)));
|
assert(types.isObject(types.create(zeroConstructor)));
|
||||||
|
|
||||||
let manyArgConstructor = function (this: any, foo, bar) {
|
let manyArgConstructor = function (this: any, foo: any, bar: any) {
|
||||||
this.foo = foo;
|
this.foo = foo;
|
||||||
this.bar = bar;
|
this.bar = bar;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -132,13 +132,13 @@ suite('Encoding', () => {
|
|||||||
assert.equal(mimes.encoding, 'windows1252');
|
assert.equal(mimes.encoding, 'windows1252');
|
||||||
});
|
});
|
||||||
|
|
||||||
async function readAndDecodeFromDisk(path, _encoding) {
|
async function readAndDecodeFromDisk(path: string, fileEncoding: string | null) {
|
||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
fs.readFile(path, (err, data) => {
|
fs.readFile(path, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
resolve(encoding.decode(data, _encoding));
|
resolve(encoding.decode(data, fileEncoding!));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
|||||||
|
|
||||||
const ignore = () => { };
|
const ignore = () => { };
|
||||||
|
|
||||||
const mkdirp = (path: string, mode: number, callback: (error) => void) => {
|
const mkdirp = (path: string, mode: number, callback: (error: any) => void) => {
|
||||||
extfs.mkdirp(path, mode).then(() => callback(null), error => callback(error));
|
extfs.mkdirp(path, mode).then(() => callback(null), error => callback(error));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ suite('Glob', () => {
|
|||||||
|
|
||||||
test('expression support (single)', function () {
|
test('expression support (single)', function () {
|
||||||
let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
|
let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
|
||||||
let hasSibling = name => siblings.indexOf(name) !== -1;
|
let hasSibling = (name: string) => siblings.indexOf(name) !== -1;
|
||||||
|
|
||||||
// { "**/*.js": { "when": "$(basename).ts" } }
|
// { "**/*.js": { "when": "$(basename).ts" } }
|
||||||
let expression: glob.IExpression = {
|
let expression: glob.IExpression = {
|
||||||
@@ -467,7 +467,7 @@ suite('Glob', () => {
|
|||||||
|
|
||||||
test('expression support (multiple)', function () {
|
test('expression support (multiple)', function () {
|
||||||
let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
|
let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
|
||||||
let hasSibling = name => siblings.indexOf(name) !== -1;
|
let hasSibling = (name: string) => siblings.indexOf(name) !== -1;
|
||||||
|
|
||||||
// { "**/*.js": { "when": "$(basename).ts" } }
|
// { "**/*.js": { "when": "$(basename).ts" } }
|
||||||
let expression: glob.IExpression = {
|
let expression: glob.IExpression = {
|
||||||
@@ -717,7 +717,7 @@ suite('Glob', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let siblings = ['foo.ts', 'foo.js', 'foo', 'bar'];
|
let siblings = ['foo.ts', 'foo.js', 'foo', 'bar'];
|
||||||
let hasSibling = name => siblings.indexOf(name) !== -1;
|
let hasSibling = (name: string) => siblings.indexOf(name) !== -1;
|
||||||
|
|
||||||
assert.strictEqual(glob.match(expr, 'bar', hasSibling), '**/bar');
|
assert.strictEqual(glob.match(expr, 'bar', hasSibling), '**/bar');
|
||||||
assert.strictEqual(glob.match(expr, 'foo', hasSibling), null);
|
assert.strictEqual(glob.match(expr, 'foo', hasSibling), null);
|
||||||
@@ -774,7 +774,7 @@ suite('Glob', () => {
|
|||||||
|
|
||||||
let expr = { '**/*.js': { when: '$(basename).ts' } };
|
let expr = { '**/*.js': { when: '$(basename).ts' } };
|
||||||
let siblings = ['foo.ts', 'foo.js'];
|
let siblings = ['foo.ts', 'foo.js'];
|
||||||
let hasSibling = name => siblings.indexOf(name) !== -1;
|
let hasSibling = (name: string) => siblings.indexOf(name) !== -1;
|
||||||
|
|
||||||
assert.strictEqual(glob.parse(expr)('bar/baz.js', 'baz.js', hasSibling), null);
|
assert.strictEqual(glob.parse(expr)('bar/baz.js', 'baz.js', hasSibling), null);
|
||||||
assert.strictEqual(glob.parse(expr)('bar/foo.js', 'foo.js', hasSibling), '**/*.js');
|
assert.strictEqual(glob.parse(expr)('bar/foo.js', 'foo.js', hasSibling), '**/*.js');
|
||||||
@@ -818,7 +818,7 @@ suite('Glob', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const siblings = ['baz', 'baz.zip', 'nope'];
|
const siblings = ['baz', 'baz.zip', 'nope'];
|
||||||
const hasSibling = name => siblings.indexOf(name) !== -1;
|
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
|
||||||
testOptimizationForBasenames({
|
testOptimizationForBasenames({
|
||||||
'**/foo/**': { when: '$(basename).zip' },
|
'**/foo/**': { when: '$(basename).zip' },
|
||||||
'**/bar/**': true
|
'**/bar/**': true
|
||||||
@@ -924,7 +924,7 @@ suite('Glob', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const siblings = ['baz', 'baz.zip', 'nope'];
|
const siblings = ['baz', 'baz.zip', 'nope'];
|
||||||
let hasSibling = name => siblings.indexOf(name) !== -1;
|
let hasSibling = (name: string) => siblings.indexOf(name) !== -1;
|
||||||
testOptimizationForPaths({
|
testOptimizationForPaths({
|
||||||
'**/foo/123/**': { when: '$(basename).zip' },
|
'**/foo/123/**': { when: '$(basename).zip' },
|
||||||
'**/bar/123/**': true
|
'**/bar/123/**': true
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ suite('SQLite Storage Library', () => {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testDBBasics(path, logError?: (error) => void) {
|
async function testDBBasics(path: string, logError?: (error: Error) => void) {
|
||||||
let options!: ISQLiteStorageDatabaseOptions;
|
let options!: ISQLiteStorageDatabaseOptions;
|
||||||
if (logError) {
|
if (logError) {
|
||||||
options = {
|
options = {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import { ILogService, getLogLevel } from 'vs/platform/log/common/log';
|
|||||||
import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
|
import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
|
||||||
import { normalizeGitHubUrl } from 'vs/code/electron-browser/issue/issueReporterUtil';
|
import { normalizeGitHubUrl } from 'vs/code/electron-browser/issue/issueReporterUtil';
|
||||||
import { Button } from 'vs/base/browser/ui/button/button';
|
import { Button } from 'vs/base/browser/ui/button/button';
|
||||||
|
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||||
|
|
||||||
const MAX_URL_LENGTH = platform.isWindows ? 2081 : 5400;
|
const MAX_URL_LENGTH = platform.isWindows ? 2081 : 5400;
|
||||||
|
|
||||||
@@ -211,7 +212,7 @@ export class IssueReporter extends Disposable {
|
|||||||
|
|
||||||
styleTag.innerHTML = content.join('\n');
|
styleTag.innerHTML = content.join('\n');
|
||||||
document.head.appendChild(styleTag);
|
document.head.appendChild(styleTag);
|
||||||
document.body.style.color = styles.color || null;
|
document.body.style.color = withUndefinedAsNull(styles.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleExtensionData(extensions: IssueReporterExtensionData[]) {
|
private handleExtensionData(extensions: IssueReporterExtensionData[]) {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ function attachTo(item: ProcessItem) {
|
|||||||
ipcRenderer.send('vscode:workbenchCommand', { id: 'debug.startFromConfig', from: 'processExplorer', args: [config] });
|
ipcRenderer.send('vscode:workbenchCommand', { id: 'debug.startFromConfig', from: 'processExplorer', args: [config] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProcessIdWithHighestProperty(processList, propertyName: string) {
|
function getProcessIdWithHighestProperty(processList: any[], propertyName: string) {
|
||||||
let max = 0;
|
let max = 0;
|
||||||
let maxProcessId;
|
let maxProcessId;
|
||||||
processList.forEach(process => {
|
processList.forEach(process => {
|
||||||
@@ -112,7 +112,7 @@ function getProcessIdWithHighestProperty(processList, propertyName: string) {
|
|||||||
return maxProcessId;
|
return maxProcessId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateProcessInfo(processList): void {
|
function updateProcessInfo(processList: any[]): void {
|
||||||
const container = document.getElementById('process-list');
|
const container = document.getElementById('process-list');
|
||||||
if (!container) {
|
if (!container) {
|
||||||
return;
|
return;
|
||||||
@@ -199,12 +199,12 @@ function applyZoom(zoomLevel: number): void {
|
|||||||
browser.setZoomLevel(webFrame.getZoomLevel(), /*isTrusted*/false);
|
browser.setZoomLevel(webFrame.getZoomLevel(), /*isTrusted*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showContextMenu(e) {
|
function showContextMenu(e: MouseEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const items: IContextMenuItem[] = [];
|
const items: IContextMenuItem[] = [];
|
||||||
|
|
||||||
const pid = parseInt(e.currentTarget.id);
|
const pid = parseInt((e.currentTarget as HTMLElement).id);
|
||||||
if (pid && typeof pid === 'number') {
|
if (pid && typeof pid === 'number') {
|
||||||
items.push({
|
items.push({
|
||||||
label: localize('killProcess', "Kill Process"),
|
label: localize('killProcess', "Kill Process"),
|
||||||
@@ -277,7 +277,7 @@ export function startup(data: ProcessExplorerData): void {
|
|||||||
applyZoom(data.zoomLevel);
|
applyZoom(data.zoomLevel);
|
||||||
|
|
||||||
// Map window process pids to titles, annotate process names with this when rendering to distinguish between them
|
// Map window process pids to titles, annotate process names with this when rendering to distinguish between them
|
||||||
ipcRenderer.on('vscode:windowsInfoResponse', (event, windows) => {
|
ipcRenderer.on('vscode:windowsInfoResponse', (_event: unknown, windows: any[]) => {
|
||||||
mapPidToWindowTitle = new Map<number, string>();
|
mapPidToWindowTitle = new Map<number, string>();
|
||||||
windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title));
|
windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ export class CodeApplication extends Disposable {
|
|||||||
this.logService.info(`Tracing: waiting for windows to get ready...`);
|
this.logService.info(`Tracing: waiting for windows to get ready...`);
|
||||||
|
|
||||||
let recordingStopped = false;
|
let recordingStopped = false;
|
||||||
const stopRecording = (timeout) => {
|
const stopRecording = (timeout: boolean) => {
|
||||||
if (recordingStopped) {
|
if (recordingStopped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -574,16 +574,17 @@ export class CodeApplication extends Disposable {
|
|||||||
const hasCliArgs = hasArgs(args._);
|
const hasCliArgs = hasArgs(args._);
|
||||||
const hasFolderURIs = hasArgs(args['folder-uri']);
|
const hasFolderURIs = hasArgs(args['folder-uri']);
|
||||||
const hasFileURIs = hasArgs(args['file-uri']);
|
const hasFileURIs = hasArgs(args['file-uri']);
|
||||||
|
const noRecentEntry = args['skip-add-to-recently-opened'] === true;
|
||||||
|
|
||||||
if (args['new-window'] && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
if (args['new-window'] && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
||||||
return this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths
|
return this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, noRecentEntry, initialStartup: true }); // new window if "-n" was used without paths
|
||||||
}
|
}
|
||||||
|
|
||||||
if (macOpenFiles && macOpenFiles.length && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
if (macOpenFiles && macOpenFiles.length && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
||||||
return this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, urisToOpen: macOpenFiles.map(file => ({ uri: URI.file(file) })), initialStartup: true }); // mac: open-file event received on startup
|
return this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, urisToOpen: macOpenFiles.map(file => ({ uri: URI.file(file) })), noRecentEntry, initialStartup: true }); // mac: open-file event received on startup
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli
|
return this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']), diffMode: args.diff, noRecentEntry, initialStartup: true }); // default: read paths from cli
|
||||||
}
|
}
|
||||||
|
|
||||||
private afterWindowOpen(accessor: ServicesAccessor): void {
|
private afterWindowOpen(accessor: ServicesAccessor): void {
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ export class WindowsManager implements IWindowsMainService {
|
|||||||
|
|
||||||
// Remember in recent document list (unless this opens for extension development)
|
// Remember in recent document list (unless this opens for extension development)
|
||||||
// Also do not add paths when files are opened for diffing, only if opened individually
|
// Also do not add paths when files are opened for diffing, only if opened individually
|
||||||
if (!usedWindows.some(w => w.isExtensionDevelopmentHost) && !openConfig.diffMode && !this.environmentService.skipAddToRecentlyOpened) {
|
if (!usedWindows.some(w => w.isExtensionDevelopmentHost) && !openConfig.diffMode && !openConfig.noRecentEntry) {
|
||||||
const recents: IRecent[] = [];
|
const recents: IRecent[] = [];
|
||||||
for (let pathToOpen of pathsToOpen) {
|
for (let pathToOpen of pathsToOpen) {
|
||||||
if (pathToOpen.workspace) {
|
if (pathToOpen.workspace) {
|
||||||
@@ -746,7 +746,7 @@ export class WindowsManager implements IWindowsMainService {
|
|||||||
private doOpenFilesInExistingWindow(configuration: IOpenConfiguration, window: ICodeWindow, fileInputs?: IFileInputs): ICodeWindow {
|
private doOpenFilesInExistingWindow(configuration: IOpenConfiguration, window: ICodeWindow, fileInputs?: IFileInputs): ICodeWindow {
|
||||||
window.focus(); // make sure window has focus
|
window.focus(); // make sure window has focus
|
||||||
|
|
||||||
const params: { filesToOpen?, filesToCreate?, filesToDiff?, filesToWait?, termProgram?} = {};
|
const params: { filesToOpen?: IPath[], filesToCreate?: IPath[], filesToDiff?: IPath[], filesToWait?: IPathsToWaitFor, termProgram?: string } = {};
|
||||||
if (fileInputs) {
|
if (fileInputs) {
|
||||||
params.filesToOpen = fileInputs.filesToOpen;
|
params.filesToOpen = fileInputs.filesToOpen;
|
||||||
params.filesToCreate = fileInputs.filesToCreate;
|
params.filesToCreate = fileInputs.filesToCreate;
|
||||||
@@ -1216,7 +1216,7 @@ export class WindowsManager implements IWindowsMainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open it
|
// Open it
|
||||||
this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: !cliArgs.length && !folderUris.length && !fileUris.length, userEnv: openConfig.userEnv });
|
this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: !cliArgs.length && !folderUris.length && !fileUris.length, userEnv: openConfig.userEnv, noRecentEntry: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private openInBrowserWindow(options: IOpenBrowserWindowOptions): ICodeWindow {
|
private openInBrowserWindow(options: IOpenBrowserWindowOptions): ICodeWindow {
|
||||||
@@ -1897,9 +1897,15 @@ class Dialogs {
|
|||||||
showMessageBox(options: Electron.MessageBoxOptions, window?: ICodeWindow): Promise<IMessageBoxResult> {
|
showMessageBox(options: Electron.MessageBoxOptions, window?: ICodeWindow): Promise<IMessageBoxResult> {
|
||||||
return this.getDialogQueue(window).queue(() => {
|
return this.getDialogQueue(window).queue(() => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
dialog.showMessageBox(window ? window.win : undefined!, options, (response: number, checkboxChecked: boolean) => {
|
const callback = (response: number, checkboxChecked: boolean) => {
|
||||||
resolve({ button: response, checkboxChecked });
|
resolve({ button: response, checkboxChecked });
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (window) {
|
||||||
|
dialog.showMessageBox(window.win, options, callback);
|
||||||
|
} else {
|
||||||
|
dialog.showMessageBox(options, callback);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1916,9 +1922,15 @@ class Dialogs {
|
|||||||
|
|
||||||
return this.getDialogQueue(window).queue(() => {
|
return this.getDialogQueue(window).queue(() => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
dialog.showSaveDialog(window ? window.win : undefined!, options, path => {
|
const callback = (path: string) => {
|
||||||
resolve(normalizePath(path));
|
resolve(normalizePath(path));
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (window) {
|
||||||
|
dialog.showSaveDialog(window.win, options, callback);
|
||||||
|
} else {
|
||||||
|
dialog.showSaveDialog(options, callback);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1948,9 +1960,15 @@ class Dialogs {
|
|||||||
|
|
||||||
// Show dialog and wrap as promise
|
// Show dialog and wrap as promise
|
||||||
validatePathPromise.then(() => {
|
validatePathPromise.then(() => {
|
||||||
dialog.showOpenDialog(window ? window.win : undefined!, options, paths => {
|
const callback = (paths: string[]) => {
|
||||||
resolve(normalizePaths(paths));
|
resolve(normalizePaths(paths));
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (window) {
|
||||||
|
dialog.showOpenDialog(window.win, options, callback);
|
||||||
|
} else {
|
||||||
|
dialog.showOpenDialog(options, callback);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { IConstructorSignature1, ServicesAccessor } from 'vs/platform/instantiat
|
|||||||
import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
|
|
||||||
export type ServicesAccessor = ServicesAccessor;
|
export type ServicesAccessor = ServicesAccessor;
|
||||||
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, IEditorContribution>;
|
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, IEditorContribution>;
|
||||||
@@ -88,7 +89,7 @@ export abstract class Command {
|
|||||||
id: this.id,
|
id: this.id,
|
||||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||||
weight: this._kbOpts.weight,
|
weight: this._kbOpts.weight,
|
||||||
when: kbWhen || null,
|
when: kbWhen,
|
||||||
primary: this._kbOpts.primary,
|
primary: this._kbOpts.primary,
|
||||||
secondary: this._kbOpts.secondary,
|
secondary: this._kbOpts.secondary,
|
||||||
win: this._kbOpts.win,
|
win: this._kbOpts.win,
|
||||||
@@ -156,7 +157,7 @@ export abstract class EditorCommand extends Command {
|
|||||||
|
|
||||||
return editor.invokeWithinContext((editorAccessor) => {
|
return editor.invokeWithinContext((editorAccessor) => {
|
||||||
const kbService = editorAccessor.get(IContextKeyService);
|
const kbService = editorAccessor.get(IContextKeyService);
|
||||||
if (!kbService.contextMatchesRules(this.precondition)) {
|
if (!kbService.contextMatchesRules(withNullAsUndefined(this.precondition))) {
|
||||||
// precondition does not hold
|
// precondition does not hold
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ class Widget {
|
|||||||
|
|
||||||
public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
||||||
this._setPosition(position, range);
|
this._setPosition(position, range);
|
||||||
this._preference = preference || null;
|
this._preference = withUndefinedAsNull(preference);
|
||||||
this._cachedDomNodeClientWidth = -1;
|
this._cachedDomNodeClientWidth = -1;
|
||||||
this._cachedDomNodeClientHeight = -1;
|
this._cachedDomNodeClientHeight = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
|||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||||
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
|
|
||||||
let EDITOR_ID = 0;
|
let EDITOR_ID = 0;
|
||||||
|
|
||||||
@@ -308,7 +309,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
|||||||
action.id,
|
action.id,
|
||||||
action.label,
|
action.label,
|
||||||
action.alias,
|
action.alias,
|
||||||
action.precondition,
|
withNullAsUndefined(action.precondition),
|
||||||
(): Promise<void> => {
|
(): Promise<void> => {
|
||||||
return this._instantiationService.invokeFunction((accessor) => {
|
return this._instantiationService.invokeFunction((accessor) => {
|
||||||
return Promise.resolve(action.runEditorCommand(accessor, this, null));
|
return Promise.resolve(action.runEditorCommand(accessor, this, null));
|
||||||
@@ -1644,6 +1645,8 @@ export class EditorModeContext extends Disposable {
|
|||||||
private readonly _hasRenameProvider: IContextKey<boolean>;
|
private readonly _hasRenameProvider: IContextKey<boolean>;
|
||||||
private readonly _hasDocumentFormattingProvider: IContextKey<boolean>;
|
private readonly _hasDocumentFormattingProvider: IContextKey<boolean>;
|
||||||
private readonly _hasDocumentSelectionFormattingProvider: IContextKey<boolean>;
|
private readonly _hasDocumentSelectionFormattingProvider: IContextKey<boolean>;
|
||||||
|
private readonly _hasMultipleDocumentFormattingProvider: IContextKey<boolean>;
|
||||||
|
private readonly _hasMultipleDocumentSelectionFormattingProvider: IContextKey<boolean>;
|
||||||
private readonly _hasSignatureHelpProvider: IContextKey<boolean>;
|
private readonly _hasSignatureHelpProvider: IContextKey<boolean>;
|
||||||
private readonly _isInWalkThrough: IContextKey<boolean>;
|
private readonly _isInWalkThrough: IContextKey<boolean>;
|
||||||
|
|
||||||
@@ -1667,9 +1670,11 @@ export class EditorModeContext extends Disposable {
|
|||||||
this._hasDocumentSymbolProvider = EditorContextKeys.hasDocumentSymbolProvider.bindTo(contextKeyService);
|
this._hasDocumentSymbolProvider = EditorContextKeys.hasDocumentSymbolProvider.bindTo(contextKeyService);
|
||||||
this._hasReferenceProvider = EditorContextKeys.hasReferenceProvider.bindTo(contextKeyService);
|
this._hasReferenceProvider = EditorContextKeys.hasReferenceProvider.bindTo(contextKeyService);
|
||||||
this._hasRenameProvider = EditorContextKeys.hasRenameProvider.bindTo(contextKeyService);
|
this._hasRenameProvider = EditorContextKeys.hasRenameProvider.bindTo(contextKeyService);
|
||||||
|
this._hasSignatureHelpProvider = EditorContextKeys.hasSignatureHelpProvider.bindTo(contextKeyService);
|
||||||
this._hasDocumentFormattingProvider = EditorContextKeys.hasDocumentFormattingProvider.bindTo(contextKeyService);
|
this._hasDocumentFormattingProvider = EditorContextKeys.hasDocumentFormattingProvider.bindTo(contextKeyService);
|
||||||
this._hasDocumentSelectionFormattingProvider = EditorContextKeys.hasDocumentSelectionFormattingProvider.bindTo(contextKeyService);
|
this._hasDocumentSelectionFormattingProvider = EditorContextKeys.hasDocumentSelectionFormattingProvider.bindTo(contextKeyService);
|
||||||
this._hasSignatureHelpProvider = EditorContextKeys.hasSignatureHelpProvider.bindTo(contextKeyService);
|
this._hasMultipleDocumentFormattingProvider = EditorContextKeys.hasMultipleDocumentFormattingProvider.bindTo(contextKeyService);
|
||||||
|
this._hasMultipleDocumentSelectionFormattingProvider = EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider.bindTo(contextKeyService);
|
||||||
this._isInWalkThrough = EditorContextKeys.isInEmbeddedEditor.bindTo(contextKeyService);
|
this._isInWalkThrough = EditorContextKeys.isInEmbeddedEditor.bindTo(contextKeyService);
|
||||||
|
|
||||||
const update = () => this._update();
|
const update = () => this._update();
|
||||||
@@ -1744,6 +1749,8 @@ export class EditorModeContext extends Disposable {
|
|||||||
this._hasSignatureHelpProvider.set(modes.SignatureHelpProviderRegistry.has(model));
|
this._hasSignatureHelpProvider.set(modes.SignatureHelpProviderRegistry.has(model));
|
||||||
this._hasDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.has(model) || modes.DocumentRangeFormattingEditProviderRegistry.has(model));
|
this._hasDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.has(model) || modes.DocumentRangeFormattingEditProviderRegistry.has(model));
|
||||||
this._hasDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.has(model));
|
this._hasDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.has(model));
|
||||||
|
this._hasMultipleDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.all(model).length > 1 || modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1);
|
||||||
|
this._hasMultipleDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1);
|
||||||
this._isInWalkThrough.set(model.uri.scheme === Schemas.walkThroughSnippet);
|
this._isInWalkThrough.set(model.uri.scheme === Schemas.walkThroughSnippet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class InternalEditorAction implements IEditorAction {
|
|||||||
public readonly label: string;
|
public readonly label: string;
|
||||||
public readonly alias: string;
|
public readonly alias: string;
|
||||||
|
|
||||||
private readonly _precondition: ContextKeyExpr | null;
|
private readonly _precondition: ContextKeyExpr | undefined;
|
||||||
private readonly _run: () => Promise<void>;
|
private readonly _run: () => Promise<void>;
|
||||||
private readonly _contextKeyService: IContextKeyService;
|
private readonly _contextKeyService: IContextKeyService;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ export class InternalEditorAction implements IEditorAction {
|
|||||||
id: string,
|
id: string,
|
||||||
label: string,
|
label: string,
|
||||||
alias: string,
|
alias: string,
|
||||||
precondition: ContextKeyExpr | null,
|
precondition: ContextKeyExpr | undefined,
|
||||||
run: () => Promise<void>,
|
run: () => Promise<void>,
|
||||||
contextKeyService: IContextKeyService
|
contextKeyService: IContextKeyService
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -46,7 +46,12 @@ export namespace EditorContextKeys {
|
|||||||
export const hasDocumentSymbolProvider = new RawContextKey<boolean>('editorHasDocumentSymbolProvider', false);
|
export const hasDocumentSymbolProvider = new RawContextKey<boolean>('editorHasDocumentSymbolProvider', false);
|
||||||
export const hasReferenceProvider = new RawContextKey<boolean>('editorHasReferenceProvider', false);
|
export const hasReferenceProvider = new RawContextKey<boolean>('editorHasReferenceProvider', false);
|
||||||
export const hasRenameProvider = new RawContextKey<boolean>('editorHasRenameProvider', false);
|
export const hasRenameProvider = new RawContextKey<boolean>('editorHasRenameProvider', false);
|
||||||
|
export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', false);
|
||||||
|
|
||||||
|
// -- mode context keys: formatting
|
||||||
export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', false);
|
export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', false);
|
||||||
export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', false);
|
export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', false);
|
||||||
export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', false);
|
export const hasMultipleDocumentFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentFormattingProvider', false);
|
||||||
|
export const hasMultipleDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentSelectionFormattingProvider', false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports';
|
|||||||
import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets';
|
import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets';
|
||||||
import { IStringStream, ITextSnapshot } from 'vs/platform/files/common/files';
|
import { IStringStream, ITextSnapshot } from 'vs/platform/files/common/files';
|
||||||
import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||||
|
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||||
|
|
||||||
const CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048;
|
const CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048;
|
||||||
|
|
||||||
@@ -2877,8 +2878,8 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions {
|
|||||||
this.stickiness = options.stickiness || model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges;
|
this.stickiness = options.stickiness || model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges;
|
||||||
this.zIndex = options.zIndex || 0;
|
this.zIndex = options.zIndex || 0;
|
||||||
this.className = options.className ? cleanClassName(options.className) : null;
|
this.className = options.className ? cleanClassName(options.className) : null;
|
||||||
this.hoverMessage = options.hoverMessage || null;
|
this.hoverMessage = withUndefinedAsNull(options.hoverMessage);
|
||||||
this.glyphMarginHoverMessage = options.glyphMarginHoverMessage || null;
|
this.glyphMarginHoverMessage = withUndefinedAsNull(options.glyphMarginHoverMessage);
|
||||||
this.isWholeLine = options.isWholeLine || false;
|
this.isWholeLine = options.isWholeLine || false;
|
||||||
this.showIfCollapsed = options.showIfCollapsed || false;
|
this.showIfCollapsed = options.showIfCollapsed || false;
|
||||||
this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false;
|
this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false;
|
||||||
|
|||||||
@@ -929,6 +929,8 @@ export interface DocumentFormattingEditProvider {
|
|||||||
*/
|
*/
|
||||||
readonly extensionId?: ExtensionIdentifier;
|
readonly extensionId?: ExtensionIdentifier;
|
||||||
|
|
||||||
|
readonly displayName?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide formatting edits for a whole document.
|
* Provide formatting edits for a whole document.
|
||||||
*/
|
*/
|
||||||
@@ -939,13 +941,13 @@ export interface DocumentFormattingEditProvider {
|
|||||||
* the formatting-feature.
|
* the formatting-feature.
|
||||||
*/
|
*/
|
||||||
export interface DocumentRangeFormattingEditProvider {
|
export interface DocumentRangeFormattingEditProvider {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
readonly extensionId?: ExtensionIdentifier;
|
readonly extensionId?: ExtensionIdentifier;
|
||||||
|
|
||||||
|
readonly displayName?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide formatting edits for a range in a document.
|
* Provide formatting edits for a range in a document.
|
||||||
*
|
*
|
||||||
@@ -1396,6 +1398,24 @@ export interface WorkspaceCommentProvider {
|
|||||||
onDidChangeCommentThreads(): Event<CommentThreadChangedEvent>;
|
onDidChangeCommentThreads(): Event<CommentThreadChangedEvent>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface IWebviewOptions {
|
||||||
|
readonly enableScripts?: boolean;
|
||||||
|
readonly enableCommandUris?: boolean;
|
||||||
|
readonly localResourceRoots?: ReadonlyArray<URI>;
|
||||||
|
readonly portMapping?: ReadonlyArray<{ port: number, resolvedPort: number }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface IWebviewPanelOptions {
|
||||||
|
readonly enableFindWidget?: boolean;
|
||||||
|
readonly retainContextWhenHidden?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ICodeLensSymbol {
|
export interface ICodeLensSymbol {
|
||||||
range: IRange;
|
range: IRange;
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export interface IEditorWorkerService {
|
|||||||
canComputeDirtyDiff(original: URI, modified: URI): boolean;
|
canComputeDirtyDiff(original: URI, modified: URI): boolean;
|
||||||
computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[] | null>;
|
computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[] | null>;
|
||||||
|
|
||||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise<TextEdit[] | null | undefined>;
|
computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise<TextEdit[] | undefined>;
|
||||||
|
|
||||||
canComputeWordRanges(resource: URI): boolean;
|
canComputeWordRanges(resource: URI): boolean;
|
||||||
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null>;
|
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null>;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/s
|
|||||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||||
import { regExpFlags } from 'vs/base/common/strings';
|
import { regExpFlags } from 'vs/base/common/strings';
|
||||||
|
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop syncing a model to the worker if it was not needed for 1 min.
|
* Stop syncing a model to the worker if it was not needed for 1 min.
|
||||||
@@ -88,14 +89,15 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
|||||||
return this._workerManager.withWorker().then(client => client.computeDirtyDiff(original, modified, ignoreTrimWhitespace));
|
return this._workerManager.withWorker().then(client => client.computeDirtyDiff(original, modified, ignoreTrimWhitespace));
|
||||||
}
|
}
|
||||||
|
|
||||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[] | null | undefined): Promise<modes.TextEdit[] | null | undefined> {
|
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[] | null | undefined): Promise<modes.TextEdit[] | undefined> {
|
||||||
if (!Array.isArray(edits) || edits.length === 0) {
|
if (isNonEmptyArray(edits)) {
|
||||||
return Promise.resolve(edits);
|
|
||||||
} else {
|
|
||||||
if (!canSyncModel(this._modelService, resource)) {
|
if (!canSyncModel(this._modelService, resource)) {
|
||||||
return Promise.resolve(edits); // File too large
|
return Promise.resolve(edits); // File too large
|
||||||
}
|
}
|
||||||
return this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits));
|
return this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { NULL_LANGUAGE_IDENTIFIER, NULL_MODE_ID } from 'vs/editor/common/modes/n
|
|||||||
import { ILanguageExtensionPoint } from 'vs/editor/common/services/modeService';
|
import { ILanguageExtensionPoint } from 'vs/editor/common/services/modeService';
|
||||||
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||||
|
|
||||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
@@ -267,7 +268,7 @@ export class LanguagesRegistry extends Disposable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const language = this._languages[modeId];
|
const language = this._languages[modeId];
|
||||||
return (language.mimetypes[0] || null);
|
return withUndefinedAsNull(language.mimetypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): string[] {
|
public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): string[] {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { keys } from 'vs/base/common/map';
|
|||||||
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
|
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
|
||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
|
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||||
|
|
||||||
function MODEL_ID(resource: URI): string {
|
function MODEL_ID(resource: URI): string {
|
||||||
return resource.toString();
|
return resource.toString();
|
||||||
@@ -80,7 +81,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
|||||||
|
|
||||||
getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null {
|
getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null {
|
||||||
const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri));
|
const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri));
|
||||||
return markerDecorations ? markerDecorations.getMarker(decoration) || null : null;
|
return markerDecorations ? withUndefinedAsNull(markerDecorations.getMarker(decoration)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLiveMarkers(model: ITextModel): [Range, IMarker][] {
|
getLiveMarkers(model: ITextModel): [Range, IMarker][] {
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
|||||||
const lineContent = model.getLineContent(lineNumber);
|
const lineContent = model.getLineContent(lineNumber);
|
||||||
const indent = TextModel.computeIndentLevel(lineContent, tabSize);
|
const indent = TextModel.computeIndentLevel(lineContent, tabSize);
|
||||||
const lineHasSpace = config.fontInfo.spaceWidth * indent > 22;
|
const lineHasSpace = config.fontInfo.spaceWidth * indent > 22;
|
||||||
const isFolded = (lineNumber) => {
|
const isFolded = (lineNumber: number) => {
|
||||||
return lineNumber > 2 && this._editor.getTopForLineNumber(lineNumber) === this._editor.getTopForLineNumber(lineNumber - 1);
|
return lineNumber > 2 && this._editor.getTopForLineNumber(lineNumber) === this._editor.getTopForLineNumber(lineNumber - 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class CodeLensViewZone implements editorBrowser.IViewZone {
|
|||||||
|
|
||||||
afterLineNumber: number;
|
afterLineNumber: number;
|
||||||
|
|
||||||
private _lastHeight: number;
|
private _lastHeight?: number;
|
||||||
private readonly _onHeight: Function;
|
private readonly _onHeight: Function;
|
||||||
|
|
||||||
constructor(afterLineNumber: number, onHeight: Function) {
|
constructor(afterLineNumber: number, onHeight: Function) {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ suite('FindController', () => {
|
|||||||
getBoolean: (key: string) => !!queryState[key],
|
getBoolean: (key: string) => !!queryState[key],
|
||||||
getNumber: (key: string) => undefined,
|
getNumber: (key: string) => undefined,
|
||||||
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
||||||
remove: (key) => undefined
|
remove: () => undefined
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
if (platform.isMacintosh) {
|
if (platform.isMacintosh) {
|
||||||
@@ -442,7 +442,7 @@ suite('FindController query options persistence', () => {
|
|||||||
getBoolean: (key: string) => !!queryState[key],
|
getBoolean: (key: string) => !!queryState[key],
|
||||||
getNumber: (key: string) => undefined,
|
getNumber: (key: string) => undefined,
|
||||||
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
||||||
remove: (key) => undefined
|
remove: () => undefined
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
test('matchCase', () => {
|
test('matchCase', () => {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export class FoldingModel {
|
|||||||
public update(newRegions: FoldingRegions, blockedLineNumers: number[] = []): void {
|
public update(newRegions: FoldingRegions, blockedLineNumers: number[] = []): void {
|
||||||
let newEditorDecorations: IModelDeltaDecoration[] = [];
|
let newEditorDecorations: IModelDeltaDecoration[] = [];
|
||||||
|
|
||||||
let isBlocked = (startLineNumber, endLineNumber) => {
|
let isBlocked = (startLineNumber: number, endLineNumber: number) => {
|
||||||
for (let blockedLineNumber of blockedLineNumers) {
|
for (let blockedLineNumber of blockedLineNumers) {
|
||||||
if (startLineNumber < blockedLineNumber && blockedLineNumber <= endLineNumber) { // first line is visible
|
if (startLineNumber < blockedLineNumber && blockedLineNumber <= endLineNumber) { // first line is visible
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -3,138 +3,258 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||||
|
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||||
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { illegalArgument, onUnexpectedExternalError } from 'vs/base/common/errors';
|
import { illegalArgument, onUnexpectedExternalError } from 'vs/base/common/errors';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
import { CodeEditorStateFlag, EditorState } from 'vs/editor/browser/core/editorState';
|
||||||
import { Range } from 'vs/editor/common/core/range';
|
import { IActiveCodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||||
import { ITextModel } from 'vs/editor/common/model';
|
import { registerLanguageCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||||
import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
|
|
||||||
import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry, FormattingOptions, TextEdit } from 'vs/editor/common/modes';
|
|
||||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
|
||||||
import { first } from 'vs/base/common/async';
|
|
||||||
import { Position } from 'vs/editor/common/core/position';
|
import { Position } from 'vs/editor/common/core/position';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { Range } from 'vs/editor/common/core/range';
|
||||||
|
import { Selection } from 'vs/editor/common/core/selection';
|
||||||
|
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||||
|
import { ISingleEditOperation, ITextModel } from 'vs/editor/common/model';
|
||||||
|
import { DocumentFormattingEditProvider, DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProvider, DocumentRangeFormattingEditProviderRegistry, FormattingOptions, OnTypeFormattingEditProviderRegistry, TextEdit } from 'vs/editor/common/modes';
|
||||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||||
|
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
|
||||||
|
|
||||||
export const enum FormatMode {
|
export function alertFormattingEdits(edits: ISingleEditOperation[]): void {
|
||||||
Auto = 1,
|
|
||||||
Manual = 2,
|
edits = edits.filter(edit => edit.range);
|
||||||
|
if (!edits.length) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum FormatKind {
|
let { range } = edits[0];
|
||||||
Document = 8,
|
for (let i = 1; i < edits.length; i++) {
|
||||||
Range = 16,
|
range = Range.plusRange(range, edits[i].range);
|
||||||
OnType = 32,
|
}
|
||||||
|
const { startLineNumber, endLineNumber } = range;
|
||||||
|
if (startLineNumber === endLineNumber) {
|
||||||
|
if (edits.length === 1) {
|
||||||
|
alert(nls.localize('hint11', "Made 1 formatting edit on line {0}", startLineNumber));
|
||||||
|
} else {
|
||||||
|
alert(nls.localize('hintn1', "Made {0} formatting edits on line {1}", edits.length, startLineNumber));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (edits.length === 1) {
|
||||||
|
alert(nls.localize('hint1n', "Made 1 formatting edit between lines {0} and {1}", startLineNumber, endLineNumber));
|
||||||
|
} else {
|
||||||
|
alert(nls.localize('hintnn', "Made {0} formatting edits between lines {1} and {2}", edits.length, startLineNumber, endLineNumber));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IFormatterConflictCallback {
|
export function getRealAndSyntheticDocumentFormattersOrdered(model: ITextModel): DocumentFormattingEditProvider[] {
|
||||||
(extensionIds: (ExtensionIdentifier | undefined)[], model: ITextModel, mode: number): void;
|
const result: DocumentFormattingEditProvider[] = [];
|
||||||
|
const seen = new Set<string>();
|
||||||
|
|
||||||
|
// (1) add all document formatter
|
||||||
|
const docFormatter = DocumentFormattingEditProviderRegistry.ordered(model);
|
||||||
|
for (const formatter of docFormatter) {
|
||||||
|
result.push(formatter);
|
||||||
|
if (formatter.extensionId) {
|
||||||
|
seen.add(ExtensionIdentifier.toKey(formatter.extensionId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _conflictResolver: IFormatterConflictCallback | undefined;
|
// (2) add all range formatter as document formatter (unless the same extension already did that)
|
||||||
|
const rangeFormatter = DocumentRangeFormattingEditProviderRegistry.ordered(model);
|
||||||
|
for (const formatter of rangeFormatter) {
|
||||||
|
if (formatter.extensionId) {
|
||||||
|
if (seen.has(ExtensionIdentifier.toKey(formatter.extensionId))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seen.add(ExtensionIdentifier.toKey(formatter.extensionId));
|
||||||
|
}
|
||||||
|
result.push({
|
||||||
|
displayName: formatter.displayName,
|
||||||
|
extensionId: formatter.extensionId,
|
||||||
|
provideDocumentFormattingEdits(model, options, token) {
|
||||||
|
return formatter.provideDocumentRangeFormattingEdits(model, model.getFullModelRange(), options, token);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export function setFormatterConflictCallback(callback: IFormatterConflictCallback): IDisposable {
|
export async function formatDocumentRangeWithProvider(
|
||||||
let oldCallback = _conflictResolver;
|
accessor: ServicesAccessor,
|
||||||
_conflictResolver = callback;
|
provider: DocumentRangeFormattingEditProvider,
|
||||||
|
editorOrModel: ITextModel | IActiveCodeEditor,
|
||||||
|
range: Range,
|
||||||
|
token: CancellationToken
|
||||||
|
): Promise<boolean> {
|
||||||
|
const workerService = accessor.get(IEditorWorkerService);
|
||||||
|
|
||||||
|
let model: ITextModel;
|
||||||
|
let validate: () => boolean;
|
||||||
|
if (isCodeEditor(editorOrModel)) {
|
||||||
|
model = editorOrModel.getModel();
|
||||||
|
const state = new EditorState(editorOrModel, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
||||||
|
validate = () => state.validate(editorOrModel);
|
||||||
|
} else {
|
||||||
|
model = editorOrModel;
|
||||||
|
const versionNow = editorOrModel.getVersionId();
|
||||||
|
validate = () => versionNow === editorOrModel.getVersionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawEdits = await provider.provideDocumentRangeFormattingEdits(
|
||||||
|
model,
|
||||||
|
range,
|
||||||
|
model.getFormattingOptions(),
|
||||||
|
token
|
||||||
|
);
|
||||||
|
|
||||||
|
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||||
|
|
||||||
|
if (!validate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!edits || edits.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCodeEditor(editorOrModel)) {
|
||||||
|
// use editor to apply edits
|
||||||
|
FormattingEdit.execute(editorOrModel, edits);
|
||||||
|
alertFormattingEdits(edits);
|
||||||
|
editorOrModel.pushUndoStop();
|
||||||
|
editorOrModel.focus();
|
||||||
|
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), editorCommon.ScrollType.Immediate);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// use model to apply edits
|
||||||
|
const [{ range }] = edits;
|
||||||
|
const initialSelection = new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
||||||
|
model.pushEditOperations([initialSelection], edits.map(edit => {
|
||||||
return {
|
return {
|
||||||
dispose() {
|
text: edit.text,
|
||||||
if (oldCallback) {
|
range: Range.lift(edit.range),
|
||||||
_conflictResolver = oldCallback;
|
forceMoveMarkers: true
|
||||||
oldCallback = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
}), undoEdits => {
|
||||||
|
for (const { range } of undoEdits) {
|
||||||
|
if (Range.areIntersectingOrTouching(range, initialSelection)) {
|
||||||
|
return [new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function invokeFormatterCallback<T extends { extensionId?: ExtensionIdentifier }>(formatter: T[], model: ITextModel, mode: number): void {
|
return true;
|
||||||
if (_conflictResolver) {
|
|
||||||
const ids = formatter.map(formatter => formatter.extensionId);
|
|
||||||
_conflictResolver(ids, model, mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDocumentRangeFormattingEdits(
|
export async function formatDocumentWithProvider(
|
||||||
telemetryService: ITelemetryService,
|
accessor: ServicesAccessor,
|
||||||
|
provider: DocumentFormattingEditProvider,
|
||||||
|
editorOrModel: ITextModel | IActiveCodeEditor,
|
||||||
|
token: CancellationToken
|
||||||
|
): Promise<boolean> {
|
||||||
|
const workerService = accessor.get(IEditorWorkerService);
|
||||||
|
|
||||||
|
let model: ITextModel;
|
||||||
|
let validate: () => boolean;
|
||||||
|
if (isCodeEditor(editorOrModel)) {
|
||||||
|
model = editorOrModel.getModel();
|
||||||
|
const state = new EditorState(editorOrModel, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
||||||
|
validate = () => state.validate(editorOrModel);
|
||||||
|
} else {
|
||||||
|
model = editorOrModel;
|
||||||
|
const versionNow = editorOrModel.getVersionId();
|
||||||
|
validate = () => versionNow === editorOrModel.getVersionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawEdits = await provider.provideDocumentFormattingEdits(
|
||||||
|
model,
|
||||||
|
model.getFormattingOptions(),
|
||||||
|
token
|
||||||
|
);
|
||||||
|
|
||||||
|
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||||
|
|
||||||
|
if (!validate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!edits || edits.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCodeEditor(editorOrModel)) {
|
||||||
|
// use editor to apply edits
|
||||||
|
FormattingEdit.execute(editorOrModel, edits);
|
||||||
|
alertFormattingEdits(edits);
|
||||||
|
editorOrModel.pushUndoStop();
|
||||||
|
editorOrModel.focus();
|
||||||
|
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), editorCommon.ScrollType.Immediate);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// use model to apply edits
|
||||||
|
const [{ range }] = edits;
|
||||||
|
const initialSelection = new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
||||||
|
model.pushEditOperations([initialSelection], edits.map(edit => {
|
||||||
|
return {
|
||||||
|
text: edit.text,
|
||||||
|
range: Range.lift(edit.range),
|
||||||
|
forceMoveMarkers: true
|
||||||
|
};
|
||||||
|
}), undoEdits => {
|
||||||
|
for (const { range } of undoEdits) {
|
||||||
|
if (Range.areIntersectingOrTouching(range, initialSelection)) {
|
||||||
|
return [new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getDocumentRangeFormattingEditsUntilResult(
|
||||||
workerService: IEditorWorkerService,
|
workerService: IEditorWorkerService,
|
||||||
model: ITextModel,
|
model: ITextModel,
|
||||||
range: Range,
|
range: Range,
|
||||||
options: FormattingOptions,
|
options: FormattingOptions,
|
||||||
mode: FormatMode,
|
|
||||||
token: CancellationToken
|
token: CancellationToken
|
||||||
): Promise<TextEdit[] | undefined | null> {
|
): Promise<TextEdit[] | undefined> {
|
||||||
|
|
||||||
const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model);
|
const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model);
|
||||||
|
for (const provider of providers) {
|
||||||
/* __GDPR__
|
let rawEdits = await Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)).catch(onUnexpectedExternalError);
|
||||||
"formatterInfo" : {
|
if (isNonEmptyArray(rawEdits)) {
|
||||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
return await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||||
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
|
||||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
telemetryService.publicLog('formatterInfo', {
|
return undefined;
|
||||||
type: 'range',
|
|
||||||
language: model.getLanguageIdentifier().language,
|
|
||||||
count: providers.length,
|
|
||||||
extensions: providers.map(p => p.extensionId ? ExtensionIdentifier.toKey(p.extensionId) : 'unknown')
|
|
||||||
});
|
|
||||||
|
|
||||||
invokeFormatterCallback(providers, model, mode | FormatKind.Range);
|
|
||||||
|
|
||||||
return first(providers.map(provider => () => {
|
|
||||||
return Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)).catch(onUnexpectedExternalError);
|
|
||||||
}), isNonEmptyArray).then(edits => {
|
|
||||||
// break edits into smaller edits
|
|
||||||
return workerService.computeMoreMinimalEdits(model.uri, edits);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDocumentFormattingEdits(
|
export async function getDocumentFormattingEditsUntilResult(
|
||||||
telemetryService: ITelemetryService,
|
|
||||||
workerService: IEditorWorkerService,
|
workerService: IEditorWorkerService,
|
||||||
model: ITextModel,
|
model: ITextModel,
|
||||||
options: FormattingOptions,
|
options: FormattingOptions,
|
||||||
mode: FormatMode,
|
|
||||||
token: CancellationToken
|
token: CancellationToken
|
||||||
): Promise<TextEdit[] | null | undefined> {
|
): Promise<TextEdit[] | undefined> {
|
||||||
|
|
||||||
const docFormattingProviders = DocumentFormattingEditProviderRegistry.ordered(model);
|
const providers = getRealAndSyntheticDocumentFormattersOrdered(model);
|
||||||
|
for (const provider of providers) {
|
||||||
/* __GDPR__
|
let rawEdits = await Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)).catch(onUnexpectedExternalError);
|
||||||
"formatterInfo" : {
|
if (isNonEmptyArray(rawEdits)) {
|
||||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
return await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||||
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
|
||||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
telemetryService.publicLog('formatterInfo', {
|
|
||||||
type: 'document',
|
|
||||||
language: model.getLanguageIdentifier().language,
|
|
||||||
count: docFormattingProviders.length,
|
|
||||||
extensions: docFormattingProviders.map(p => p.extensionId ? ExtensionIdentifier.toKey(p.extensionId) : 'unknown')
|
|
||||||
});
|
|
||||||
|
|
||||||
if (docFormattingProviders.length > 0) {
|
|
||||||
return first(docFormattingProviders.map(provider => () => {
|
|
||||||
// first with result wins...
|
|
||||||
return Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)).catch(onUnexpectedExternalError);
|
|
||||||
}), isNonEmptyArray).then(edits => {
|
|
||||||
// break edits into smaller edits
|
|
||||||
return workerService.computeMoreMinimalEdits(model.uri, edits);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// try range formatters when no document formatter is registered
|
|
||||||
return getDocumentRangeFormattingEdits(telemetryService, workerService, model, model.getFullModelRange(), options, mode | FormatKind.Document, token);
|
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOnTypeFormattingEdits(
|
export function getOnTypeFormattingEdits(
|
||||||
telemetryService: ITelemetryService,
|
|
||||||
workerService: IEditorWorkerService,
|
workerService: IEditorWorkerService,
|
||||||
model: ITextModel,
|
model: ITextModel,
|
||||||
position: Position,
|
position: Position,
|
||||||
@@ -144,21 +264,6 @@ export function getOnTypeFormattingEdits(
|
|||||||
|
|
||||||
const providers = OnTypeFormattingEditProviderRegistry.ordered(model);
|
const providers = OnTypeFormattingEditProviderRegistry.ordered(model);
|
||||||
|
|
||||||
/* __GDPR__
|
|
||||||
"formatterInfo" : {
|
|
||||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
|
||||||
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
|
||||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
telemetryService.publicLog('formatterInfo', {
|
|
||||||
type: 'ontype',
|
|
||||||
language: model.getLanguageIdentifier().language,
|
|
||||||
count: providers.length,
|
|
||||||
extensions: providers.map(p => p.extensionId ? ExtensionIdentifier.toKey(p.extensionId) : 'unknown')
|
|
||||||
});
|
|
||||||
|
|
||||||
if (providers.length === 0) {
|
if (providers.length === 0) {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
}
|
}
|
||||||
@@ -181,7 +286,7 @@ registerLanguageCommand('_executeFormatRangeProvider', function (accessor, args)
|
|||||||
if (!model) {
|
if (!model) {
|
||||||
throw illegalArgument('resource');
|
throw illegalArgument('resource');
|
||||||
}
|
}
|
||||||
return getDocumentRangeFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, Range.lift(range), options, FormatMode.Auto, CancellationToken.None);
|
return getDocumentRangeFormattingEditsUntilResult(accessor.get(IEditorWorkerService), model, Range.lift(range), options, CancellationToken.None);
|
||||||
});
|
});
|
||||||
|
|
||||||
registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, args) {
|
registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, args) {
|
||||||
@@ -194,7 +299,7 @@ registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, ar
|
|||||||
throw illegalArgument('resource');
|
throw illegalArgument('resource');
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDocumentFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, options, FormatMode.Auto, CancellationToken.None);
|
return getDocumentFormattingEditsUntilResult(accessor.get(IEditorWorkerService), model, options, CancellationToken.None);
|
||||||
});
|
});
|
||||||
|
|
||||||
registerLanguageCommand('_executeFormatOnTypeProvider', function (accessor, args) {
|
registerLanguageCommand('_executeFormatOnTypeProvider', function (accessor, args) {
|
||||||
@@ -207,5 +312,5 @@ registerLanguageCommand('_executeFormatOnTypeProvider', function (accessor, args
|
|||||||
throw illegalArgument('resource');
|
throw illegalArgument('resource');
|
||||||
}
|
}
|
||||||
|
|
||||||
return getOnTypeFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, Position.lift(position), ch, options);
|
return getOnTypeFormattingEdits(accessor.get(IEditorWorkerService), model, Position.lift(position), ch, options);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,122 +3,27 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
|
||||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { CodeEditorStateFlag, EditorState } from 'vs/editor/browser/core/editorState';
|
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||||
import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
|
||||||
import { EditorAction, registerEditorAction, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
import { EditorAction, registerEditorAction, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||||
import { CharacterSet } from 'vs/editor/common/core/characterClassifier';
|
import { CharacterSet } from 'vs/editor/common/core/characterClassifier';
|
||||||
import { Range } from 'vs/editor/common/core/range';
|
import { Range } from 'vs/editor/common/core/range';
|
||||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
import { DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
|
||||||
import { DocumentRangeFormattingEditProviderRegistry, FormattingOptions, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
|
|
||||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||||
import { getOnTypeFormattingEdits, getDocumentFormattingEdits, getDocumentRangeFormattingEdits, FormatMode } from 'vs/editor/contrib/format/format';
|
import { getOnTypeFormattingEdits, formatDocumentWithProvider, formatDocumentRangeWithProvider, alertFormattingEdits, getRealAndSyntheticDocumentFormattersOrdered } from 'vs/editor/contrib/format/format';
|
||||||
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
|
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||||
function alertFormattingEdits(edits: ISingleEditOperation[]): void {
|
|
||||||
|
|
||||||
edits = edits.filter(edit => edit.range);
|
|
||||||
if (!edits.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { range } = edits[0];
|
|
||||||
for (let i = 1; i < edits.length; i++) {
|
|
||||||
range = Range.plusRange(range, edits[i].range);
|
|
||||||
}
|
|
||||||
const { startLineNumber, endLineNumber } = range;
|
|
||||||
if (startLineNumber === endLineNumber) {
|
|
||||||
if (edits.length === 1) {
|
|
||||||
alert(nls.localize('hint11', "Made 1 formatting edit on line {0}", startLineNumber));
|
|
||||||
} else {
|
|
||||||
alert(nls.localize('hintn1', "Made {0} formatting edits on line {1}", edits.length, startLineNumber));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (edits.length === 1) {
|
|
||||||
alert(nls.localize('hint1n', "Made 1 formatting edit between lines {0} and {1}", startLineNumber, endLineNumber));
|
|
||||||
} else {
|
|
||||||
alert(nls.localize('hintnn', "Made {0} formatting edits between lines {1} and {2}", edits.length, startLineNumber, endLineNumber));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const enum FormatRangeType {
|
|
||||||
Full,
|
|
||||||
Selection,
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDocumentRange(
|
|
||||||
telemetryService: ITelemetryService,
|
|
||||||
workerService: IEditorWorkerService,
|
|
||||||
editor: IActiveCodeEditor,
|
|
||||||
rangeOrRangeType: Range | FormatRangeType,
|
|
||||||
options: FormattingOptions,
|
|
||||||
token: CancellationToken
|
|
||||||
): Promise<void> {
|
|
||||||
|
|
||||||
|
|
||||||
const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
|
||||||
const model = editor.getModel();
|
|
||||||
|
|
||||||
let range: Range;
|
|
||||||
if (rangeOrRangeType === FormatRangeType.Full) {
|
|
||||||
// full
|
|
||||||
range = model.getFullModelRange();
|
|
||||||
|
|
||||||
} else if (rangeOrRangeType === FormatRangeType.Selection) {
|
|
||||||
// selection or line (when empty)
|
|
||||||
range = editor.getSelection();
|
|
||||||
if (range.isEmpty()) {
|
|
||||||
range = new Range(range.startLineNumber, 1, range.endLineNumber, model.getLineMaxColumn(range.endLineNumber));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// as is
|
|
||||||
range = rangeOrRangeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getDocumentRangeFormattingEdits(telemetryService, workerService, model, range, options, FormatMode.Manual, token).then(edits => {
|
|
||||||
// make edit only when the editor didn't change while
|
|
||||||
// computing and only when there are edits
|
|
||||||
if (state.validate(editor) && isNonEmptyArray(edits)) {
|
|
||||||
FormattingEdit.execute(editor, edits);
|
|
||||||
alertFormattingEdits(edits);
|
|
||||||
editor.focus();
|
|
||||||
editor.revealPositionInCenterIfOutsideViewport(editor.getPosition(), editorCommon.ScrollType.Immediate);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDocument(telemetryService: ITelemetryService, workerService: IEditorWorkerService, editor: IActiveCodeEditor, options: FormattingOptions, token: CancellationToken): Promise<void> {
|
|
||||||
|
|
||||||
const allEdits: ISingleEditOperation[] = [];
|
|
||||||
const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
|
||||||
|
|
||||||
return getDocumentFormattingEdits(telemetryService, workerService, editor.getModel(), options, FormatMode.Manual, token).then(edits => {
|
|
||||||
// make edit only when the editor didn't change while
|
|
||||||
// computing and only when there are edits
|
|
||||||
if (state.validate(editor) && isNonEmptyArray(edits)) {
|
|
||||||
FormattingEdit.execute(editor, edits);
|
|
||||||
|
|
||||||
alertFormattingEdits(allEdits);
|
|
||||||
editor.pushUndoStop();
|
|
||||||
editor.focus();
|
|
||||||
editor.revealPositionInCenterIfOutsideViewport(editor.getPosition(), editorCommon.ScrollType.Immediate);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class FormatOnType implements editorCommon.IEditorContribution {
|
class FormatOnType implements editorCommon.IEditorContribution {
|
||||||
|
|
||||||
@@ -130,17 +35,25 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
editor: ICodeEditor,
|
editor: ICodeEditor,
|
||||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
|
||||||
@IEditorWorkerService private readonly _workerService: IEditorWorkerService
|
@IEditorWorkerService private readonly _workerService: IEditorWorkerService
|
||||||
) {
|
) {
|
||||||
this._editor = editor;
|
this._editor = editor;
|
||||||
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this.update()));
|
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this._update()));
|
||||||
this._callOnDispose.push(editor.onDidChangeModel(() => this.update()));
|
this._callOnDispose.push(editor.onDidChangeModel(() => this._update()));
|
||||||
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this.update()));
|
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this._update()));
|
||||||
this._callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this.update, this));
|
this._callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this._update, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private update(): void {
|
getId(): string {
|
||||||
|
return FormatOnType.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
this._callOnDispose = dispose(this._callOnDispose);
|
||||||
|
this._callOnModel = dispose(this._callOnModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _update(): void {
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
this._callOnModel = dispose(this._callOnModel);
|
this._callOnModel = dispose(this._callOnModel);
|
||||||
@@ -171,12 +84,12 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
|||||||
this._callOnModel.push(this._editor.onDidType((text: string) => {
|
this._callOnModel.push(this._editor.onDidType((text: string) => {
|
||||||
let lastCharCode = text.charCodeAt(text.length - 1);
|
let lastCharCode = text.charCodeAt(text.length - 1);
|
||||||
if (triggerChars.has(lastCharCode)) {
|
if (triggerChars.has(lastCharCode)) {
|
||||||
this.trigger(String.fromCharCode(lastCharCode));
|
this._trigger(String.fromCharCode(lastCharCode));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private trigger(ch: string): void {
|
private _trigger(ch: string): void {
|
||||||
if (!this._editor.hasModel()) {
|
if (!this._editor.hasModel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -214,7 +127,6 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
|||||||
});
|
});
|
||||||
|
|
||||||
getOnTypeFormattingEdits(
|
getOnTypeFormattingEdits(
|
||||||
this._telemetryService,
|
|
||||||
this._workerService,
|
this._workerService,
|
||||||
model,
|
model,
|
||||||
position,
|
position,
|
||||||
@@ -238,42 +150,41 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
|||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getId(): string {
|
|
||||||
return FormatOnType.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public dispose(): void {
|
|
||||||
this._callOnDispose = dispose(this._callOnDispose);
|
|
||||||
this._callOnModel = dispose(this._callOnModel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FormatOnPaste implements editorCommon.IEditorContribution {
|
class FormatOnPaste implements editorCommon.IEditorContribution {
|
||||||
|
|
||||||
private static readonly ID = 'editor.contrib.formatOnPaste';
|
private static readonly ID = 'editor.contrib.formatOnPaste';
|
||||||
|
|
||||||
private callOnDispose: IDisposable[];
|
private _callOnDispose: IDisposable[];
|
||||||
private callOnModel: IDisposable[];
|
private _callOnModel: IDisposable[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly editor: ICodeEditor,
|
private readonly editor: ICodeEditor,
|
||||||
@IEditorWorkerService private readonly workerService: IEditorWorkerService,
|
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
|
||||||
) {
|
) {
|
||||||
this.callOnDispose = [];
|
this._callOnDispose = [];
|
||||||
this.callOnModel = [];
|
this._callOnModel = [];
|
||||||
|
|
||||||
this.callOnDispose.push(editor.onDidChangeConfiguration(() => this.update()));
|
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this._update()));
|
||||||
this.callOnDispose.push(editor.onDidChangeModel(() => this.update()));
|
this._callOnDispose.push(editor.onDidChangeModel(() => this._update()));
|
||||||
this.callOnDispose.push(editor.onDidChangeModelLanguage(() => this.update()));
|
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this._update()));
|
||||||
this.callOnDispose.push(DocumentRangeFormattingEditProviderRegistry.onDidChange(this.update, this));
|
this._callOnDispose.push(DocumentRangeFormattingEditProviderRegistry.onDidChange(this._update, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private update(): void {
|
getId(): string {
|
||||||
|
return FormatOnPaste.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
this._callOnDispose = dispose(this._callOnDispose);
|
||||||
|
this._callOnModel = dispose(this._callOnModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _update(): void {
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
this.callOnModel = dispose(this.callOnModel);
|
this._callOnModel = dispose(this._callOnModel);
|
||||||
|
|
||||||
// we are disabled
|
// we are disabled
|
||||||
if (!this.editor.getConfiguration().contribInfo.formatOnPaste) {
|
if (!this.editor.getConfiguration().contribInfo.formatOnPaste) {
|
||||||
@@ -285,53 +196,41 @@ class FormatOnPaste implements editorCommon.IEditorContribution {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let model = this.editor.getModel();
|
// no formatter
|
||||||
|
if (!DocumentRangeFormattingEditProviderRegistry.has(this.editor.getModel())) {
|
||||||
// no support
|
|
||||||
if (!DocumentRangeFormattingEditProviderRegistry.has(model)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.callOnModel.push(this.editor.onDidPaste((range: Range) => {
|
this._callOnModel.push(this.editor.onDidPaste(range => this._trigger(range)));
|
||||||
this.trigger(range);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private trigger(range: Range): void {
|
private _trigger(range: Range): void {
|
||||||
if (!this.editor.hasModel()) {
|
if (!this.editor.hasModel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.editor.getSelections().length > 1) {
|
if (this.editor.getSelections().length > 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const provider = DocumentRangeFormattingEditProviderRegistry.ordered(this.editor.getModel());
|
||||||
const model = this.editor.getModel();
|
if (provider.length !== 1) {
|
||||||
formatDocumentRange(this.telemetryService, this.workerService, this.editor, range, model.getFormattingOptions(), CancellationToken.None);
|
// print status in n>1 case?
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
this._instantiationService.invokeFunction(formatDocumentRangeWithProvider, provider[0], this.editor, range, CancellationToken.None).catch(onUnexpectedError);
|
||||||
public getId(): string {
|
|
||||||
return FormatOnPaste.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public dispose(): void {
|
|
||||||
this.callOnDispose = dispose(this.callOnDispose);
|
|
||||||
this.callOnModel = dispose(this.callOnModel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FormatDocumentAction extends EditorAction {
|
class FormatDocumentAction extends EditorAction {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
id: 'editor.action.formatDocument',
|
id: 'editor.action.formatDocument',
|
||||||
label: nls.localize('formatDocument.label', "Format Document"),
|
label: nls.localize('formatDocument.label', "Format Document"),
|
||||||
alias: 'Format Document',
|
alias: 'Format Document',
|
||||||
precondition: EditorContextKeys.writable,
|
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentFormattingProvider, EditorContextKeys.hasMultipleDocumentFormattingProvider.toNegated()),
|
||||||
kbOpts: {
|
kbOpts: {
|
||||||
kbExpr: EditorContextKeys.editorTextFocus,
|
kbExpr: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, EditorContextKeys.hasDocumentFormattingProvider),
|
||||||
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F,
|
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F,
|
||||||
// secondary: [KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_D)],
|
|
||||||
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I },
|
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I },
|
||||||
weight: KeybindingWeight.EditorContrib
|
weight: KeybindingWeight.EditorContrib
|
||||||
},
|
},
|
||||||
@@ -343,26 +242,29 @@ export class FormatDocumentAction extends EditorAction {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> | void {
|
async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
|
||||||
if (!editor.hasModel()) {
|
if (!editor.hasModel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const workerService = accessor.get(IEditorWorkerService);
|
const instaService = accessor.get(IInstantiationService);
|
||||||
const telemetryService = accessor.get(ITelemetryService);
|
const model = editor.getModel();
|
||||||
return formatDocument(telemetryService, workerService, editor, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
const [provider] = getRealAndSyntheticDocumentFormattersOrdered(model);
|
||||||
|
if (provider) {
|
||||||
|
await instaService.invokeFunction(formatDocumentWithProvider, provider, editor, CancellationToken.None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FormatSelectionAction extends EditorAction {
|
class FormatSelectionAction extends EditorAction {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
id: 'editor.action.formatSelection',
|
id: 'editor.action.formatSelection',
|
||||||
label: nls.localize('formatSelection.label', "Format Selection"),
|
label: nls.localize('formatSelection.label', "Format Selection"),
|
||||||
alias: 'Format Code',
|
alias: 'Format Code',
|
||||||
precondition: ContextKeyExpr.and(EditorContextKeys.writable),
|
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentSelectionFormattingProvider, EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider.toNegated()),
|
||||||
kbOpts: {
|
kbOpts: {
|
||||||
kbExpr: EditorContextKeys.editorTextFocus,
|
kbExpr: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, EditorContextKeys.hasDocumentSelectionFormattingProvider),
|
||||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_F),
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_F),
|
||||||
weight: KeybindingWeight.EditorContrib
|
weight: KeybindingWeight.EditorContrib
|
||||||
},
|
},
|
||||||
@@ -374,13 +276,19 @@ export class FormatSelectionAction extends EditorAction {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> | void {
|
async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
|
||||||
if (!editor.hasModel()) {
|
if (!editor.hasModel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const workerService = accessor.get(IEditorWorkerService);
|
const instaService = accessor.get(IInstantiationService);
|
||||||
const telemetryService = accessor.get(ITelemetryService);
|
const [best] = DocumentRangeFormattingEditProviderRegistry.ordered(editor.getModel());
|
||||||
return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
if (best) {
|
||||||
|
let range: Range = editor.getSelection();
|
||||||
|
if (range.isEmpty()) {
|
||||||
|
range = new Range(range.startLineNumber, 1, range.startLineNumber, editor.getModel().getLineMaxColumn(range.startLineNumber));
|
||||||
|
}
|
||||||
|
await instaService.invokeFunction(formatDocumentRangeWithProvider, best, editor, range, CancellationToken.None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,17 +299,15 @@ registerEditorAction(FormatSelectionAction);
|
|||||||
|
|
||||||
// this is the old format action that does both (format document OR format selection)
|
// this is the old format action that does both (format document OR format selection)
|
||||||
// and we keep it here such that existing keybinding configurations etc will still work
|
// and we keep it here such that existing keybinding configurations etc will still work
|
||||||
CommandsRegistry.registerCommand('editor.action.format', accessor => {
|
CommandsRegistry.registerCommand('editor.action.format', async accessor => {
|
||||||
const editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
const editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||||
if (!editor || !editor.hasModel()) {
|
if (!editor || !editor.hasModel()) {
|
||||||
return undefined;
|
return;
|
||||||
}
|
}
|
||||||
const workerService = accessor.get(IEditorWorkerService);
|
const commandService = accessor.get(ICommandService);
|
||||||
const telemetryService = accessor.get(ITelemetryService);
|
|
||||||
|
|
||||||
if (editor.getSelection().isEmpty()) {
|
if (editor.getSelection().isEmpty()) {
|
||||||
return formatDocument(telemetryService, workerService, editor, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
await commandService.executeCommand('editor.action.formatDocument');
|
||||||
} else {
|
} else {
|
||||||
return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
await commandService.executeCommand('editor.action.formatSelection');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -203,8 +203,8 @@ export class MarkerController implements editorCommon.IEditorContribution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly _editor: ICodeEditor;
|
private readonly _editor: ICodeEditor;
|
||||||
private _model: MarkerModel | null;
|
private _model: MarkerModel | null = null;
|
||||||
private _widget: MarkerNavigationWidget | null;
|
private _widget: MarkerNavigationWidget | null = null;
|
||||||
private readonly _widgetVisible: IContextKey<boolean>;
|
private readonly _widgetVisible: IContextKey<boolean>;
|
||||||
private _disposeOnClose: IDisposable[] = [];
|
private _disposeOnClose: IDisposable[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export class MoveLinesCommand implements ICommand {
|
|||||||
private readonly _autoIndent: boolean;
|
private readonly _autoIndent: boolean;
|
||||||
|
|
||||||
private _selectionId: string;
|
private _selectionId: string;
|
||||||
private _moveEndPositionDown: boolean;
|
private _moveEndPositionDown?: boolean;
|
||||||
private _moveEndLineSelectionShrink: boolean;
|
private _moveEndLineSelectionShrink: boolean;
|
||||||
|
|
||||||
constructor(selection: Selection, isMovingDown: boolean, autoIndent: boolean) {
|
constructor(selection: Selection, isMovingDown: boolean, autoIndent: boolean) {
|
||||||
|
|||||||
@@ -196,10 +196,9 @@ suite('Editor Contrib - Line Operations', () => {
|
|||||||
const endOfNonono = new Selection(5, 11, 5, 11);
|
const endOfNonono = new Selection(5, 11, 5, 11);
|
||||||
|
|
||||||
editor.setSelections([beforeSecondWasoSelection, endOfBCCSelection, endOfNonono]);
|
editor.setSelections([beforeSecondWasoSelection, endOfBCCSelection, endOfNonono]);
|
||||||
let selections;
|
|
||||||
|
|
||||||
deleteAllLeftAction.run(null!, editor);
|
deleteAllLeftAction.run(null!, editor);
|
||||||
selections = editor.getSelections();
|
let selections = editor.getSelections()!;
|
||||||
|
|
||||||
assert.equal(model.getLineContent(2), '');
|
assert.equal(model.getLineContent(2), '');
|
||||||
assert.equal(model.getLineContent(3), ' waso waso');
|
assert.equal(model.getLineContent(3), ' waso waso');
|
||||||
@@ -227,7 +226,7 @@ suite('Editor Contrib - Line Operations', () => {
|
|||||||
], [5, 1, 5, 1]);
|
], [5, 1, 5, 1]);
|
||||||
|
|
||||||
deleteAllLeftAction.run(null!, editor);
|
deleteAllLeftAction.run(null!, editor);
|
||||||
selections = editor.getSelections();
|
selections = editor.getSelections()!;
|
||||||
|
|
||||||
assert.equal(model.getLineContent(1), 'hi my name is Carlos Matos waso waso');
|
assert.equal(model.getLineContent(1), 'hi my name is Carlos Matos waso waso');
|
||||||
assert.equal(selections.length, 2);
|
assert.equal(selections.length, 2);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { Choice, Placeholder, SnippetParser, Text, TextmateSnippet } from './sni
|
|||||||
import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver, CommentBasedVariableResolver, WorkspaceBasedVariableResolver } from './snippetVariables';
|
import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver, CommentBasedVariableResolver, WorkspaceBasedVariableResolver } from './snippetVariables';
|
||||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||||
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
|
|
||||||
registerThemingParticipant((theme, collector) => {
|
registerThemingParticipant((theme, collector) => {
|
||||||
|
|
||||||
@@ -281,7 +282,7 @@ export class OneSnippet {
|
|||||||
let result: Range | undefined;
|
let result: Range | undefined;
|
||||||
const model = this._editor.getModel();
|
const model = this._editor.getModel();
|
||||||
this._placeholderDecorations.forEach((decorationId) => {
|
this._placeholderDecorations.forEach((decorationId) => {
|
||||||
const placeholderRange = model.getDecorationRange(decorationId) || undefined;
|
const placeholderRange = withNullAsUndefined(model.getDecorationRange(decorationId));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = placeholderRange;
|
result = placeholderRange;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ export class SuggestAlternatives {
|
|||||||
private _index: number;
|
private _index: number;
|
||||||
private _model: CompletionModel | undefined;
|
private _model: CompletionModel | undefined;
|
||||||
private _acceptNext: ((selected: ISelectedSuggestion) => any) | undefined;
|
private _acceptNext: ((selected: ISelectedSuggestion) => any) | undefined;
|
||||||
private _listener: IDisposable;
|
private _listener: IDisposable | undefined;
|
||||||
private _ignore: boolean;
|
private _ignore: boolean | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _editor: ICodeEditor,
|
private readonly _editor: ICodeEditor,
|
||||||
|
|||||||
@@ -63,16 +63,16 @@ export class Colorizer {
|
|||||||
// Send out the event to create the mode
|
// Send out the event to create the mode
|
||||||
modeService.triggerMode(language);
|
modeService.triggerMode(language);
|
||||||
|
|
||||||
let tokenizationSupport = TokenizationRegistry.get(language);
|
const tokenizationSupport = TokenizationRegistry.get(language);
|
||||||
if (tokenizationSupport) {
|
if (tokenizationSupport) {
|
||||||
return _colorize(lines, tabSize, tokenizationSupport);
|
return _colorize(lines, tabSize, tokenizationSupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tokenizationSupportPromise = TokenizationRegistry.getPromise(language);
|
const tokenizationSupportPromise = TokenizationRegistry.getPromise(language);
|
||||||
if (tokenizationSupportPromise) {
|
if (tokenizationSupportPromise) {
|
||||||
// A tokenizer will be registered soon
|
// A tokenizer will be registered soon
|
||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
tokenizationSupportPromise!.then(tokenizationSupport => {
|
tokenizationSupportPromise.then(tokenizationSupport => {
|
||||||
_colorize(lines, tabSize, tokenizationSupport).then(resolve, reject);
|
_colorize(lines, tabSize, tokenizationSupport).then(resolve, reject);
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public addDynamicKeybinding(commandId: string, _keybinding: number, handler: ICommandHandler, when: ContextKeyExpr | null): IDisposable {
|
public addDynamicKeybinding(commandId: string, _keybinding: number, handler: ICommandHandler, when: ContextKeyExpr | undefined): IDisposable {
|
||||||
const keybinding = createKeybinding(_keybinding, OS);
|
const keybinding = createKeybinding(_keybinding, OS);
|
||||||
if (!keybinding) {
|
if (!keybinding) {
|
||||||
throw new Error(`Invalid keybinding`);
|
throw new Error(`Invalid keybinding`);
|
||||||
@@ -342,7 +342,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
|
|||||||
private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
|
private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
|
||||||
let result: ResolvedKeybindingItem[] = [], resultLen = 0;
|
let result: ResolvedKeybindingItem[] = [], resultLen = 0;
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const when = (item.when ? item.when.normalize() : null);
|
const when = (item.when ? item.when.normalize() : undefined);
|
||||||
const keybinding = item.keybinding;
|
const keybinding = item.keybinding;
|
||||||
|
|
||||||
if (!keybinding) {
|
if (!keybinding) {
|
||||||
@@ -665,9 +665,5 @@ export class SimpleLayoutService implements ILayoutService {
|
|||||||
return this._container;
|
return this._container;
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasWorkbench(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(private _container: HTMLElement) { }
|
constructor(private _container: HTMLElement) { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,7 +202,12 @@ export class DynamicStandaloneServices extends Disposable {
|
|||||||
|
|
||||||
let contextViewService = ensure(IContextViewService, () => this._register(new ContextViewService(layoutService)));
|
let contextViewService = ensure(IContextViewService, () => this._register(new ContextViewService(layoutService)));
|
||||||
|
|
||||||
ensure(IContextMenuService, () => this._register(new ContextMenuService(layoutService, telemetryService, notificationService, contextViewService, keybindingService, themeService)));
|
ensure(IContextMenuService, () => {
|
||||||
|
const contextMenuService = new ContextMenuService(telemetryService, notificationService, contextViewService, keybindingService, themeService);
|
||||||
|
contextMenuService.configure({ blockMouse: false }); // we do not want that in the standalone editor
|
||||||
|
|
||||||
|
return this._register(contextMenuService);
|
||||||
|
});
|
||||||
|
|
||||||
ensure(IMenuService, () => new MenuService(commandService));
|
ensure(IMenuService, () => new MenuService(commandService));
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ suite('StandaloneKeybindingService', () => {
|
|||||||
let commandInvoked = false;
|
let commandInvoked = false;
|
||||||
keybindingService.addDynamicKeybinding('testCommand', KeyCode.F9, () => {
|
keybindingService.addDynamicKeybinding('testCommand', KeyCode.F9, () => {
|
||||||
commandInvoked = true;
|
commandInvoked = true;
|
||||||
}, null);
|
}, undefined);
|
||||||
|
|
||||||
keybindingService.testDispatch({
|
keybindingService.testDispatch({
|
||||||
_standardKeyboardEventBrand: true,
|
_standardKeyboardEventBrand: true,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { IResourceInput } from 'vs/platform/editor/common/editor';
|
|||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
export class TestCodeEditorService extends AbstractCodeEditorService {
|
export class TestCodeEditorService extends AbstractCodeEditorService {
|
||||||
public lastInput: IResourceInput;
|
public lastInput?: IResourceInput;
|
||||||
public getActiveCodeEditor(): ICodeEditor | null { return null; }
|
public getActiveCodeEditor(): ICodeEditor | null { return null; }
|
||||||
public openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Promise<ICodeEditor | null> {
|
public openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Promise<ICodeEditor | null> {
|
||||||
this.lastInput = input;
|
this.lastInput = input;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ suite('OpenerService', function () {
|
|||||||
test('delegate to editorService, scheme:///fff', function () {
|
test('delegate to editorService, scheme:///fff', function () {
|
||||||
const openerService = new OpenerService(editorService, NullCommandService);
|
const openerService = new OpenerService(editorService, NullCommandService);
|
||||||
openerService.open(URI.parse('another:///somepath'));
|
openerService.open(URI.parse('another:///somepath'));
|
||||||
assert.equal(editorService.lastInput.options!.selection, undefined);
|
assert.equal(editorService.lastInput!.options!.selection, undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('delegate to editorService, scheme:///fff#L123', function () {
|
test('delegate to editorService, scheme:///fff#L123', function () {
|
||||||
@@ -38,22 +38,22 @@ suite('OpenerService', function () {
|
|||||||
const openerService = new OpenerService(editorService, NullCommandService);
|
const openerService = new OpenerService(editorService, NullCommandService);
|
||||||
|
|
||||||
openerService.open(URI.parse('file:///somepath#L23'));
|
openerService.open(URI.parse('file:///somepath#L23'));
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 1);
|
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||||
|
|
||||||
openerService.open(URI.parse('another:///somepath#L23'));
|
openerService.open(URI.parse('another:///somepath#L23'));
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 1);
|
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||||
|
|
||||||
openerService.open(URI.parse('another:///somepath#L23,45'));
|
openerService.open(URI.parse('another:///somepath#L23,45'));
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 45);
|
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('delegate to editorService, scheme:///fff#123,123', function () {
|
test('delegate to editorService, scheme:///fff#123,123', function () {
|
||||||
@@ -61,18 +61,18 @@ suite('OpenerService', function () {
|
|||||||
const openerService = new OpenerService(editorService, NullCommandService);
|
const openerService = new OpenerService(editorService, NullCommandService);
|
||||||
|
|
||||||
openerService.open(URI.parse('file:///somepath#23'));
|
openerService.open(URI.parse('file:///somepath#23'));
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 1);
|
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||||
|
|
||||||
openerService.open(URI.parse('file:///somepath#23,45'));
|
openerService.open(URI.parse('file:///somepath#23,45'));
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 45);
|
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('delegate to commandsService, command:someid', function () {
|
test('delegate to commandsService, command:someid', function () {
|
||||||
|
|||||||
Vendored
+2
@@ -5205,6 +5205,7 @@ declare namespace monaco.languages {
|
|||||||
* the formatting-feature.
|
* the formatting-feature.
|
||||||
*/
|
*/
|
||||||
export interface DocumentFormattingEditProvider {
|
export interface DocumentFormattingEditProvider {
|
||||||
|
readonly displayName?: string;
|
||||||
/**
|
/**
|
||||||
* Provide formatting edits for a whole document.
|
* Provide formatting edits for a whole document.
|
||||||
*/
|
*/
|
||||||
@@ -5216,6 +5217,7 @@ declare namespace monaco.languages {
|
|||||||
* the formatting-feature.
|
* the formatting-feature.
|
||||||
*/
|
*/
|
||||||
export interface DocumentRangeFormattingEditProvider {
|
export interface DocumentRangeFormattingEditProvider {
|
||||||
|
readonly displayName?: string;
|
||||||
/**
|
/**
|
||||||
* Provide formatting edits for a range in a document.
|
* Provide formatting edits for a range in a document.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class Menu implements IMenu {
|
|||||||
const [id, items] = group;
|
const [id, items] = group;
|
||||||
const activeActions: Array<MenuItemAction | SubmenuItemAction> = [];
|
const activeActions: Array<MenuItemAction | SubmenuItemAction> = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (this._contextKeyService.contextMatchesRules(item.when || null)) {
|
if (this._contextKeyService.contextMatchesRules(item.when)) {
|
||||||
const action = isIMenuItem(item) ? new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService) : new SubmenuItemAction(item);
|
const action = isIMenuItem(item) ? new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService) : new SubmenuItemAction(item);
|
||||||
activeActions.push(action);
|
activeActions.push(action);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ export class Configuration {
|
|||||||
if (workspace && resource) {
|
if (workspace && resource) {
|
||||||
const root = workspace.getFolder(resource);
|
const root = workspace.getFolder(resource);
|
||||||
if (root) {
|
if (root) {
|
||||||
return this._folderConfigurations.get(root.uri) || null;
|
return types.withUndefinedAsNull(this._folderConfigurations.get(root.uri));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { testFile } from 'vs/base/test/node/utils';
|
|||||||
|
|
||||||
class SettingsTestEnvironmentService extends EnvironmentService {
|
class SettingsTestEnvironmentService extends EnvironmentService {
|
||||||
|
|
||||||
constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome) {
|
constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome: string) {
|
||||||
super(args, _execPath);
|
super(args, _execPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
|
|||||||
return new ScopedContextKeyService(this, this._onDidChangeContextKey, domNode);
|
return new ScopedContextKeyService(this, this._onDidChangeContextKey, domNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public contextMatchesRules(rules: ContextKeyExpr | null): boolean {
|
public contextMatchesRules(rules: ContextKeyExpr | undefined): boolean {
|
||||||
if (this._isDisposed) {
|
if (this._isDisposed) {
|
||||||
throw new Error(`AbstractContextKeyService has been disposed`);
|
throw new Error(`AbstractContextKeyService has been disposed`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,14 +58,15 @@ export abstract class ContextKeyExpr {
|
|||||||
public static greaterThanEquals(key: string, value: any): ContextKeyExpr {
|
public static greaterThanEquals(key: string, value: any): ContextKeyExpr {
|
||||||
return new ContextKeyGreaterThanEqualsExpr(key, value);
|
return new ContextKeyGreaterThanEqualsExpr(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static lessThanEquals(key: string, value: any): ContextKeyExpr {
|
public static lessThanEquals(key: string, value: any): ContextKeyExpr {
|
||||||
return new ContextKeyLessThanEqualsExpr(key, value);
|
return new ContextKeyLessThanEqualsExpr(key, value);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
||||||
public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpr | null {
|
public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpr | undefined {
|
||||||
if (!serialized) {
|
if (!serialized) {
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pieces = serialized.split('&&');
|
let pieces = serialized.split('&&');
|
||||||
@@ -167,7 +168,7 @@ export abstract class ContextKeyExpr {
|
|||||||
public abstract getType(): ContextKeyExprType;
|
public abstract getType(): ContextKeyExprType;
|
||||||
public abstract equals(other: ContextKeyExpr): boolean;
|
public abstract equals(other: ContextKeyExpr): boolean;
|
||||||
public abstract evaluate(context: IContext): boolean;
|
public abstract evaluate(context: IContext): boolean;
|
||||||
public abstract normalize(): ContextKeyExpr | null;
|
public abstract normalize(): ContextKeyExpr | undefined;
|
||||||
public abstract serialize(): string;
|
public abstract serialize(): string;
|
||||||
public abstract keys(): string[];
|
public abstract keys(): string[];
|
||||||
public abstract map(mapFnc: IContextKeyExprMapper): ContextKeyExpr;
|
public abstract map(mapFnc: IContextKeyExprMapper): ContextKeyExpr;
|
||||||
@@ -549,9 +550,9 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public normalize(): ContextKeyExpr | null {
|
public normalize(): ContextKeyExpr | undefined {
|
||||||
if (this.expr.length === 0) {
|
if (this.expr.length === 0) {
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.expr.length === 1) {
|
if (this.expr.length === 1) {
|
||||||
@@ -762,7 +763,7 @@ export interface IContextKeyService {
|
|||||||
|
|
||||||
onDidChangeContext: Event<IContextKeyChangeEvent>;
|
onDidChangeContext: Event<IContextKeyChangeEvent>;
|
||||||
createKey<T>(key: string, defaultValue: T | undefined): IContextKey<T>;
|
createKey<T>(key: string, defaultValue: T | undefined): IContextKey<T>;
|
||||||
contextMatchesRules(rules: ContextKeyExpr | null): boolean;
|
contextMatchesRules(rules: ContextKeyExpr | undefined): boolean;
|
||||||
getContextKeyValue<T>(key: string): T | undefined;
|
getContextKeyValue<T>(key: string): T | undefined;
|
||||||
|
|
||||||
createScoped(target?: IContextKeyServiceTarget): IContextKeyService;
|
createScoped(target?: IContextKeyServiceTarget): IContextKeyService;
|
||||||
|
|||||||
@@ -5,50 +5,38 @@
|
|||||||
|
|
||||||
import 'vs/css!./contextMenuHandler';
|
import 'vs/css!./contextMenuHandler';
|
||||||
|
|
||||||
import { combinedDisposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
|
||||||
import { ActionRunner, IRunEvent } from 'vs/base/common/actions';
|
import { ActionRunner, IRunEvent } from 'vs/base/common/actions';
|
||||||
import { Menu } from 'vs/base/browser/ui/menu/menu';
|
import { Menu } from 'vs/base/browser/ui/menu/menu';
|
||||||
|
|
||||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
|
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
|
||||||
import { addDisposableListener, EventType, $, removeNode } from 'vs/base/browser/dom';
|
import { EventType, $, removeNode } from 'vs/base/browser/dom';
|
||||||
import { attachMenuStyler } from 'vs/platform/theme/common/styler';
|
import { attachMenuStyler } from 'vs/platform/theme/common/styler';
|
||||||
import { domEvent } from 'vs/base/browser/event';
|
import { domEvent } from 'vs/base/browser/event';
|
||||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
|
||||||
|
export interface IContextMenuHandlerOptions {
|
||||||
|
blockMouse: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class ContextMenuHandler {
|
export class ContextMenuHandler {
|
||||||
private element: HTMLElement | null;
|
|
||||||
private elementDisposable: IDisposable;
|
|
||||||
private menuContainerElement: HTMLElement | null;
|
|
||||||
private focusToReturn: HTMLElement;
|
private focusToReturn: HTMLElement;
|
||||||
private block: HTMLElement | null;
|
private block: HTMLElement | null;
|
||||||
|
private options: IContextMenuHandlerOptions = { blockMouse: true };
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private layoutService: ILayoutService,
|
|
||||||
private contextViewService: IContextViewService,
|
private contextViewService: IContextViewService,
|
||||||
private telemetryService: ITelemetryService,
|
private telemetryService: ITelemetryService,
|
||||||
private notificationService: INotificationService,
|
private notificationService: INotificationService,
|
||||||
private keybindingService: IKeybindingService,
|
private keybindingService: IKeybindingService,
|
||||||
private themeService: IThemeService
|
private themeService: IThemeService
|
||||||
) {
|
) { }
|
||||||
this.setContainer(this.layoutService.container);
|
|
||||||
}
|
|
||||||
|
|
||||||
setContainer(container: HTMLElement | null): void {
|
configure(options: IContextMenuHandlerOptions): void {
|
||||||
if (this.element) {
|
this.options = options;
|
||||||
this.elementDisposable = dispose(this.elementDisposable);
|
|
||||||
this.element = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container) {
|
|
||||||
this.element = container;
|
|
||||||
this.elementDisposable = addDisposableListener(this.element, EventType.MOUSE_DOWN, (e) => this.onMouseDown(e as MouseEvent));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showContextMenu(delegate: IContextMenuDelegate): void {
|
showContextMenu(delegate: IContextMenuDelegate): void {
|
||||||
@@ -67,8 +55,6 @@ export class ContextMenuHandler {
|
|||||||
anchorAlignment: delegate.anchorAlignment,
|
anchorAlignment: delegate.anchorAlignment,
|
||||||
|
|
||||||
render: (container) => {
|
render: (container) => {
|
||||||
this.menuContainerElement = container;
|
|
||||||
|
|
||||||
let className = delegate.getMenuClassName ? delegate.getMenuClassName() : '';
|
let className = delegate.getMenuClassName ? delegate.getMenuClassName() : '';
|
||||||
|
|
||||||
if (className) {
|
if (className) {
|
||||||
@@ -76,7 +62,7 @@ export class ContextMenuHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render invisible div to block mouse interaction in the rest of the UI
|
// Render invisible div to block mouse interaction in the rest of the UI
|
||||||
if (this.layoutService.hasWorkbench) {
|
if (this.options.blockMouse) {
|
||||||
this.block = container.appendChild($('.context-view-block'));
|
this.block = container.appendChild($('.context-view-block'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +106,6 @@ export class ContextMenuHandler {
|
|||||||
if (this.focusToReturn) {
|
if (this.focusToReturn) {
|
||||||
this.focusToReturn.focus();
|
this.focusToReturn.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.menuContainerElement = null;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -150,27 +134,4 @@ export class ContextMenuHandler {
|
|||||||
this.notificationService.error(e.error);
|
this.notificationService.error(e.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMouseDown(e: MouseEvent): void {
|
|
||||||
if (!this.menuContainerElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let event = new StandardMouseEvent(e);
|
|
||||||
let element: HTMLElement | null = event.target;
|
|
||||||
|
|
||||||
while (element) {
|
|
||||||
if (element === this.menuContainerElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
element = element.parentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.contextViewService.hideContextView();
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose(): void {
|
|
||||||
this.setContainer(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { ContextMenuHandler } from './contextMenuHandler';
|
import { ContextMenuHandler, IContextMenuHandlerOptions } from './contextMenuHandler';
|
||||||
import { IContextViewService, IContextMenuService } from './contextView';
|
import { IContextViewService, IContextMenuService } from './contextView';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
@@ -12,7 +12,6 @@ import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
|
|||||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
|
||||||
|
|
||||||
export class ContextMenuService extends Disposable implements IContextMenuService {
|
export class ContextMenuService extends Disposable implements IContextMenuService {
|
||||||
_serviceBrand: any;
|
_serviceBrand: any;
|
||||||
@@ -23,7 +22,6 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
|
|||||||
private contextMenuHandler: ContextMenuHandler;
|
private contextMenuHandler: ContextMenuHandler;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ILayoutService layoutService: ILayoutService,
|
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
@INotificationService notificationService: INotificationService,
|
@INotificationService notificationService: INotificationService,
|
||||||
@IContextViewService contextViewService: IContextViewService,
|
@IContextViewService contextViewService: IContextViewService,
|
||||||
@@ -32,15 +30,11 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
|
|||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.contextMenuHandler = this._register(new ContextMenuHandler(layoutService, contextViewService, telemetryService, notificationService, keybindingService, themeService));
|
this.contextMenuHandler = new ContextMenuHandler(contextViewService, telemetryService, notificationService, keybindingService, themeService);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
configure(options: IContextMenuHandlerOptions): void {
|
||||||
this.contextMenuHandler.dispose();
|
this.contextMenuHandler.configure(options);
|
||||||
}
|
|
||||||
|
|
||||||
setContainer(container: HTMLElement): void {
|
|
||||||
this.contextMenuHandler.setContainer(container);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContextMenu
|
// ContextMenu
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ function collectWorkspaceStats(folder: string, filter: string[]): Promise<Worksp
|
|||||||
|
|
||||||
const MAX_FILES = 20000;
|
const MAX_FILES = 20000;
|
||||||
|
|
||||||
function walk(dir: string, filter: string[], token, done: (allFiles: string[]) => void): void {
|
function walk(dir: string, filter: string[], token: { count: any; maxReached: any; }, done: (allFiles: string[]) => void): void {
|
||||||
let results: string[] = [];
|
let results: string[] = [];
|
||||||
readdir(dir, async (err, files) => {
|
readdir(dir, async (err, files) => {
|
||||||
// Ignore folders that can't be read
|
// Ignore folders that can't be read
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { parseExtensionHostPort, parseUserDataDir } from 'vs/platform/environmen
|
|||||||
suite('EnvironmentService', () => {
|
suite('EnvironmentService', () => {
|
||||||
|
|
||||||
test('parseExtensionHostPort when built', () => {
|
test('parseExtensionHostPort when built', () => {
|
||||||
const parse = a => parseExtensionHostPort(parseArgs(a), true);
|
const parse = (a: string[]) => parseExtensionHostPort(parseArgs(a), true);
|
||||||
|
|
||||||
assert.deepEqual(parse([]), { port: null, break: false, debugId: undefined });
|
assert.deepEqual(parse([]), { port: null, break: false, debugId: undefined });
|
||||||
assert.deepEqual(parse(['--debugPluginHost']), { port: null, break: false, debugId: undefined });
|
assert.deepEqual(parse(['--debugPluginHost']), { port: null, break: false, debugId: undefined });
|
||||||
@@ -28,7 +28,7 @@ suite('EnvironmentService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('parseExtensionHostPort when unbuilt', () => {
|
test('parseExtensionHostPort when unbuilt', () => {
|
||||||
const parse = a => parseExtensionHostPort(parseArgs(a), false);
|
const parse = (a: string[]) => parseExtensionHostPort(parseArgs(a), false);
|
||||||
|
|
||||||
assert.deepEqual(parse([]), { port: 5870, break: false, debugId: undefined });
|
assert.deepEqual(parse([]), { port: 5870, break: false, debugId: undefined });
|
||||||
assert.deepEqual(parse(['--debugPluginHost']), { port: 5870, break: false, debugId: undefined });
|
assert.deepEqual(parse(['--debugPluginHost']), { port: 5870, break: false, debugId: undefined });
|
||||||
@@ -45,7 +45,7 @@ suite('EnvironmentService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('userDataPath', () => {
|
test('userDataPath', () => {
|
||||||
const parse = (a, b: { cwd: () => string, env: { [key: string]: string } }) => parseUserDataDir(parseArgs(a), <any>b);
|
const parse = (a: string[], b: { cwd: () => string, env: { [key: string]: string } }) => parseUserDataDir(parseArgs(a), <any>b);
|
||||||
|
|
||||||
assert.equal(parse(['--user-data-dir', './dir'], { cwd: () => '/foo', env: {} }), path.resolve('/foo/dir'),
|
assert.equal(parse(['--user-data-dir', './dir'], { cwd: () => '/foo', env: {} }), path.resolve('/foo/dir'),
|
||||||
'should use cwd when --user-data-dir is specified');
|
'should use cwd when --user-data-dir is specified');
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export function getGalleryExtensionId(publisher: string, name: string): string {
|
|||||||
|
|
||||||
export function groupByExtension<T>(extensions: T[], getExtensionIdentifier: (t: T) => IExtensionIdentifier): T[][] {
|
export function groupByExtension<T>(extensions: T[], getExtensionIdentifier: (t: T) => IExtensionIdentifier): T[][] {
|
||||||
const byExtension: T[][] = [];
|
const byExtension: T[][] = [];
|
||||||
const findGroup = extension => {
|
const findGroup = (extension: T) => {
|
||||||
for (const group of byExtension) {
|
for (const group of byExtension) {
|
||||||
if (group.some(e => areSameExtensions(getExtensionIdentifier(e), getExtensionIdentifier(extension)))) {
|
if (group.some(e => areSameExtensions(getExtensionIdentifier(e), getExtensionIdentifier(extension)))) {
|
||||||
return group;
|
return group;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export interface ITranslations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function localizeManifest(manifest: IExtensionManifest, translations: ITranslations): IExtensionManifest {
|
export function localizeManifest(manifest: IExtensionManifest, translations: ITranslations): IExtensionManifest {
|
||||||
const patcher = value => {
|
const patcher = (value: string) => {
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export class ExtensionsLifecycle extends Disposable {
|
|||||||
return new Promise<void>((c, e) => {
|
return new Promise<void>((c, e) => {
|
||||||
|
|
||||||
const extensionLifecycleProcess = this.start(lifecycleHook, lifecycleType, args, extension);
|
const extensionLifecycleProcess = this.start(lifecycleHook, lifecycleType, args, extension);
|
||||||
let timeoutHandler;
|
let timeoutHandler: any;
|
||||||
|
|
||||||
const onexit = (error?: string) => {
|
const onexit = (error?: string) => {
|
||||||
if (timeoutHandler) {
|
if (timeoutHandler) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class ExtensionManagementChannel implements IServerChannel {
|
|||||||
this.onDidUninstallExtension = Event.buffer(service.onDidUninstallExtension, true);
|
this.onDidUninstallExtension = Event.buffer(service.onDidUninstallExtension, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
listen(context, event: string): Event<any> {
|
listen(context: any, event: string): Event<any> {
|
||||||
const uriTransformer = this.getUriTransformer(context);
|
const uriTransformer = this.getUriTransformer(context);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case 'onInstallExtension': return this.onInstallExtension;
|
case 'onInstallExtension': return this.onInstallExtension;
|
||||||
@@ -56,7 +56,7 @@ export class ExtensionManagementChannel implements IServerChannel {
|
|||||||
throw new Error('Invalid listen');
|
throw new Error('Invalid listen');
|
||||||
}
|
}
|
||||||
|
|
||||||
call(context, command: string, args?: any): Promise<any> {
|
call(context: any, command: string, args?: any): Promise<any> {
|
||||||
const uriTransformer: IURITransformer | null = this.getUriTransformer(context);
|
const uriTransformer: IURITransformer | null = this.getUriTransformer(context);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'zip': return this.service.zip(transformIncomingExtension(args[0], uriTransformer)).then(uri => transformOutgoingURI(uri, uriTransformer));
|
case 'zip': return this.service.zip(transformIncomingExtension(args[0], uriTransformer)).then(uri => transformOutgoingURI(uri, uriTransformer));
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||||||
|
|
||||||
private collectFiles(extension: ILocalExtension): Promise<IFile[]> {
|
private collectFiles(extension: ILocalExtension): Promise<IFile[]> {
|
||||||
|
|
||||||
const collectFilesFromDirectory = async (dir): Promise<string[]> => {
|
const collectFilesFromDirectory = async (dir: string): Promise<string[]> => {
|
||||||
let entries = await pfs.readdir(dir);
|
let entries = await pfs.readdir(dir);
|
||||||
entries = entries.map(e => path.join(dir, e));
|
entries = entries.map(e => path.join(dir, e));
|
||||||
const stats = await Promise.all(entries.map(e => pfs.stat(e)));
|
const stats = await Promise.all(entries.map(e => pfs.stat(e)));
|
||||||
@@ -288,7 +288,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||||||
this.reportTelemetry(this.getTelemetryEvent(operation), getGalleryExtensionTelemetryData(extension), new Date().getTime() - startTime, undefined);
|
this.reportTelemetry(this.getTelemetryEvent(operation), getGalleryExtensionTelemetryData(extension), new Date().getTime() - startTime, undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDidInstallExtensionFailure = (extension: IGalleryExtension, operation: InstallOperation, error) => {
|
const onDidInstallExtensionFailure = (extension: IGalleryExtension, operation: InstallOperation, error: Error) => {
|
||||||
const errorCode = error && (<ExtensionManagementError>error).code ? (<ExtensionManagementError>error).code : ERROR_UNKNOWN;
|
const errorCode = error && (<ExtensionManagementError>error).code ? (<ExtensionManagementError>error).code : ERROR_UNKNOWN;
|
||||||
this.logService.error(`Failed to install extension:`, extension.identifier.id, error ? error.message : errorCode);
|
this.logService.error(`Failed to install extension:`, extension.identifier.id, error ? error.message : errorCode);
|
||||||
this._onDidInstallExtension.fire({ identifier: extension.identifier, gallery: extension, operation, error: errorCode });
|
this._onDidInstallExtension.fire({ identifier: extension.identifier, gallery: extension, operation, error: errorCode });
|
||||||
|
|||||||
@@ -84,13 +84,18 @@ export interface IFileService {
|
|||||||
* If the optional parameter "resolveSingleChildDescendants" is specified in options,
|
* If the optional parameter "resolveSingleChildDescendants" is specified in options,
|
||||||
* the stat service is asked to automatically resolve child folders that only
|
* the stat service is asked to automatically resolve child folders that only
|
||||||
* contain a single element.
|
* contain a single element.
|
||||||
|
*
|
||||||
|
* If the optional parameter "resolveMetadata" is specified in options,
|
||||||
|
* the stat will contain metadata information such as size, mtime and etag.
|
||||||
*/
|
*/
|
||||||
|
resolveFile(resource: URI, options: IResolveMetadataFileOptions): Promise<IFileStatWithMetadata>;
|
||||||
resolveFile(resource: URI, options?: IResolveFileOptions): Promise<IFileStat>;
|
resolveFile(resource: URI, options?: IResolveFileOptions): Promise<IFileStat>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as resolveFile but supports resolving multiple resources in parallel.
|
* Same as resolveFile but supports resolving multiple resources in parallel.
|
||||||
* If one of the resolve targets fails to resolve returns a fake IFileStat instead of making the whole call fail.
|
* If one of the resolve targets fails to resolve returns a fake IFileStat instead of making the whole call fail.
|
||||||
*/
|
*/
|
||||||
|
resolveFiles(toResolve: { resource: URI, options: IResolveMetadataFileOptions }[]): Promise<IResolveFileResult[]>;
|
||||||
resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]>;
|
resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,21 +120,21 @@ export interface IFileService {
|
|||||||
/**
|
/**
|
||||||
* Updates the content replacing its previous value.
|
* Updates the content replacing its previous value.
|
||||||
*/
|
*/
|
||||||
updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): Promise<IFileStat>;
|
updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): Promise<IFileStatWithMetadata>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the file to a new path identified by the resource.
|
* Moves the file to a new path identified by the resource.
|
||||||
*
|
*
|
||||||
* The optional parameter overwrite can be set to replace an existing file at the location.
|
* The optional parameter overwrite can be set to replace an existing file at the location.
|
||||||
*/
|
*/
|
||||||
moveFile(source: URI, target: URI, overwrite?: boolean): Promise<IFileStat>;
|
moveFile(source: URI, target: URI, overwrite?: boolean): Promise<IFileStatWithMetadata>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the file to a path identified by the resource.
|
* Copies the file to a path identified by the resource.
|
||||||
*
|
*
|
||||||
* The optional parameter overwrite can be set to replace an existing file at the location.
|
* The optional parameter overwrite can be set to replace an existing file at the location.
|
||||||
*/
|
*/
|
||||||
copyFile(source: URI, target: URI, overwrite?: boolean): Promise<IFileStat>;
|
copyFile(source: URI, target: URI, overwrite?: boolean): Promise<IFileStatWithMetadata>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new file with the given path. The returned promise
|
* Creates a new file with the given path. The returned promise
|
||||||
@@ -137,13 +142,13 @@ export interface IFileService {
|
|||||||
*
|
*
|
||||||
* The optional parameter content can be used as value to fill into the new file.
|
* The optional parameter content can be used as value to fill into the new file.
|
||||||
*/
|
*/
|
||||||
createFile(resource: URI, content?: string, options?: ICreateFileOptions): Promise<IFileStat>;
|
createFile(resource: URI, content?: string, options?: ICreateFileOptions): Promise<IFileStatWithMetadata>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new folder with the given path. The returned promise
|
* Creates a new folder with the given path. The returned promise
|
||||||
* will have the stat model object as a result.
|
* will have the stat model object as a result.
|
||||||
*/
|
*/
|
||||||
createFolder(resource: URI): Promise<IFileStat>;
|
createFolder(resource: URI): Promise<IFileStatWithMetadata>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the provided file. The optional useTrash parameter allows to
|
* Deletes the provided file. The optional useTrash parameter allows to
|
||||||
@@ -194,9 +199,9 @@ export enum FileType {
|
|||||||
|
|
||||||
export interface IStat {
|
export interface IStat {
|
||||||
type: FileType;
|
type: FileType;
|
||||||
mtime: number;
|
mtime?: number;
|
||||||
ctime: number;
|
ctime?: number;
|
||||||
size: number;
|
size?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWatchOptions {
|
export interface IWatchOptions {
|
||||||
@@ -329,7 +334,7 @@ export const enum FileOperation {
|
|||||||
|
|
||||||
export class FileOperationEvent {
|
export class FileOperationEvent {
|
||||||
|
|
||||||
constructor(private _resource: URI, private _operation: FileOperation, private _target?: IFileStat) {
|
constructor(private _resource: URI, private _operation: FileOperation, private _target?: IFileStatWithMetadata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
get resource(): URI {
|
get resource(): URI {
|
||||||
@@ -481,7 +486,7 @@ export function isParent(path: string, candidate: string, ignoreCase?: boolean):
|
|||||||
return path.indexOf(candidate) === 0;
|
return path.indexOf(candidate) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBaseStat {
|
interface IBaseStat {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unified resource identifier of this file or folder.
|
* The unified resource identifier of this file or folder.
|
||||||
@@ -494,15 +499,29 @@ export interface IBaseStat {
|
|||||||
*/
|
*/
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the file.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
|
*/
|
||||||
|
size?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last modifictaion date represented
|
* The last modifictaion date represented
|
||||||
* as millis from unix epoch.
|
* as millis from unix epoch.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
*/
|
*/
|
||||||
mtime: number;
|
mtime?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unique identifier thet represents the
|
* A unique identifier thet represents the
|
||||||
* current state of the file or directory.
|
* current state of the file or directory.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
*/
|
*/
|
||||||
etag?: string;
|
etag?: string;
|
||||||
|
|
||||||
@@ -512,6 +531,12 @@ export interface IBaseStat {
|
|||||||
isReadonly?: boolean;
|
isReadonly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IBaseStatWithMetadata extends IBaseStat {
|
||||||
|
mtime: number;
|
||||||
|
etag: string;
|
||||||
|
size: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A file resource with meta information.
|
* A file resource with meta information.
|
||||||
*/
|
*/
|
||||||
@@ -532,11 +557,13 @@ export interface IFileStat extends IBaseStat {
|
|||||||
* The children of the file stat or undefined if none.
|
* The children of the file stat or undefined if none.
|
||||||
*/
|
*/
|
||||||
children?: IFileStat[];
|
children?: IFileStat[];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
export interface IFileStatWithMetadata extends IFileStat, IBaseStatWithMetadata {
|
||||||
* The size of the file if known.
|
mtime: number;
|
||||||
*/
|
etag: string;
|
||||||
size?: number;
|
size: number;
|
||||||
|
children?: IFileStatWithMetadata[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IResolveFileResult {
|
export interface IResolveFileResult {
|
||||||
@@ -544,10 +571,14 @@ export interface IResolveFileResult {
|
|||||||
success: boolean;
|
success: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IResolveFileResultWithMetadata extends IResolveFileResult {
|
||||||
|
stat?: IFileStatWithMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content and meta information of a file.
|
* Content and meta information of a file.
|
||||||
*/
|
*/
|
||||||
export interface IContent extends IBaseStat {
|
export interface IContent extends IBaseStatWithMetadata {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The content of a text file.
|
* The content of a text file.
|
||||||
@@ -614,7 +645,7 @@ export function snapshotToString(snapshot: ITextSnapshot): string {
|
|||||||
/**
|
/**
|
||||||
* Streamable content and meta information of a file.
|
* Streamable content and meta information of a file.
|
||||||
*/
|
*/
|
||||||
export interface IStreamContent extends IBaseStat {
|
export interface IStreamContent extends IBaseStatWithMetadata {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The streamable content of a text file.
|
* The streamable content of a text file.
|
||||||
@@ -712,6 +743,16 @@ export interface IResolveFileOptions {
|
|||||||
* Automatically continue resolving children of a directory if the number of children is 1.
|
* Automatically continue resolving children of a directory if the number of children is 1.
|
||||||
*/
|
*/
|
||||||
resolveSingleChildDescendants?: boolean;
|
resolveSingleChildDescendants?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will resolve mtime, size and etag of files if enabled. This can have a negative impact
|
||||||
|
* on performance and thus should only be used when these values are required.
|
||||||
|
*/
|
||||||
|
resolveMetadata?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IResolveMetadataFileOptions extends IResolveFileOptions {
|
||||||
|
resolveMetadata: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreateFileOptions {
|
export interface ICreateFileOptions {
|
||||||
@@ -1033,6 +1074,17 @@ export enum FileKind {
|
|||||||
export const MIN_MAX_MEMORY_SIZE_MB = 2048;
|
export const MIN_MAX_MEMORY_SIZE_MB = 2048;
|
||||||
export const FALLBACK_MAX_MEMORY_SIZE_MB = 4096;
|
export const FALLBACK_MAX_MEMORY_SIZE_MB = 4096;
|
||||||
|
|
||||||
|
export function etag(mtime: number, size: number): string;
|
||||||
|
export function etag(mtime: number | undefined, size: number | undefined): string | undefined;
|
||||||
|
export function etag(mtime: number | undefined, size: number | undefined): string | undefined {
|
||||||
|
if (typeof size !== 'number' || typeof mtime !== 'number') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mtime.toString(29) + size.toString(31);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO@ben remove traces of legacy file service
|
// TODO@ben remove traces of legacy file service
|
||||||
export const ILegacyFileService = createDecorator<ILegacyFileService>('legacyFileService');
|
export const ILegacyFileService = createDecorator<ILegacyFileService>('legacyFileService');
|
||||||
export interface ILegacyFileService {
|
export interface ILegacyFileService {
|
||||||
@@ -1049,10 +1101,6 @@ export interface ILegacyFileService {
|
|||||||
|
|
||||||
updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): Promise<IFileStat>;
|
updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): Promise<IFileStat>;
|
||||||
|
|
||||||
moveFile(source: URI, target: URI, overwrite?: boolean): Promise<IFileStat>;
|
|
||||||
|
|
||||||
copyFile(source: URI, target: URI, overwrite?: boolean): Promise<IFileStat>;
|
|
||||||
|
|
||||||
createFile(resource: URI, content?: string, options?: ICreateFileOptions): Promise<IFileStat>;
|
createFile(resource: URI, content?: string, options?: ICreateFileOptions): Promise<IFileStat>;
|
||||||
|
|
||||||
del(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): Promise<void>;
|
del(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): Promise<void>;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class Service1Consumer {
|
|||||||
|
|
||||||
class Target2Dep {
|
class Target2Dep {
|
||||||
|
|
||||||
constructor(@IService1 service1: IService1, @IService2 service2) {
|
constructor(@IService1 service1: IService1, @IService2 service2: Service2) {
|
||||||
assert.ok(service1 instanceof Service1);
|
assert.ok(service1 instanceof Service1);
|
||||||
assert.ok(service2 instanceof Service2);
|
assert.ok(service2 instanceof Service2);
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ class TargetOptional {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DependentServiceTarget {
|
class DependentServiceTarget {
|
||||||
constructor(@IDependentService d) {
|
constructor(@IDependentService d: IDependentService) {
|
||||||
assert.ok(d);
|
assert.ok(d);
|
||||||
assert.equal(d.name, 'farboo');
|
assert.equal(d.name, 'farboo');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export class IssueService implements IIssueService {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('vscode:workbenchCommand', (_: unknown, commandInfo) => {
|
ipcMain.on('vscode:workbenchCommand', (_: unknown, commandInfo: { id: any; from: any; args: any; }) => {
|
||||||
const { id, from, args } = commandInfo;
|
const { id, from, args } = commandInfo;
|
||||||
|
|
||||||
let parentWindow: BrowserWindow | null;
|
let parentWindow: BrowserWindow | null;
|
||||||
@@ -92,7 +92,7 @@ export class IssueService implements IIssueService {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('vscode:openExternal', (_: unknown, arg) => {
|
ipcMain.on('vscode:openExternal', (_: unknown, arg: string) => {
|
||||||
this.windowsService.openExternal(arg);
|
this.windowsService.openExternal(arg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export class KeybindingResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _isTargetedForRemoval(defaultKb: ResolvedKeybindingItem, keypressFirstPart: string | null, keypressChordPart: string | null, command: string, when: ContextKeyExpr | null): boolean {
|
private static _isTargetedForRemoval(defaultKb: ResolvedKeybindingItem, keypressFirstPart: string | null, keypressChordPart: string | null, command: string, when: ContextKeyExpr | undefined): boolean {
|
||||||
if (defaultKb.command !== command) {
|
if (defaultKb.command !== command) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ export class KeybindingResolver {
|
|||||||
* Returns true if it is provable `a` implies `b`.
|
* Returns true if it is provable `a` implies `b`.
|
||||||
* **Precondition**: Assumes `a` and `b` are normalized!
|
* **Precondition**: Assumes `a` and `b` are normalized!
|
||||||
*/
|
*/
|
||||||
public static whenIsEntirelyIncluded(a: ContextKeyExpr | null, b: ContextKeyExpr | null): boolean {
|
public static whenIsEntirelyIncluded(a: ContextKeyExpr | null | undefined, b: ContextKeyExpr | null | undefined): boolean {
|
||||||
if (!b) {
|
if (!b) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ export class KeybindingResolver {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static contextMatchesRules(context: IContext, rules: ContextKeyExpr | null): boolean {
|
public static contextMatchesRules(context: IContext, rules: ContextKeyExpr | null | undefined): boolean {
|
||||||
if (!rules) {
|
if (!rules) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export interface IKeybindingRule2 {
|
|||||||
id: string;
|
id: string;
|
||||||
args?: any;
|
args?: any;
|
||||||
weight: number;
|
weight: number;
|
||||||
when: ContextKeyExpr | null;
|
when: ContextKeyExpr | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum KeybindingWeight {
|
export const enum KeybindingWeight {
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ export class ResolvedKeybindingItem {
|
|||||||
public readonly bubble: boolean;
|
public readonly bubble: boolean;
|
||||||
public readonly command: string | null;
|
public readonly command: string | null;
|
||||||
public readonly commandArgs: any;
|
public readonly commandArgs: any;
|
||||||
public readonly when: ContextKeyExpr | null;
|
public readonly when: ContextKeyExpr | undefined;
|
||||||
public readonly isDefault: boolean;
|
public readonly isDefault: boolean;
|
||||||
|
|
||||||
constructor(resolvedKeybinding: ResolvedKeybinding | null, command: string | null, commandArgs: any, when: ContextKeyExpr | null, isDefault: boolean) {
|
constructor(resolvedKeybinding: ResolvedKeybinding | null, command: string | null, commandArgs: any, when: ContextKeyExpr | undefined, isDefault: boolean) {
|
||||||
this.resolvedKeybinding = resolvedKeybinding;
|
this.resolvedKeybinding = resolvedKeybinding;
|
||||||
this.keypressParts = resolvedKeybinding ? removeElementsAfterNulls(resolvedKeybinding.getDispatchParts()) : [];
|
this.keypressParts = resolvedKeybinding ? removeElementsAfterNulls(resolvedKeybinding.getDispatchParts()) : [];
|
||||||
this.bubble = (command ? command.charCodeAt(0) === CharCode.Caret : false);
|
this.bubble = (command ? command.charCodeAt(0) === CharCode.Caret : false);
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ suite('AbstractKeybindingService', () => {
|
|||||||
statusMessageCallsDisposed = null;
|
statusMessageCallsDisposed = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
function kbItem(keybinding: number, command: string, when: ContextKeyExpr | null = null): ResolvedKeybindingItem {
|
function kbItem(keybinding: number, command: string, when?: ContextKeyExpr): ResolvedKeybindingItem {
|
||||||
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS)!, OS) : null);
|
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS)!, OS) : null);
|
||||||
return new ResolvedKeybindingItem(
|
return new ResolvedKeybindingItem(
|
||||||
resolvedKeybinding,
|
resolvedKeybinding,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ suite('KeybindingResolver', () => {
|
|||||||
resolvedKeybinding,
|
resolvedKeybinding,
|
||||||
command,
|
command,
|
||||||
commandArgs,
|
commandArgs,
|
||||||
when ? when.normalize() : null,
|
when ? when.normalize() : undefined,
|
||||||
isDefault
|
isDefault
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,8 @@ export class LaunchService implements ILaunchService {
|
|||||||
preferNewWindow: !args['reuse-window'] && !args.wait,
|
preferNewWindow: !args['reuse-window'] && !args.wait,
|
||||||
forceReuseWindow: args['reuse-window'],
|
forceReuseWindow: args['reuse-window'],
|
||||||
diffMode: args.diff,
|
diffMode: args.diff,
|
||||||
addMode: args.add
|
addMode: args.add,
|
||||||
|
noRecentEntry: !!args['skip-add-to-recently-opened']
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,4 @@ export interface ILayoutService {
|
|||||||
* event carries the dimensions of the container as part of it.
|
* event carries the dimensions of the container as part of it.
|
||||||
*/
|
*/
|
||||||
readonly onLayout: Event<IDimension>;
|
readonly onLayout: Event<IDimension>;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the layout has a workbench surrounding the editor
|
|
||||||
*/
|
|
||||||
readonly hasWorkbench: boolean;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class LifecycleService extends AbstractLifecycleService {
|
|||||||
const windowId = this.windowService.getCurrentWindowId();
|
const windowId = this.windowService.getCurrentWindowId();
|
||||||
|
|
||||||
// Main side indicates that window is about to unload, check for vetos
|
// Main side indicates that window is about to unload, check for vetos
|
||||||
ipc.on('vscode:onBeforeUnload', (event, reply: { okChannel: string, cancelChannel: string, reason: ShutdownReason }) => {
|
ipc.on('vscode:onBeforeUnload', (_event: unknown, reply: { okChannel: string, cancelChannel: string, reason: ShutdownReason }) => {
|
||||||
this.logService.trace(`lifecycle: onBeforeUnload (reason: ${reply.reason})`);
|
this.logService.trace(`lifecycle: onBeforeUnload (reason: ${reply.reason})`);
|
||||||
|
|
||||||
// trigger onBeforeShutdown events and veto collecting
|
// trigger onBeforeShutdown events and veto collecting
|
||||||
@@ -75,7 +75,7 @@ export class LifecycleService extends AbstractLifecycleService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Main side indicates that we will indeed shutdown
|
// Main side indicates that we will indeed shutdown
|
||||||
ipc.on('vscode:onWillUnload', (event, reply: { replyChannel: string, reason: ShutdownReason }) => {
|
ipc.on('vscode:onWillUnload', (_event: unknown, reply: { replyChannel: string, reason: ShutdownReason }) => {
|
||||||
this.logService.trace(`lifecycle: onWillUnload (reason: ${reply.reason})`);
|
this.logService.trace(`lifecycle: onWillUnload (reason: ${reply.reason})`);
|
||||||
|
|
||||||
// trigger onWillShutdown events and joining
|
// trigger onWillShutdown events and joining
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ export class LifecycleService extends Disposable implements ILifecycleService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Window After Closing
|
// Window After Closing
|
||||||
window.win.on('closed', e => {
|
window.win.on('closed', () => {
|
||||||
this.logService.trace(`Lifecycle#window.on('closed') - window ID ${window.id}`);
|
this.logService.trace(`Lifecycle#window.on('closed') - window ID ${window.id}`);
|
||||||
|
|
||||||
// update window count
|
// update window count
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface IRemoteAgentEnvironment {
|
|||||||
pid: number;
|
pid: number;
|
||||||
appRoot: URI;
|
appRoot: URI;
|
||||||
appSettingsHome: URI;
|
appSettingsHome: URI;
|
||||||
|
appSettingsPath: URI;
|
||||||
logsPath: URI;
|
logsPath: URI;
|
||||||
extensionsPath: URI;
|
extensionsPath: URI;
|
||||||
extensionHostLogsPath: URI;
|
extensionHostLogsPath: URI;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user