Revert "Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)" (#5983)

This reverts commit d15a3fcc98.
This commit is contained in:
Karl Burtram
2019-06-11 12:35:58 -07:00
committed by GitHub
parent 95a50b7892
commit 5a7562a37b
926 changed files with 11394 additions and 19540 deletions

View File

@@ -42,6 +42,7 @@ import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { ResolvedAuthority, RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as codeInset from 'vs/workbench/contrib/codeinset/common/codeInset';
import * as callHierarchy from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
import { IRelativePattern } from 'vs/base/common/glob';
import { IRemoteConsoleLog } from 'vs/base/common/console';
@@ -139,7 +140,7 @@ export interface MainThreadCommentsShape extends IDisposable {
$registerCommentController(handle: number, id: string, label: string): void;
$unregisterCommentController(handle: number): void;
$updateCommentControllerFeatures(handle: number, features: CommentProviderFeatures): void;
$createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, extensionId: ExtensionIdentifier): modes.CommentThread2 | undefined;
$createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange): modes.CommentThread2 | undefined;
$updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string, contextValue: string | undefined, comments: modes.Comment[], acceptInputCommand: modes.Command | undefined, additionalCommands: modes.Command[], deleteCommand: modes.Command | undefined, collapseState: modes.CommentThreadCollapsibleState): void;
$deleteCommentThread(handle: number, commentThreadHandle: number): void;
$setInputValue(handle: number, input: string): void;
@@ -335,6 +336,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$unregister(handle: number): void;
$registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void;
$registerCodeInsetSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void;
$emitCodeLensEvent(eventHandle: number, event?: any): void;
$registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
@@ -391,7 +393,7 @@ export interface MainThreadProgressShape extends IDisposable {
}
export interface MainThreadTerminalServiceShape extends IDisposable {
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean, runInBackground?: boolean): Promise<{ id: number, name: string }>;
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }>;
$createTerminalRenderer(name: string): Promise<number>;
$dispose(terminalId: number): void;
$hide(terminalId: number): void;
@@ -498,7 +500,7 @@ export interface MainThreadQuickOpenShape extends IDisposable {
}
export interface MainThreadStatusBarShape extends IDisposable {
$setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void;
$setEntry(id: number, extensionId: ExtensionIdentifier | undefined, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void;
$dispose(id: number): void;
}
@@ -511,22 +513,10 @@ export interface MainThreadTelemetryShape extends IDisposable {
$publicLog(eventName: string, data?: any): void;
}
export interface MainThreadEditorInsetsShape extends IDisposable {
$createEditorInset(handle: number, editorId: string, document: UriComponents, range: IRange, options: modes.IWebviewOptions): Promise<void>;
$disposeEditorInset(handle: number): void;
$setHtml(handle: number, value: string): void;
$setOptions(handle: number, options: modes.IWebviewOptions): void;
$postMessage(handle: number, value: any): Promise<boolean>;
}
export interface ExtHostEditorInsetsShape {
$onDidDispose(handle: number): void;
$onDidReceiveMessage(handle: number, message: any): void;
}
export type WebviewPanelHandle = string;
export type WebviewInsetHandle = number;
export interface WebviewPanelShowOptions {
readonly viewColumn?: EditorViewColumn;
readonly preserveFocus?: boolean;
@@ -534,14 +524,15 @@ export interface WebviewPanelShowOptions {
export interface MainThreadWebviewsShape extends IDisposable {
$createWebviewPanel(handle: WebviewPanelHandle, viewType: string, title: string, showOptions: WebviewPanelShowOptions, options: modes.IWebviewPanelOptions & modes.IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): void;
$createWebviewCodeInset(handle: WebviewInsetHandle, symbolId: string, options: modes.IWebviewOptions, extensionId: ExtensionIdentifier | undefined, extensionLocation: UriComponents | undefined): void;
$disposeWebview(handle: WebviewPanelHandle): void;
$reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void;
$setTitle(handle: WebviewPanelHandle, value: string): void;
$setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents } | undefined): void;
$setHtml(handle: WebviewPanelHandle, value: string): void;
$setOptions(handle: WebviewPanelHandle, options: modes.IWebviewOptions): void;
$postMessage(handle: WebviewPanelHandle, value: any): Promise<boolean>;
$setHtml(handle: WebviewPanelHandle | WebviewInsetHandle, value: string): void;
$setOptions(handle: WebviewPanelHandle | WebviewInsetHandle, options: modes.IWebviewOptions): void;
$postMessage(handle: WebviewPanelHandle | WebviewInsetHandle, value: any): Promise<boolean>;
$registerSerializer(viewType: string): void;
$unregisterSerializer(viewType: string): void;
@@ -997,11 +988,6 @@ export interface CodeActionDto {
isPreferred?: boolean;
}
export interface CodeActionListDto {
cacheId: number;
actions: ReadonlyArray<CodeActionDto>;
}
export type CacheId = number;
export type ChainedCacheId = [CacheId, CacheId];
@@ -1014,20 +1000,16 @@ export interface LinkDto {
cacheId?: ChainedCacheId;
range: IRange;
url?: string | UriComponents;
tooltip?: string;
}
export interface CodeLensListDto {
cacheId?: number;
lenses: CodeLensDto[];
}
export interface CodeLensDto {
cacheId?: ChainedCacheId;
export interface CodeLensDto extends ObjectIdentifier {
range: IRange;
id?: string;
command?: CommandDto;
}
export type CodeInsetDto = ObjectIdentifier & codeInset.ICodeInsetSymbol;
export interface CallHierarchyDto {
_id: number;
kind: modes.SymbolKind;
@@ -1040,9 +1022,10 @@ export interface CallHierarchyDto {
export interface ExtHostLanguageFeaturesShape {
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensListDto | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensDto[]>;
$resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined>;
$releaseCodeLenses(handle: number, id: number): void;
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeInsetDto[] | undefined>;
$resolveCodeInset(handle: number, resource: UriComponents, symbol: CodeInsetDto, token: CancellationToken): Promise<CodeInsetDto>;
$provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
@@ -1050,8 +1033,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined>;
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined>;
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<LocationDto[] | undefined>;
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionListDto | undefined>;
$releaseCodeActions(handle: number, cacheId: number): void;
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[] | undefined>;
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
@@ -1230,7 +1212,6 @@ export interface ExtHostCommentsShape {
$provideDocumentComments(handle: number, document: UriComponents): Promise<modes.CommentInfo | null>;
$createNewCommentThread(handle: number, document: UriComponents, range: IRange, text: string): Promise<modes.CommentThread | null>;
$createCommentThreadTemplate(commentControllerHandle: number, uriComponents: UriComponents, range: IRange): void;
$updateCommentThreadTemplate(commentControllerHandle: number, threadHandle: number, range: IRange): Promise<void>;
$onCommentWidgetInputChange(commentControllerHandle: number, document: UriComponents, range: IRange, input: string | undefined): Promise<number | undefined>;
$deleteCommentThread(commentControllerHandle: number, commentThreadHandle: number): void;
$provideCommentingRanges(commentControllerHandle: number, uriComponents: UriComponents, token: CancellationToken): Promise<IRange[] | undefined>;
@@ -1268,7 +1249,6 @@ export const MainContext = {
MainThreadDocuments: createMainId<MainThreadDocumentsShape>('MainThreadDocuments'),
MainThreadDocumentContentProviders: createMainId<MainThreadDocumentContentProvidersShape>('MainThreadDocumentContentProviders'),
MainThreadTextEditors: createMainId<MainThreadTextEditorsShape>('MainThreadTextEditors'),
MainThreadEditorInsets: createMainId<MainThreadEditorInsetsShape>('MainThreadEditorInsets'),
MainThreadErrors: createMainId<MainThreadErrorsShape>('MainThreadErrors'),
MainThreadTreeViews: createMainId<MainThreadTreeViewsShape>('MainThreadTreeViews'),
MainThreadKeytar: createMainId<MainThreadKeytarShape>('MainThreadKeytar'),
@@ -1319,7 +1299,6 @@ export const ExtHostContext = {
ExtHostWorkspace: createExtId<ExtHostWorkspaceShape>('ExtHostWorkspace'),
ExtHostWindow: createExtId<ExtHostWindowShape>('ExtHostWindow'),
ExtHostWebviews: createExtId<ExtHostWebviewsShape>('ExtHostWebviews'),
ExtHostEditorInsets: createExtId<ExtHostEditorInsetsShape>('ExtHostEditorInsets'),
ExtHostProgress: createMainId<ExtHostProgressShape>('ExtHostProgress'),
ExtHostComments: createMainId<ExtHostCommentsShape>('ExtHostComments'),
ExtHostStorage: createMainId<ExtHostStorageShape>('ExtHostStorage'),

View File

@@ -504,7 +504,7 @@ export class ExtHostApiCommands {
private _executeCodeLensProvider(resource: URI, itemResolveCount: number): Promise<vscode.CodeLens[] | undefined> {
const args = { resource, itemResolveCount };
return this._commands.executeCommand<modes.CodeLens[]>('_executeCodeLensProvider', args)
return this._commands.executeCommand<modes.ICodeLensSymbol[]>('_executeCodeLensProvider', args)
.then(tryMapWith(item => {
return new types.CodeLens(
typeConverters.Range.to(item.range),

View File

@@ -1,130 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Emitter } from 'vs/base/common/event';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import * as vscode from 'vscode';
import { MainThreadEditorInsetsShape } from './extHost.protocol';
import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor';
export class ExtHostEditorInsets implements ExtHostEditorInsets {
private _handlePool = 0;
private _disposables = new DisposableStore();
private _insets = new Map<number, { editor: vscode.TextEditor, inset: vscode.WebviewEditorInset, onDidReceiveMessage: Emitter<any> }>();
constructor(
private readonly _proxy: MainThreadEditorInsetsShape,
private readonly _editors: ExtHostEditors
) {
// dispose editor inset whenever the hosting editor goes away
this._disposables.add(_editors.onDidChangeVisibleTextEditors(() => {
const visibleEditor = _editors.getVisibleTextEditors();
this._insets.forEach(value => {
if (visibleEditor.indexOf(value.editor) < 0) {
value.inset.dispose(); // will remove from `this._insets`
}
});
}));
}
dispose(): void {
this._insets.forEach(value => value.inset.dispose());
this._disposables.dispose();
}
createWebviewEditorInset(editor: vscode.TextEditor, range: vscode.Range, options?: vscode.WebviewOptions): vscode.WebviewEditorInset {
let apiEditor: ExtHostTextEditor | undefined;
for (const candidate of this._editors.getVisibleTextEditors()) {
if (candidate === editor) {
apiEditor = <ExtHostTextEditor>candidate;
break;
}
}
if (!apiEditor) {
throw new Error('not a visible editor');
}
const that = this;
const handle = this._handlePool++;
const onDidReceiveMessage = new Emitter<any>();
const onDidDispose = new Emitter<void>();
const webview = new class implements vscode.Webview {
private _html: string = '';
private _options: vscode.WebviewOptions;
set options(value: vscode.WebviewOptions) {
this._options = value;
that._proxy.$setOptions(handle, value);
}
get options(): vscode.WebviewOptions {
return this._options;
}
set html(value: string) {
this._html = value;
that._proxy.$setHtml(handle, value);
}
get html(): string {
return this._html;
}
get onDidReceiveMessage(): vscode.Event<any> {
return onDidReceiveMessage.event;
}
postMessage(message: any): Thenable<boolean> {
return that._proxy.$postMessage(handle, message);
}
};
const inset = new class implements vscode.WebviewEditorInset {
readonly editor: vscode.TextEditor = editor;
readonly range: vscode.Range = range;
readonly webview: vscode.Webview = webview;
readonly onDidDispose: vscode.Event<void> = onDidDispose.event;
dispose(): void {
if (that._insets.has(handle)) {
that._insets.delete(handle);
that._proxy.$disposeEditorInset(handle);
onDidDispose.fire();
// final cleanup
onDidDispose.dispose();
onDidReceiveMessage.dispose();
}
}
};
this._proxy.$createEditorInset(handle, apiEditor.id, apiEditor.document.uri, typeConverters.Range.from(range), options || {});
this._insets.set(handle, { editor, inset, onDidReceiveMessage });
return inset;
}
$onDidDispose(handle: number): void {
const value = this._insets.get(handle);
if (value) {
value.inset.dispose();
}
}
$onDidReceiveMessage(handle: number, message: any): void {
const value = this._insets.get(handle);
if (value) {
value.onDidReceiveMessage.fire(message);
}
}
}

View File

@@ -18,7 +18,6 @@ import { revive } from 'vs/base/common/marshalling';
import { Range } from 'vs/editor/common/core/range';
import { Position } from 'vs/editor/common/core/position';
import { URI } from 'vs/base/common/uri';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
interface CommandHandler {
callback: Function;
@@ -212,35 +211,6 @@ export class CommandsConverter {
this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this);
}
toInternal2(command: vscode.Command | undefined, disposables: DisposableStore): CommandDto | undefined {
if (!command) {
return undefined;
}
const result: CommandDto = {
$ident: undefined,
id: command.command,
title: command.title,
tooltip: command.tooltip
};
if (command.command && isNonEmptyArray(command.arguments)) {
// we have a contributed command with arguments. that
// means we don't want to send the arguments around
const id = this._heap.keep(command);
disposables.add(toDisposable(() => this._heap.delete(id)));
result.$ident = id;
result.id = this._delegatingCommandId;
result.arguments = [id];
}
return result;
}
toInternal(command: vscode.Command): CommandDto;
toInternal(command: undefined): undefined;
toInternal(command: vscode.Command | undefined): CommandDto | undefined;

View File

@@ -162,16 +162,6 @@ export class ExtHostComments implements ExtHostCommentsShape {
commentController.$createCommentThreadTemplate(uriComponents, range);
}
async $updateCommentThreadTemplate(commentControllerHandle: number, threadHandle: number, range: IRange) {
const commentController = this._commentControllers.get(commentControllerHandle);
if (!commentController) {
return;
}
commentController.$updateCommentThreadTemplate(threadHandle, range);
}
$onCommentWidgetInputChange(commentControllerHandle: number, uriComponents: UriComponents, range: IRange, input: string): Promise<number | undefined> {
const commentController = this._commentControllers.get(commentControllerHandle);
@@ -592,8 +582,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
private _id: string | undefined,
private _uri: vscode.Uri,
private _range: vscode.Range,
private _comments: vscode.Comment[],
extensionId: ExtensionIdentifier
private _comments: vscode.Comment[]
) {
if (this._id === undefined) {
this._id = `${_commentController.id}.${this.handle}`;
@@ -604,8 +593,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
this.handle,
this._id,
this._uri,
extHostTypeConverter.Range.from(this._range),
extensionId
extHostTypeConverter.Range.from(this._range)
);
this._localDisposables = [];
@@ -753,7 +741,7 @@ class ExtHostCommentController implements vscode.CommentController {
}
constructor(
private _extension: IExtensionDescription,
_extension: IExtensionDescription,
private _handle: number,
private readonly _commandsConverter: CommandsConverter,
private _proxy: MainThreadCommentsShape,
@@ -767,30 +755,23 @@ class ExtHostCommentController implements vscode.CommentController {
createCommentThread(id: string, resource: vscode.Uri, range: vscode.Range, comments: vscode.Comment[]): vscode.CommentThread;
createCommentThread(arg0: vscode.Uri | string, arg1: vscode.Uri | vscode.Range, arg2: vscode.Range | vscode.Comment[], arg3?: vscode.Comment[]): vscode.CommentThread {
if (typeof arg0 === 'string') {
const commentThread = new ExtHostCommentThread(this._proxy, this._commandsConverter, this, arg0, arg1 as vscode.Uri, arg2 as vscode.Range, arg3 as vscode.Comment[], this._extension.identifier);
const commentThread = new ExtHostCommentThread(this._proxy, this._commandsConverter, this, arg0, arg1 as vscode.Uri, arg2 as vscode.Range, arg3 as vscode.Comment[]);
this._threads.set(commentThread.handle, commentThread);
return commentThread;
} else {
const commentThread = new ExtHostCommentThread(this._proxy, this._commandsConverter, this, undefined, arg0 as vscode.Uri, arg1 as vscode.Range, arg2 as vscode.Comment[], this._extension.identifier);
const commentThread = new ExtHostCommentThread(this._proxy, this._commandsConverter, this, undefined, arg0 as vscode.Uri, arg1 as vscode.Range, arg2 as vscode.Comment[]);
this._threads.set(commentThread.handle, commentThread);
return commentThread;
}
}
$createCommentThreadTemplate(uriComponents: UriComponents, range: IRange) {
const commentThread = new ExtHostCommentThread(this._proxy, this._commandsConverter, this, undefined, URI.revive(uriComponents), extHostTypeConverter.Range.to(range), [], this._extension.identifier);
const commentThread = new ExtHostCommentThread(this._proxy, this._commandsConverter, this, undefined, URI.revive(uriComponents), extHostTypeConverter.Range.to(range), []);
commentThread.collapsibleState = modes.CommentThreadCollapsibleState.Expanded;
this._threads.set(commentThread.handle, commentThread);
return commentThread;
}
$updateCommentThreadTemplate(threadHandle: number, range: IRange) {
let thread = this._threads.get(threadHandle);
if (thread) {
thread.range = extHostTypeConverter.Range.to(range);
}
}
$deleteCommentThread(threadHandle: number) {
let thread = this._threads.get(threadHandle);

View File

@@ -15,7 +15,7 @@ import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics';
import { asPromise } from 'vs/base/common/async';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CodeLensDto, SuggestDataDto, LinksListDto, ChainedCacheId, CodeLensListDto, CodeActionListDto } from './extHost.protocol';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CodeLensDto, MainThreadWebviewsShape, CodeInsetDto, SuggestDataDto, LinksListDto, ChainedCacheId } from './extHost.protocol';
import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings';
import { IPosition } from 'vs/editor/common/core/position';
import { IRange, Range as EditorRange } from 'vs/editor/common/core/range';
@@ -25,10 +25,11 @@ import { ISelection, Selection } from 'vs/editor/common/core/selection';
import { ILogService } from 'vs/platform/log/common/log';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostWebview } from 'vs/workbench/api/common/extHostWebview';
import * as codeInset from 'vs/workbench/contrib/codeinset/common/codeInset';
import { generateUuid } from 'vs/base/common/uuid';
import * as callHierarchy from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
import { LRUCache } from 'vs/base/common/map';
import { IURITransformer } from 'vs/base/common/uriIpc';
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
// --- adapter
@@ -103,48 +104,34 @@ class CodeLensAdapter {
private static _badCmd: vscode.Command = { command: 'missing', title: '!!MISSING: command!!' };
private readonly _cache = new Cache<vscode.CodeLens>();
private readonly _disposables = new Map<number, DisposableStore>();
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _commands: CommandsConverter,
private readonly _heapService: ExtHostHeapService,
private readonly _provider: vscode.CodeLensProvider
) { }
provideCodeLenses(resource: URI, token: CancellationToken): Promise<CodeLensListDto | undefined> {
provideCodeLenses(resource: URI, token: CancellationToken): Promise<CodeLensDto[]> {
const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideCodeLenses(doc, token)).then(lenses => {
if (!lenses || token.isCancellationRequested) {
return undefined;
const result: CodeLensDto[] = [];
if (isNonEmptyArray(lenses)) {
for (const lens of lenses) {
const id = this._heapService.keep(lens);
result.push(ObjectIdentifier.mixin({
range: typeConvert.Range.from(lens.range),
command: this._commands.toInternal(lens.command)
}, id));
}
}
const cacheId = this._cache.add(lenses);
const disposables = new DisposableStore();
this._disposables.set(cacheId, disposables);
const result: CodeLensListDto = {
cacheId,
lenses: [],
};
for (let i = 0; i < lenses.length; i++) {
result.lenses.push({
cacheId: [cacheId, i],
range: typeConvert.Range.from(lenses[i].range),
command: this._commands.toInternal2(lenses[i].command, disposables)
});
}
return result;
});
}
resolveCodeLens(symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
const lens = symbol.cacheId && this._cache.get(...symbol.cacheId);
const lens = this._heapService.get<vscode.CodeLens>(ObjectIdentifier.of(symbol));
if (!lens) {
return Promise.resolve(undefined);
}
@@ -157,26 +144,51 @@ class CodeLensAdapter {
}
return resolve.then(newLens => {
if (token.isCancellationRequested) {
return undefined;
}
const disposables = symbol.cacheId && this._disposables.get(symbol.cacheId[0]);
if (!disposables) {
// We've already been disposed of
return undefined;
}
newLens = newLens || lens;
symbol.command = this._commands.toInternal2(newLens.command || CodeLensAdapter._badCmd, disposables);
symbol.command = this._commands.toInternal(newLens.command || CodeLensAdapter._badCmd);
return symbol;
});
}
}
releaseCodeLenses(cachedId: number): void {
dispose(this._disposables.get(cachedId));
this._disposables.delete(cachedId);
this._cache.delete(cachedId);
class CodeInsetAdapter {
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _heapService: ExtHostHeapService,
private readonly _provider: vscode.CodeInsetProvider
) { }
provideCodeInsets(resource: URI, token: CancellationToken): Promise<CodeInsetDto[] | undefined> {
const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideCodeInsets(doc, token)).then(insets => {
if (Array.isArray(insets)) {
return insets.map(inset => {
const $ident = this._heapService.keep(inset);
const id = generateUuid();
return {
$ident,
id,
range: typeConvert.Range.from(inset.range),
height: inset.height
};
});
}
return undefined;
});
}
resolveCodeInset(symbol: CodeInsetDto, webview: vscode.Webview, token: CancellationToken): Promise<CodeInsetDto> {
const inset = this._heapService.get<vscode.CodeInset>(ObjectIdentifier.of(symbol));
if (!inset) {
return Promise.resolve(symbol);
}
return asPromise(() => this._provider.resolveCodeInset(inset, webview, token)).then(newInset => {
newInset = newInset || inset;
return symbol;
});
}
}
@@ -316,9 +328,6 @@ export interface CustomCodeAction extends CodeActionDto {
class CodeActionAdapter {
private static readonly _maxCodeActionsPerFile: number = 1000;
private readonly _cache = new Cache<vscode.CodeAction | vscode.Command>();
private readonly _disposables = new Map<number, DisposableStore>();
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _commands: CommandsConverter,
@@ -328,7 +337,7 @@ class CodeActionAdapter {
private readonly _extensionId: ExtensionIdentifier
) { }
provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionListDto | undefined> {
provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[] | undefined> {
const doc = this._documents.getDocument(resource);
const ran = Selection.isISelection(rangeOrSelection)
@@ -351,39 +360,34 @@ class CodeActionAdapter {
};
return asPromise(() => this._provider.provideCodeActions(doc, ran, codeActionContext, token)).then(commandsOrActions => {
if (!isNonEmptyArray(commandsOrActions) || token.isCancellationRequested) {
if (!isNonEmptyArray(commandsOrActions)) {
return undefined;
}
const cacheId = this._cache.add(commandsOrActions);
const disposables = new DisposableStore();
this._disposables.set(cacheId, disposables);
const actions: CustomCodeAction[] = [];
const result: CustomCodeAction[] = [];
for (const candidate of commandsOrActions) {
if (!candidate) {
continue;
}
if (CodeActionAdapter._isCommand(candidate)) {
// old school: synthetic code action
actions.push({
result.push({
_isSynthetic: true,
title: candidate.title,
command: this._commands.toInternal2(candidate, disposables),
command: this._commands.toInternal(candidate),
});
} else {
if (codeActionContext.only) {
if (!candidate.kind) {
this._logService.warn(`${this._extensionId.value} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action does not have a 'kind'. Code action will be dropped. Please set 'CodeAction.kind'.`);
} else if (!codeActionContext.only.contains(candidate.kind)) {
this._logService.warn(`${this._extensionId.value} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action is of kind '${candidate.kind.value}'. Code action will be dropped. Please check 'CodeActionContext.only' to only return requested code actions.`);
this._logService.warn(`${this._extensionId.value} -Code actions of kind '${codeActionContext.only.value} 'requested but returned code action is of kind '${candidate.kind.value}'. Code action will be dropped. Please check 'CodeActionContext.only' to only return requested code actions.`);
}
}
// new school: convert code action
actions.push({
result.push({
title: candidate.title,
command: candidate.command && this._commands.toInternal2(candidate.command, disposables),
command: candidate.command && this._commands.toInternal(candidate.command),
diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from),
edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit),
kind: candidate.kind && candidate.kind.value,
@@ -392,16 +396,10 @@ class CodeActionAdapter {
}
}
return <CodeActionListDto>{ cacheId, actions };
return result;
});
}
public releaseCodeActions(cachedId: number): void {
dispose(this._disposables.get(cachedId));
this._disposables.delete(cachedId);
this._cache.delete(cachedId);
}
private static _isCommand(thing: any): thing is vscode.Command {
return typeof (<vscode.Command>thing).command === 'string' && typeof (<vscode.Command>thing).title === 'string';
}
@@ -626,7 +624,6 @@ class SuggestAdapter {
private _provider: vscode.CompletionItemProvider;
private _cache = new Cache<vscode.CompletionItem>();
private _disposables = new Map<number, DisposableStore>();
constructor(documents: ExtHostDocuments, commands: CommandsConverter, provider: vscode.CompletionItemProvider) {
this._documents = documents;
@@ -646,18 +643,13 @@ class SuggestAdapter {
return undefined;
}
if (token.isCancellationRequested) {
// cancelled -> return without further ado, esp no caching
// of results as they will leak
return undefined;
}
const list = Array.isArray(value) ? new CompletionList(value) : value;
let list = Array.isArray(value) ? new CompletionList(value) : value;
let pid: number | undefined;
// keep result for providers that support resolving
const pid: number = SuggestAdapter.supportsResolving(this._provider) ? this._cache.add(list.items) : this._cache.add([]);
const disposables = new DisposableStore();
this._disposables.set(pid, disposables);
if (SuggestAdapter.supportsResolving(this._provider)) {
pid = this._cache.add(list.items);
}
// the default text edit range
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos))
@@ -671,7 +663,7 @@ class SuggestAdapter {
};
for (let i = 0; i < list.items.length; i++) {
const suggestion = this._convertCompletionItem(list.items[i], pos, [pid, i]);
const suggestion = this._convertCompletionItem(list.items[i], pos, pid && [pid, i] || undefined);
// check for bad completion item
// for the converter did warn
if (suggestion) {
@@ -706,22 +698,15 @@ class SuggestAdapter {
}
releaseCompletionItems(id: number): any {
dispose(this._disposables.get(id));
this._disposables.delete(id);
this._cache.delete(id);
}
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: ChainedCacheId): SuggestDataDto | undefined {
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: ChainedCacheId | undefined): SuggestDataDto | undefined {
if (typeof item.label !== 'string' || item.label.length === 0) {
console.warn('INVALID text edit -> must have at least a label');
return undefined;
}
const disposables = this._disposables.get(id[0]);
if (!disposables) {
throw Error('DisposableStore is missing...');
}
const result: SuggestDataDto = {
//
x: id,
@@ -736,7 +721,7 @@ class SuggestAdapter {
i: item.keepWhitespace ? modes.CompletionItemInsertTextRule.KeepWhitespace : 0,
k: item.commitCharacters,
l: item.additionalTextEdits && item.additionalTextEdits.map(typeConvert.TextEdit.from),
m: this._commands.toInternal2(item.command, disposables),
m: this._commands.toInternal(item.command),
};
// 'insertText'-logic
@@ -846,12 +831,6 @@ class LinkProviderAdapter {
return undefined;
}
if (token.isCancellationRequested) {
// cancelled -> return without further ado, esp no caching
// of results as they will leak
return undefined;
}
if (typeof this._provider.resolveDocumentLink !== 'function') {
// no resolve -> no caching
return { links: links.map(typeConvert.DocumentLink.from) };
@@ -1048,7 +1027,7 @@ type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | Hov
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter | TypeDefinitionAdapter
| ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter | SelectionRangeAdapter | CallHierarchyAdapter;
| ColorProviderAdapter | FoldingProviderAdapter | CodeInsetAdapter | DeclarationAdapter | SelectionRangeAdapter | CallHierarchyAdapter;
class AdapterData {
constructor(
@@ -1057,11 +1036,15 @@ class AdapterData {
) { }
}
export interface ISchemeTransformer {
transformOutgoing(scheme: string): string;
}
export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
private static _handlePool: number = 0;
private readonly _uriTransformer: IURITransformer | null;
private readonly _schemeTransformer: ISchemeTransformer | null;
private _proxy: MainThreadLanguageFeaturesShape;
private _documents: ExtHostDocuments;
private _commands: ExtHostCommands;
@@ -1069,23 +1052,25 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
private _diagnostics: ExtHostDiagnostics;
private _adapter = new Map<number, AdapterData>();
private readonly _logService: ILogService;
private _webviewProxy: MainThreadWebviewsShape;
constructor(
mainContext: IMainContext,
uriTransformer: IURITransformer | null,
schemeTransformer: ISchemeTransformer | null,
documents: ExtHostDocuments,
commands: ExtHostCommands,
heapMonitor: ExtHostHeapService,
diagnostics: ExtHostDiagnostics,
logService: ILogService
) {
this._uriTransformer = uriTransformer;
this._schemeTransformer = schemeTransformer;
this._proxy = mainContext.getProxy(MainContext.MainThreadLanguageFeatures);
this._documents = documents;
this._commands = commands;
this._heapService = heapMonitor;
this._diagnostics = diagnostics;
this._logService = logService;
this._webviewProxy = mainContext.getProxy(MainContext.MainThreadWebviews);
}
private _transformDocumentSelector(selector: vscode.DocumentSelector): Array<ISerializedDocumentFilter> {
@@ -1114,8 +1099,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
}
private _transformScheme(scheme: string | undefined): string | undefined {
if (this._uriTransformer && typeof scheme === 'string') {
return this._uriTransformer.transformOutgoingScheme(scheme);
if (this._schemeTransformer && typeof scheme === 'string') {
return this._schemeTransformer.transformOutgoing(scheme);
}
return scheme;
}
@@ -1188,7 +1173,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
const handle = this._nextHandle();
const eventHandle = typeof provider.onDidChangeCodeLenses === 'function' ? this._nextHandle() : undefined;
this._adapter.set(handle, new AdapterData(new CodeLensAdapter(this._documents, this._commands.converter, provider), extension));
this._adapter.set(handle, new AdapterData(new CodeLensAdapter(this._documents, this._commands.converter, this._heapService, provider), extension));
this._proxy.$registerCodeLensSupport(handle, this._transformDocumentSelector(selector), eventHandle);
let result = this._createDisposable(handle);
@@ -1200,16 +1185,43 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return result;
}
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensListDto | undefined> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.provideCodeLenses(URI.revive(resource), token), undefined);
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.ICodeLensSymbol[]> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.provideCodeLenses(URI.revive(resource), token), []);
}
$resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
$resolveCodeLens(handle: number, symbol: modes.ICodeLensSymbol, token: CancellationToken): Promise<modes.ICodeLensSymbol | undefined> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLens(symbol, token), undefined);
}
$releaseCodeLenses(handle: number, cacheId: number): void {
this._withAdapter(handle, CodeLensAdapter, adapter => Promise.resolve(adapter.releaseCodeLenses(cacheId)), undefined);
// --- code insets
registerCodeInsetProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CodeInsetProvider): vscode.Disposable {
const handle = this._nextHandle();
const eventHandle = typeof provider.onDidChangeCodeInsets === 'function' ? this._nextHandle() : undefined;
this._adapter.set(handle, new AdapterData(new CodeInsetAdapter(this._documents, this._heapService, provider), extension));
this._proxy.$registerCodeInsetSupport(handle, this._transformDocumentSelector(selector), eventHandle);
let result = this._createDisposable(handle);
if (eventHandle !== undefined && provider.onDidChangeCodeInsets) {
const subscription = provider.onDidChangeCodeInsets(_ => this._proxy.$emitCodeLensEvent(eventHandle));
result = Disposable.from(result, subscription);
}
return result;
}
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<codeInset.ICodeInsetSymbol[] | undefined> {
return this._withAdapter(handle, CodeInsetAdapter, adapter => adapter.provideCodeInsets(URI.revive(resource), token), undefined);
}
$resolveCodeInset(handle: number, _resource: UriComponents, symbol: codeInset.ICodeInsetSymbol, token: CancellationToken): Promise<codeInset.ICodeInsetSymbol> {
const webviewHandle = Math.random();
const webview = new ExtHostWebview(webviewHandle, this._webviewProxy, { enableScripts: true });
return this._withAdapter(handle, CodeInsetAdapter, async (adapter, extension) => {
await this._webviewProxy.$createWebviewCodeInset(webviewHandle, symbol.id, { enableCommandUris: true, enableScripts: true }, extension ? extension.identifier : undefined, extension ? extension.extensionLocation : undefined);
return adapter.resolveCodeInset(symbol, webview, token);
}, symbol);
}
// --- declaration
@@ -1299,14 +1311,10 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
}
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionListDto | undefined> {
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[] | undefined> {
return this._withAdapter(handle, CodeActionAdapter, adapter => adapter.provideCodeActions(URI.revive(resource), rangeOrSelection, context, token), undefined);
}
$releaseCodeActions(handle: number, cacheId: number): void {
this._withAdapter(handle, CodeActionAdapter, adapter => Promise.resolve(adapter.releaseCodeActions(cacheId)), undefined);
}
// --- formatting
registerDocumentFormattingEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {

View File

@@ -7,7 +7,7 @@ import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/
import { StatusBarAlignment as ExtHostStatusBarAlignment, Disposable, ThemeColor } from './extHostTypes';
import { StatusBarItem, StatusBarAlignment } from 'vscode';
import { MainContext, MainThreadStatusBarShape, IMainContext } from './extHost.protocol';
import { localize } from 'vs/nls';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
export class ExtHostStatusBarEntry implements StatusBarItem {
private static ID_GEN = 0;
@@ -18,9 +18,6 @@ export class ExtHostStatusBarEntry implements StatusBarItem {
private _disposed: boolean;
private _visible: boolean;
private _statusId: string;
private _statusName: string;
private _text: string;
private _tooltip: string;
private _color: string | ThemeColor;
@@ -29,13 +26,14 @@ export class ExtHostStatusBarEntry implements StatusBarItem {
private _timeoutHandle: any;
private _proxy: MainThreadStatusBarShape;
constructor(proxy: MainThreadStatusBarShape, id: string, name: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
private _extensionId?: ExtensionIdentifier;
constructor(proxy: MainThreadStatusBarShape, extensionId: ExtensionIdentifier | undefined, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
this._id = ExtHostStatusBarEntry.ID_GEN++;
this._proxy = proxy;
this._statusId = id;
this._statusName = name;
this._alignment = alignment;
this._priority = priority;
this._extensionId = extensionId;
}
public get id(): number {
@@ -109,7 +107,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem {
this._timeoutHandle = undefined;
// Set to status bar
this._proxy.$setEntry(this.id, this._statusId, this._statusName, this.text, this.tooltip, this.command, this.color,
this._proxy.$setEntry(this.id, this._extensionId, this.text, this.tooltip, this.command, this.color,
this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT,
this._priority);
}, 0);
@@ -127,7 +125,7 @@ class StatusBarMessage {
private _messages: { message: string }[] = [];
constructor(statusBar: ExtHostStatusBar) {
this._item = statusBar.createStatusBarEntry('status.extensionMessage', localize('status.extensionMessage', "Extension Status"), ExtHostStatusBarAlignment.Left, Number.MIN_VALUE);
this._item = statusBar.createStatusBarEntry(undefined, ExtHostStatusBarAlignment.Left, Number.MIN_VALUE);
}
dispose() {
@@ -169,8 +167,8 @@ export class ExtHostStatusBar {
this._statusMessage = new StatusBarMessage(this);
}
createStatusBarEntry(id: string, name: string, alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem {
return new ExtHostStatusBarEntry(this._proxy, id, name, alignment, priority);
createStatusBarEntry(extensionId: ExtensionIdentifier | undefined, alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem {
return new ExtHostStatusBarEntry(this._proxy, extensionId, alignment, priority);
}
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): Disposable {

View File

@@ -808,8 +808,7 @@ export namespace DocumentLink {
export function from(link: vscode.DocumentLink): modes.ILink {
return {
range: Range.from(link.range),
url: link.target,
tooltip: link.tooltip
url: link.target
};
}
@@ -859,7 +858,10 @@ export namespace Color {
export namespace SelectionRange {
export function from(obj: vscode.SelectionRange): modes.SelectionRange {
return { range: Range.from(obj.range) };
return {
kind: '',
range: Range.from(obj.range)
};
}
export function to(obj: modes.SelectionRange): vscode.SelectionRange {

View File

@@ -1440,8 +1440,6 @@ export class DocumentLink {
target?: URI;
tooltip?: string;
constructor(range: Range, target: URI | undefined) {
if (target && !(target instanceof URI)) {
throw illegalArgument('target');

View File

@@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import * as vscode from 'vscode';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewState } from './extHost.protocol';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewState, WebviewInsetHandle } from './extHost.protocol';
import { Disposable } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as modes from 'vs/editor/common/modes';
@@ -16,7 +16,7 @@ import * as modes from 'vs/editor/common/modes';
type IconPath = URI | { light: URI, dark: URI };
export class ExtHostWebview implements vscode.Webview {
private readonly _handle: WebviewPanelHandle;
private readonly _handle: WebviewPanelHandle | WebviewInsetHandle;
private readonly _proxy: MainThreadWebviewsShape;
private _html: string;
private _options: vscode.WebviewOptions;
@@ -26,7 +26,7 @@ export class ExtHostWebview implements vscode.Webview {
public readonly onDidReceiveMessage: Event<any> = this._onMessageEmitter.event;
constructor(
handle: WebviewPanelHandle,
handle: WebviewPanelHandle | WebviewInsetHandle,
proxy: MainThreadWebviewsShape,
options: vscode.WebviewOptions
) {

View File

@@ -21,6 +21,7 @@ namespace schema {
export interface IUserFriendlyMenuItem {
command: string;
alt?: string;
precondition?: string;
when?: string;
group?: string;
}
@@ -83,6 +84,10 @@ namespace schema {
collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", 'alt'));
return false;
}
if (item.precondition && typeof item.precondition !== 'string') {
collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", 'precondition'));
return false;
}
if (item.when && typeof item.when !== 'string') {
collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", 'when'));
return false;
@@ -107,6 +112,10 @@ namespace schema {
description: localize('vscode.extension.contributes.menuItem.alt', 'Identifier of an alternative command to execute. The command must be declared in the \'commands\'-section'),
type: 'string'
},
precondition: {
description: localize('vscode.extension.contributes.menuItem.precondition', 'Condition which must be true to enable this item'),
type: 'string'
},
when: {
description: localize('vscode.extension.contributes.menuItem.when', 'Condition which must be true to show this item'),
type: 'string'
@@ -197,8 +206,8 @@ namespace schema {
type: 'array',
items: menuItem
},
'comments/commentThread/context': {
description: localize('commentThread.actions', "The contributed comment thread context menu, rendered as buttons below the comment editor"),
'comments/commentThread/actions': {
description: localize('commentThread.actions', "The contributed comment thread actions"),
type: 'array',
items: menuItem
},
@@ -207,8 +216,8 @@ namespace schema {
type: 'array',
items: menuItem
},
'comments/comment/context': {
description: localize('comment.actions', "The contributed comment context menu, rendered as buttons below the comment editor"),
'comments/comment/actions': {
description: localize('comment.actions', "The contributed comment actions"),
type: 'array',
items: menuItem
},
@@ -220,7 +229,6 @@ namespace schema {
export interface IUserFriendlyCommand {
command: string;
title: string | ILocalizedString;
enablement?: string;
category?: string | ILocalizedString;
icon?: IUserFriendlyIcon;
}
@@ -239,10 +247,6 @@ namespace schema {
if (!isValidLocalizedString(command.title, collector, 'title')) {
return false;
}
if (command.enablement && typeof command.enablement !== 'string') {
collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", 'precondition'));
return false;
}
if (command.category && !isValidLocalizedString(command.category, collector, 'category')) {
return false;
}
@@ -296,10 +300,6 @@ namespace schema {
description: localize('vscode.extension.contributes.commandType.category', '(Optional) Category string by the command is grouped in the UI'),
type: 'string'
},
enablement: {
description: localize('vscode.extension.contributes.commandType.precondition', '(Optional) Condition which must be true to enable the command'),
type: 'string'
},
icon: {
description: localize('vscode.extension.contributes.commandType.icon', '(Optional) Icon which is used to represent the command in the UI. Either a file path or a themable configuration'),
anyOf: [{
@@ -336,12 +336,10 @@ namespace schema {
let _commandRegistrations: IDisposable[] = [];
export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<schema.IUserFriendlyCommand | schema.IUserFriendlyCommand[]>({
ExtensionsRegistry.registerExtensionPoint<schema.IUserFriendlyCommand | schema.IUserFriendlyCommand[]>({
extensionPoint: 'commands',
jsonSchema: schema.commandsContribution
});
commandsExtensionPoint.setHandler(extensions => {
}).setHandler(extensions => {
function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser<any>, disposables: IDisposable[]) {
@@ -349,7 +347,7 @@ commandsExtensionPoint.setHandler(extensions => {
return;
}
const { icon, enablement, category, title, command } = userFriendlyCommand;
const { icon, category, title, command } = userFriendlyCommand;
let absoluteIcon: { dark: URI; light?: URI; } | undefined;
if (icon) {
@@ -366,13 +364,7 @@ commandsExtensionPoint.setHandler(extensions => {
if (MenuRegistry.getCommand(command)) {
extension.collector.info(localize('dup', "Command `{0}` appears multiple times in the `commands` section.", userFriendlyCommand.command));
}
const registration = MenuRegistry.addCommand({
id: command,
title,
category,
precondition: ContextKeyExpr.deserialize(enablement),
iconLocation: absoluteIcon
});
const registration = MenuRegistry.addCommand({ id: command, title, category, iconLocation: absoluteIcon });
disposables.push(registration);
}
@@ -447,6 +439,14 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM
}
}
if (item.precondition) {
command.precondition = ContextKeyExpr.deserialize(item.precondition);
}
if (alt && item.precondition) {
alt.precondition = command.precondition;
}
const registration = MenuRegistry.appendMenuItem(menu, {
command,
alt,