Merge branch 'main' into joh/shortcut_fs

This commit is contained in:
Johannes Rieken
2021-11-16 10:20:45 +01:00
639 changed files with 13615 additions and 9181 deletions

View File

@@ -13,7 +13,7 @@ import { OverviewRulerLane } from 'vs/editor/common/model';
import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration';
import { score } from 'vs/editor/common/modes/languageSelector';
import * as files from 'vs/platform/files/common/files';
import { ExtHostContext, MainContext, ExtHostLogServiceShape, UIKind, CandidatePortSource } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostContext, MainContext, UIKind, CandidatePortSource, ExtHostLogLevelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands';
import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
@@ -46,7 +46,6 @@ import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls';
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
import { IExtHostWindow } from 'vs/workbench/api/common/extHostWindow';
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import type * as vscode from 'vscode';
@@ -60,7 +59,7 @@ import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
import { ILogService } from 'vs/platform/log/common/log';
import { ILoggerService, ILogService } from 'vs/platform/log/common/log';
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
@@ -92,6 +91,7 @@ import { ExtHostNotebookEditors } from 'vs/workbench/api/common/extHostNotebookE
import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments';
import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive';
import { combinedDisposable } from 'vs/base/common/lifecycle';
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
export interface IExtensionApiFactory {
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
@@ -114,6 +114,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const rpcProtocol = accessor.get(IExtHostRpcService);
const extHostStorage = accessor.get(IExtHostStorage);
const extensionStoragePaths = accessor.get(IExtensionStoragePaths);
const extHostLoggerService = accessor.get(ILoggerService);
const extHostLogService = accessor.get(ILogService);
const extHostTunnelService = accessor.get(IExtHostTunnelService);
const extHostApiDeprecation = accessor.get(IExtHostApiDeprecationService);
@@ -123,7 +124,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// register addressable instances
rpcProtocol.set(ExtHostContext.ExtHostFileSystemInfo, extHostFileSystemInfo);
rpcProtocol.set(ExtHostContext.ExtHostLogService, <ExtHostLogServiceShape><any>extHostLogService);
rpcProtocol.set(ExtHostContext.ExtHostLogLevelServiceShape, <ExtHostLogLevelServiceShape><any>extHostLoggerService);
rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace);
rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration);
rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
@@ -200,8 +201,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// We only inform once, it is not a warning because we just want to raise awareness and because
// we cannot say if the extension is doing it right or wrong...
const checkSelector = (function () {
let done = (!extension.isUnderDevelopment);
function informOnce(selector: vscode.DocumentSelector) {
let done = !extension.isUnderDevelopment;
function informOnce() {
if (!done) {
extHostLogService.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`);
done = true;
@@ -211,14 +212,14 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
if (Array.isArray(selector)) {
selector.forEach(perform);
} else if (typeof selector === 'string') {
informOnce(selector);
informOnce();
} else {
const filter = selector as vscode.DocumentFilter; // TODO: microsoft/TypeScript#42768
if (typeof filter.scheme === 'undefined') {
informOnce(selector);
informOnce();
}
if (!extension.enableProposedApi && typeof filter.exclusive === 'boolean') {
throwProposedApiError(extension);
if (typeof filter.exclusive === 'boolean') {
checkProposedApiEnabled(extension, 'documentFiltersExclusive');
}
}
return selector;
@@ -227,14 +228,14 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const authentication: typeof vscode.authentication = {
getSession(providerId: string, scopes: readonly string[], options?: vscode.AuthenticationGetSessionOptions) {
if (options?.forceNewSession || options?.silent) {
checkProposedApiEnabled(extension);
if (options?.forceNewSession) {
checkProposedApiEnabled(extension, 'authSession');
}
return extHostAuthentication.getSession(extension, providerId, scopes, options as any);
},
// TODO: remove this after GHPR and Codespaces move off of it
async hasSession(providerId: string, scopes: readonly string[]) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'authSession');
return !!(await extHostAuthentication.getSession(extension, providerId, scopes, { silent: true } as any));
},
get onDidChangeSessions(): Event<vscode.AuthenticationSessionsChangeEvent> {
@@ -271,7 +272,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
}, undefined, undefined, extension);
},
registerDiffInformationCommand: (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'diffCommand');
return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise<any> => {
const activeTextEditor = extHostDocumentsAndEditors.activeEditor(true);
if (!activeTextEditor) {
@@ -339,7 +340,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return getRemoteName(initData.remote.authority);
},
get remoteAuthority() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
return initData.remote.authority;
},
get uiKind() {
@@ -360,19 +361,19 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostTesting.createTestController(provider, label);
},
createTestObserver() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'testObserver');
return extHostTesting.createTestObserver();
},
runTests(provider) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'testObserver');
return extHostTesting.runTests(provider);
},
get onDidChangeTestResults() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'testObserver');
return extHostTesting.onResultsChanged;
},
get testResults() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'testObserver');
return extHostTesting.results;
},
};
@@ -484,7 +485,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters);
},
registerInlineCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider): vscode.Disposable {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'inlineCompletions');
return extHostLanguageFeatures.registerInlineCompletionsProvider(extension, checkSelector(selector), provider);
},
registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable {
@@ -509,15 +510,15 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostLanguageFeatures.setLanguageConfiguration(extension, language, configuration);
},
getTokenInformationAtPosition(doc: vscode.TextDocument, pos: vscode.Position) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'tokenInformation');
return extHostLanguages.tokenAtPosition(doc, pos);
},
registerInlayHintsProvider(selector: vscode.DocumentSelector, provider: vscode.InlayHintsProvider): vscode.Disposable {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'inlayHints');
return extHostLanguageFeatures.registerInlayHintsProvider(extension, selector, provider);
},
createLanguageStatusItem(id: string, selector: vscode.DocumentSelector): vscode.LanguageStatusItem {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'languageStatus');
return extHostLanguages.createLanguageStatusItem(extension, id, selector);
}
};
@@ -574,14 +575,14 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables);
},
onDidChangeTerminalDimensions(listener, thisArg?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'terminalDimensions');
return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables);
},
onDidChangeTerminalState(listener, thisArg?, disposables?) {
return extHostTerminalService.onDidChangeTerminalState(listener, thisArg, disposables);
},
onDidWriteTerminalData(listener, thisArg?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'terminalDataWriteEvent');
return extHostTerminalService.onDidWriteTerminalData(listener, thisArg, disposables);
},
get state() {
@@ -600,7 +601,11 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return <Thenable<any>>extHostMessageService.showMessage(extension, Severity.Error, message, rest[0], <Array<string | vscode.MessageItem>>rest.slice(1));
},
showQuickPick(items: any, options?: vscode.QuickPickOptions, token?: vscode.CancellationToken): any {
return extHostQuickOpen.showQuickPick(items, !!extension.enableProposedApi, options, token);
// TODO: remove this once quickPickSeparators has been finalized.
if (Array.isArray(items) && items.some((item) => item.kind !== undefined)) {
checkProposedApiEnabled(extension, 'quickPickSeparators');
}
return extHostQuickOpen.showQuickPick(items, options, token);
},
showWorkspaceFolderPick(options?: vscode.WorkspaceFolderPickOptions) {
return extHostQuickOpen.showWorkspaceFolderPick(options);
@@ -649,13 +654,13 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostWebviewPanels.createWebviewPanel(extension, viewType, title, showOptions, options);
},
createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options?: vscode.WebviewOptions): vscode.WebviewEditorInset {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'editorInsets');
return extHostEditorInsets.createWebviewEditorInset(editor, line, height, options, extension);
},
createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.ExtensionTerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
if (typeof nameOrOptions === 'object') {
if ('location' in nameOrOptions) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'terminalLocation');
}
if ('pty' in nameOrOptions) {
return extHostTerminalService.createExtensionTerminal(nameOrOptions);
@@ -689,7 +694,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostUrls.registerUriHandler(extension.identifier, handler);
},
createQuickPick<T extends vscode.QuickPickItem>(): vscode.QuickPick<T> {
return extHostQuickOpen.createQuickPick(extension.identifier, !!extension.enableProposedApi);
return extHostQuickOpen.createQuickPick(extension);
},
createInputBox(): vscode.InputBox {
return extHostQuickOpen.createInputBox(extension.identifier);
@@ -708,55 +713,55 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostWebviewViews.registerWebviewViewProvider(extension, viewId, provider, options?.webviewOptions);
},
get activeNotebookEditor(): vscode.NotebookEditor | undefined {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.activeNotebookEditor;
},
onDidChangeActiveNotebookEditor(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.onDidChangeActiveNotebookEditor(listener, thisArgs, disposables);
},
get visibleNotebookEditors() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.visibleNotebookEditors;
},
get onDidChangeVisibleNotebookEditors() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.onDidChangeVisibleNotebookEditors;
},
onDidChangeNotebookEditorSelection(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebookEditors.onDidChangeNotebookEditorSelection(listener, thisArgs, disposables);
},
onDidChangeNotebookEditorVisibleRanges(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebookEditors.onDidChangeNotebookEditorVisibleRanges(listener, thisArgs, disposables);
},
showNotebookDocument(uriOrDocument, options?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.showNotebookDocument(uriOrDocument, options);
},
registerExternalUriOpener(id: string, opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'externalUriOpener');
return extHostUriOpeners.registerExternalUriOpener(extension.identifier, id, opener, metadata);
},
get tabs() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'tabs');
return extHostEditorTabs.tabs;
},
get activeTab() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'tabs');
return extHostEditorTabs.activeTab;
},
get onDidChangeTabs() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'tabs');
return extHostEditorTabs.onDidChangeTabs;
},
get onDidChangeActiveTab() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'tabs');
return extHostEditorTabs.onDidChangeActiveTab;
},
getInlineCompletionItemController<T extends vscode.InlineCompletionItem>(provider: vscode.InlineCompletionItemProvider<T>): vscode.InlineCompletionController<T> {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'inlineCompletions');
return InlineCompletionController.get(provider);
}
};
@@ -805,6 +810,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token);
},
findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => {
checkProposedApiEnabled(extension, 'findTextInFiles');
let options: vscode.FindTextInFilesOptions;
let callback: (result: vscode.TextSearchResult) => void;
@@ -891,11 +897,11 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostNotebook.onDidCloseNotebookDocument;
},
registerNotebookSerializer(viewType: string, serializer: vscode.NotebookSerializer, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) {
return extHostNotebook.registerNotebookSerializer(extension, viewType, serializer, options, extension.enableProposedApi ? registration : undefined);
return extHostNotebook.registerNotebookSerializer(extension, viewType, serializer, options, isProposedApiEnabled(extension, 'notebookLiveShare') ? registration : undefined);
},
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) => {
checkProposedApiEnabled(extension);
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options, extension.enableProposedApi ? registration : undefined);
checkProposedApiEnabled(extension, 'notebookContentProvider');
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options, isProposedApiEnabled(extension, 'notebookLiveShare') ? registration : undefined);
},
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
@@ -923,19 +929,19 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostConsumerFileSystem.value;
},
registerFileSearchProvider: (scheme: string, provider: vscode.FileSearchProvider) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'fileSearchProvider');
return extHostSearch.registerFileSearchProvider(scheme, provider);
},
registerTextSearchProvider: (scheme: string, provider: vscode.TextSearchProvider) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'textSearchProvider');
return extHostSearch.registerTextSearchProvider(scheme, provider);
},
registerRemoteAuthorityResolver: (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver);
},
registerResourceLabelFormatter: (formatter: vscode.ResourceLabelFormatter) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
return extHostLabelService.$registerResourceLabelFormatter(formatter);
},
onDidCreateFiles: (listener, thisArg, disposables) => {
@@ -957,7 +963,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostFileSystemEvent.getOnWillRenameFileEvent(extension)(listener, thisArg, disposables);
},
openTunnel: (forward: vscode.TunnelOptions) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
return extHostTunnelService.openTunnel(extension, forward).then(value => {
if (!value) {
throw new Error('cannot open tunnel');
@@ -966,26 +972,26 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
});
},
get tunnels() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
return extHostTunnelService.getTunnels();
},
onDidChangeTunnels: (listener, thisArg?, disposables?) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
return extHostTunnelService.onDidChangeTunnels(listener, thisArg, disposables);
},
registerPortAttributesProvider: (portSelector: { pid?: number, portRange?: [number, number], commandMatcher?: RegExp }, provider: vscode.PortAttributesProvider) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'portsAttributes');
return extHostTunnelService.registerPortsAttributesProvider(portSelector, provider);
},
registerTimelineProvider: (scheme: string | string[], provider: vscode.TimelineProvider) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'timeline');
return extHostTimeline.registerTimelineProvider(scheme, provider, extension.identifier, extHostCommands.converter);
},
get isTrusted() {
return extHostWorkspace.trusted;
},
requestWorkspaceTrust: (options?: vscode.WorkspaceTrustRequestOptions) => {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'workspaceTrust');
return extHostWorkspace.requestWorkspaceTrust(options);
},
onDidGrantWorkspaceTrust: (listener, thisArgs?, disposables?) => {
@@ -1098,44 +1104,44 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// namespace: notebook
const notebooks: typeof vscode.notebooks = {
createNotebookController(id: string, notebookType: string, label: string, handler?, rendererScripts?: vscode.NotebookRendererScript[]) {
return extHostNotebookKernels.createNotebookController(extension, id, notebookType, label, handler, extension.enableProposedApi ? rendererScripts : undefined);
return extHostNotebookKernels.createNotebookController(extension, id, notebookType, label, handler, isProposedApiEnabled(extension, 'notebookMessaging') ? rendererScripts : undefined);
},
registerNotebookCellStatusBarItemProvider: (notebookType: string, provider: vscode.NotebookCellStatusBarItemProvider) => {
return extHostNotebook.registerNotebookCellStatusBarItemProvider(extension, notebookType, provider);
},
get onDidSaveNotebookDocument(): Event<vscode.NotebookDocument> {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebookDocuments.onDidSaveNotebookDocument;
},
createNotebookEditorDecorationType(options: vscode.NotebookDecorationRenderOptions): vscode.NotebookEditorDecorationType {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditorDecorationType');
return extHostNotebookEditors.createNotebookEditorDecorationType(options);
},
createRendererMessaging(rendererId) {
return extHostNotebookRenderers.createRendererMessaging(extension, rendererId);
},
onDidChangeNotebookDocumentMetadata(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebookDocuments.onDidChangeNotebookDocumentMetadata(listener, thisArgs, disposables);
},
onDidChangeNotebookCells(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.onDidChangeNotebookCells(listener, thisArgs, disposables);
},
onDidChangeNotebookCellExecutionState(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookCellExecutionState');
return extHostNotebook.onDidChangeNotebookCellExecutionState(listener, thisArgs, disposables);
},
onDidChangeCellOutputs(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.onDidChangeCellOutputs(listener, thisArgs, disposables);
},
onDidChangeCellMetadata(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookEditor');
return extHostNotebook.onDidChangeCellMetadata(listener, thisArgs, disposables);
},
createConcatTextDocument(notebook, selector) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookConcatTextDocument');
return new ExtHostNotebookConcatDocument(extHostNotebook, extHostDocuments, notebook, selector);
},
};
@@ -1309,6 +1315,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
FunctionCoverage: extHostTypes.FunctionCoverage,
WorkspaceTrustState: extHostTypes.WorkspaceTrustState,
LanguageStatusSeverity: extHostTypes.LanguageStatusSeverity,
QuickPickItemKind: extHostTypes.QuickPickItemKind,
};
};
}

View File

@@ -23,7 +23,12 @@ import { IExtHostFileSystemInfo, ExtHostFileSystemInfo } from 'vs/workbench/api/
import { IExtHostSecretState, ExtHostSecretState } from 'vs/workbench/api/common/exHostSecretState';
import { ExtHostTelemetry, IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry';
import { ExtHostEditorTabs, IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs';
import { ExtHostLoggerService } from 'vs/workbench/api/common/extHostLoggerService';
import { ILoggerService, ILogService } from 'vs/platform/log/common/log';
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
registerSingleton(ILoggerService, ExtHostLoggerService);
registerSingleton(ILogService, ExtHostLogService);
registerSingleton(IExtHostApiDeprecationService, ExtHostApiDeprecationService);
registerSingleton(IExtHostCommands, ExtHostCommands);
registerSingleton(IExtHostConfiguration, ExtHostConfiguration);

View File

@@ -31,7 +31,7 @@ import { ConfigurationScope } from 'vs/platform/configuration/common/configurati
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as files from 'vs/platform/files/common/files';
import { ResourceLabelFormatter } from 'vs/platform/label/common/label';
import { LogLevel } from 'vs/platform/log/common/log';
import { ILoggerOptions, LogLevel } from 'vs/platform/log/common/log';
import { IMarkerData } from 'vs/platform/markers/common/markers';
import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress';
import * as quickInput from 'vs/platform/quickinput/common/quickInput';
@@ -56,6 +56,7 @@ import { IAdapterDescriptor, IConfig, IDebugSessionReplMode } from 'vs/workbench
import * as notebookCommon from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellExecutionUpdateType, ICellExecutionComplete, ICellExecutionStateUpdate } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
import { OutputChannelUpdateMode } from 'vs/workbench/contrib/output/common/output';
import { InputValidationType } from 'vs/workbench/contrib/scm/common/scm';
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
@@ -443,14 +444,12 @@ export interface MainThreadMessageServiceShape extends IDisposable {
}
export interface MainThreadOutputServiceShape extends IDisposable {
$register(label: string, log: boolean, file?: UriComponents, extensionId?: string): Promise<string>;
$append(channelId: string, value: string): Promise<void> | undefined;
$update(channelId: string): Promise<void> | undefined;
$clear(channelId: string, till: number): Promise<void> | undefined;
$replaceAll(channelId: string, till: number, value?: string): Promise<void> | undefined;
$reveal(channelId: string, preserveFocus: boolean): Promise<void> | undefined;
$close(channelId: string): Promise<void> | undefined;
$dispose(channelId: string): Promise<void> | undefined;
$register(label: string, log: boolean, file: UriComponents, extensionId: string): Promise<string>;
$update(channelId: string, mode: OutputChannelUpdateMode.Append): Promise<void>;
$update(channelId: string, mode: OutputChannelUpdateMode, till: number): Promise<void>;
$reveal(channelId: string, preserveFocus: boolean): Promise<void>;
$close(channelId: string): Promise<void>;
$dispose(channelId: string): Promise<void>;
}
export interface MainThreadProgressShape extends IDisposable {
@@ -511,7 +510,8 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
$sendProcessExit(terminalId: number, exitCode: number | undefined): void;
}
export interface TransferQuickPickItems extends quickInput.IQuickPickItem {
export type TransferQuickPickItemOrSeparator = TransferQuickPickItem | quickInput.IQuickPickSeparator;
export interface TransferQuickPickItem extends quickInput.IQuickPickItem {
handle: number;
buttons?: TransferQuickInputButton[];
}
@@ -549,7 +549,7 @@ export interface TransferQuickPick extends BaseTransferQuickInput {
buttons?: TransferQuickInputButton[];
items?: TransferQuickPickItems[];
items?: TransferQuickPickItemOrSeparator[];
activeItems?: number[];
@@ -594,8 +594,8 @@ export interface IInputBoxOptions {
}
export interface MainThreadQuickOpenShape extends IDisposable {
$show(instance: number, options: quickInput.IPickOptions<TransferQuickPickItems>, token: CancellationToken): Promise<number | number[] | undefined>;
$setItems(instance: number, items: TransferQuickPickItems[]): Promise<void>;
$show(instance: number, options: quickInput.IPickOptions<TransferQuickPickItem>, token: CancellationToken): Promise<number | number[] | undefined>;
$setItems(instance: number, items: TransferQuickPickItemOrSeparator[]): Promise<void>;
$setError(instance: number, error: Error): Promise<void>;
$input(options: IInputBoxOptions | undefined, validateInput: boolean, token: CancellationToken): Promise<string | undefined>;
$createOrUpdate(params: TransferQuickInput): Promise<void>;
@@ -619,11 +619,11 @@ export interface MainThreadTelemetryShape extends IDisposable {
}
export interface MainThreadEditorInsetsShape extends IDisposable {
$createEditorInset(handle: number, id: string, uri: UriComponents, line: number, height: number, options: IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise<void>;
$createEditorInset(handle: number, id: string, uri: UriComponents, line: number, height: number, options: IWebviewContentOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise<void>;
$disposeEditorInset(handle: number): void;
$setHtml(handle: number, value: string): void;
$setOptions(handle: number, options: IWebviewOptions): void;
$setOptions(handle: number, options: IWebviewContentOptions): void;
$postMessage(handle: number, value: any): Promise<boolean>;
}
@@ -682,12 +682,12 @@ export interface IWebviewPortMapping {
readonly extensionHostPort: number;
}
export interface IWebviewOptions {
export interface IWebviewContentOptions {
readonly enableScripts?: boolean;
readonly enableForms?: boolean;
readonly enableCommandUris?: boolean;
readonly localResourceRoots?: ReadonlyArray<UriComponents>;
readonly portMapping?: ReadonlyArray<IWebviewPortMapping>;
readonly localResourceRoots?: readonly UriComponents[];
readonly portMapping?: readonly IWebviewPortMapping[];
}
export interface IWebviewPanelOptions {
@@ -730,27 +730,34 @@ export interface WebviewMessageArrayBufferReference {
export interface MainThreadWebviewsShape extends IDisposable {
$setHtml(handle: WebviewHandle, value: string): void;
$setOptions(handle: WebviewHandle, options: IWebviewOptions): void;
$setOptions(handle: WebviewHandle, options: IWebviewContentOptions): void;
$postMessage(handle: WebviewHandle, value: string, ...buffers: VSBuffer[]): Promise<boolean>
}
export interface IWebviewIconPath {
readonly light: UriComponents;
readonly dark: UriComponents;
}
export interface IWebviewInitData {
readonly title: string;
readonly webviewOptions: IWebviewContentOptions;
readonly panelOptions: IWebviewPanelOptions;
readonly serializeBuffersForPostMessage: boolean;
}
export interface MainThreadWebviewPanelsShape extends IDisposable {
$createWebviewPanel(
extension: WebviewExtensionDescription,
handle: WebviewHandle,
viewType: string,
initData: {
title: string;
webviewOptions: IWebviewOptions;
panelOptions: IWebviewPanelOptions;
serializeBuffersForPostMessage: boolean;
},
initData: IWebviewInitData,
showOptions: WebviewPanelShowOptions,
): void;
$disposeWebview(handle: WebviewHandle): void;
$reveal(handle: WebviewHandle, showOptions: WebviewPanelShowOptions): void;
$setTitle(handle: WebviewHandle, value: string): void;
$setIconPath(handle: WebviewHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void;
$setIconPath(handle: WebviewHandle, value: IWebviewIconPath | undefined): void;
$registerSerializer(viewType: string, options: { serializeBuffersForPostMessage: boolean }): void;
$unregisterSerializer(viewType: string): void;
@@ -797,7 +804,7 @@ export interface ExtHostWebviewPanelsShape {
initData: {
title: string;
state: any;
webviewOptions: IWebviewOptions;
webviewOptions: IWebviewContentOptions;
panelOptions: IWebviewPanelOptions;
},
position: EditorGroupColumn,
@@ -811,7 +818,7 @@ export interface ExtHostCustomEditorsShape {
viewType: string,
initData: {
title: string;
webviewOptions: IWebviewOptions;
webviewOptions: IWebviewContentOptions;
panelOptions: IWebviewPanelOptions;
},
position: EditorGroupColumn,
@@ -1099,7 +1106,6 @@ export interface MainThreadSCMShape extends IDisposable {
$setInputBoxValue(sourceControlHandle: number, value: string): void;
$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
$setInputBoxVisibility(sourceControlHandle: number, visible: boolean): void;
$setInputBoxFocus(sourceControlHandle: number): void;
$showValidationMessage(sourceControlHandle: number, message: string | IMarkdownString, type: InputValidationType): void;
$setValidationProviderIsEnabled(sourceControlHandle: number, enabled: boolean): void;
}
@@ -1895,12 +1901,13 @@ export interface ExtHostWindowShape {
$onDidChangeWindowFocus(value: boolean): void;
}
export interface ExtHostLogServiceShape {
export interface ExtHostLogLevelServiceShape {
$setLevel(level: LogLevel): void;
}
export interface MainThreadLogShape {
$log(file: UriComponents, level: LogLevel, args: any[]): void;
export interface MainThreadLoggerShape {
$log(file: UriComponents, messages: [LogLevel, string][]): void;
$createLogger(file: UriComponents, options?: ILoggerOptions): Promise<void>;
}
export interface ExtHostOutputServiceShape {
@@ -2213,7 +2220,7 @@ export const MainContext = {
MainThreadKeytar: createMainId<MainThreadKeytarShape>('MainThreadKeytar'),
MainThreadLanguageFeatures: createMainId<MainThreadLanguageFeaturesShape>('MainThreadLanguageFeatures'),
MainThreadLanguages: createMainId<MainThreadLanguagesShape>('MainThreadLanguages'),
MainThreadLog: createMainId<MainThreadLogShape>('MainThread'),
MainThreadLogger: createMainId<MainThreadLoggerShape>('MainThreadLogger'),
MainThreadMessageService: createMainId<MainThreadMessageServiceShape>('MainThreadMessageService'),
MainThreadOutputService: createMainId<MainThreadOutputServiceShape>('MainThreadOutputService'),
MainThreadProgress: createMainId<MainThreadProgressShape>('MainThreadProgress'),
@@ -2268,7 +2275,7 @@ export const ExtHostContext = {
ExtHostLanguageFeatures: createExtId<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures'),
ExtHostQuickOpen: createExtId<ExtHostQuickOpenShape>('ExtHostQuickOpen'),
ExtHostExtensionService: createExtId<ExtHostExtensionServiceShape>('ExtHostExtensionService'),
ExtHostLogService: createExtId<ExtHostLogServiceShape>('ExtHostLogService'),
ExtHostLogLevelServiceShape: createExtId<ExtHostLogLevelServiceShape>('ExtHostLogLevelServiceShape'),
ExtHostTerminalService: createExtId<ExtHostTerminalServiceShape>('ExtHostTerminalService'),
ExtHostSCM: createExtId<ExtHostSCMShape>('ExtHostSCM'),
ExtHostSearch: createExtId<ExtHostSearchShape>('ExtHostSearch'),

View File

@@ -253,7 +253,7 @@ export class ExtHostCustomEditors implements extHostProtocol.ExtHostCustomEditor
viewType: string,
initData: {
title: string;
webviewOptions: extHostProtocol.IWebviewOptions;
webviewOptions: extHostProtocol.IWebviewContentOptions;
panelOptions: extHostProtocol.IWebviewPanelOptions;
},
position: EditorGroupColumn,

View File

@@ -17,7 +17,7 @@ import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/co
import { ActivatedExtension, EmptyExtension, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { MissingExtensionDependency, checkProposedApiEnabled, ActivationKind } from 'vs/workbench/services/extensions/common/extensions';
import { MissingExtensionDependency, ActivationKind, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import * as errors from 'vs/base/common/errors';
import type * as vscode from 'vscode';
@@ -447,7 +447,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
return extension;
},
get extensionRuntime() {
checkProposedApiEnabled(extensionDescription);
checkProposedApiEnabled(extensionDescription, 'extensionRuntime');
return that.extensionRuntime;
},
get environmentVariableCollection() { return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription); }
@@ -698,7 +698,8 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
};
const options: ResolvedOptions = {
extensionHostEnv: result.extensionHostEnv,
isTrusted: result.isTrusted
isTrusted: result.isTrusted,
authenticationSession: result.authenticationSession ? { id: result.authenticationSession.id, providerId: result.authenticationSession.providerId } : undefined
};
return {

View File

@@ -15,7 +15,8 @@ import { State, StateMachine, LinkComputer, Edge } from 'vs/editor/common/modes/
import { commonPrefixLength } from 'vs/base/common/strings';
import { CharCode } from 'vs/base/common/charCode';
import { VSBuffer } from 'vs/base/common/buffer';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
class FsLinkProvider {
@@ -133,7 +134,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
}
}
registerFileSystemProvider(extension: ExtensionIdentifier, scheme: string, provider: vscode.FileSystemProvider, options: { isCaseSensitive?: boolean, isReadonly?: boolean } = {}) {
registerFileSystemProvider(extension: IExtensionDescription, scheme: string, provider: vscode.FileSystemProvider, options: { isCaseSensitive?: boolean, isReadonly?: boolean } = {}) {
if (this._registeredSchemes.has(scheme)) {
throw new Error(`a provider for the scheme '${scheme}' is already registered`);
@@ -160,11 +161,12 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
if (typeof provider.open === 'function' && typeof provider.close === 'function'
&& typeof provider.read === 'function' && typeof provider.write === 'function'
) {
checkProposedApiEnabled(extension, 'fsChunks');
capabilities += files.FileSystemProviderCapabilities.FileOpenReadWriteClose;
}
this._proxy.$registerFileSystemProvider(handle, scheme, capabilities).catch(err => {
console.error(`FAILED to register filesystem provider of ${extension.value}-extension for the scheme ${scheme}`);
console.error(`FAILED to register filesystem provider of ${extension.identifier.value}-extension for the scheme ${scheme}`);
console.error(err);
});

View File

@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ILoggerService, LogService } from 'vs/platform/log/common/log';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
export class ExtHostLogService extends LogService {
declare readonly _serviceBrand: undefined;
constructor(
@ILoggerService loggerService: ILoggerService,
@IExtHostInitDataService initData: IExtHostInitDataService,
) {
super(loggerService.createLogger(initData.logFile, { name: ExtensionHostLogFileName }));
}
}

View File

@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ILogger, ILoggerOptions, AbstractMessageLogger, LogLevel, AbstractLoggerService } from 'vs/platform/log/common/log';
import { MainThreadLoggerShape, MainContext, ExtHostLogLevelServiceShape as ExtHostLogLevelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { URI } from 'vs/base/common/uri';
import { Emitter } from 'vs/base/common/event';
export class ExtHostLoggerService extends AbstractLoggerService implements ExtHostLogLevelServiceShape {
declare readonly _serviceBrand: undefined;
private readonly _onDidChangeLogLevel: Emitter<LogLevel>;
private readonly _proxy: MainThreadLoggerShape;
constructor(
@IExtHostRpcService rpc: IExtHostRpcService,
@IExtHostInitDataService initData: IExtHostInitDataService,
) {
const emitter = new Emitter<LogLevel>();
super(initData.logLevel, emitter.event);
this._proxy = rpc.getProxy(MainContext.MainThreadLogger);
this._onDidChangeLogLevel = this._register(emitter);
}
$setLevel(level: LogLevel): void {
this._onDidChangeLogLevel.fire(level);
}
protected doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger {
return new Logger(this._proxy, resource, logLevel, options);
}
}
class Logger extends AbstractMessageLogger {
private isLoggerCreated: boolean = false;
private buffer: [LogLevel, string][] = [];
constructor(
private readonly proxy: MainThreadLoggerShape,
private readonly file: URI,
logLevel: LogLevel,
loggerOptions?: ILoggerOptions,
) {
super(loggerOptions?.always);
this.setLevel(logLevel);
this.proxy.$createLogger(file, loggerOptions)
.then(() => {
this.doLog(this.buffer);
this.isLoggerCreated = true;
});
}
protected log(level: LogLevel, message: string) {
const messages: [LogLevel, string][] = [[level, message]];
if (this.isLoggerCreated) {
this.doLog(messages);
} else {
this.buffer.push(...messages);
}
}
private doLog(messages: [LogLevel, string][]) {
this.proxy.$log(this.file, messages);
}
}

View File

@@ -44,7 +44,7 @@ export class ExtHostMessageService {
}
if (options.useCustom) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'resolvers');
}
const commands: { title: string; isCloseAffordance: boolean; handle: number; }[] = [];

View File

@@ -167,11 +167,11 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
_update();
},
get kind() {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookControllerKind');
return data.kind ?? '';
},
set kind(value) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookControllerKind');
data.kind = value;
_update();
},
@@ -234,11 +234,11 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
// --- ipc
onDidReceiveMessage: onDidReceiveMessage.event,
postMessage(message, editor) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookMessaging');
return that._proxy.$postMessage(handle, editor && that._extHostNotebook.getIdByEditor(editor), message);
},
asWebviewUri(uri: URI) {
checkProposedApiEnabled(extension);
checkProposedApiEnabled(extension, 'notebookMessaging');
return asWebviewUri(uri, that._initData.remote);
},
};

View File

@@ -4,10 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter } from 'vs/base/common/event';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostNotebookRenderersShape, IMainContext, MainContext, MainThreadNotebookRenderersShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
import { ExtHostNotebookEditor } from 'vs/workbench/api/common/extHostNotebookEditor';
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import * as vscode from 'vscode';
@@ -24,14 +25,14 @@ export class ExtHostNotebookRenderers implements ExtHostNotebookRenderersShape {
this._rendererMessageEmitters.get(rendererId)?.fire({ editor: editor.apiEditor, message });
}
public createRendererMessaging(manifest: IExtensionManifest, rendererId: string): vscode.NotebookRendererMessaging {
public createRendererMessaging(manifest: IExtensionDescription, rendererId: string): vscode.NotebookRendererMessaging {
if (!manifest.contributes?.notebookRenderer?.some(r => r.id === rendererId)) {
throw new Error(`Extensions may only call createRendererMessaging() for renderers they contribute (got ${rendererId})`);
}
// In the stable API, the editor is given as an empty object, and this map
// is used to maintain references. This can be removed after editor finalization.
const notebookEditorVisible = !!manifest.enableProposedApi;
const notebookEditorVisible = isProposedApiEnabled(manifest, 'notebookEditor');
const notebookEditorAliases = new WeakMap<{}, vscode.NotebookEditor>();
const messaging: vscode.NotebookRendererMessaging = {

View File

@@ -7,150 +7,114 @@ import { MainContext, MainThreadOutputServiceShape, ExtHostOutputServiceShape }
import type * as vscode from 'vscode';
import { URI } from 'vs/base/common/uri';
import { Disposable } from 'vs/base/common/lifecycle';
import { VSBuffer } from 'vs/base/common/buffer';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ILogger, ILoggerService } from 'vs/platform/log/common/log';
import { OutputChannelUpdateMode } from 'vs/workbench/contrib/output/common/output';
import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo';
import { toLocalISOString } from 'vs/base/common/date';
import { VSBuffer } from 'vs/base/common/buffer';
export abstract class AbstractExtHostOutputChannel extends Disposable implements vscode.OutputChannel {
readonly _id: Promise<string>;
private readonly _name: string;
protected readonly _proxy: MainThreadOutputServiceShape;
private _disposed: boolean;
private _offset: number;
private readonly _extension: IExtensionDescription;
export class ExtHostOutputChannel extends Disposable implements vscode.OutputChannel {
private offset: number = 0;
public visible: boolean = false;
constructor(name: string, log: boolean, file: URI | undefined, extension: IExtensionDescription, proxy: MainThreadOutputServiceShape) {
private _disposed: boolean = false;
get disposed(): boolean { return this._disposed; }
constructor(
readonly id: string, readonly name: string,
private readonly logger: ILogger,
private readonly proxy: MainThreadOutputServiceShape
) {
super();
this._name = name;
this._proxy = proxy;
this._id = proxy.$register(this.name, log, file, extension.identifier.value);
this._disposed = false;
this._offset = 0;
this._extension = extension;
}
get name(): string {
return this._name;
}
append(value: string): void {
this.validate();
this.incrementOffset(value);
}
appendLine(value: string): void {
this.validate();
this.append(value + '\n');
}
clear(): void {
this.validate();
const till = this._offset;
this._id.then(id => this._proxy.$clear(id, till));
append(value: string): void {
this.write(value);
if (this.visible) {
this.logger.flush();
this.proxy.$update(this.id, OutputChannelUpdateMode.Append);
}
}
replaceAll(value: string, donotSendValue?: boolean): void {
this.validate(true);
const till = this._offset;
this.incrementOffset(value);
this._id.then(id => this._proxy.$replaceAll(id, till, donotSendValue ? undefined : value));
clear(): void {
const till = this.offset;
this.logger.flush();
this.proxy.$update(this.id, OutputChannelUpdateMode.Clear, till);
}
replace(value: string): void {
const till = this.offset;
this.write(value);
this.proxy.$update(this.id, OutputChannelUpdateMode.Replace, till);
if (this.visible) {
this.logger.flush();
}
}
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
this.validate();
this._id.then(id => this._proxy.$reveal(id, !!(typeof columnOrPreserveFocus === 'boolean' ? columnOrPreserveFocus : preserveFocus)));
this.logger.flush();
this.proxy.$reveal(this.id, !!(typeof columnOrPreserveFocus === 'boolean' ? columnOrPreserveFocus : preserveFocus));
}
hide(): void {
this.validate();
this._id.then(id => this._proxy.$close(id));
this.proxy.$close(this.id);
}
protected validate(checkProposedApi?: boolean): void {
if (checkProposedApi) {
checkProposedApiEnabled(this._extension);
}
if (this._disposed) {
throw new Error('Channel has been closed');
}
}
private incrementOffset(value: string) {
this._offset += value ? VSBuffer.fromString(value).byteLength : 0;
private write(value: string): void {
this.offset += VSBuffer.fromString(value).byteLength;
this.logger.info(value);
}
override dispose(): void {
super.dispose();
if (!this._disposed) {
this._id
.then(id => this._proxy.$dispose(id))
.then(() => this._disposed = true);
this.proxy.$dispose(this.id);
this._disposed = true;
}
}
}
export class ExtHostPushOutputChannel extends AbstractExtHostOutputChannel {
constructor(name: string, extension: IExtensionDescription, proxy: MainThreadOutputServiceShape) {
super(name, false, undefined, extension, proxy);
}
override append(value: string): void {
super.append(value);
this._id.then(id => this._proxy.$append(id, value));
}
}
export class LazyOutputChannel implements vscode.OutputChannel {
constructor(
readonly name: string,
private readonly _channel: Promise<AbstractExtHostOutputChannel>
) { }
append(value: string): void {
this._channel.then(channel => channel.append(value));
}
appendLine(value: string): void {
this._channel.then(channel => channel.appendLine(value));
}
clear(): void {
this._channel.then(channel => channel.clear());
}
replaceAll(value: string): void {
this._channel.then(channel => channel.replaceAll(value));
}
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
this._channel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus));
}
hide(): void {
this._channel.then(channel => channel.hide());
}
dispose(): void {
this._channel.then(channel => channel.dispose());
}
}
export class ExtHostOutputService implements ExtHostOutputServiceShape {
readonly _serviceBrand: undefined;
protected readonly _proxy: MainThreadOutputServiceShape;
private readonly proxy: MainThreadOutputServiceShape;
constructor(@IExtHostRpcService extHostRpc: IExtHostRpcService) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadOutputService);
private readonly outputsLocation: URI;
private outputDirectoryPromise: Thenable<URI> | undefined;
private namePool: number = 1;
private readonly channels: Map<string, ExtHostOutputChannel> = new Map<string, ExtHostOutputChannel>();
private visibleChannelId: string | null = null;
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@IExtHostConsumerFileSystem private readonly extHostFileSystem: IExtHostConsumerFileSystem,
@IExtHostFileSystemInfo private readonly extHostFileSystemInfo: IExtHostFileSystemInfo,
@ILoggerService private readonly loggerService: ILoggerService,
) {
this.proxy = extHostRpc.getProxy(MainContext.MainThreadOutputService);
this.outputsLocation = this.extHostFileSystemInfo.extUri.joinPath(initData.logsLocation, `output_logging_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`);
}
$setVisibleChannel(channelId: string): void {
$setVisibleChannel(visibleChannelId: string | null): void {
this.visibleChannelId = visibleChannelId;
for (const [id, channel] of this.channels) {
channel.visible = id === this.visibleChannelId;
}
}
createOutputChannel(name: string, extension: IExtensionDescription): vscode.OutputChannel {
@@ -158,9 +122,68 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
if (!name) {
throw new Error('illegal argument `name`. must not be falsy');
}
return new ExtHostPushOutputChannel(name, extension, this._proxy);
const extHostOutputChannel = this.doCreateOutputChannel(name, extension);
extHostOutputChannel.then(channel => {
this.channels.set(channel.id, channel);
channel.visible = channel.id === this.visibleChannelId;
});
return this.createExtHostOutputChannel(name, extHostOutputChannel);
}
private async doCreateOutputChannel(name: string, extension: IExtensionDescription): Promise<ExtHostOutputChannel> {
const outputDir = await this.createOutputDirectory();
const file = this.extHostFileSystemInfo.extUri.joinPath(outputDir, `${this.namePool++}-${name.replace(/[\\/:\*\?"<>\|]/g, '')}.log`);
const logger = this.loggerService.createLogger(file, { always: true, donotRotate: true, donotUseFormatters: true });
const id = await this.proxy.$register(name, false, file, extension.identifier.value);
return new ExtHostOutputChannel(id, name, logger, this.proxy);
}
private createOutputDirectory(): Thenable<URI> {
if (!this.outputDirectoryPromise) {
this.outputDirectoryPromise = this.extHostFileSystem.value.createDirectory(this.outputsLocation).then(() => this.outputsLocation);
}
return this.outputDirectoryPromise;
}
private createExtHostOutputChannel(name: string, channelPromise: Promise<ExtHostOutputChannel>): vscode.OutputChannel {
let disposed = false;
const validate = () => {
if (disposed) {
throw new Error('Channel has been closed');
}
};
return {
get name(): string { return name; },
append(value: string): void {
validate();
channelPromise.then(channel => channel.append(value));
},
appendLine(value: string): void {
validate();
channelPromise.then(channel => channel.appendLine(value));
},
clear(): void {
validate();
channelPromise.then(channel => channel.clear());
},
replace(value: string): void {
validate();
channelPromise.then(channel => channel.replace(value));
},
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
validate();
channelPromise.then(channel => channel.show(columnOrPreserveFocus, preserveFocus));
},
hide(): void {
validate();
channelPromise.then(channel => channel.hide());
},
dispose(): void {
disposed = true;
channelPromise.then(channel => channel.dispose());
}
};
}
}
export interface IExtHostOutputService extends ExtHostOutputService { }

View File

@@ -9,29 +9,30 @@ import { Emitter } from 'vs/base/common/event';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { IExtHostWorkspaceProvider } from 'vs/workbench/api/common/extHostWorkspace';
import { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickItemButtonEvent, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
import { ExtHostQuickOpenShape, IMainContext, MainContext, TransferQuickPickItems, TransferQuickInput, TransferQuickInputButton } from './extHost.protocol';
import type { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickItemButtonEvent, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
import { ExtHostQuickOpenShape, IMainContext, MainContext, TransferQuickInput, TransferQuickInputButton, TransferQuickPickItemOrSeparator } from './extHost.protocol';
import { URI } from 'vs/base/common/uri';
import { ThemeIcon, QuickInputButtons } from 'vs/workbench/api/common/extHostTypes';
import { ThemeIcon, QuickInputButtons, QuickPickItemKind } from 'vs/workbench/api/common/extHostTypes';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { coalesce } from 'vs/base/common/arrays';
import Severity from 'vs/base/common/severity';
import { ThemeIcon as ThemeIconUtils } from 'vs/platform/theme/common/themeService';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
export type Item = string | QuickPickItem;
export interface ExtHostQuickOpen {
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, enableProposedApi: boolean, options: QuickPickOptions & { canPickMany: true; }, token?: CancellationToken): Promise<QuickPickItem[] | undefined>;
showQuickPick(itemsOrItemsPromise: string[] | Promise<string[]>, enableProposedApi: boolean, options?: QuickPickOptions, token?: CancellationToken): Promise<string | undefined>;
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, enableProposedApi: boolean, options?: QuickPickOptions, token?: CancellationToken): Promise<QuickPickItem | undefined>;
showQuickPick(itemsOrItemsPromise: Item[] | Promise<Item[]>, enableProposedApi: boolean, options?: QuickPickOptions, token?: CancellationToken): Promise<Item | Item[] | undefined>;
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, options: QuickPickOptions & { canPickMany: true; }, token?: CancellationToken): Promise<QuickPickItem[] | undefined>;
showQuickPick(itemsOrItemsPromise: string[] | Promise<string[]>, options?: QuickPickOptions, token?: CancellationToken): Promise<string | undefined>;
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, options?: QuickPickOptions, token?: CancellationToken): Promise<QuickPickItem | undefined>;
showQuickPick(itemsOrItemsPromise: Item[] | Promise<Item[]>, options?: QuickPickOptions, token?: CancellationToken): Promise<Item | Item[] | undefined>;
showInput(options?: InputBoxOptions, token?: CancellationToken): Promise<string | undefined>;
showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions, token?: CancellationToken): Promise<WorkspaceFolder | undefined>
createQuickPick<T extends QuickPickItem>(extensionId: ExtensionIdentifier, enableProposedApi: boolean): QuickPick<T>;
createQuickPick<T extends QuickPickItem>(extensionId: IExtensionDescription): QuickPick<T>;
createInputBox(extensionId: ExtensionIdentifier): InputBox;
}
@@ -56,10 +57,10 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
this._commands = commands;
}
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, enableProposedApi: boolean, options: QuickPickOptions & { canPickMany: true; }, token?: CancellationToken): Promise<QuickPickItem[] | undefined>;
showQuickPick(itemsOrItemsPromise: string[] | Promise<string[]>, enableProposedApi: boolean, options?: QuickPickOptions, token?: CancellationToken): Promise<string | undefined>;
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, enableProposedApi: boolean, options?: QuickPickOptions, token?: CancellationToken): Promise<QuickPickItem | undefined>;
showQuickPick(itemsOrItemsPromise: Item[] | Promise<Item[]>, enableProposedApi: boolean, options?: QuickPickOptions, token: CancellationToken = CancellationToken.None): Promise<Item | Item[] | undefined> {
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, options: QuickPickOptions & { canPickMany: true; }, token?: CancellationToken): Promise<QuickPickItem[] | undefined>;
showQuickPick(itemsOrItemsPromise: string[] | Promise<string[]>, options?: QuickPickOptions, token?: CancellationToken): Promise<string | undefined>;
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Promise<QuickPickItem[]>, options?: QuickPickOptions, token?: CancellationToken): Promise<QuickPickItem | undefined>;
showQuickPick(itemsOrItemsPromise: Item[] | Promise<Item[]>, options?: QuickPickOptions, token: CancellationToken = CancellationToken.None): Promise<Item | Item[] | undefined> {
// clear state from last invocation
this._onDidSelectItem = undefined;
@@ -87,33 +88,23 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
return itemsPromise.then(items => {
const pickItems: TransferQuickPickItems[] = [];
const pickItems: TransferQuickPickItemOrSeparator[] = [];
for (let handle = 0; handle < items.length; handle++) {
const item = items[handle];
let label: string;
let description: string | undefined;
let detail: string | undefined;
let picked: boolean | undefined;
let alwaysShow: boolean | undefined;
if (typeof item === 'string') {
label = item;
pickItems.push({ label: item, handle });
} else if (item.kind === QuickPickItemKind.Separator) {
pickItems.push({ type: 'separator', label: item.label });
} else {
label = item.label;
description = item.description;
detail = item.detail;
picked = item.picked;
alwaysShow = item.alwaysShow;
pickItems.push({
label: item.label,
description: item.description,
detail: item.detail,
picked: item.picked,
alwaysShow: item.alwaysShow,
handle
});
}
pickItems.push({
label,
description,
handle,
detail,
picked,
alwaysShow
});
}
// handle selection changes
@@ -192,8 +183,8 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
// ---- QuickInput
createQuickPick<T extends QuickPickItem>(extensionId: ExtensionIdentifier, enableProposedApi: boolean): QuickPick<T> {
const session: ExtHostQuickPick<T> = new ExtHostQuickPick(extensionId, enableProposedApi, () => this._sessions.delete(session._id));
createQuickPick<T extends QuickPickItem>(extension: IExtensionDescription): QuickPick<T> {
const session: ExtHostQuickPick<T> = new ExtHostQuickPick(extension, () => this._sessions.delete(session._id));
this._sessions.set(session._id, session);
return session;
}
@@ -531,8 +522,9 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
private readonly _onDidChangeSelectionEmitter = new Emitter<T[]>();
private readonly _onDidTriggerItemButtonEmitter = new Emitter<QuickPickItemButtonEvent<T>>();
constructor(extensionId: ExtensionIdentifier, private readonly enableProposedApi: boolean, onDispose: () => void) {
super(extensionId, onDispose);
// TODO: revert this change once quickPickSeparators has been finalized.
constructor(private readonly extension: IExtensionDescription, onDispose: () => void) {
super(extension.identifier, onDispose);
this._disposables.push(
this._onDidChangeActiveEmitter,
this._onDidChangeSelectionEmitter,
@@ -546,6 +538,10 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
}
set items(items: T[]) {
if (items.some((item) => item.kind !== undefined)) {
checkProposedApiEnabled(this.extension, 'quickPickSeparators');
}
this._items = items.slice();
this._handlesToItems.clear();
this._itemsToHandles.clear();
@@ -553,25 +549,33 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
this._handlesToItems.set(i, item);
this._itemsToHandles.set(item, i);
});
this.update({
items: items.map((item, i) => ({
label: item.label,
description: item.description,
handle: i,
detail: item.detail,
picked: item.picked,
alwaysShow: item.alwaysShow,
// Proposed API only at the moment
buttons: item.buttons && this.enableProposedApi
? item.buttons.map<TransferQuickInputButton>((button, i) => {
const pickItems: TransferQuickPickItemOrSeparator[] = [];
for (let handle = 0; handle < items.length; handle++) {
const item = items[handle];
if (item.kind === QuickPickItemKind.Separator) {
pickItems.push({ type: 'separator', label: item.label });
} else {
pickItems.push({
handle,
label: item.label,
description: item.description,
detail: item.detail,
picked: item.picked,
alwaysShow: item.alwaysShow,
buttons: item.buttons?.map<TransferQuickInputButton>((button, i) => {
return {
...getIconPathOrClass(button),
tooltip: button.tooltip,
handle: i
};
})
: undefined,
}))
}),
});
}
}
this.update({
items: pickItems,
});
}

View File

@@ -17,11 +17,11 @@ import { ISplice } from 'vs/base/common/sequence';
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 { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { MarshalledId } from 'vs/base/common/marshalling';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { MarkdownString } from 'vs/workbench/api/common/extHostTypeConverters';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
type ProviderHandle = number;
type GroupHandle = number;
@@ -230,13 +230,13 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
private _validateInput: IValidateInput | undefined;
get validateInput(): IValidateInput | undefined {
checkProposedApiEnabled(this._extension);
checkProposedApiEnabled(this._extension, 'scmValidation');
return this._validateInput;
}
set validateInput(fn: IValidateInput | undefined) {
checkProposedApiEnabled(this._extension);
checkProposedApiEnabled(this._extension, 'scmValidation');
if (fn && typeof fn !== 'function') {
throw new Error(`[${this._extension.identifier.value}]: Invalid SCM input box validation function`);
@@ -267,18 +267,8 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
// noop
}
focus(): void {
checkProposedApiEnabled(this._extension);
if (!this._visible) {
this.visible = true;
}
this._proxy.$setInputBoxFocus(this._sourceControlHandle);
}
showValidationMessage(message: string | vscode.MarkdownString, type: vscode.SourceControlInputBoxValidationType) {
checkProposedApiEnabled(this._extension);
checkProposedApiEnabled(this._extension, 'scmValidation');
this._proxy.$showValidationMessage(this._sourceControlHandle, message, type as any);
}
@@ -512,11 +502,11 @@ class ExtHostSourceControl implements vscode.SourceControl {
private _actionButtonDisposables = new MutableDisposable<DisposableStore>();
private _actionButton: vscode.Command | undefined;
get actionButton(): vscode.Command | undefined {
checkProposedApiEnabled(this._extension);
checkProposedApiEnabled(this._extension, 'scmActionButton');
return this._actionButton;
}
set actionButton(actionButton: vscode.Command | undefined) {
checkProposedApiEnabled(this._extension);
checkProposedApiEnabled(this._extension, 'scmActionButton');
this._actionButtonDisposables.value = new DisposableStore();
this._actionButton = actionButton;

View File

@@ -275,15 +275,11 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
}
input(data: string): void {
if (this._pty.handleInput) {
this._pty.handleInput(data);
}
this._pty.handleInput?.(data);
}
resize(cols: number, rows: number): void {
if (this._pty.setDimensions) {
this._pty.setDimensions({ columns: cols, rows });
}
this._pty.setDimensions?.({ columns: cols, rows });
}
async processBinary(data: string): Promise<void> {
@@ -314,28 +310,22 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void {
// Attach the listeners
this._pty.onDidWrite(e => this._onProcessData.fire(e));
if (this._pty.onDidClose) {
this._pty.onDidClose((e: number | void = undefined) => {
this._onProcessExit.fire(e === void 0 ? undefined : e);
});
}
if (this._pty.onDidOverrideDimensions) {
this._pty.onDidOverrideDimensions(e => {
if (e) {
this._onDidChangeProperty.fire({ type: ProcessPropertyType.OverrideDimensions, value: { cols: e.columns, rows: e.rows } });
}
});
}
if (this._pty.onDidChangeName) {
this._pty.onDidChangeName(title => {
this._onDidChangeProperty.fire({ type: ProcessPropertyType.Title, value: title });
});
}
this._pty.onDidClose?.((e: number | void = undefined) => {
this._onProcessExit.fire(e === void 0 ? undefined : e);
});
this._pty.onDidOverrideDimensions?.(e => {
if (e) {
this._onDidChangeProperty.fire({ type: ProcessPropertyType.OverrideDimensions, value: { cols: e.columns, rows: e.rows } });
}
});
this._pty.onDidChangeName?.(title => {
this._onDidChangeProperty.fire({ type: ProcessPropertyType.Title, value: title });
});
this._pty.open(initialDimensions ? initialDimensions : undefined);
if (this._pty.setDimensions && initialDimensions) {
this._pty.setDimensions(initialDimensions);
if (initialDimensions) {
this._pty.setDimensions?.(initialDimensions);
}
this._onProcessReady.fire({ pid: -1, cwd: '', capabilities: this._capabilities });
@@ -586,7 +576,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
protected _setupExtHostProcessListeners(id: number, p: ITerminalChildProcess): IDisposable {
const disposables = new DisposableStore();
disposables.add(p.onProcessReady((e: { pid: number, cwd: string }) => this._proxy.$sendProcessReady(id, e.pid, e.cwd)));
disposables.add(p.onProcessReady(e => this._proxy.$sendProcessReady(id, e.pid, e.cwd)));
disposables.add(p.onDidChangeProperty(property => this._proxy.$sendProcessProperty(id, property)));
// Buffer data events to reduce the amount of messages going to the renderer

View File

@@ -1776,7 +1776,7 @@ export enum TaskPanelKind {
@es5ClassCompat
export class TaskGroup implements vscode.TaskGroup {
isDefault?: boolean;
isDefault: boolean | undefined;
private _id: string;
public static Clean: TaskGroup = new TaskGroup('clean', 'Clean');
@@ -2904,6 +2904,11 @@ export class QuickInputButtons {
private constructor() { }
}
export enum QuickPickItemKind {
Default = 1,
Separator = 2,
}
export enum ExtensionKind {
UI = 1,
Workspace = 2

View File

@@ -176,7 +176,7 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
this._logService.warn(`${extensionId} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
}
public createNewWebview(handle: string, options: extHostProtocol.IWebviewOptions, extension: IExtensionDescription): ExtHostWebview {
public createNewWebview(handle: string, options: extHostProtocol.IWebviewContentOptions, extension: IExtensionDescription): ExtHostWebview {
const webview = new ExtHostWebview(handle, this._webviewProxy, reviveOptions(options), this.initData, this.workspace, extension, this._deprecationService);
this._webviews.set(handle, webview);
@@ -202,7 +202,7 @@ export function serializeWebviewOptions(
extension: IExtensionDescription,
workspace: IExtHostWorkspace | undefined,
options: vscode.WebviewOptions,
): extHostProtocol.IWebviewOptions {
): extHostProtocol.IWebviewContentOptions {
return {
enableCommandUris: options.enableCommandUris,
enableScripts: options.enableScripts,
@@ -212,7 +212,7 @@ export function serializeWebviewOptions(
};
}
export function reviveOptions(options: extHostProtocol.IWebviewOptions): vscode.WebviewOptions {
export function reviveOptions(options: extHostProtocol.IWebviewContentOptions): vscode.WebviewOptions {
return {
enableCommandUris: options.enableCommandUris,
enableScripts: options.enableScripts,

View File

@@ -281,7 +281,7 @@ export class ExtHostWebviewPanels implements extHostProtocol.ExtHostWebviewPanel
initData: {
title: string;
state: any;
webviewOptions: extHostProtocol.IWebviewOptions;
webviewOptions: extHostProtocol.IWebviewContentOptions;
panelOptions: extHostProtocol.IWebviewPanelOptions;
},
position: EditorGroupColumn

View File

@@ -16,14 +16,15 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { Iterable } from 'vs/base/common/iterator';
import { index } from 'vs/base/common/arrays';
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ApiProposalName } from 'vs/workbench/services/extensions/common/extensionsApiProposals';
interface IAPIMenu {
readonly key: string;
readonly id: MenuId;
readonly description: string;
readonly proposed?: boolean; // defaults to false
readonly proposed?: ApiProposalName;
readonly supportsSubmenus?: boolean; // defaults to true
readonly deprecationMessage?: string;
}
const apiMenus: IAPIMenu[] = [
@@ -84,17 +85,11 @@ const apiMenus: IAPIMenu[] = [
id: MenuId.DebugToolBar,
description: localize('menus.debugToolBar', "The debug toolbar menu")
},
{
key: 'menuBar/file',
id: MenuId.MenubarFileMenu,
description: localize('menus.file', "The top level file menu"),
proposed: true
},
{
key: 'menuBar/home',
id: MenuId.MenubarHomeMenu,
description: localize('menus.home', "The home indicator context menu (web only)"),
proposed: true,
proposed: 'contribMenuBarHome',
supportsSubmenus: false
},
{
@@ -132,14 +127,6 @@ const apiMenus: IAPIMenu[] = [
id: MenuId.SCMChangeContext,
description: localize('menus.changeTitle', "The Source Control inline change menu")
},
{
key: 'statusBar/windowIndicator',
id: MenuId.StatusBarWindowIndicatorMenu,
description: localize('menus.statusBarWindowIndicator', "The window indicator menu in the status bar"),
proposed: true,
supportsSubmenus: false,
deprecationMessage: localize('menus.statusBarWindowIndicator.deprecated', "Use menu 'statusBar/remoteIndicator' instead."),
},
{
key: 'statusBar/remoteIndicator',
id: MenuId.StatusBarRemoteIndicatorMenu,
@@ -197,19 +184,19 @@ const apiMenus: IAPIMenu[] = [
key: 'notebook/cell/executePrimary',
id: MenuId.NotebookCellExecutePrimary,
description: localize('notebook.cell.executePrimary', "The contributed primary notebook cell execution button"),
proposed: true
proposed: 'notebookEditor'
},
{
key: 'interactive/toolbar',
id: MenuId.InteractiveToolbar,
description: localize('interactive.toolbar', "The contributed interactive toolbar menu"),
proposed: true
proposed: 'notebookEditor'
},
{
key: 'interactive/cell/title',
id: MenuId.InteractiveCellTitle,
description: localize('interactive.cell.title', "The contributed interactive cell title menu"),
proposed: true
proposed: 'notebookEditor'
},
{
key: 'testing/item/context',
@@ -262,7 +249,7 @@ const apiMenus: IAPIMenu[] = [
id: MenuId.InlineCompletionsActions,
description: localize('inlineCompletions.actions', "The actions shown when hovering on an inline completion"),
supportsSubmenus: false,
proposed: true
proposed: 'inlineCompletions'
},
];
@@ -450,8 +437,7 @@ namespace schema {
description: localize('vscode.extension.contributes.menus', "Contributes menu items to the editor"),
type: 'object',
properties: index(apiMenus, menu => menu.key, menu => ({
description: menu.proposed ? `(${localize('proposed', "Proposed API")}) ${menu.description}` : menu.description,
deprecationMessage: menu.deprecationMessage,
markdownDescription: menu.proposed ? localize('proposed', "Proposed API, requires `enabledApiProposal: [\"{0}\"]` - {1}", menu.proposed, menu.description) : menu.description,
type: 'array',
items: menu.supportsSubmenus === false ? menuItem : { oneOf: [menuItem, submenuItem] }
})),
@@ -633,7 +619,7 @@ commandsExtensionPoint.setHandler(extensions => {
title,
source: extension.description.displayName ?? extension.description.name,
shortTitle,
tooltip: extension.description.enableProposedApi ? title : undefined,
tooltip: title,
category,
precondition: ContextKeyExpr.deserialize(enablement),
icon: absoluteIcon
@@ -763,8 +749,8 @@ menusExtensionPoint.setHandler(extensions => {
return;
}
if (menu.proposed && !extension.description.enableProposedApi) {
collector.error(localize('proposedAPI.invalid', "{0} is a proposed menu identifier and is only available when running out of dev or with the following command line switch: --enable-proposed-api {1}", entry.key, extension.description.identifier.value));
if (menu.proposed && !isProposedApiEnabled(extension.description, menu.proposed)) {
collector.error(localize('proposedAPI.invalid', "{0} is a proposed menu identifier. It requires 'package.json#enabledApiProposals: [\"{1}\"]' and is only available when running out of dev or with the following command line switch: --enable-proposed-api {2}", entry.key, menu.proposed, extension.description.identifier.value));
return;
}