Merge VS Code 1.23.1 (#1520)

This commit is contained in:
Matt Irvine
2018-06-05 11:24:51 -07:00
committed by GitHub
parent e3baf5c443
commit 0c58f09e59
3651 changed files with 74249 additions and 48599 deletions

View File

@@ -10,25 +10,30 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import * as vscode from 'vscode';
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
import * as types from 'vs/workbench/api/node/extHostTypes';
import { IRawColorInfo } from 'vs/workbench/api/node/extHost.protocol';
import { ISingleEditOperation } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search';
import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor';
import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures';
import { ExtHostTask } from './extHostTask';
import { ICommandsExecutor, PreviewHTMLAPICommand, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand } from './apiCommands';
export class ExtHostApiCommands {
static register(commands: ExtHostCommands) {
return new ExtHostApiCommands(commands).registerCommands();
static register(commands: ExtHostCommands, workspace: ExtHostTask) {
return new ExtHostApiCommands(commands, workspace).registerCommands();
}
private _commands: ExtHostCommands;
private _tasks: ExtHostTask;
private _disposables: IDisposable[] = [];
private constructor(commands: ExtHostCommands) {
private constructor(commands: ExtHostCommands, task: ExtHostTask) {
this._commands = commands;
this._tasks = task;
}
registerCommands() {
@@ -46,6 +51,14 @@ export class ExtHostApiCommands {
],
returns: 'A promise that resolves to an array of Location-instances.'
});
this._register('vscode.executeTypeDefinitionProvider', this._executeTypeDefinitionProvider, {
description: 'Execute all type definition providers.',
args: [
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
{ name: 'position', description: 'Position of a symbol', constraint: types.Position }
],
returns: 'A promise that resolves to an array of Location-instances.'
});
this._register('vscode.executeImplementationProvider', this._executeImplementationProvider, {
description: 'Execute all implementation providers.',
args: [
@@ -108,7 +121,8 @@ export class ExtHostApiCommands {
args: [
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
{ name: 'position', description: 'Position in a text document', constraint: types.Position },
{ name: 'triggerCharacter', description: '(optional) Trigger completion when the user types the character, like `,` or `(`', constraint: value => value === void 0 || typeof value === 'string' }
{ name: 'triggerCharacter', description: '(optional) Trigger completion when the user types the character, like `,` or `(`', constraint: value => value === void 0 || typeof value === 'string' },
{ name: 'itemResolveCount', description: '(optional) Number of completions to resolve (too large numbers slow down completions)', constraint: value => value === void 0 || typeof value === 'number' }
],
returns: 'A promise that resolves to a CompletionList-instance.'
});
@@ -123,7 +137,8 @@ export class ExtHostApiCommands {
this._register('vscode.executeCodeLensProvider', this._executeCodeLensProvider, {
description: 'Execute CodeLens provider.',
args: [
{ name: 'uri', description: 'Uri of a text document', constraint: URI }
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
{ name: 'itemResolveCount', description: '(optional) Number of lenses that should be resolved and returned. Will only retrun resolved lenses, will impact performance)', constraint: value => value === void 0 || typeof value === 'number' }
],
returns: 'A promise that resolves to an array of CodeLens-instances.'
});
@@ -161,99 +176,94 @@ export class ExtHostApiCommands {
],
returns: 'A promise that resolves to an array of DocumentLink-instances.'
});
this._register('vscode.executeTaskProvider', this._executeTaskProvider, {
description: 'Execute task provider',
args: [],
returns: 'An array of task handles'
});
this._register('vscode.executeDocumentColorProvider', this._executeDocumentColorProvider, {
description: 'Execute document color provider.',
args: [
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
],
returns: 'A promise that resolves to an array of ColorInformation objects.'
});
this._register('vscode.executeColorPresentationProvider', this._executeColorPresentationProvider, {
description: 'Execute color presentation provider.',
args: [
{ name: 'color', description: 'The color to show and insert', constraint: types.Color },
{ name: 'context', description: 'Context object with uri and range' }
],
returns: 'A promise that resolves to an array of ColorPresentation objects.'
});
this._register('vscode.previewHtml', (uri: URI, position?: vscode.ViewColumn, label?: string, options?: any) => {
return this._commands.executeCommand('_workbench.previewHtml',
uri,
typeof position === 'number' && typeConverters.fromViewColumn(position),
label,
options);
}, {
description: `
Render the html of the resource in an editor view.
See [working with the html preview](https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands#working-with-the-html-preview) for more information about the html preview's intergration with the editor and for best practices for extension authors.
// -----------------------------------------------------------------
// The following commands are registered on both sides separately.
//
// We are trying to maintain backwards compatibility for cases where
// API commands are encoded as markdown links, for example.
// -----------------------------------------------------------------
type ICommandHandler = (...args: any[]) => any;
const adjustHandler = (handler: (executor: ICommandsExecutor, ...args: any[]) => any): ICommandHandler => {
return (...args: any[]) => {
return handler(this._commands, ...args);
};
};
this._register(PreviewHTMLAPICommand.ID, adjustHandler(PreviewHTMLAPICommand.execute), {
description: `
Render the HTML of the resource in an editor view.
See [working with the HTML preview](https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands#working-with-the-html-preview) for more information about the HTML preview's integration with the editor and for best practices for extension authors.
`,
args: [
{ name: 'uri', description: 'Uri of the resource to preview.', constraint: value => value instanceof URI || typeof value === 'string' },
{ name: 'column', description: '(optional) Column in which to preview.', constraint: value => typeof value === 'undefined' || (typeof value === 'number' && typeof types.ViewColumn[value] === 'string') },
{ name: 'label', description: '(optional) An human readable string that is used as title for the preview.', constraint: v => typeof v === 'string' || typeof v === 'undefined' },
{ name: 'options', description: '(optional) Options for controlling webview environment.', constraint: v => typeof v === 'object' || typeof v === 'undefined' }
]
});
args: [
{ name: 'uri', description: 'Uri of the resource to preview.', constraint: value => value instanceof URI || typeof value === 'string' },
{ name: 'column', description: '(optional) Column in which to preview.', constraint: value => typeof value === 'undefined' || (typeof value === 'number' && typeof types.ViewColumn[value] === 'string') },
{ name: 'label', description: '(optional) An human readable string that is used as title for the preview.', constraint: v => typeof v === 'string' || typeof v === 'undefined' },
{ name: 'options', description: '(optional) Options for controlling webview environment.', constraint: v => typeof v === 'object' || typeof v === 'undefined' }
]
});
this._register('vscode.openFolder', (uri?: URI, forceNewWindow?: boolean) => {
if (!uri) {
return this._commands.executeCommand('_files.pickFolderAndOpen', forceNewWindow);
}
this._register(OpenFolderAPICommand.ID, adjustHandler(OpenFolderAPICommand.execute), {
description: 'Open a folder or workspace in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder/workspace unless the newWindow parameter is set to true.',
args: [
{ name: 'uri', description: '(optional) Uri of the folder or workspace file to open. If not provided, a native dialog will ask the user for the folder', constraint: value => value === void 0 || value instanceof URI },
{ name: 'newWindow', description: '(optional) Whether to open the folder/workspace in a new window or the same. Defaults to opening in the same window.', constraint: value => value === void 0 || typeof value === 'boolean' }
]
});
return this._commands.executeCommand('_files.windowOpen', [uri.fsPath], forceNewWindow);
}, {
description: 'Open a folder or workspace in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder/workspace unless the newWindow parameter is set to true.',
args: [
{ name: 'uri', description: '(optional) Uri of the folder or workspace file to open. If not provided, a native dialog will ask the user for the folder', constraint: value => value === void 0 || value instanceof URI },
{ name: 'newWindow', description: '(optional) Whether to open the folder/workspace in a new window or the same. Defaults to opening in the same window.', constraint: value => value === void 0 || typeof value === 'boolean' }
]
});
this._register(DiffAPICommand.ID, adjustHandler(DiffAPICommand.execute), {
description: 'Opens the provided resources in the diff editor to compare their contents.',
args: [
{ name: 'left', description: 'Left-hand side resource of the diff editor', constraint: URI },
{ name: 'right', description: 'Right-hand side resource of the diff editor', constraint: URI },
{ name: 'title', description: '(optional) Human readable title for the diff editor', constraint: v => v === void 0 || typeof v === 'string' },
{ name: 'options', description: '(optional) Editor options, see vscode.TextDocumentShowOptions' }
]
});
this._register('vscode.diff', (left: URI, right: URI, label: string, options?: vscode.TextDocumentShowOptions) => {
return this._commands.executeCommand('_workbench.diff', [
left, right,
label,
undefined,
typeConverters.toTextEditorOptions(options),
options ? typeConverters.fromViewColumn(options.viewColumn) : undefined
]);
}, {
description: 'Opens the provided resources in the diff editor to compare their contents.',
args: [
{ name: 'left', description: 'Left-hand side resource of the diff editor', constraint: URI },
{ name: 'right', description: 'Right-hand side resource of the diff editor', constraint: URI },
{ name: 'title', description: '(optional) Human readable title for the diff editor', constraint: v => v === void 0 || typeof v === 'string' },
{ name: 'options', description: '(optional) Editor options, see vscode.TextDocumentShowOptions' }
]
});
this._register(OpenAPICommand.ID, adjustHandler(OpenAPICommand.execute), {
description: 'Opens the provided resource in the editor. Can be a text or binary file, or a http(s) url. If you need more control over the options for opening a text file, use vscode.window.showTextDocument instead.',
args: [
{ name: 'resource', description: 'Resource to open', constraint: URI },
{ name: 'columnOrOptions', description: '(optional) Either the column in which to open or editor options, see vscode.TextDocumentShowOptions', constraint: v => v === void 0 || typeof v === 'number' || typeof v === 'object' }
]
});
this._register('vscode.open', (resource: URI, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions) => {
let options: ITextEditorOptions;
let column: EditorPosition;
if (columnOrOptions) {
if (typeof columnOrOptions === 'number') {
column = typeConverters.fromViewColumn(columnOrOptions);
} else {
options = typeConverters.toTextEditorOptions(columnOrOptions);
column = typeConverters.fromViewColumn(columnOrOptions.viewColumn);
}
}
return this._commands.executeCommand('_workbench.open', [
resource,
options,
column
]);
}, {
description: 'Opens the provided resource in the editor. Can be a text or binary file, or a http(s) url. If you need more control over the options for opening a text file, use vscode.window.showTextDocument instead.',
args: [
{ name: 'resource', description: 'Resource to open', constraint: URI },
{ name: 'columnOrOptions', description: '(optional) Either the column in which to open or editor options, see vscode.TextDocumentShowOptions', constraint: v => v === void 0 || typeof v === 'number' || typeof v === 'object' }
]
});
this._register('vscode.removeFromRecentlyOpened', (path: string) => {
return this._commands.executeCommand('_workbench.removeFromRecentlyOpened', path);
}, {
description: 'Removes an entry with the given path from the recently opened list.',
args: [
{ name: 'path', description: 'Path to remove from recently opened.', constraint: value => typeof value === 'string' }
]
});
this._register(RemoveFromRecentlyOpenedAPICommand.ID, adjustHandler(RemoveFromRecentlyOpenedAPICommand.execute), {
description: 'Removes an entry with the given path from the recently opened list.',
args: [
{ name: 'path', description: 'Path to remove from recently opened.', constraint: value => typeof value === 'string' }
]
});
}
// --- command impl
private _register(id: string, handler: (...args: any[]) => any, description?: ICommandHandlerDescription): void {
let disposable = this._commands.registerCommand(id, handler, this, description);
let disposable = this._commands.registerCommand(false, id, handler, this, description);
this._disposables.push(disposable);
}
@@ -280,12 +290,17 @@ export class ExtHostApiCommands {
resource,
position: position && typeConverters.fromPosition(position)
};
return this._commands.executeCommand<modes.Location[]>('_executeDefinitionProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(typeConverters.location.to);
}
return undefined;
});
return this._commands.executeCommand<modes.Location[]>('_executeDefinitionProvider', args)
.then(tryMapWith(typeConverters.location.to));
}
private _executeTypeDefinitionProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
const args = {
resource,
position: position && typeConverters.fromPosition(position)
};
return this._commands.executeCommand<modes.Location[]>('_executeTypeDefinitionProvider', args)
.then(tryMapWith(typeConverters.location.to));
}
private _executeImplementationProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
@@ -293,12 +308,8 @@ export class ExtHostApiCommands {
resource,
position: position && typeConverters.fromPosition(position)
};
return this._commands.executeCommand<modes.Location[]>('_executeImplementationProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(typeConverters.location.to);
}
return undefined;
});
return this._commands.executeCommand<modes.Location[]>('_executeImplementationProvider', args)
.then(tryMapWith(typeConverters.location.to));
}
private _executeHoverProvider(resource: URI, position: types.Position): Thenable<types.Hover[]> {
@@ -306,12 +317,8 @@ export class ExtHostApiCommands {
resource,
position: position && typeConverters.fromPosition(position)
};
return this._commands.executeCommand<modes.Hover[]>('_executeHoverProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(typeConverters.toHover);
}
return undefined;
});
return this._commands.executeCommand<modes.Hover[]>('_executeHoverProvider', args)
.then(tryMapWith(typeConverters.toHover));
}
private _executeDocumentHighlights(resource: URI, position: types.Position): Thenable<types.DocumentHighlight[]> {
@@ -319,12 +326,8 @@ export class ExtHostApiCommands {
resource,
position: position && typeConverters.fromPosition(position)
};
return this._commands.executeCommand<modes.DocumentHighlight[]>('_executeDocumentHighlights', args).then(value => {
if (Array.isArray(value)) {
return value.map(typeConverters.toDocumentHighlight);
}
return undefined;
});
return this._commands.executeCommand<modes.DocumentHighlight[]>('_executeDocumentHighlights', args)
.then(tryMapWith(typeConverters.toDocumentHighlight));
}
private _executeReferenceProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
@@ -332,12 +335,8 @@ export class ExtHostApiCommands {
resource,
position: position && typeConverters.fromPosition(position)
};
return this._commands.executeCommand<modes.Location[]>('_executeReferenceProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(typeConverters.location.to);
}
return undefined;
});
return this._commands.executeCommand<modes.Location[]>('_executeReferenceProvider', args)
.then(tryMapWith(typeConverters.location.to));
}
private _executeDocumentRenameProvider(resource: URI, position: types.Position, newName: string): Thenable<types.WorkspaceEdit> {
@@ -371,11 +370,12 @@ export class ExtHostApiCommands {
});
}
private _executeCompletionItemProvider(resource: URI, position: types.Position, triggerCharacter: string): Thenable<types.CompletionList> {
private _executeCompletionItemProvider(resource: URI, position: types.Position, triggerCharacter: string, maxItemsToResolve: number): Thenable<types.CompletionList> {
const args = {
resource,
position: position && typeConverters.fromPosition(position),
triggerCharacter
triggerCharacter,
maxItemsToResolve
};
return this._commands.executeCommand<modes.ISuggestResult>('_executeCompletionItemProvider', args).then(result => {
if (result) {
@@ -387,6 +387,32 @@ export class ExtHostApiCommands {
});
}
private _executeDocumentColorProvider(resource: URI): Thenable<types.ColorInformation[]> {
const args = {
resource
};
return this._commands.executeCommand<IRawColorInfo[]>('_executeDocumentColorProvider', args).then(result => {
if (result) {
return result.map(ci => ({ range: typeConverters.toRange(ci.range), color: typeConverters.Color.to(ci.color) }));
}
return [];
});
}
private _executeColorPresentationProvider(color: types.Color, context: { uri: URI, range: types.Range }): Thenable<types.ColorPresentation[]> {
const args = {
resource: context.uri,
color: typeConverters.Color.from(color),
range: typeConverters.fromRange(context.range),
};
return this._commands.executeCommand<modes.IColorPresentation[]>('_executeColorPresentationProvider', args).then(result => {
if (result) {
return result.map(typeConverters.ColorPresentation.to);
}
return [];
});
}
private _executeDocumentSymbolProvider(resource: URI): Thenable<types.SymbolInformation[]> {
const args = {
resource
@@ -404,11 +430,8 @@ export class ExtHostApiCommands {
resource,
range: typeConverters.fromRange(range)
};
return this._commands.executeCommand<CustomCodeAction[]>('_executeCodeActionProvider', args).then(value => {
if (!Array.isArray(value)) {
return undefined;
}
return value.map(codeAction => {
return this._commands.executeCommand<CustomCodeAction[]>('_executeCodeActionProvider', args)
.then(tryMapWith(codeAction => {
if (codeAction._isSynthetic) {
return this._commands.converter.fromInternal(codeAction.command);
} else {
@@ -424,22 +447,18 @@ export class ExtHostApiCommands {
}
return ret;
}
});
});
}));
}
private _executeCodeLensProvider(resource: URI): Thenable<vscode.CodeLens[]> {
const args = { resource };
return this._commands.executeCommand<modes.ICodeLensSymbol[]>('_executeCodeLensProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(item => {
return new types.CodeLens(
typeConverters.toRange(item.range),
this._commands.converter.fromInternal(item.command));
});
}
return undefined;
});
private _executeCodeLensProvider(resource: URI, itemResolveCount: number): Thenable<vscode.CodeLens[]> {
const args = { resource, itemResolveCount };
return this._commands.executeCommand<modes.ICodeLensSymbol[]>('_executeCodeLensProvider', args)
.then(tryMapWith(item => {
return new types.CodeLens(
typeConverters.toRange(item.range),
this._commands.converter.fromInternal(item.command));
}));
}
private _executeFormatDocumentProvider(resource: URI, options: vscode.FormattingOptions): Thenable<vscode.TextEdit[]> {
@@ -447,12 +466,8 @@ export class ExtHostApiCommands {
resource,
options
};
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatDocumentProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text));
}
return undefined;
});
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatDocumentProvider', args)
.then(tryMapWith(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text)));
}
private _executeFormatRangeProvider(resource: URI, range: types.Range, options: vscode.FormattingOptions): Thenable<vscode.TextEdit[]> {
@@ -461,12 +476,8 @@ export class ExtHostApiCommands {
range: typeConverters.fromRange(range),
options
};
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatRangeProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text));
}
return undefined;
});
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatRangeProvider', args)
.then(tryMapWith(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text)));
}
private _executeFormatOnTypeProvider(resource: URI, position: types.Position, ch: string, options: vscode.FormattingOptions): Thenable<vscode.TextEdit[]> {
@@ -476,20 +487,25 @@ export class ExtHostApiCommands {
ch,
options
};
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatOnTypeProvider', args).then(value => {
if (Array.isArray(value)) {
return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text));
}
return undefined;
});
return this._commands.executeCommand<ISingleEditOperation[]>('_executeFormatOnTypeProvider', args)
.then(tryMapWith(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text)));
}
private _executeDocumentLinkProvider(resource: URI): Thenable<vscode.DocumentLink[]> {
return this._commands.executeCommand<modes.ILink[]>('_executeLinkProvider', resource).then(value => {
if (Array.isArray(value)) {
return value.map(typeConverters.DocumentLink.to);
}
return undefined;
});
return this._commands.executeCommand<modes.ILink[]>('_executeLinkProvider', resource)
.then(tryMapWith(typeConverters.DocumentLink.to));
}
private _executeTaskProvider(): Thenable<vscode.Task[]> {
return this._tasks.fetchTasks();
}
}
function tryMapWith<T, R>(f: (x: T) => R) {
return (value: T[]) => {
if (Array.isArray(value)) {
return value.map(f);
}
return undefined;
};
}