Merge branch 'master' into sandy081/languageConfiguration

This commit is contained in:
Sandeep Somavarapu
2019-12-17 08:24:54 +01:00
52 changed files with 732 additions and 677 deletions

View File

@@ -39,17 +39,16 @@ const configurationEntrySchema: IJSONSchema = {
},
scope: {
type: 'string',
enum: ['application', 'machine', 'window', 'resource', 'resource-language', 'machine-overridable'],
enum: ['application', 'machine', 'window', 'resource', 'machine-overridable'],
default: 'window',
enumDescriptions: [
nls.localize('scope.application.description', "Configuration that can be configured only in the user settings."),
nls.localize('scope.machine.description', "Configuration that can be configured only in the user settings when the extension is running locally, or only in the remote settings when the extension is running remotely."),
nls.localize('scope.window.description', "Configuration that can be configured in the user, remote or workspace settings."),
nls.localize('scope.resource.description', "Configuration that can be configured in the user, remote, workspace or folder settings."),
nls.localize('scope.resource-language.description', "Resource configuration that can be configured also in language specific settings."),
nls.localize('scope.machine-overridable.description', "Machine configuration that can be configured also in workspace or folder settings.")
],
description: nls.localize('scope.description', "Scope in which the configuration is applicable. Available scopes are `application`, `machine`, `window`, `resource`, `resource-language` and `machine-overridable`.")
description: nls.localize('scope.description', "Scope in which the configuration is applicable. Available scopes are `application`, `machine`, `window`, `resource`, and `machine-overridable`.")
},
enumDescriptions: {
type: 'array',
@@ -219,8 +218,6 @@ function validateProperties(configuration: IConfigurationNode, extension: IExten
propertyConfiguration.scope = ConfigurationScope.RESOURCE;
} else if (propertyConfiguration.scope.toString() === 'machine-overridable') {
propertyConfiguration.scope = ConfigurationScope.MACHINE_OVERRIDABLE;
} else if (propertyConfiguration.scope.toString() === 'resource-language') {
propertyConfiguration.scope = ConfigurationScope.RESOURCE_LANGUAGE;
} else {
propertyConfiguration.scope = ConfigurationScope.WINDOW;
}

View File

@@ -532,9 +532,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
return extHostWebviews.registerWebviewPanelSerializer(extension, viewType, serializer);
},
registerWebviewEditorProvider: (viewType: string, provider: vscode.WebviewEditorProvider, options?: vscode.WebviewPanelOptions) => {
registerWebviewCustomEditorProvider: (viewType: string, provider: vscode.WebviewCustomEditorProvider, options?: vscode.WebviewPanelOptions) => {
checkProposedApiEnabled(extension);
return extHostWebviews.registerWebviewEditorProvider(extension, viewType, provider, options);
return extHostWebviews.registerWebviewCustomEditorProvider(extension, viewType, provider, options);
},
registerDecorationProvider(provider: vscode.DecorationProvider) {
checkProposedApiEnabled(extension);

View File

@@ -572,11 +572,10 @@ export interface MainThreadWebviewsShape extends IDisposable {
$registerSerializer(viewType: string): void;
$unregisterSerializer(viewType: string): void;
$registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions): void;
$registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: readonly WebviewEditorCapabilities[]): void;
$unregisterEditorProvider(viewType: string): void;
$registerCapabilities(handle: WebviewPanelHandle, capabilities: readonly WebviewEditorCapabilities[]): void;
$onEdit(handle: WebviewPanelHandle, editJson: any): void;
$onEdit(resource: UriComponents, viewType: string, editJson: any): void;
}
export interface WebviewPanelViewStateData {
@@ -594,13 +593,13 @@ export interface ExtHostWebviewsShape {
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void>;
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$resolveWebviewEditor(input: { resource: UriComponents, edits: readonly any[] }, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$undoEdits(handle: WebviewPanelHandle, edits: readonly any[]): void;
$applyEdits(handle: WebviewPanelHandle, edits: readonly any[]): void;
$undoEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void;
$applyEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void;
$onSave(handle: WebviewPanelHandle): Promise<void>;
$onSaveAs(handle: WebviewPanelHandle, resource: UriComponents, targetResource: UriComponents): Promise<void>;
$onSave(resource: UriComponents, viewType: string): Promise<void>;
$onSaveAs(resource: UriComponents, viewType: string, targetResource: UriComponents): Promise<void>;
}
export interface MainThreadUrlsShape extends IDisposable {
@@ -777,6 +776,7 @@ export interface MainThreadTunnelServiceShape extends IDisposable {
$openTunnel(tunnelOptions: TunnelOptions): Promise<TunnelDto | undefined>;
$closeTunnel(remotePort: number): Promise<void>;
$registerCandidateFinder(): Promise<void>;
$setTunnelProvider(): Promise<void>;
}
// -- extension host
@@ -1396,6 +1396,8 @@ export interface ExtHostStorageShape {
export interface ExtHostTunnelServiceShape {
$findCandidatePorts(): Promise<{ port: number, detail: string }[]>;
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined;
$closeTunnel(remote: { host: string, port: number }): Promise<void>;
}
// --- proxy identifiers

View File

@@ -32,6 +32,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService';
interface ITestRunner {
/** Old test runner API, as exported from `vscode/lib/testrunner` */
@@ -76,6 +77,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
protected readonly _extHostWorkspace: ExtHostWorkspace;
protected readonly _extHostConfiguration: ExtHostConfiguration;
protected readonly _logService: ILogService;
protected readonly _extHostTunnelService: IExtHostTunnelService;
protected readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape;
protected readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape;
@@ -104,7 +106,8 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
@IExtHostConfiguration extHostConfiguration: IExtHostConfiguration,
@ILogService logService: ILogService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@IExtensionStoragePaths storagePath: IExtensionStoragePaths
@IExtensionStoragePaths storagePath: IExtensionStoragePaths,
@IExtHostTunnelService extHostTunnelService: IExtHostTunnelService
) {
this._hostUtils = hostUtils;
this._extHostContext = extHostContext;
@@ -113,6 +116,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
this._extHostWorkspace = extHostWorkspace;
this._extHostConfiguration = extHostConfiguration;
this._logService = logService;
this._extHostTunnelService = extHostTunnelService;
this._disposables = new DisposableStore();
this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace);
@@ -641,6 +645,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
try {
const result = await resolver.resolve(remoteAuthority, { resolveAttempt });
this._disposables.add(await this._extHostTunnelService.setForwardPortProvider(resolver));
// Split merged API result into separate authority/options
const authority: ResolvedAuthority = {

View File

@@ -6,6 +6,8 @@
import { ExtHostTunnelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import * as vscode from 'vscode';
import { RemoteTunnel } from 'vs/platform/remote/common/tunnel';
import { IDisposable } from 'vs/base/common/lifecycle';
export interface TunnelOptions {
remote: { port: number, host: string };
@@ -19,9 +21,24 @@ export interface TunnelDto {
localAddress: string;
}
export namespace TunnelDto {
export function fromApiTunnel(tunnel: vscode.Tunnel): TunnelDto {
return { remote: tunnel.remote, localAddress: tunnel.localAddress };
}
export function fromServiceTunnel(tunnel: RemoteTunnel): TunnelDto {
return { remote: { host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort }, localAddress: tunnel.localAddress };
}
}
export interface Tunnel extends vscode.Disposable {
remote: { port: number, host: string };
localAddress: string;
}
export interface IExtHostTunnelService extends ExtHostTunnelServiceShape {
readonly _serviceBrand: undefined;
makeTunnel(forward: TunnelOptions): Promise<vscode.Tunnel | undefined>;
setForwardPortProvider(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable>;
}
export const IExtHostTunnelService = createDecorator<IExtHostTunnelService>('IExtHostTunnelService');
@@ -34,4 +51,8 @@ export class ExtHostTunnelService implements IExtHostTunnelService {
async $findCandidatePorts(): Promise<{ port: number; detail: string; }[]> {
return [];
}
async setForwardPortProvider(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> { return { dispose: () => { } }; }
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined { return undefined; }
async $closeTunnel(remote: { host: string, port: number }): Promise<void> { }
}

View File

@@ -14,7 +14,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import * as vscode from 'vscode';
import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files';
import { RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { markdownUnescapeCodicons, escapeCodicons } from 'vs/base/common/codicons';
import { escapeCodicons } from 'vs/base/common/codicons';
function es5ClassCompat(target: Function): any {
///@ts-ignore
@@ -1234,17 +1234,16 @@ export class MarkdownString {
isTrusted?: boolean;
readonly supportThemeIcons?: boolean;
constructor(value?: string, { supportThemeIcons }: { supportThemeIcons?: boolean } = {}) {
constructor(value?: string, supportThemeIcons: boolean = false) {
this.value = value ?? '';
this.supportThemeIcons = supportThemeIcons ?? false;
this.supportThemeIcons = supportThemeIcons;
}
appendText(value: string): MarkdownString {
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
value = value
this.value += (this.supportThemeIcons ? escapeCodicons(value) : value)
.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
.replace('\n', '\n\n');
this.value += this.supportThemeIcons ? markdownUnescapeCodicons(value) : value;
return this;
}
@@ -1263,10 +1262,6 @@ export class MarkdownString {
this.value += '\n```\n';
return this;
}
static escapeThemeIcons(value: string): string {
return escapeCodicons(value);
}
}
@es5ClassCompat

View File

@@ -5,7 +5,6 @@
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { assertIsDefined } from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import * as modes from 'vs/editor/common/modes';
@@ -16,7 +15,7 @@ import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import * as vscode from 'vscode';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewStateData, WebviewEditorCapabilities } from './extHost.protocol';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewEditorCapabilities, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol';
import { Disposable as VSCodeDisposable } from './extHostTypes';
type IconPath = URI | { light: URI, dark: URI };
@@ -117,8 +116,6 @@ export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPa
readonly _onDidChangeViewStateEmitter = this._register(new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>());
public readonly onDidChangeViewState: Event<vscode.WebviewPanelOnDidChangeViewStateEvent> = this._onDidChangeViewStateEmitter.event;
public _capabilities?: vscode.WebviewEditorCapabilities;
constructor(
handle: WebviewPanelHandle,
proxy: MainThreadWebviewsShape,
@@ -239,31 +236,6 @@ export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPa
});
}
_setCapabilities(capabilities: vscode.WebviewEditorCapabilities) {
this._capabilities = capabilities;
if (capabilities.editingCapability) {
this._register(capabilities.editingCapability.onEdit(edit => {
this._proxy.$onEdit(this._handle, edit);
}));
}
}
_undoEdits(edits: readonly any[]): void {
assertIsDefined(this._capabilities).editingCapability?.undoEdits(edits);
}
_redoEdits(edits: readonly any[]): void {
assertIsDefined(this._capabilities).editingCapability?.applyEdits(edits);
}
async _onSave(): Promise<void> {
await assertIsDefined(this._capabilities?.editingCapability)?.save();
}
async _onSaveAs(resource: vscode.Uri, targetResource: vscode.Uri): Promise<void> {
await assertIsDefined(this._capabilities?.editingCapability)?.saveAs(resource, targetResource);
}
private assertNotDisposed() {
if (this._isDisposed) {
throw new Error('Webview is disposed');
@@ -280,7 +252,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
private readonly _proxy: MainThreadWebviewsShape;
private readonly _webviewPanels = new Map<WebviewPanelHandle, ExtHostWebviewEditor>();
private readonly _serializers = new Map<string, { readonly serializer: vscode.WebviewPanelSerializer, readonly extension: IExtensionDescription }>();
private readonly _editorProviders = new Map<string, { readonly provider: vscode.WebviewEditorProvider, readonly extension: IExtensionDescription }>();
private readonly _editorProviders = new Map<string, { readonly provider: vscode.WebviewCustomEditorProvider, readonly extension: IExtensionDescription }>();
constructor(
mainContext: IMainContext,
@@ -331,10 +303,10 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
});
}
public registerWebviewEditorProvider(
public registerWebviewCustomEditorProvider(
extension: IExtensionDescription,
viewType: string,
provider: vscode.WebviewEditorProvider,
provider: vscode.WebviewCustomEditorProvider,
options?: vscode.WebviewPanelOptions,
): vscode.Disposable {
if (this._editorProviders.has(viewType)) {
@@ -342,7 +314,10 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
}
this._editorProviders.set(viewType, { extension, provider, });
this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {});
this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {}, this.getCapabilites(provider));
provider?.editingDelegate?.onEdit(({ edit, resource }) => {
this._proxy.$onEdit(resource, viewType, edit);
});
return new VSCodeDisposable(() => {
this._editorProviders.delete(viewType);
@@ -431,7 +406,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
}
async $resolveWebviewEditor(
input: { resource: UriComponents, edits: readonly any[] },
resource: UriComponents,
handle: WebviewPanelHandle,
viewType: string,
title: string,
@@ -447,46 +422,44 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
const revivedPanel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
this._webviewPanels.set(handle, revivedPanel);
const capabilities = await provider.resolveWebviewEditor({ resource: URI.revive(input.resource) }, revivedPanel);
revivedPanel._setCapabilities(capabilities);
this.registerCapabilites(handle, capabilities);
// TODO: the first set of edits should likely be passed when resolving
if (input.edits.length) {
revivedPanel._redoEdits(input.edits);
}
const revivedResource = URI.revive(resource);
await provider.resolveWebviewEditor(revivedResource, revivedPanel);
}
$undoEdits(handle: WebviewPanelHandle, edits: readonly any[]): void {
const panel = this.getWebviewPanel(handle);
panel?._undoEdits(edits);
$undoEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void {
const provider = this.getEditorProvider(viewType);
provider?.editingDelegate?.undoEdits(URI.revive(resource), edits);
}
$applyEdits(handle: WebviewPanelHandle, edits: readonly any[]): void {
const panel = this.getWebviewPanel(handle);
panel?._redoEdits(edits);
$applyEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void {
const provider = this.getEditorProvider(viewType);
provider?.editingDelegate?.applyEdits(URI.revive(resource), edits);
}
async $onSave(handle: WebviewPanelHandle): Promise<void> {
const panel = this.getWebviewPanel(handle);
return panel?._onSave();
async $onSave(resource: UriComponents, viewType: string): Promise<void> {
const provider = this.getEditorProvider(viewType);
return provider?.editingDelegate?.save(URI.revive(resource));
}
async $onSaveAs(handle: WebviewPanelHandle, resource: UriComponents, targetResource: UriComponents): Promise<void> {
const panel = this.getWebviewPanel(handle);
return panel?._onSaveAs(URI.revive(resource), URI.revive(targetResource));
async $onSaveAs(resource: UriComponents, viewType: string, targetResource: UriComponents): Promise<void> {
const provider = this.getEditorProvider(viewType);
return provider?.editingDelegate?.saveAs(URI.revive(resource), URI.revive(targetResource));
}
private getWebviewPanel(handle: WebviewPanelHandle): ExtHostWebviewEditor | undefined {
return this._webviewPanels.get(handle);
}
private registerCapabilites(handle: WebviewPanelHandle, capabilities: vscode.WebviewEditorCapabilities) {
private getEditorProvider(viewType: string): vscode.WebviewCustomEditorProvider | undefined {
return this._editorProviders.get(viewType)?.provider;
}
private getCapabilites(capabilities: vscode.WebviewCustomEditorProvider) {
const declaredCapabilites: WebviewEditorCapabilities[] = [];
if (capabilities.editingCapability) {
if (capabilities.editingDelegate) {
declaredCapabilites.push(WebviewEditorCapabilities.Editable);
}
this._proxy.$registerCapabilities(handle, declaredCapabilites);
return declaredCapabilites;
}
}