mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-29 13:03:42 +01:00
Merge branch 'master' into pty_bug
This commit is contained in:
@@ -446,7 +446,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
|
||||
|
||||
private registerPanel(commentsPanelAlreadyConstructed: boolean) {
|
||||
if (!commentsPanelAlreadyConstructed) {
|
||||
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(new PanelDescriptor(
|
||||
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(PanelDescriptor.create(
|
||||
CommentsPanel,
|
||||
COMMENTS_PANEL_ID,
|
||||
COMMENTS_PANEL_TITLE,
|
||||
|
||||
@@ -33,11 +33,11 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
|
||||
|
||||
private static _convertOpenOptions(options: MainThreadDialogOpenOptions): IOpenDialogOptions {
|
||||
const result: IOpenDialogOptions = {
|
||||
openLabel: options.openLabel,
|
||||
openLabel: options.openLabel || undefined,
|
||||
canSelectFiles: options.canSelectFiles || (!options.canSelectFiles && !options.canSelectFolders),
|
||||
canSelectFolders: options.canSelectFolders,
|
||||
canSelectMany: options.canSelectMany,
|
||||
defaultUri: URI.revive(options.defaultUri)
|
||||
defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined
|
||||
};
|
||||
if (options.filters) {
|
||||
result.filters = [];
|
||||
@@ -48,8 +48,8 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
|
||||
|
||||
private static _convertSaveOptions(options: MainThreadDialogSaveOptions): ISaveDialogOptions {
|
||||
const result: ISaveDialogOptions = {
|
||||
defaultUri: URI.revive(options.defaultUri),
|
||||
saveLabel: options.saveLabel
|
||||
defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined,
|
||||
saveLabel: options.saveLabel || undefined
|
||||
};
|
||||
if (options.filters) {
|
||||
result.filters = [];
|
||||
|
||||
@@ -16,7 +16,7 @@ import { MainThreadDocumentsAndEditors } from 'vs/workbench/api/browser/mainThre
|
||||
import { ExtHostContext, ExtHostDocumentsShape, IExtHostContext, MainThreadDocumentsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ITextEditorModel } from 'vs/workbench/common/editor';
|
||||
import { ITextFileService, TextFileModelChangeEvent } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { toLocalResource } from 'vs/base/common/resources';
|
||||
|
||||
@@ -70,7 +70,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
|
||||
private readonly _textModelResolverService: ITextModelService;
|
||||
private readonly _textFileService: ITextFileService;
|
||||
private readonly _fileService: IFileService;
|
||||
private readonly _untitledEditorService: IUntitledEditorService;
|
||||
private readonly _untitledTextEditorService: IUntitledTextEditorService;
|
||||
private readonly _environmentService: IWorkbenchEnvironmentService;
|
||||
|
||||
private readonly _toDispose = new DisposableStore();
|
||||
@@ -87,14 +87,14 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
|
||||
@ITextFileService textFileService: ITextFileService,
|
||||
@IFileService fileService: IFileService,
|
||||
@ITextModelService textModelResolverService: ITextModelService,
|
||||
@IUntitledEditorService untitledEditorService: IUntitledEditorService,
|
||||
@IUntitledTextEditorService untitledTextEditorService: IUntitledTextEditorService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
this._modelService = modelService;
|
||||
this._textModelResolverService = textModelResolverService;
|
||||
this._textFileService = textFileService;
|
||||
this._fileService = fileService;
|
||||
this._untitledEditorService = untitledEditorService;
|
||||
this._untitledTextEditorService = untitledTextEditorService;
|
||||
this._environmentService = environmentService;
|
||||
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocuments);
|
||||
@@ -227,13 +227,13 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
|
||||
}
|
||||
|
||||
private _doCreateUntitled(resource?: URI, mode?: string, initialValue?: string): Promise<URI> {
|
||||
return this._untitledEditorService.loadOrCreate({
|
||||
return this._untitledTextEditorService.loadOrCreate({
|
||||
resource,
|
||||
mode,
|
||||
initialValue,
|
||||
useResourcePath: Boolean(resource && resource.path)
|
||||
}).then(model => {
|
||||
const resource = model.getResource();
|
||||
const resource = model.resource;
|
||||
|
||||
if (!this._modelIsSynced.has(resource.toString())) {
|
||||
throw new Error(`expected URI ${resource.toString()} to have come to LIFE`);
|
||||
|
||||
@@ -28,7 +28,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
namespace delta {
|
||||
@@ -327,7 +327,7 @@ export class MainThreadDocumentsAndEditors {
|
||||
@IModeService modeService: IModeService,
|
||||
@IFileService fileService: IFileService,
|
||||
@ITextModelService textModelResolverService: ITextModelService,
|
||||
@IUntitledEditorService untitledEditorService: IUntitledEditorService,
|
||||
@IUntitledTextEditorService untitledTextEditorService: IUntitledTextEditorService,
|
||||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
|
||||
@IBulkEditService bulkEditService: IBulkEditService,
|
||||
@IPanelService panelService: IPanelService,
|
||||
@@ -335,7 +335,7 @@ export class MainThreadDocumentsAndEditors {
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentsAndEditors);
|
||||
|
||||
const mainThreadDocuments = this._toDispose.add(new MainThreadDocuments(this, extHostContext, this._modelService, modeService, this._textFileService, fileService, textModelResolverService, untitledEditorService, environmentService));
|
||||
const mainThreadDocuments = this._toDispose.add(new MainThreadDocuments(this, extHostContext, this._modelService, modeService, this._textFileService, fileService, textModelResolverService, untitledTextEditorService, environmentService));
|
||||
extHostContext.set(MainContext.MainThreadDocuments, mainThreadDocuments);
|
||||
|
||||
const mainThreadTextEditors = this._toDispose.add(new MainThreadTextEditors(this, extHostContext, codeEditorService, bulkEditService, this._editorService, this._editorGroupService));
|
||||
|
||||
@@ -52,10 +52,10 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
|
||||
$stat(uri: UriComponents): Promise<IStat> {
|
||||
return this._fileService.resolve(URI.revive(uri), { resolveMetadata: true }).then(stat => {
|
||||
return {
|
||||
ctime: 0,
|
||||
ctime: stat.ctime,
|
||||
mtime: stat.mtime,
|
||||
size: stat.size,
|
||||
type: MainThreadFileSystem._getFileType(stat)
|
||||
type: MainThreadFileSystem._asFileType(stat)
|
||||
};
|
||||
}).catch(MainThreadFileSystem._handleError);
|
||||
}
|
||||
@@ -67,12 +67,22 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
|
||||
err.name = FileSystemProviderErrorCode.FileNotADirectory;
|
||||
throw err;
|
||||
}
|
||||
return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._getFileType(child)] as [string, FileType]);
|
||||
return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._asFileType(child)] as [string, FileType]);
|
||||
}).catch(MainThreadFileSystem._handleError);
|
||||
}
|
||||
|
||||
private static _getFileType(stat: IFileStat): FileType {
|
||||
return (stat.isDirectory ? FileType.Directory : FileType.File) + (stat.isSymbolicLink ? FileType.SymbolicLink : 0);
|
||||
private static _asFileType(stat: IFileStat): FileType {
|
||||
let res = 0;
|
||||
if (stat.isFile) {
|
||||
res += FileType.File;
|
||||
|
||||
} else if (stat.isDirectory) {
|
||||
res += FileType.Directory;
|
||||
}
|
||||
if (stat.isSymbolicLink) {
|
||||
res += FileType.SymbolicLink;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
$readFile(uri: UriComponents): Promise<VSBuffer> {
|
||||
|
||||
@@ -498,39 +498,35 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
||||
this._registrations.set(handle, callh.CallHierarchyProviderRegistry.register(selector, {
|
||||
|
||||
prepareCallHierarchy: async (document, position, token) => {
|
||||
const result = await this._proxy.$prepareCallHierarchy(handle, document.uri, position, token);
|
||||
if (!result) {
|
||||
const item = await this._proxy.$prepareCallHierarchy(handle, document.uri, position, token);
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
dispose: () => this._proxy.$releaseCallHierarchy(handle, result.sessionId),
|
||||
root: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(result.root)
|
||||
dispose: () => this._proxy.$releaseCallHierarchy(handle, item._sessionId),
|
||||
root: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item)
|
||||
};
|
||||
},
|
||||
|
||||
provideOutgoingCalls: async (item, token) => {
|
||||
const outgoing = await this._proxy.$provideCallHierarchyOutgoingCalls(handle, item.id, token);
|
||||
const outgoing = await this._proxy.$provideCallHierarchyOutgoingCalls(handle, item._sessionId, item._itemId, token);
|
||||
if (!outgoing) {
|
||||
return outgoing;
|
||||
}
|
||||
return outgoing.map(([item, fromRanges]): callh.OutgoingCall => {
|
||||
return {
|
||||
to: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item),
|
||||
fromRanges
|
||||
};
|
||||
outgoing.forEach(value => {
|
||||
value.to = MainThreadLanguageFeatures._reviveCallHierarchyItemDto(value.to);
|
||||
});
|
||||
return <any>outgoing;
|
||||
},
|
||||
provideIncomingCalls: async (item, token) => {
|
||||
const incoming = await this._proxy.$provideCallHierarchyIncomingCalls(handle, item.id, token);
|
||||
const incoming = await this._proxy.$provideCallHierarchyIncomingCalls(handle, item._sessionId, item._itemId, token);
|
||||
if (!incoming) {
|
||||
return incoming;
|
||||
}
|
||||
return incoming.map(([item, fromRanges]): callh.IncomingCall => {
|
||||
return {
|
||||
from: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item),
|
||||
fromRanges
|
||||
};
|
||||
incoming.forEach(value => {
|
||||
value.from = MainThreadLanguageFeatures._reviveCallHierarchyItemDto(value.from);
|
||||
});
|
||||
return <any>incoming;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { CodeAction } from 'vs/editor/common/modes';
|
||||
import { shouldSynchronizeModel } from 'vs/editor/common/services/modelService';
|
||||
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
|
||||
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
|
||||
import { CodeActionKind } from 'vs/editor/contrib/codeAction/types';
|
||||
import { formatDocumentWithSelectedProvider, FormattingMode } from 'vs/editor/contrib/format/format';
|
||||
import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -30,7 +30,8 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
|
||||
import { ISaveParticipant, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ISaveParticipant, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../common/extHost.protocol';
|
||||
|
||||
export interface ICodeActionsOnSaveOptions {
|
||||
@@ -51,7 +52,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
|
||||
}
|
||||
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
|
||||
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
|
||||
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
|
||||
this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO);
|
||||
}
|
||||
}
|
||||
@@ -113,7 +114,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant {
|
||||
}
|
||||
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
|
||||
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
|
||||
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
|
||||
this.doInsertFinalNewLine(model.textEditorModel);
|
||||
}
|
||||
}
|
||||
@@ -147,7 +148,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant
|
||||
}
|
||||
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
|
||||
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
|
||||
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
|
||||
this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO);
|
||||
}
|
||||
}
|
||||
@@ -257,7 +258,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
|
||||
|
||||
const model = editorModel.textEditorModel;
|
||||
|
||||
const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() };
|
||||
const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.resource };
|
||||
const setting = this._configurationService.getValue<ICodeActionsOnSaveOptions>('editor.codeActionsOnSave', settingsOverrides);
|
||||
if (!setting) {
|
||||
return undefined;
|
||||
@@ -282,6 +283,10 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const excludedActions = Object.keys(setting)
|
||||
.filter(x => setting[x] === false)
|
||||
.map(x => new CodeActionKind(x));
|
||||
|
||||
const tokenSource = new CancellationTokenSource();
|
||||
|
||||
const timeout = this._configurationService.getValue<number>('editor.codeActionsOnSaveTimeout', settingsOverrides);
|
||||
@@ -292,15 +297,15 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
|
||||
tokenSource.cancel();
|
||||
reject(localize('codeActionsOnSave.didTimeout', "Aborted codeActionsOnSave after {0}ms", timeout));
|
||||
}, timeout)),
|
||||
this.applyOnSaveActions(model, codeActionsOnSave, tokenSource.token)
|
||||
this.applyOnSaveActions(model, codeActionsOnSave, excludedActions, tokenSource.token)
|
||||
]).finally(() => {
|
||||
tokenSource.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
private async applyOnSaveActions(model: ITextModel, codeActionsOnSave: CodeActionKind[], token: CancellationToken): Promise<void> {
|
||||
private async applyOnSaveActions(model: ITextModel, codeActionsOnSave: readonly CodeActionKind[], excludes: readonly CodeActionKind[], token: CancellationToken): Promise<void> {
|
||||
for (const codeActionKind of codeActionsOnSave) {
|
||||
const actionsToRun = await this.getActionsToRun(model, codeActionKind, token);
|
||||
const actionsToRun = await this.getActionsToRun(model, codeActionKind, excludes, token);
|
||||
try {
|
||||
await this.applyCodeActions(actionsToRun.actions);
|
||||
} catch {
|
||||
@@ -317,10 +322,10 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
|
||||
}
|
||||
}
|
||||
|
||||
private getActionsToRun(model: ITextModel, codeActionKind: CodeActionKind, token: CancellationToken) {
|
||||
private getActionsToRun(model: ITextModel, codeActionKind: CodeActionKind, excludes: readonly CodeActionKind[], token: CancellationToken) {
|
||||
return getCodeActions(model, model.getFullModelRange(), {
|
||||
type: 'auto',
|
||||
filter: { kind: codeActionKind, includeSourceActions: true },
|
||||
filter: { include: codeActionKind, excludes: excludes, includeSourceActions: true },
|
||||
}, token);
|
||||
}
|
||||
}
|
||||
@@ -343,7 +348,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant {
|
||||
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
setTimeout(() => reject(localize('timeout.onWillSave', "Aborted onWillSaveTextDocument-event after 1750ms")), 1750);
|
||||
this._proxy.$participateInSave(editorModel.getResource(), env.reason).then(values => {
|
||||
this._proxy.$participateInSave(editorModel.resource, env.reason).then(values => {
|
||||
if (!values.every(success => success)) {
|
||||
return Promise.reject(new Error('listener failed'));
|
||||
}
|
||||
|
||||
@@ -163,15 +163,22 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
}
|
||||
|
||||
private _onTerminalDisposed(terminalInstance: ITerminalInstance): void {
|
||||
this._proxy.$acceptTerminalClosed(terminalInstance.id);
|
||||
this._proxy.$acceptTerminalClosed(terminalInstance.id, terminalInstance.exitCode);
|
||||
}
|
||||
|
||||
private _onTerminalOpened(terminalInstance: ITerminalInstance): void {
|
||||
const shellLaunchConfigDto: IShellLaunchConfigDto = {
|
||||
name: terminalInstance.shellLaunchConfig.name,
|
||||
executable: terminalInstance.shellLaunchConfig.executable,
|
||||
args: terminalInstance.shellLaunchConfig.args,
|
||||
cwd: terminalInstance.shellLaunchConfig.cwd,
|
||||
env: terminalInstance.shellLaunchConfig.env
|
||||
};
|
||||
if (terminalInstance.title) {
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, terminalInstance.title);
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, terminalInstance.title, shellLaunchConfigDto);
|
||||
} else {
|
||||
terminalInstance.waitForTitle().then(title => {
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, title);
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, title, shellLaunchConfigDto);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -257,7 +264,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
this._getTerminalProcess(terminalId).then(e => e.emitReady(pid, cwd));
|
||||
}
|
||||
|
||||
public $sendProcessExit(terminalId: number, exitCode: number): void {
|
||||
public $sendProcessExit(terminalId: number, exitCode: number | undefined): void {
|
||||
this._getTerminalProcess(terminalId).then(e => e.emitExit(exitCode));
|
||||
this._terminalProcesses.delete(terminalId);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
import { isUndefinedOrNull, isNumber } from 'vs/base/common/types';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadTreeViews)
|
||||
export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape {
|
||||
@@ -23,13 +24,16 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
extHostContext: IExtHostContext,
|
||||
@IViewsService private readonly viewsService: IViewsService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) {
|
||||
super();
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews);
|
||||
}
|
||||
|
||||
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void {
|
||||
this.logService.trace('MainThreadTreeViews#$registerTreeViewDataProvider', treeViewId, options);
|
||||
|
||||
this.extensionService.whenInstalledExtensionsRegistered().then(() => {
|
||||
const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService);
|
||||
this._dataProviders.set(treeViewId, dataProvider);
|
||||
@@ -49,6 +53,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
}
|
||||
|
||||
$reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void> {
|
||||
this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, item, parentChain, options);
|
||||
|
||||
return this.viewsService.openView(treeViewId, options.focus)
|
||||
.then(() => {
|
||||
const viewer = this.getTreeView(treeViewId);
|
||||
@@ -60,6 +66,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
}
|
||||
|
||||
$refresh(treeViewId: string, itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeItem }): Promise<void> {
|
||||
this.logService.trace('MainThreadTreeViews#$refresh', treeViewId, itemsToRefreshByHandle);
|
||||
|
||||
const viewer = this.getTreeView(treeViewId);
|
||||
const dataProvider = this._dataProviders.get(treeViewId);
|
||||
if (viewer && dataProvider) {
|
||||
@@ -70,6 +78,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
}
|
||||
|
||||
$setMessage(treeViewId: string, message: string): void {
|
||||
this.logService.trace('MainThreadTreeViews#$setMessage', treeViewId, message);
|
||||
|
||||
const viewer = this.getTreeView(treeViewId);
|
||||
if (viewer) {
|
||||
viewer.message = message;
|
||||
@@ -77,6 +87,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
||||
}
|
||||
|
||||
$setTitle(treeViewId: string, title: string): void {
|
||||
this.logService.trace('MainThreadTreeViews#$setTitle', treeViewId, title);
|
||||
|
||||
const viewer = this.getTreeView(treeViewId);
|
||||
if (viewer) {
|
||||
viewer.title = title;
|
||||
|
||||
@@ -20,6 +20,7 @@ import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } fr
|
||||
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { CustomFileEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput';
|
||||
import { ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
|
||||
import { WebviewExtensionDescription } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
|
||||
import { ICreateWebViewShowOptions, IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
@@ -98,6 +99,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
constructor(
|
||||
context: extHostProtocol.IExtHostContext,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@ICustomEditorService private readonly _customEditorService: ICustomEditorService,
|
||||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@IOpenerService private readonly _openerService: IOpenerService,
|
||||
@@ -261,7 +263,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
canResolve: (webviewInput) => {
|
||||
return webviewInput instanceof CustomFileEditorInput && webviewInput.viewType === viewType;
|
||||
},
|
||||
resolveWebview: async (webviewInput) => {
|
||||
resolveWebview: async (webviewInput: CustomFileEditorInput) => {
|
||||
const handle = webviewInput.id;
|
||||
this._webviewInputs.add(handle, webviewInput);
|
||||
this.hookupWebviewEventDelegate(handle, webviewInput);
|
||||
@@ -269,6 +271,20 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
webviewInput.webview.options = options;
|
||||
webviewInput.webview.extension = extension;
|
||||
|
||||
const model = await this._customEditorService.models.loadOrCreate(webviewInput.getResource(), webviewInput.viewType);
|
||||
|
||||
model.onUndo(edit => {
|
||||
this._proxy.$undoEdits(handle, [edit]);
|
||||
});
|
||||
|
||||
model.onRedo(edit => {
|
||||
this._proxy.$redoEdits(handle, [edit]);
|
||||
});
|
||||
|
||||
webviewInput.onDispose(() => {
|
||||
this._customEditorService.models.disposeModel(model);
|
||||
});
|
||||
|
||||
try {
|
||||
await this._proxy.$resolveWebviewEditor(
|
||||
webviewInput.getResource(),
|
||||
@@ -296,6 +312,20 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
this._editorProviders.delete(viewType);
|
||||
}
|
||||
|
||||
public $onEdit(handle: extHostProtocol.WebviewPanelHandle, editData: string): void {
|
||||
const webview = this.getWebviewInput(handle);
|
||||
if (!(webview instanceof CustomFileEditorInput)) {
|
||||
throw new Error('Webview is not a webview editor');
|
||||
}
|
||||
|
||||
const model = this._customEditorService.models.get(webview.getResource(), webview.viewType);
|
||||
if (!model) {
|
||||
throw new Error('Could not find model for webview editor');
|
||||
}
|
||||
|
||||
model.makeEdit(editData);
|
||||
}
|
||||
|
||||
private hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput) {
|
||||
input.webview.onDidClickLink((uri: URI) => this.onDidClickLink(handle, uri));
|
||||
input.webview.onMessage((message: any) => this._proxy.$onMessage(handle, message));
|
||||
|
||||
@@ -42,9 +42,17 @@ export class MainThreadWindow implements MainThreadWindowShape {
|
||||
return Promise.resolve(this.hostService.hasFocus);
|
||||
}
|
||||
|
||||
async $openUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<boolean> {
|
||||
async $openUri(uriComponents: UriComponents, uriString: string | undefined, options: IOpenUriOptions): Promise<boolean> {
|
||||
const uri = URI.from(uriComponents);
|
||||
return this.openerService.open(uri, { openExternal: true, allowTunneling: options.allowTunneling });
|
||||
let target: URI | string;
|
||||
if (uriString && URI.parse(uriString).toString() === uri.toString()) {
|
||||
// called with string and no transformation happened -> keep string
|
||||
target = uriString;
|
||||
} else {
|
||||
// called with URI or transformed -> use uri
|
||||
target = uri;
|
||||
}
|
||||
return this.openerService.open(target, { openExternal: true, allowTunneling: options.allowTunneling });
|
||||
}
|
||||
|
||||
async $asExternalUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<UriComponents> {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { IFileMatch, IPatternInfo, ISearchProgressItem, ISearchService } from 'v
|
||||
import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
|
||||
import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape, IWorkspaceData, ITextSearchComplete } from '../common/extHost.protocol';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
@@ -37,7 +37,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
|
||||
extHostContext: IExtHostContext,
|
||||
@ISearchService private readonly _searchService: ISearchService,
|
||||
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService,
|
||||
@ITextFileService private readonly _textFileService: ITextFileService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@IWorkspaceEditingService private readonly _workspaceEditingService: IWorkspaceEditingService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@IRequestService private readonly _requestService: IRequestService,
|
||||
@@ -212,9 +212,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
|
||||
// --- save & edit resources ---
|
||||
|
||||
$saveAll(includeUntitled?: boolean): Promise<boolean> {
|
||||
return this._textFileService.saveAll(includeUntitled).then(result => {
|
||||
return result.results.every(each => each.success === true);
|
||||
});
|
||||
return this._editorService.saveAll({ includeUntitled });
|
||||
}
|
||||
|
||||
$resolveProxy(url: string): Promise<string | undefined> {
|
||||
|
||||
@@ -335,7 +335,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
super(id, `${id}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
}
|
||||
}
|
||||
const viewletDescriptor = new ViewletDescriptor(
|
||||
const viewletDescriptor = ViewletDescriptor.create(
|
||||
CustomViewlet,
|
||||
id,
|
||||
title,
|
||||
@@ -359,7 +359,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
}
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(OpenCustomViewletAction, id, localize('showViewlet', "Show {0}", title)),
|
||||
SyncActionDescriptor.create(OpenCustomViewletAction, id, localize('showViewlet', "Show {0}", title)),
|
||||
`View: Show ${title}`,
|
||||
localize('view', "View")
|
||||
);
|
||||
|
||||
@@ -105,7 +105,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService));
|
||||
|
||||
// manually create and register addressable instances
|
||||
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace));
|
||||
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace, extHostLogService));
|
||||
const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol));
|
||||
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
|
||||
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
|
||||
@@ -113,7 +113,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
|
||||
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
|
||||
const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment));
|
||||
const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol));
|
||||
const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol, extHostLogService));
|
||||
const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, uriTransformer, extHostDocuments, extHostCommands, extHostDiagnostics, extHostLogService));
|
||||
const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures));
|
||||
const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors));
|
||||
@@ -130,7 +130,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
|
||||
// Other instances
|
||||
const extHostClipboard = new ExtHostClipboard(rpcProtocol);
|
||||
const extHostMessageService = new ExtHostMessageService(rpcProtocol);
|
||||
const extHostMessageService = new ExtHostMessageService(rpcProtocol, extHostLogService);
|
||||
const extHostDialogs = new ExtHostDialogs(rpcProtocol);
|
||||
const extHostStatusBar = new ExtHostStatusBar(rpcProtocol);
|
||||
const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments);
|
||||
@@ -149,7 +149,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
let done = (!extension.isUnderDevelopment);
|
||||
function informOnce(selector: vscode.DocumentSelector) {
|
||||
if (!done) {
|
||||
console.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -180,20 +180,19 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
return extHostCommands.registerCommand(true, id, (...args: any[]): any => {
|
||||
const activeTextEditor = extHostEditors.getActiveTextEditor();
|
||||
if (!activeTextEditor) {
|
||||
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
extHostLogService.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return activeTextEditor.edit((edit: vscode.TextEditorEdit) => {
|
||||
args.unshift(activeTextEditor, edit);
|
||||
callback.apply(thisArg, args);
|
||||
callback.apply(thisArg, [activeTextEditor, edit, ...args]);
|
||||
|
||||
}).then((result) => {
|
||||
if (!result) {
|
||||
console.warn('Edits from command ' + id + ' were not applied.');
|
||||
extHostLogService.warn('Edits from command ' + id + ' were not applied.');
|
||||
}
|
||||
}, (err) => {
|
||||
console.warn('An error occurred while running command ' + id, err);
|
||||
extHostLogService.warn('An error occurred while running command ' + id, err);
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -202,7 +201,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise<any> => {
|
||||
const activeTextEditor = extHostEditors.getActiveTextEditor();
|
||||
if (!activeTextEditor) {
|
||||
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
extHostLogService.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -778,7 +777,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
if (!parentSessionOrOptions || (typeof parentSessionOrOptions === 'object' && 'configuration' in parentSessionOrOptions)) {
|
||||
return extHostDebugService.startDebugging(folder, nameOrConfig, { parentSession: parentSessionOrOptions });
|
||||
}
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostDebugService.startDebugging(folder, nameOrConfig, parentSessionOrOptions || {});
|
||||
},
|
||||
addBreakpoints(breakpoints: vscode.Breakpoint[]) {
|
||||
@@ -786,6 +784,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
},
|
||||
removeBreakpoints(breakpoints: vscode.Breakpoint[]) {
|
||||
return extHostDebugService.removeBreakpoints(breakpoints);
|
||||
},
|
||||
asDebugSourceUri(source: vscode.DebugSource, session?: vscode.DebugSession): vscode.Uri {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostDebugService.asDebugSourceUri(source, session);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import { ITerminalDimensions, IShellLaunchConfig } from 'vs/workbench/contrib/te
|
||||
import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
||||
import * as search from 'vs/workbench/services/search/common/search';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator';
|
||||
|
||||
export interface IEnvironment {
|
||||
@@ -71,7 +71,7 @@ export interface IStaticWorkspaceData {
|
||||
}
|
||||
|
||||
export interface IWorkspaceData extends IStaticWorkspaceData {
|
||||
folders: { uri: UriComponents, name: string, index: number }[];
|
||||
folders: { uri: UriComponents, name: string, index: number; }[];
|
||||
}
|
||||
|
||||
export interface IInitData {
|
||||
@@ -97,7 +97,7 @@ export interface IConfigurationInitData extends IConfigurationData {
|
||||
|
||||
export interface IWorkspaceConfigurationChangeEventData {
|
||||
changedConfiguration: IConfigurationModel;
|
||||
changedConfigurationByResource: { [folder: string]: IConfigurationModel };
|
||||
changedConfigurationByResource: { [folder: string]: IConfigurationModel; };
|
||||
}
|
||||
|
||||
export interface IExtHostContext extends IRPCProtocol {
|
||||
@@ -136,7 +136,7 @@ export type CommentThreadChanges = Partial<{
|
||||
label: string,
|
||||
contextValue: string,
|
||||
comments: modes.Comment[],
|
||||
collapseState: modes.CommentThreadCollapsibleState
|
||||
collapseState: modes.CommentThreadCollapsibleState;
|
||||
}>;
|
||||
|
||||
export interface MainThreadCommentsShape extends IDisposable {
|
||||
@@ -165,13 +165,13 @@ export interface MainThreadDialogOpenOptions {
|
||||
canSelectFiles?: boolean;
|
||||
canSelectFolders?: boolean;
|
||||
canSelectMany?: boolean;
|
||||
filters?: { [name: string]: string[] };
|
||||
filters?: { [name: string]: string[]; };
|
||||
}
|
||||
|
||||
export interface MainThreadDialogSaveOptions {
|
||||
defaultUri?: UriComponents;
|
||||
saveLabel?: string;
|
||||
filters?: { [name: string]: string[] };
|
||||
filters?: { [name: string]: string[]; };
|
||||
}
|
||||
|
||||
export interface MainThreadDiaglogsShape extends IDisposable {
|
||||
@@ -254,8 +254,8 @@ export interface MainThreadTextEditorsShape extends IDisposable {
|
||||
}
|
||||
|
||||
export interface MainThreadTreeViewsShape extends IDisposable {
|
||||
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void;
|
||||
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise<void>;
|
||||
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean; }): void;
|
||||
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem; }): Promise<void>;
|
||||
$reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void>;
|
||||
$setMessage(treeViewId: string, message: string): void;
|
||||
$setTitle(treeViewId: string, title: string): void;
|
||||
@@ -278,7 +278,7 @@ export interface MainThreadKeytarShape extends IDisposable {
|
||||
$setPassword(service: string, account: string, password: string): Promise<void>;
|
||||
$deletePassword(service: string, account: string): Promise<boolean>;
|
||||
$findPassword(service: string): Promise<string | null>;
|
||||
$findCredentials(service: string): Promise<Array<{ account: string, password: string }>>;
|
||||
$findCredentials(service: string): Promise<Array<{ account: string, password: string; }>>;
|
||||
}
|
||||
|
||||
export interface IRegExpDto {
|
||||
@@ -321,7 +321,7 @@ export interface ILanguageConfigurationDto {
|
||||
};
|
||||
}
|
||||
|
||||
export type GlobPattern = string | { base: string; pattern: string };
|
||||
export type GlobPattern = string | { base: string; pattern: string; };
|
||||
|
||||
export interface IDocumentFilterDto {
|
||||
$serialized: true;
|
||||
@@ -400,7 +400,7 @@ export interface TerminalLaunchConfig {
|
||||
shellPath?: string;
|
||||
shellArgs?: string[] | string;
|
||||
cwd?: string | UriComponents;
|
||||
env?: { [key: string]: string | null };
|
||||
env?: { [key: string]: string | null; };
|
||||
waitOnExit?: boolean;
|
||||
strictEnv?: boolean;
|
||||
hideFromUser?: boolean;
|
||||
@@ -408,7 +408,7 @@ export interface TerminalLaunchConfig {
|
||||
}
|
||||
|
||||
export interface MainThreadTerminalServiceShape extends IDisposable {
|
||||
$createTerminal(config: TerminalLaunchConfig): Promise<{ id: number, name: string }>;
|
||||
$createTerminal(config: TerminalLaunchConfig): Promise<{ id: number, name: string; }>;
|
||||
$dispose(terminalId: number): void;
|
||||
$hide(terminalId: number): void;
|
||||
$sendText(terminalId: number, text: string, addNewLine: boolean): void;
|
||||
@@ -420,7 +420,7 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
|
||||
$sendProcessTitle(terminalId: number, title: string): void;
|
||||
$sendProcessData(terminalId: number, data: string): void;
|
||||
$sendProcessReady(terminalId: number, pid: number, cwd: string): void;
|
||||
$sendProcessExit(terminalId: number, exitCode: number): void;
|
||||
$sendProcessExit(terminalId: number, exitCode: number | undefined): void;
|
||||
$sendProcessInitialCwd(terminalId: number, cwd: string): void;
|
||||
$sendProcessCwd(terminalId: number, initialCwd: string): void;
|
||||
$sendOverrideDimensions(terminalId: number, dimensions: ITerminalDimensions | undefined): void;
|
||||
@@ -558,7 +558,7 @@ export interface MainThreadWebviewsShape extends IDisposable {
|
||||
$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;
|
||||
$setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void;
|
||||
|
||||
$setHtml(handle: WebviewPanelHandle, value: string): void;
|
||||
$setOptions(handle: WebviewPanelHandle, options: modes.IWebviewOptions): void;
|
||||
@@ -570,6 +570,8 @@ export interface MainThreadWebviewsShape extends IDisposable {
|
||||
|
||||
$registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions): void;
|
||||
$unregisterEditorProvider(viewType: string): void;
|
||||
|
||||
$onEdit(handle: WebviewPanelHandle, editJson: string): void;
|
||||
}
|
||||
|
||||
export interface WebviewPanelViewStateData {
|
||||
@@ -587,13 +589,15 @@ export interface ExtHostWebviewsShape {
|
||||
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void>;
|
||||
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
|
||||
$resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
|
||||
$undoEdits(handle: WebviewPanelHandle, edits: string[]): void;
|
||||
$redoEdits(handle: WebviewPanelHandle, edits: string[]): void;
|
||||
}
|
||||
|
||||
export interface MainThreadUrlsShape extends IDisposable {
|
||||
$registerUriHandler(handle: number, extensionId: ExtensionIdentifier): Promise<void>;
|
||||
$unregisterUriHandler(handle: number): Promise<void>;
|
||||
$createAppUri(uri: UriComponents): Promise<UriComponents>;
|
||||
$proposedCreateAppUri(extensionId: ExtensionIdentifier, options?: { payload?: Partial<UriComponents> }): Promise<UriComponents>;
|
||||
$proposedCreateAppUri(extensionId: ExtensionIdentifier, options?: { payload?: Partial<UriComponents>; }): Promise<UriComponents>;
|
||||
}
|
||||
|
||||
export interface ExtHostUrlsShape {
|
||||
@@ -609,7 +613,7 @@ export interface MainThreadWorkspaceShape extends IDisposable {
|
||||
$startTextSearch(query: search.IPatternInfo, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<ITextSearchComplete>;
|
||||
$checkExists(folders: UriComponents[], includes: string[], token: CancellationToken): Promise<boolean>;
|
||||
$saveAll(includeUntitled?: boolean): Promise<boolean>;
|
||||
$updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string }[]): Promise<void>;
|
||||
$updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string; }[]): Promise<void>;
|
||||
$resolveProxy(url: string): Promise<string | undefined>;
|
||||
}
|
||||
|
||||
@@ -756,7 +760,7 @@ export interface IOpenUriOptions {
|
||||
|
||||
export interface MainThreadWindowShape extends IDisposable {
|
||||
$getWindowVisibility(): Promise<boolean>;
|
||||
$openUri(uri: UriComponents, options: IOpenUriOptions): Promise<boolean>;
|
||||
$openUri(uri: UriComponents, uriString: string | undefined, options: IOpenUriOptions): Promise<boolean>;
|
||||
$asExternalUri(uri: UriComponents, options: IOpenUriOptions): Promise<UriComponents>;
|
||||
}
|
||||
|
||||
@@ -764,7 +768,7 @@ export interface MainThreadWindowShape extends IDisposable {
|
||||
|
||||
export interface ExtHostCommandsShape {
|
||||
$executeContributedCommand<T>(id: string, ...args: any[]): Promise<T>;
|
||||
$getContributedCommandHandlerDescriptions(): Promise<{ [id: string]: string | ICommandHandlerDescription }>;
|
||||
$getContributedCommandHandlerDescriptions(): Promise<{ [id: string]: string | ICommandHandlerDescription; }>;
|
||||
}
|
||||
|
||||
export interface ExtHostConfigurationShape {
|
||||
@@ -898,7 +902,7 @@ export interface ExtHostExtensionServiceShape {
|
||||
$startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise<void>;
|
||||
$activateByEvent(activationEvent: string): Promise<void>;
|
||||
$activate(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<boolean>;
|
||||
$setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void>;
|
||||
$setRemoteEnvironment(env: { [key: string]: string | null; }): Promise<void>;
|
||||
|
||||
$deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise<void>;
|
||||
|
||||
@@ -978,7 +982,7 @@ export interface ISuggestDataDto {
|
||||
[ISuggestDataDtoField.preselect]?: boolean;
|
||||
[ISuggestDataDtoField.insertText]?: string;
|
||||
[ISuggestDataDtoField.insertTextRules]?: modes.CompletionItemInsertTextRule;
|
||||
[ISuggestDataDtoField.range]?: IRange | { insert: IRange, replace: IRange };
|
||||
[ISuggestDataDtoField.range]?: IRange | { insert: IRange, replace: IRange; };
|
||||
[ISuggestDataDtoField.commitCharacters]?: string[];
|
||||
[ISuggestDataDtoField.additionalTextEdits]?: ISingleEditOperation[];
|
||||
[ISuggestDataDtoField.command]?: modes.Command;
|
||||
@@ -989,7 +993,7 @@ export interface ISuggestDataDto {
|
||||
|
||||
export interface ISuggestResultDto {
|
||||
x?: number;
|
||||
a: { insert: IRange, replace: IRange };
|
||||
a: { insert: IRange, replace: IRange; };
|
||||
b: ISuggestDataDto[];
|
||||
c?: boolean;
|
||||
}
|
||||
@@ -1112,7 +1116,8 @@ export interface ICodeLensDto {
|
||||
}
|
||||
|
||||
export interface ICallHierarchyItemDto {
|
||||
id: string;
|
||||
_sessionId: string;
|
||||
_itemId: string;
|
||||
kind: modes.SymbolKind;
|
||||
name: string;
|
||||
detail?: string;
|
||||
@@ -1121,6 +1126,16 @@ export interface ICallHierarchyItemDto {
|
||||
selectionRange: IRange;
|
||||
}
|
||||
|
||||
export interface IIncomingCallDto {
|
||||
from: ICallHierarchyItemDto;
|
||||
fromRanges: IRange[];
|
||||
}
|
||||
|
||||
export interface IOutgoingCallDto {
|
||||
fromRanges: IRange[];
|
||||
to: ICallHierarchyItemDto;
|
||||
}
|
||||
|
||||
export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
|
||||
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<ICodeLensListDto | undefined>;
|
||||
@@ -1155,9 +1170,9 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[] | undefined>;
|
||||
$provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[] | undefined>;
|
||||
$provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]>;
|
||||
$prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<{ sessionId: string, root: ICallHierarchyItemDto } | undefined>;
|
||||
$provideCallHierarchyIncomingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[ICallHierarchyItemDto, IRange[]][] | undefined>;
|
||||
$provideCallHierarchyOutgoingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[ICallHierarchyItemDto, IRange[]][] | undefined>;
|
||||
$prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<ICallHierarchyItemDto | undefined>;
|
||||
$provideCallHierarchyIncomingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<IIncomingCallDto[] | undefined>;
|
||||
$provideCallHierarchyOutgoingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<IOutgoingCallDto[] | undefined>;
|
||||
$releaseCallHierarchy(handle: number, sessionId: string): void;
|
||||
}
|
||||
|
||||
@@ -1177,7 +1192,7 @@ export interface IShellLaunchConfigDto {
|
||||
executable?: string;
|
||||
args?: string[] | string;
|
||||
cwd?: string | UriComponents;
|
||||
env?: { [key: string]: string | null };
|
||||
env?: { [key: string]: string | null; };
|
||||
}
|
||||
|
||||
export interface IShellDefinitionDto {
|
||||
@@ -1196,8 +1211,8 @@ export interface ITerminalDimensionsDto {
|
||||
}
|
||||
|
||||
export interface ExtHostTerminalServiceShape {
|
||||
$acceptTerminalClosed(id: number): void;
|
||||
$acceptTerminalOpened(id: number, name: string): void;
|
||||
$acceptTerminalClosed(id: number, exitCode: number | undefined): void;
|
||||
$acceptTerminalOpened(id: number, name: string, shellLaunchConfig: IShellLaunchConfigDto): void;
|
||||
$acceptActiveTerminalChanged(id: number | null): void;
|
||||
$acceptTerminalProcessId(id: number, processId: number): void;
|
||||
$acceptTerminalProcessData(id: number, data: string): void;
|
||||
@@ -1232,8 +1247,8 @@ export interface ExtHostTaskShape {
|
||||
$onDidStartTaskProcess(value: tasks.TaskProcessStartedDTO): void;
|
||||
$onDidEndTaskProcess(value: tasks.TaskProcessEndedDTO): void;
|
||||
$OnDidEndTask(execution: tasks.TaskExecutionDTO): void;
|
||||
$resolveVariables(workspaceFolder: UriComponents, toResolve: { process?: { name: string; cwd?: string }, variables: string[] }): Promise<{ process?: string; variables: { [key: string]: string } }>;
|
||||
$getDefaultShellAndArgs(): Thenable<{ shell: string, args: string[] | string | undefined }>;
|
||||
$resolveVariables(workspaceFolder: UriComponents, toResolve: { process?: { name: string; cwd?: string; }, variables: string[]; }): Promise<{ process?: string; variables: { [key: string]: string; }; }>;
|
||||
$getDefaultShellAndArgs(): Thenable<{ shell: string, args: string[] | string | undefined; }>;
|
||||
$jsonTasksSupported(): Thenable<boolean>;
|
||||
}
|
||||
|
||||
@@ -1321,7 +1336,7 @@ export interface DecorationRequest {
|
||||
}
|
||||
|
||||
export type DecorationData = [number, boolean, string, string, ThemeColor];
|
||||
export type DecorationReply = { [id: number]: DecorationData };
|
||||
export type DecorationReply = { [id: number]: DecorationData; };
|
||||
|
||||
export interface ExtHostDecorationsShape {
|
||||
$provideDecorations(requests: DecorationRequest[], token: CancellationToken): Promise<DecorationReply>;
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as vscode from 'vscode';
|
||||
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as types from 'vs/workbench/api/common/extHostTypes';
|
||||
import { IRawColorInfo, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IRawColorInfo, IWorkspaceEditDto, ICallHierarchyItemDto, IIncomingCallDto, IOutgoingCallDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as search from 'vs/workbench/contrib/search/common/search';
|
||||
@@ -19,10 +19,97 @@ import { ICommandsExecutor, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand
|
||||
import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
|
||||
//#region --- NEW world
|
||||
|
||||
export class ApiCommandArgument<V, O = V> {
|
||||
|
||||
static readonly Uri = new ApiCommandArgument<URI>('uri', 'Uri of a text document', v => URI.isUri(v), v => v);
|
||||
static readonly Position = new ApiCommandArgument<types.Position, IPosition>('position', 'A position in a text document', v => types.Position.isPosition(v), typeConverters.Position.from);
|
||||
|
||||
static readonly CallHierarchyItem = new ApiCommandArgument('item', 'A call hierarchy item', v => v instanceof types.CallHierarchyItem, typeConverters.CallHierarchyItem.to);
|
||||
|
||||
constructor(
|
||||
readonly name: string,
|
||||
readonly description: string,
|
||||
readonly validate: (v: V) => boolean,
|
||||
readonly convert: (v: V) => O
|
||||
) { }
|
||||
}
|
||||
|
||||
export class ApiCommandResult<V, O = V> {
|
||||
|
||||
constructor(
|
||||
readonly description: string,
|
||||
readonly convert: (v: V) => O
|
||||
) { }
|
||||
}
|
||||
|
||||
export class ApiCommand {
|
||||
|
||||
constructor(
|
||||
readonly id: string,
|
||||
readonly internalId: string,
|
||||
readonly description: string,
|
||||
readonly args: ApiCommandArgument<any, any>[],
|
||||
readonly result: ApiCommandResult<any, any>
|
||||
) { }
|
||||
|
||||
register(commands: ExtHostCommands): IDisposable {
|
||||
|
||||
return commands.registerCommand(false, this.id, async (...apiArgs) => {
|
||||
|
||||
const internalArgs = this.args.map((arg, i) => {
|
||||
if (!arg.validate(apiArgs[i])) {
|
||||
throw new Error(`Invalid argument '${arg.name}' when running '${this.id}', receieved: ${apiArgs[i]}`);
|
||||
}
|
||||
return arg.convert(apiArgs[i]);
|
||||
});
|
||||
|
||||
const internalResult = await commands.executeCommand(this.internalId, ...internalArgs);
|
||||
return this.result.convert(internalResult);
|
||||
}, undefined, this._getCommandHandlerDesc());
|
||||
}
|
||||
|
||||
private _getCommandHandlerDesc(): ICommandHandlerDescription {
|
||||
return {
|
||||
description: this.description,
|
||||
args: this.args,
|
||||
returns: this.result.description
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const newCommands: ApiCommand[] = [
|
||||
new ApiCommand(
|
||||
'vscode.prepareCallHierarchy', '_executePrepareCallHierarchy', 'Prepare call hierarchy at a position inside a document',
|
||||
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
|
||||
new ApiCommandResult<ICallHierarchyItemDto, types.CallHierarchyItem>('A CallHierarchyItem or undefined', v => typeConverters.CallHierarchyItem.to(v))
|
||||
),
|
||||
new ApiCommand(
|
||||
'vscode.provideIncomingCalls', '_executeProvideIncomingCalls', 'Compute incoming calls for an item',
|
||||
[ApiCommandArgument.CallHierarchyItem],
|
||||
new ApiCommandResult<IIncomingCallDto[], types.CallHierarchyIncomingCall[]>('A CallHierarchyItem or undefined', v => v.map(typeConverters.CallHierarchyIncomingCall.to))
|
||||
),
|
||||
new ApiCommand(
|
||||
'vscode.provideOutgoingCalls', '_executeProvideOutgoingCalls', 'Compute outgoing calls for an item',
|
||||
[ApiCommandArgument.CallHierarchyItem],
|
||||
new ApiCommandResult<IOutgoingCallDto[], types.CallHierarchyOutgoingCall[]>('A CallHierarchyItem or undefined', v => v.map(typeConverters.CallHierarchyOutgoingCall.to))
|
||||
),
|
||||
];
|
||||
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region OLD world
|
||||
|
||||
export class ExtHostApiCommands {
|
||||
|
||||
static register(commands: ExtHostCommands) {
|
||||
newCommands.forEach(command => command.register(commands));
|
||||
return new ExtHostApiCommands(commands).registerCommands();
|
||||
}
|
||||
|
||||
@@ -433,7 +520,7 @@ export class ExtHostApiCommands {
|
||||
});
|
||||
}
|
||||
|
||||
private _executeColorPresentationProvider(color: types.Color, context: { uri: URI, range: types.Range }): Promise<types.ColorPresentation[]> {
|
||||
private _executeColorPresentationProvider(color: types.Color, context: { uri: URI, range: types.Range; }): Promise<types.ColorPresentation[]> {
|
||||
const args = {
|
||||
resource: context.uri,
|
||||
color: typeConverters.Color.from(color),
|
||||
|
||||
@@ -47,7 +47,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadCommands);
|
||||
this._logService = logService;
|
||||
this._converter = new CommandsConverter(this);
|
||||
this._converter = new CommandsConverter(this, logService);
|
||||
this._argumentProcessors = [
|
||||
{
|
||||
processArgument(a) {
|
||||
@@ -218,14 +218,15 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
export class CommandsConverter {
|
||||
|
||||
private readonly _delegatingCommandId: string;
|
||||
private readonly _commands: ExtHostCommands;
|
||||
private readonly _cache = new Map<number, vscode.Command>();
|
||||
private _cachIdPool = 0;
|
||||
|
||||
// --- conversion between internal and api commands
|
||||
constructor(commands: ExtHostCommands) {
|
||||
constructor(
|
||||
private readonly _commands: ExtHostCommands,
|
||||
private readonly _logService: ILogService
|
||||
) {
|
||||
this._delegatingCommandId = `_vscode_delegate_cmd_${Date.now().toString(36)}`;
|
||||
this._commands = commands;
|
||||
this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this);
|
||||
}
|
||||
|
||||
@@ -248,12 +249,16 @@ export class CommandsConverter {
|
||||
|
||||
const id = ++this._cachIdPool;
|
||||
this._cache.set(id, command);
|
||||
disposables.add(toDisposable(() => this._cache.delete(id)));
|
||||
disposables.add(toDisposable(() => {
|
||||
this._cache.delete(id);
|
||||
this._logService.trace('CommandsConverter#DISPOSE', id);
|
||||
}));
|
||||
result.$ident = id;
|
||||
|
||||
result.id = this._delegatingCommandId;
|
||||
result.arguments = [id];
|
||||
|
||||
this._logService.trace('CommandsConverter#CREATE', command.command, id);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -276,6 +281,8 @@ export class CommandsConverter {
|
||||
|
||||
private _executeConvertedCommand<R>(...args: any[]): Promise<R> {
|
||||
const actualCmd = this._cache.get(args[0]);
|
||||
this._logService.trace('CommandsConverter#EXECUTE', args[0], actualCmd ? actualCmd.command : 'MISSING');
|
||||
|
||||
if (!actualCmd) {
|
||||
return Promise.reject('actual command NOT FOUND');
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
function lookUp(tree: any, key: string) {
|
||||
if (key) {
|
||||
@@ -45,16 +46,19 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _proxy: MainThreadConfigurationShape;
|
||||
private readonly _logService: ILogService;
|
||||
private readonly _extHostWorkspace: ExtHostWorkspace;
|
||||
private readonly _barrier: Barrier;
|
||||
private _actual: ExtHostConfigProvider | null;
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService extHostRpc: IExtHostRpcService,
|
||||
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace
|
||||
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace,
|
||||
@ILogService logService: ILogService,
|
||||
) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadConfiguration);
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._logService = logService;
|
||||
this._barrier = new Barrier();
|
||||
this._actual = null;
|
||||
}
|
||||
@@ -64,7 +68,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
}
|
||||
|
||||
$initializeConfiguration(data: IConfigurationInitData): void {
|
||||
this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data);
|
||||
this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data, this._logService);
|
||||
this._barrier.open();
|
||||
}
|
||||
|
||||
@@ -80,9 +84,11 @@ export class ExtHostConfigProvider {
|
||||
private readonly _extHostWorkspace: ExtHostWorkspace;
|
||||
private _configurationScopes: Map<string, ConfigurationScope | undefined>;
|
||||
private _configuration: Configuration;
|
||||
private _logService: ILogService;
|
||||
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData) {
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData, logService: ILogService) {
|
||||
this._proxy = proxy;
|
||||
this._logService = logService;
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._configuration = ExtHostConfigProvider.parse(data);
|
||||
this._configurationScopes = this._toMap(data.configurationScopes);
|
||||
@@ -236,13 +242,13 @@ export class ExtHostConfigProvider {
|
||||
const extensionIdText = extensionId ? `[${extensionId.value}] ` : '';
|
||||
if (ConfigurationScope.RESOURCE === scope) {
|
||||
if (resource === undefined) {
|
||||
console.warn(`${extensionIdText}Accessing a resource scoped configuration without providing a resource is not expected. To get the effective value for '${key}', provide the URI of a resource or 'null' for any resource.`);
|
||||
this._logService.warn(`${extensionIdText}Accessing a resource scoped configuration without providing a resource is not expected. To get the effective value for '${key}', provide the URI of a resource or 'null' for any resource.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ConfigurationScope.WINDOW === scope) {
|
||||
if (resource) {
|
||||
console.warn(`${extensionIdText}Accessing a window scoped configuration for a resource is not expected. To associate '${key}' to a resource, define its scope to 'resource' in configuration contributions in 'package.json'.`);
|
||||
this._logService.warn(`${extensionIdText}Accessing a window scoped configuration for a resource is not expected. To associate '${key}' to a resource, define its scope to 'resource' in configuration contributions in 'package.json'.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConstructorSignature1, BrandedService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
||||
|
||||
@@ -13,12 +13,12 @@ export type IExtHostNamedCustomer<T extends IDisposable> = [ProxyIdentifier<T>,
|
||||
export type IExtHostCustomerCtor<T extends IDisposable> = IConstructorSignature1<IExtHostContext, T>;
|
||||
|
||||
export function extHostNamedCustomer<T extends IDisposable>(id: ProxyIdentifier<T>) {
|
||||
return function (ctor: IExtHostCustomerCtor<T>): void {
|
||||
return function <Services extends BrandedService[]>(ctor: { new(context: IExtHostContext, ...services: Services): T }): void {
|
||||
ExtHostCustomersRegistryImpl.INSTANCE.registerNamedCustomer(id, ctor);
|
||||
};
|
||||
}
|
||||
|
||||
export function extHostCustomer<T extends IDisposable>(ctor: IExtHostCustomerCtor<T>): void {
|
||||
export function extHostCustomer<T extends IDisposable, Services extends BrandedService[]>(ctor: { new(context: IExtHostContext, ...services: Services): T }): void {
|
||||
ExtHostCustomersRegistryImpl.INSTANCE.registerCustomer(ctor);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,5 +30,6 @@ export interface IExtHostDebugService extends ExtHostDebugServiceShape {
|
||||
registerDebugConfigurationProvider(type: string, provider: vscode.DebugConfigurationProvider): vscode.Disposable;
|
||||
registerDebugAdapterDescriptorFactory(extension: IExtensionDescription, type: string, factory: vscode.DebugAdapterDescriptorFactory): vscode.Disposable;
|
||||
registerDebugAdapterTrackerFactory(type: string, factory: vscode.DebugAdapterTrackerFactory): vscode.Disposable;
|
||||
asDebugSourceUri(source: vscode.DebugSource, session?: vscode.DebugSession): vscode.Uri;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { asArray } from 'vs/base/common/arrays';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
interface ProviderData {
|
||||
provider: vscode.DecorationProvider;
|
||||
@@ -28,6 +29,7 @@ export class ExtHostDecorations implements IExtHostDecorations {
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService extHostRpc: IExtHostRpcService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadDecorations);
|
||||
}
|
||||
@@ -66,10 +68,10 @@ export class ExtHostDecorations implements IExtHostDecorations {
|
||||
Decoration.validate(data);
|
||||
result[id] = <DecorationData>[data.priority, data.bubble, data.title, data.letter, data.color];
|
||||
} catch (e) {
|
||||
console.warn(`INVALID decoration from extension '${extensionId.value}': ${e}`);
|
||||
this._logService.warn(`INVALID decoration from extension '${extensionId.value}': ${e}`);
|
||||
}
|
||||
}, err => {
|
||||
console.error(err);
|
||||
this._logService.error(err);
|
||||
});
|
||||
|
||||
})).then(() => {
|
||||
|
||||
@@ -13,6 +13,7 @@ import * as converter from './extHostTypeConverters';
|
||||
import { mergeSort } from 'vs/base/common/arrays';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { keys } from 'vs/base/common/map';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
|
||||
@@ -253,7 +254,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
|
||||
readonly onDidChangeDiagnostics: Event<vscode.DiagnosticChangeEvent> = Event.map(Event.debounce(this._onDidChangeDiagnostics.event, ExtHostDiagnostics._debouncer, 50), ExtHostDiagnostics._mapper);
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
constructor(mainContext: IMainContext, @ILogService private readonly _logService: ILogService) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadDiagnostics);
|
||||
}
|
||||
|
||||
@@ -266,7 +267,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
} else if (!_collections.has(name)) {
|
||||
owner = name;
|
||||
} else {
|
||||
console.warn(`DiagnosticCollection with name '${name}' does already exist.`);
|
||||
this._logService.warn(`DiagnosticCollection with name '${name}' does already exist.`);
|
||||
do {
|
||||
owner = name + ExtHostDiagnostics._idPool++;
|
||||
} while (_collections.has(owner));
|
||||
|
||||
@@ -239,8 +239,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
|
||||
|
||||
} else if (regExpLeadsToEndlessLoop(regexp)) {
|
||||
// use default when custom-regexp is bad
|
||||
console.warn(`[getWordRangeAtPosition]: ignoring custom regexp '${regexp.source}' because it matches the empty string.`);
|
||||
regexp = getWordDefinitionFor(this._languageId);
|
||||
throw new Error(`[getWordRangeAtPosition]: ignoring custom regexp '${regexp.source}' because it matches the empty string.`);
|
||||
}
|
||||
|
||||
const wordAtText = getWordAtText(
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IResou
|
||||
import { TextEdit } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { Range, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import * as vscode from 'vscode';
|
||||
import { LinkedList } from 'vs/base/common/linkedList';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
@@ -44,6 +44,7 @@ class FsLinkProvider {
|
||||
const edges: Edge[] = [];
|
||||
let prevScheme: string | undefined;
|
||||
let prevState: State;
|
||||
let lastState = State.LastKnownState;
|
||||
let nextState = State.LastKnownState;
|
||||
for (const scheme of schemes) {
|
||||
|
||||
@@ -60,6 +61,8 @@ class FsLinkProvider {
|
||||
// keep creating new (next) states until the
|
||||
// end (and the BeforeColon-state) is reached
|
||||
if (pos + 1 === scheme.length) {
|
||||
// Save the last state here, because we need to continue for the next scheme
|
||||
lastState = nextState;
|
||||
nextState = State.BeforeColon;
|
||||
} else {
|
||||
nextState += 1;
|
||||
@@ -70,6 +73,8 @@ class FsLinkProvider {
|
||||
}
|
||||
|
||||
prevScheme = scheme;
|
||||
// Restore the last state
|
||||
nextState = lastState;
|
||||
}
|
||||
|
||||
// all link must match this pattern `<scheme>:/<more>`
|
||||
|
||||
@@ -26,6 +26,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { IURITransformer } from 'vs/base/common/uriIpc';
|
||||
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IdGenerator } from 'vs/base/common/idGenerator';
|
||||
|
||||
// --- adapter
|
||||
|
||||
@@ -473,11 +474,11 @@ class NavigateTypeAdapter {
|
||||
|
||||
private readonly _symbolCache = new Map<number, vscode.SymbolInformation>();
|
||||
private readonly _resultCache = new Map<number, [number, number]>();
|
||||
private readonly _provider: vscode.WorkspaceSymbolProvider;
|
||||
|
||||
constructor(provider: vscode.WorkspaceSymbolProvider) {
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _provider: vscode.WorkspaceSymbolProvider,
|
||||
private readonly _logService: ILogService
|
||||
) { }
|
||||
|
||||
provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<extHostProtocol.IWorkspaceSymbolsDto> {
|
||||
const result: extHostProtocol.IWorkspaceSymbolsDto = extHostProtocol.IdObject.mixin({ symbols: [] });
|
||||
@@ -489,7 +490,7 @@ class NavigateTypeAdapter {
|
||||
continue;
|
||||
}
|
||||
if (!item.name) {
|
||||
console.warn('INVALID SymbolInformation, lacks name', item);
|
||||
this._logService.warn('INVALID SymbolInformation, lacks name', item);
|
||||
continue;
|
||||
}
|
||||
const symbol = extHostProtocol.IdObject.mixin(typeConvert.WorkspaceSymbol.from(item));
|
||||
@@ -537,7 +538,8 @@ class RenameAdapter {
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.RenameProvider
|
||||
private readonly _provider: vscode.RenameProvider,
|
||||
private readonly _logService: ILogService
|
||||
) { }
|
||||
|
||||
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<extHostProtocol.IWorkspaceEditDto | undefined> {
|
||||
@@ -586,7 +588,7 @@ class RenameAdapter {
|
||||
return undefined;
|
||||
}
|
||||
if (range.start.line > pos.line || range.end.line < pos.line) {
|
||||
console.warn('INVALID rename location: position line must be within range start/end lines');
|
||||
this._logService.warn('INVALID rename location: position line must be within range start/end lines');
|
||||
return undefined;
|
||||
}
|
||||
return { range: typeConvert.Range.from(range), text };
|
||||
@@ -617,18 +619,15 @@ class SuggestAdapter {
|
||||
return typeof provider.resolveCompletionItem === 'function';
|
||||
}
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: CommandsConverter;
|
||||
private _provider: vscode.CompletionItemProvider;
|
||||
|
||||
private _cache = new Cache<vscode.CompletionItem>('CompletionItem');
|
||||
private _disposables = new Map<number, DisposableStore>();
|
||||
|
||||
constructor(documents: ExtHostDocuments, commands: CommandsConverter, provider: vscode.CompletionItemProvider) {
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._provider = provider;
|
||||
}
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _commands: CommandsConverter,
|
||||
private readonly _provider: vscode.CompletionItemProvider,
|
||||
private readonly _logService: ILogService
|
||||
) { }
|
||||
|
||||
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<extHostProtocol.ISuggestResultDto | undefined> {
|
||||
|
||||
@@ -711,7 +710,7 @@ class SuggestAdapter {
|
||||
|
||||
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: extHostProtocol.ChainedCacheId): extHostProtocol.ISuggestDataDto | undefined {
|
||||
if (typeof item.label !== 'string' || item.label.length === 0) {
|
||||
console.warn('INVALID text edit -> must have at least a label');
|
||||
this._logService.warn('INVALID text edit -> must have at least a label');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -751,7 +750,7 @@ class SuggestAdapter {
|
||||
}
|
||||
|
||||
// 'overwrite[Before|After]'-logic
|
||||
let range: vscode.Range | { inserting: vscode.Range, replacing: vscode.Range } | undefined;
|
||||
let range: vscode.Range | { inserting: vscode.Range, replacing: vscode.Range; } | undefined;
|
||||
if (item.textEdit) {
|
||||
range = item.textEdit.range;
|
||||
} else if (item.range) {
|
||||
@@ -763,7 +762,7 @@ class SuggestAdapter {
|
||||
if (range) {
|
||||
if (Range.isRange(range)) {
|
||||
if (!SuggestAdapter._isValidRangeForCompletion(range, position)) {
|
||||
console.trace('INVALID range -> must be single line and on the same line');
|
||||
this._logService.trace('INVALID range -> must be single line and on the same line');
|
||||
return undefined;
|
||||
}
|
||||
result[extHostProtocol.ISuggestDataDtoField.range] = typeConvert.Range.from(range);
|
||||
@@ -775,7 +774,7 @@ class SuggestAdapter {
|
||||
|| !range.inserting.start.isEqual(range.replacing.start)
|
||||
|| !range.replacing.contains(range.inserting)
|
||||
) {
|
||||
console.trace('INVALID range -> must be single line, on the same line, insert range must be a prefix of replace range');
|
||||
this._logService.trace('INVALID range -> must be single line, on the same line, insert range must be a prefix of replace range');
|
||||
return undefined;
|
||||
}
|
||||
result[extHostProtocol.ISuggestDataDtoField.range] = {
|
||||
@@ -991,7 +990,8 @@ class SelectionRangeAdapter {
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.SelectionRangeProvider
|
||||
private readonly _provider: vscode.SelectionRangeProvider,
|
||||
private readonly _logService: ILogService
|
||||
) { }
|
||||
|
||||
provideSelectionRanges(resource: URI, pos: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]> {
|
||||
@@ -1003,7 +1003,7 @@ class SelectionRangeAdapter {
|
||||
return [];
|
||||
}
|
||||
if (allProviderRanges.length !== positions.length) {
|
||||
console.warn('BAD selection ranges, provider must return ranges for each position');
|
||||
this._logService.warn('BAD selection ranges, provider must return ranges for each position');
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -1034,15 +1034,15 @@ class SelectionRangeAdapter {
|
||||
|
||||
class CallHierarchyAdapter {
|
||||
|
||||
private _idPool: number = 0;
|
||||
private readonly _cache = new Map<string, vscode.CallHierarchyItem[]>();
|
||||
private readonly _idPool = new IdGenerator('');
|
||||
private readonly _cache = new Map<string, Map<string, vscode.CallHierarchyItem>>();
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.CallHierarchyProvider
|
||||
) { }
|
||||
|
||||
async prepareSession(uri: URI, position: IPosition, token: CancellationToken): Promise<{ sessionId: string, root: extHostProtocol.ICallHierarchyItemDto } | undefined> {
|
||||
async prepareSession(uri: URI, position: IPosition, token: CancellationToken): Promise<extHostProtocol.ICallHierarchyItemDto | undefined> {
|
||||
const doc = this._documents.getDocument(uri);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
|
||||
@@ -1050,13 +1050,14 @@ class CallHierarchyAdapter {
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
const sessionId = String.fromCharCode(this._idPool++);
|
||||
this._cache.set(sessionId, []);
|
||||
return { sessionId, root: this._cacheAndConvertItem(sessionId, item) };
|
||||
const sessionId = this._idPool.nextId();
|
||||
|
||||
this._cache.set(sessionId, new Map());
|
||||
return this._cacheAndConvertItem(sessionId, item);
|
||||
}
|
||||
|
||||
async provideCallsTo(itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> {
|
||||
const item = this._itemFromCache(itemId);
|
||||
async provideCallsTo(sessionId: string, itemId: string, token: CancellationToken): Promise<extHostProtocol.IIncomingCallDto[] | undefined> {
|
||||
const item = this._itemFromCache(sessionId, itemId);
|
||||
if (!item) {
|
||||
throw new Error('missing call hierarchy item');
|
||||
}
|
||||
@@ -1064,11 +1065,16 @@ class CallHierarchyAdapter {
|
||||
if (!calls) {
|
||||
return undefined;
|
||||
}
|
||||
return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[this._cacheAndConvertItem(itemId, call.from), call.fromRanges.map(typeConvert.Range.from)]));
|
||||
return calls.map(call => {
|
||||
return {
|
||||
from: this._cacheAndConvertItem(sessionId, call.from),
|
||||
fromRanges: call.fromRanges.map(r => typeConvert.Range.from(r))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async provideCallsFrom(itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> {
|
||||
const item = this._itemFromCache(itemId);
|
||||
async provideCallsFrom(sessionId: string, itemId: string, token: CancellationToken): Promise<extHostProtocol.IOutgoingCallDto[] | undefined> {
|
||||
const item = this._itemFromCache(sessionId, itemId);
|
||||
if (!item) {
|
||||
throw new Error('missing call hierarchy item');
|
||||
}
|
||||
@@ -1076,7 +1082,12 @@ class CallHierarchyAdapter {
|
||||
if (!calls) {
|
||||
return undefined;
|
||||
}
|
||||
return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[this._cacheAndConvertItem(itemId, call.to), call.fromRanges.map(typeConvert.Range.from)]));
|
||||
return calls.map(call => {
|
||||
return {
|
||||
to: this._cacheAndConvertItem(sessionId, call.to),
|
||||
fromRanges: call.fromRanges.map(r => typeConvert.Range.from(r))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
releaseSession(sessionId: string): void {
|
||||
@@ -1085,9 +1096,10 @@ class CallHierarchyAdapter {
|
||||
|
||||
private _cacheAndConvertItem(itemOrSessionId: string, item: vscode.CallHierarchyItem): extHostProtocol.ICallHierarchyItemDto {
|
||||
const sessionId = itemOrSessionId.charAt(0);
|
||||
const array = this._cache.get(sessionId)!;
|
||||
const map = this._cache.get(sessionId)!;
|
||||
const dto: extHostProtocol.ICallHierarchyItemDto = {
|
||||
id: sessionId + String.fromCharCode(array.length),
|
||||
_sessionId: sessionId,
|
||||
_itemId: map.size.toString(36),
|
||||
name: item.name,
|
||||
detail: item.detail,
|
||||
kind: typeConvert.SymbolKind.from(item.kind),
|
||||
@@ -1095,17 +1107,13 @@ class CallHierarchyAdapter {
|
||||
range: typeConvert.Range.from(item.range),
|
||||
selectionRange: typeConvert.Range.from(item.selectionRange),
|
||||
};
|
||||
array.push(item);
|
||||
map.set(dto._itemId, item);
|
||||
return dto;
|
||||
}
|
||||
|
||||
private _itemFromCache(itemId: string): vscode.CallHierarchyItem | undefined {
|
||||
const sessionId = itemId.charAt(0);
|
||||
const array = this._cache.get(sessionId);
|
||||
if (!array) {
|
||||
return undefined;
|
||||
}
|
||||
return array[itemId.charCodeAt(1)];
|
||||
private _itemFromCache(sessionId: string, itemId: string): vscode.CallHierarchyItem | undefined {
|
||||
const map = this._cache.get(sessionId);
|
||||
return map && map.get(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1193,7 +1201,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
return ExtHostLanguageFeatures._handlePool++;
|
||||
}
|
||||
|
||||
private _withAdapter<A, R>(handle: number, ctor: { new(...args: any[]): A }, callback: (adapter: A, extension: IExtensionDescription | undefined) => Promise<R>, fallbackValue: R): Promise<R> {
|
||||
private _withAdapter<A, R>(handle: number, ctor: { new(...args: any[]): A; }, callback: (adapter: A, extension: IExtensionDescription | undefined) => Promise<R>, fallbackValue: R): Promise<R> {
|
||||
const data = this._adapter.get(handle);
|
||||
if (!data) {
|
||||
return Promise.resolve(fallbackValue);
|
||||
@@ -1404,7 +1412,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
// --- navigate types
|
||||
|
||||
registerWorkspaceSymbolProvider(extension: IExtensionDescription, provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new NavigateTypeAdapter(provider), extension);
|
||||
const handle = this._addNewAdapter(new NavigateTypeAdapter(provider, this._logService), extension);
|
||||
this._proxy.$registerNavigateTypeSupport(handle);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -1424,7 +1432,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
// --- rename
|
||||
|
||||
registerRenameProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new RenameAdapter(this._documents, provider), extension);
|
||||
const handle = this._addNewAdapter(new RenameAdapter(this._documents, provider, this._logService), extension);
|
||||
this._proxy.$registerRenameSupport(handle, this._transformDocumentSelector(selector), RenameAdapter.supportsResolving(provider));
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -1440,7 +1448,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
// --- suggestion
|
||||
|
||||
registerCompletionItemProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider), extension);
|
||||
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider, this._logService), extension);
|
||||
this._proxy.$registerSuggestSupport(handle, this._transformDocumentSelector(selector), triggerCharacters, SuggestAdapter.supportsResolving(provider), extension.identifier);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -1524,7 +1532,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
// --- smart select
|
||||
|
||||
registerSelectionRangeProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new SelectionRangeAdapter(this._documents, provider), extension);
|
||||
const handle = this._addNewAdapter(new SelectionRangeAdapter(this._documents, provider, this._logService), extension);
|
||||
this._proxy.$registerSelectionRangeProvider(handle, this._transformDocumentSelector(selector));
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -1541,16 +1549,16 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<{ sessionId: string, root: extHostProtocol.ICallHierarchyItemDto } | undefined> {
|
||||
$prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<extHostProtocol.ICallHierarchyItemDto | undefined> {
|
||||
return this._withAdapter(handle, CallHierarchyAdapter, adapter => Promise.resolve(adapter.prepareSession(URI.revive(resource), position, token)), undefined);
|
||||
}
|
||||
|
||||
$provideCallHierarchyIncomingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> {
|
||||
return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsTo(itemId, token), undefined);
|
||||
$provideCallHierarchyIncomingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<extHostProtocol.IIncomingCallDto[] | undefined> {
|
||||
return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsTo(sessionId, itemId, token), undefined);
|
||||
}
|
||||
|
||||
$provideCallHierarchyOutgoingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> {
|
||||
return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsFrom(itemId, token), undefined);
|
||||
$provideCallHierarchyOutgoingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<extHostProtocol.IOutgoingCallDto[] | undefined> {
|
||||
return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsFrom(sessionId, itemId, token), undefined);
|
||||
}
|
||||
|
||||
$releaseCallHierarchy(handle: number, sessionId: string): void {
|
||||
|
||||
@@ -7,6 +7,7 @@ import Severity from 'vs/base/common/severity';
|
||||
import * as vscode from 'vscode';
|
||||
import { MainContext, MainThreadMessageServiceShape, MainThreadMessageOptions, IMainContext } from './extHost.protocol';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
function isMessageItem(item: any): item is vscode.MessageItem {
|
||||
return item && item.title;
|
||||
@@ -16,7 +17,10 @@ export class ExtHostMessageService {
|
||||
|
||||
private _proxy: MainThreadMessageServiceShape;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
@ILogService private readonly _logService: ILogService
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadMessageService);
|
||||
}
|
||||
|
||||
@@ -45,7 +49,7 @@ export class ExtHostMessageService {
|
||||
let { title, isCloseAffordance } = command;
|
||||
commands.push({ title, isCloseAffordance: !!isCloseAffordance, handle });
|
||||
} else {
|
||||
console.warn('Invalid message item:', command);
|
||||
this._logService.warn('Invalid message item:', command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
|
||||
import { platform } from 'vs/base/common/process';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
|
||||
interface LoadFunction {
|
||||
@@ -41,7 +42,8 @@ export abstract class RequireInterceptor {
|
||||
@IInstantiationService private readonly _instaService: IInstantiationService,
|
||||
@IExtHostConfiguration private readonly _extHostConfiguration: IExtHostConfiguration,
|
||||
@IExtHostExtensionService private readonly _extHostExtensionService: IExtHostExtensionService,
|
||||
@IExtHostInitDataService private readonly _initData: IExtHostInitDataService
|
||||
@IExtHostInitDataService private readonly _initData: IExtHostInitDataService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
) {
|
||||
this._factories = new Map<string, INodeModuleFactory>();
|
||||
this._alternatives = [];
|
||||
@@ -54,7 +56,7 @@ export abstract class RequireInterceptor {
|
||||
const configProvider = await this._extHostConfiguration.getConfigProvider();
|
||||
const extensionPaths = await this._extHostExtensionService.getExtensionPathIndex();
|
||||
|
||||
this.register(new VSCodeNodeModuleFactory(this._apiFactory, extensionPaths, this._extensionRegistry, configProvider));
|
||||
this.register(new VSCodeNodeModuleFactory(this._apiFactory, extensionPaths, this._extensionRegistry, configProvider, this._logService));
|
||||
this.register(this._instaService.createInstance(KeytarNodeModuleFactory));
|
||||
if (this._initData.remote.isRemote) {
|
||||
this.register(this._instaService.createInstance(OpenNodeModuleFactory, extensionPaths, this._initData.environment.appUriScheme));
|
||||
@@ -91,7 +93,8 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory {
|
||||
private readonly _apiFactory: IExtensionApiFactory,
|
||||
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
|
||||
private readonly _extensionRegistry: ExtensionDescriptionRegistry,
|
||||
private readonly _configProvider: ExtHostConfigProvider
|
||||
private readonly _configProvider: ExtHostConfigProvider,
|
||||
private readonly _logService: ILogService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -112,7 +115,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory {
|
||||
if (!this._defaultApiImpl) {
|
||||
let extensionPathsPretty = '';
|
||||
this._extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`);
|
||||
console.warn(`Could not identify extension for 'vscode' require call from ${parent.fsPath}. These are the extension path mappings: \n${extensionPathsPretty}`);
|
||||
this._logService.warn(`Could not identify extension for 'vscode' require call from ${parent.fsPath}. These are the extension path mappings: \n${extensionPathsPretty}`);
|
||||
this._defaultApiImpl = this._apiFactory(nullExtensionDescription, this._extensionRegistry, this._configProvider);
|
||||
}
|
||||
return this._defaultApiImpl;
|
||||
@@ -242,9 +245,9 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
|
||||
return this.callOriginal(target, options);
|
||||
}
|
||||
if (uri.scheme === 'http' || uri.scheme === 'https') {
|
||||
return mainThreadWindow.$openUri(uri, { allowTunneling: true });
|
||||
return mainThreadWindow.$openUri(uri, target, { allowTunneling: true });
|
||||
} else if (uri.scheme === 'mailto' || uri.scheme === this._appUriScheme) {
|
||||
return mainThreadWindow.$openUri(uri, {});
|
||||
return mainThreadWindow.$openUri(uri, target, {});
|
||||
}
|
||||
return this.callOriginal(target, options);
|
||||
};
|
||||
|
||||
@@ -180,8 +180,7 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
|
||||
}
|
||||
|
||||
if (fn && typeof fn !== 'function') {
|
||||
console.warn('Invalid SCM input box validation function');
|
||||
return;
|
||||
throw new Error(`[${this._extension.identifier.value}]: Invalid SCM input box validation function`);
|
||||
}
|
||||
|
||||
this._validateInput = fn;
|
||||
|
||||
@@ -3,10 +3,17 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostSearchShape } from '../common/extHost.protocol';
|
||||
import { ExtHostSearchShape, MainThreadSearchShape, MainContext } from '../common/extHost.protocol';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IRawFileQuery, ISearchCompleteStats, IFileQuery, IRawTextQuery, IRawQuery, ITextQuery, IFolderQuery } from 'vs/workbench/services/search/common/search';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
|
||||
|
||||
export interface IExtHostSearch extends ExtHostSearchShape {
|
||||
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable;
|
||||
@@ -14,3 +21,111 @@ export interface IExtHostSearch extends ExtHostSearchShape {
|
||||
}
|
||||
|
||||
export const IExtHostSearch = createDecorator<IExtHostSearch>('IExtHostSearch');
|
||||
|
||||
export class ExtHostSearch implements ExtHostSearchShape {
|
||||
|
||||
protected readonly _proxy: MainThreadSearchShape = this.extHostRpc.getProxy(MainContext.MainThreadSearch);
|
||||
protected _handlePool: number = 0;
|
||||
|
||||
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider>();
|
||||
private readonly _textSearchUsedSchemes = new Set<string>();
|
||||
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider>();
|
||||
private readonly _fileSearchUsedSchemes = new Set<string>();
|
||||
|
||||
private readonly _fileSearchManager = new FileSearchManager();
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService private extHostRpc: IExtHostRpcService,
|
||||
@IURITransformerService protected _uriTransformer: IURITransformerService,
|
||||
@ILogService protected _logService: ILogService
|
||||
) { }
|
||||
|
||||
protected _transformScheme(scheme: string): string {
|
||||
return this._uriTransformer.transformOutgoingScheme(scheme);
|
||||
}
|
||||
|
||||
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable {
|
||||
if (this._textSearchUsedSchemes.has(scheme)) {
|
||||
throw new Error(`a text search provider for the scheme '${scheme}' is already registered`);
|
||||
}
|
||||
|
||||
this._textSearchUsedSchemes.add(scheme);
|
||||
const handle = this._handlePool++;
|
||||
this._textSearchProvider.set(handle, provider);
|
||||
this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme));
|
||||
return toDisposable(() => {
|
||||
this._textSearchUsedSchemes.delete(scheme);
|
||||
this._textSearchProvider.delete(handle);
|
||||
this._proxy.$unregisterProvider(handle);
|
||||
});
|
||||
}
|
||||
|
||||
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable {
|
||||
if (this._fileSearchUsedSchemes.has(scheme)) {
|
||||
throw new Error(`a file search provider for the scheme '${scheme}' is already registered`);
|
||||
}
|
||||
|
||||
this._fileSearchUsedSchemes.add(scheme);
|
||||
const handle = this._handlePool++;
|
||||
this._fileSearchProvider.set(handle, provider);
|
||||
this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme));
|
||||
return toDisposable(() => {
|
||||
this._fileSearchUsedSchemes.delete(scheme);
|
||||
this._fileSearchProvider.delete(handle);
|
||||
this._proxy.$unregisterProvider(handle);
|
||||
});
|
||||
}
|
||||
|
||||
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const query = reviveQuery(rawQuery);
|
||||
const provider = this._fileSearchProvider.get(handle);
|
||||
if (provider) {
|
||||
return this._fileSearchManager.fileSearch(query, provider, batch => {
|
||||
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
|
||||
}, token);
|
||||
} else {
|
||||
throw new Error('unknown provider: ' + handle);
|
||||
}
|
||||
}
|
||||
|
||||
$clearCache(cacheKey: string): Promise<void> {
|
||||
this._fileSearchManager.clearCache(cacheKey);
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const provider = this._textSearchProvider.get(handle);
|
||||
if (!provider || !provider.provideTextSearchResults) {
|
||||
throw new Error(`Unknown provider ${handle}`);
|
||||
}
|
||||
|
||||
const query = reviveQuery(rawQuery);
|
||||
const engine = this.createTextSearchManager(query, provider);
|
||||
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
|
||||
}
|
||||
|
||||
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
|
||||
return new TextSearchManager(query, provider, {
|
||||
readdir: resource => Promise.resolve([]), // TODO@rob implement
|
||||
toCanonicalName: encoding => encoding
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
|
||||
return {
|
||||
...<any>rawQuery, // TODO@rob ???
|
||||
...{
|
||||
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
|
||||
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolderQuery<URI> {
|
||||
return {
|
||||
...rawFolderQuery,
|
||||
folder: URI.revive(rawFolderQuery.folder)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import * as Platform from 'vs/base/common/platform';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export interface IExtHostTask extends ExtHostTaskShape {
|
||||
|
||||
@@ -374,6 +375,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
protected readonly _editorService: IExtHostDocumentsAndEditors;
|
||||
protected readonly _configurationService: IExtHostConfiguration;
|
||||
protected readonly _terminalService: IExtHostTerminalService;
|
||||
protected readonly _logService: ILogService;
|
||||
protected _handleCounter: number;
|
||||
protected _handlers: Map<number, HandlerData>;
|
||||
protected _taskExecutions: Map<string, TaskExecutionImpl>;
|
||||
@@ -393,7 +395,8 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
|
||||
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
|
||||
@IExtHostConfiguration configurationService: IExtHostConfiguration,
|
||||
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
|
||||
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
|
||||
@ILogService logService: ILogService
|
||||
) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadTask);
|
||||
this._workspaceProvider = workspaceService;
|
||||
@@ -406,6 +409,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
this._providedCustomExecutions2 = new Map<string, types.CustomExecution>();
|
||||
this._notProvidedCustomExecutions = new Set<string>();
|
||||
this._activeCustomExecutions2 = new Map<string, types.CustomExecution>();
|
||||
this._logService = logService;
|
||||
}
|
||||
|
||||
public registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
@@ -661,9 +665,10 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
|
||||
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
|
||||
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
|
||||
@IExtHostConfiguration configurationService: IExtHostConfiguration,
|
||||
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
|
||||
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
|
||||
@ILogService logService: ILogService
|
||||
) {
|
||||
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService);
|
||||
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService);
|
||||
if (initData.remote.isRemote && initData.remote.authority) {
|
||||
this.registerTaskSystem(Schemas.vscodeRemote, {
|
||||
scheme: Schemas.vscodeRemote,
|
||||
@@ -696,7 +701,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
|
||||
if (value) {
|
||||
for (let task of value) {
|
||||
if (!task.definition || !validTypes[task.definition.type]) {
|
||||
console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
|
||||
this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
|
||||
}
|
||||
|
||||
const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension);
|
||||
@@ -707,7 +712,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
|
||||
// is invoked, we have to be able to map it back to our data.
|
||||
taskIdPromises.push(this.addCustomExecution(taskDTO, task, true));
|
||||
} else {
|
||||
console.warn('Only custom execution tasks supported.');
|
||||
this._logService.warn('Only custom execution tasks supported.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -721,7 +726,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
|
||||
if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) {
|
||||
return resolvedTaskDTO;
|
||||
} else {
|
||||
console.warn('Only custom execution tasks supported.');
|
||||
this._logService.warn('Only custom execution tasks supported.');
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShap
|
||||
import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { EXT_HOST_CREATION_DELAY, ITerminalChildProcess, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ITerminalChildProcess, ITerminalDimensions, EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
|
||||
@@ -97,15 +97,18 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
|
||||
private _cols: number | undefined;
|
||||
private _pidPromiseComplete: ((value: number | undefined) => any) | undefined;
|
||||
private _rows: number | undefined;
|
||||
private _exitStatus: vscode.TerminalExitStatus | undefined;
|
||||
|
||||
public isOpen: boolean = false;
|
||||
|
||||
constructor(
|
||||
proxy: MainThreadTerminalServiceShape,
|
||||
private readonly _creationOptions: vscode.TerminalOptions | vscode.ExtensionTerminalOptions,
|
||||
private _name?: string,
|
||||
id?: number
|
||||
) {
|
||||
super(proxy, id);
|
||||
this._creationOptions = Object.freeze(this._creationOptions);
|
||||
this._pidPromise = new Promise<number>(c => this._pidPromiseComplete = c);
|
||||
}
|
||||
|
||||
@@ -138,6 +141,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
public get exitStatus(): vscode.TerminalExitStatus | undefined {
|
||||
return this._exitStatus;
|
||||
}
|
||||
|
||||
public get dimensions(): vscode.TerminalDimensions | undefined {
|
||||
if (this._cols === undefined || this._rows === undefined) {
|
||||
return undefined;
|
||||
@@ -148,6 +155,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
|
||||
};
|
||||
}
|
||||
|
||||
public setExitCode(code: number | undefined) {
|
||||
this._exitStatus = Object.freeze({ code });
|
||||
}
|
||||
|
||||
public setDimensions(cols: number, rows: number): boolean {
|
||||
if (cols === this._cols && rows === this._rows) {
|
||||
// Nothing changed
|
||||
@@ -162,6 +173,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
|
||||
return this._pidPromise;
|
||||
}
|
||||
|
||||
public get creationOptions(): Readonly<vscode.TerminalOptions | vscode.ExtensionTerminalOptions> {
|
||||
return this._creationOptions;
|
||||
}
|
||||
|
||||
public sendText(text: string, addNewLine: boolean = true): void {
|
||||
this._checkDisposed();
|
||||
this._queueApiRequest(this._proxy.$sendText, [text, addNewLine]);
|
||||
@@ -210,8 +225,8 @@ class ApiRequest {
|
||||
export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
||||
private readonly _onProcessData = new Emitter<string>();
|
||||
public readonly onProcessData: Event<string> = this._onProcessData.event;
|
||||
private readonly _onProcessExit = new Emitter<number>();
|
||||
public readonly onProcessExit: Event<number> = this._onProcessExit.event;
|
||||
private readonly _onProcessExit = new Emitter<number | undefined>();
|
||||
public readonly onProcessExit: Event<number | undefined> = this._onProcessExit.event;
|
||||
private readonly _onProcessReady = new Emitter<{ pid: number, cwd: string }>();
|
||||
public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; }
|
||||
private readonly _onProcessTitleChanged = new Emitter<string>();
|
||||
@@ -253,7 +268,9 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
||||
// Attach the listeners
|
||||
this._pty.onDidWrite(e => this._onProcessData.fire(e));
|
||||
if (this._pty.onDidClose) {
|
||||
this._pty.onDidClose(e => this._onProcessExit.fire(e || 0));
|
||||
this._pty.onDidClose((e: number | undefined = undefined) => {
|
||||
this._onProcessExit.fire(e);
|
||||
});
|
||||
}
|
||||
if (this._pty.onDidOverrideDimensions) {
|
||||
this._pty.onDidOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e ? { cols: e.columns, rows: e.rows } : e));
|
||||
@@ -312,7 +329,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
public abstract $acceptWorkspacePermissionsChanged(isAllowed: boolean): void;
|
||||
|
||||
public createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal {
|
||||
const terminal = new ExtHostTerminal(this._proxy, options.name);
|
||||
const terminal = new ExtHostTerminal(this._proxy, options, options.name);
|
||||
const p = new ExtHostPseudoterminal(options.pty);
|
||||
terminal.createExtensionTerminal().then(id => this._setupExtHostProcessListeners(id, p));
|
||||
this._terminals.push(terminal);
|
||||
@@ -383,16 +400,17 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
}
|
||||
}
|
||||
|
||||
public async $acceptTerminalClosed(id: number): Promise<void> {
|
||||
public async $acceptTerminalClosed(id: number, exitCode: number | undefined): Promise<void> {
|
||||
await this._getTerminalByIdEventually(id);
|
||||
const index = this._getTerminalObjectIndexById(this.terminals, id);
|
||||
if (index !== null) {
|
||||
const terminal = this._terminals.splice(index, 1)[0];
|
||||
terminal.setExitCode(exitCode);
|
||||
this._onDidCloseTerminal.fire(terminal);
|
||||
}
|
||||
}
|
||||
|
||||
public $acceptTerminalOpened(id: number, name: string): void {
|
||||
public $acceptTerminalOpened(id: number, name: string, shellLaunchConfigDto: IShellLaunchConfigDto): void {
|
||||
const index = this._getTerminalObjectIndexById(this._terminals, id);
|
||||
if (index !== null) {
|
||||
// The terminal has already been created (via createTerminal*), only fire the event
|
||||
@@ -401,7 +419,14 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
return;
|
||||
}
|
||||
|
||||
const terminal = new ExtHostTerminal(this._proxy, name, id);
|
||||
const creationOptions: vscode.TerminalOptions = {
|
||||
name: shellLaunchConfigDto.name,
|
||||
shellPath: shellLaunchConfigDto.executable,
|
||||
shellArgs: shellLaunchConfigDto.args,
|
||||
cwd: typeof shellLaunchConfigDto.cwd === 'string' ? shellLaunchConfigDto.cwd : URI.revive(shellLaunchConfigDto.cwd),
|
||||
env: shellLaunchConfigDto.env
|
||||
};
|
||||
const terminal = new ExtHostTerminal(this._proxy, creationOptions, name, id);
|
||||
this._terminals.push(terminal);
|
||||
this._onDidOpenTerminal.fire(terminal);
|
||||
terminal.isOpen = true;
|
||||
@@ -414,22 +439,6 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
}
|
||||
}
|
||||
|
||||
public performTerminalIdAction(id: number, callback: (terminal: ExtHostTerminal) => void): void {
|
||||
// TODO: Use await this._getTerminalByIdEventually(id);
|
||||
let terminal = this._getTerminalById(id);
|
||||
if (terminal) {
|
||||
callback(terminal);
|
||||
} else {
|
||||
// Retry one more time in case the terminal has not yet been initialized.
|
||||
setTimeout(() => {
|
||||
terminal = this._getTerminalById(id);
|
||||
if (terminal) {
|
||||
callback(terminal);
|
||||
}
|
||||
}, EXT_HOST_CREATION_DELAY * 2);
|
||||
}
|
||||
}
|
||||
|
||||
public async $startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): Promise<void> {
|
||||
// Make sure the ExtHostTerminal exists so onDidOpenTerminal has fired before we call
|
||||
// Pseudoterminal.start
|
||||
@@ -517,7 +526,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
return id;
|
||||
}
|
||||
|
||||
private _onProcessExit(id: number, exitCode: number): void {
|
||||
private _onProcessExit(id: number, exitCode: number | undefined): void {
|
||||
this._bufferer.stopBuffering(id);
|
||||
|
||||
// Remove process reference
|
||||
@@ -532,10 +541,6 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
private _getTerminalByIdEventually(id: number, retries: number = 5): Promise<ExtHostTerminal | undefined> {
|
||||
if (!this._getTerminalPromises[id]) {
|
||||
this._getTerminalPromises[id] = this._createGetTerminalPromise(id, retries);
|
||||
} else {
|
||||
this._getTerminalPromises[id].then(c => {
|
||||
return this._createGetTerminalPromise(id, retries);
|
||||
});
|
||||
}
|
||||
return this._getTerminalPromises[id];
|
||||
}
|
||||
@@ -553,7 +558,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
} else {
|
||||
// This should only be needed immediately after createTerminalRenderer is called as
|
||||
// the ExtHostTerminal has not yet been iniitalized
|
||||
timeout(200).then(() => c(this._createGetTerminalPromise(id, retries - 1)));
|
||||
timeout(EXT_HOST_CREATION_DELAY * 2).then(() => c(this._createGetTerminalPromise(id, retries - 1)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -198,7 +198,13 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
private refreshPromise: Promise<void> = Promise.resolve();
|
||||
private refreshQueue: Promise<void> = Promise.resolve();
|
||||
|
||||
constructor(private viewId: string, options: vscode.TreeViewOptions<T>, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) {
|
||||
constructor(
|
||||
private viewId: string, options: vscode.TreeViewOptions<T>,
|
||||
private proxy: MainThreadTreeViewsShape,
|
||||
private commands: CommandsConverter,
|
||||
private logService: ILogService,
|
||||
private extension: IExtensionDescription
|
||||
) {
|
||||
super();
|
||||
if (extension.contributes && extension.contributes.views) {
|
||||
for (const location in extension.contributes.views) {
|
||||
@@ -250,7 +256,7 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
getChildren(parentHandle: TreeItemHandle | Root): Promise<ITreeItem[]> {
|
||||
const parentElement = parentHandle ? this.getExtensionElement(parentHandle) : undefined;
|
||||
if (parentHandle && !parentElement) {
|
||||
console.error(`No tree item with id \'${parentHandle}\' found.`);
|
||||
this.logService.error(`No tree item with id \'${parentHandle}\' found.`);
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/mode
|
||||
import * as vscode from 'vscode';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import * as editorRange from 'vs/editor/common/core/range';
|
||||
import { ISelection } from 'vs/editor/common/core/selection';
|
||||
@@ -31,7 +31,6 @@ import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
|
||||
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
|
||||
export interface PositionLike {
|
||||
line: number;
|
||||
character: number;
|
||||
@@ -255,7 +254,7 @@ export namespace MarkdownString {
|
||||
}
|
||||
|
||||
// extract uris into a separate object
|
||||
const resUris: { [href: string]: UriComponents } = Object.create(null);
|
||||
const resUris: { [href: string]: UriComponents; } = Object.create(null);
|
||||
res.uris = resUris;
|
||||
|
||||
const collectUri = (href: string): string => {
|
||||
@@ -277,7 +276,7 @@ export namespace MarkdownString {
|
||||
return res;
|
||||
}
|
||||
|
||||
function _uriMassage(part: string, bucket: { [n: string]: UriComponents }): string {
|
||||
function _uriMassage(part: string, bucket: { [n: string]: UriComponents; }): string {
|
||||
if (!part) {
|
||||
return part;
|
||||
}
|
||||
@@ -513,7 +512,7 @@ export namespace WorkspaceEdit {
|
||||
|
||||
export namespace SymbolKind {
|
||||
|
||||
const _fromMapping: { [kind: number]: modes.SymbolKind } = Object.create(null);
|
||||
const _fromMapping: { [kind: number]: modes.SymbolKind; } = Object.create(null);
|
||||
_fromMapping[types.SymbolKind.File] = modes.SymbolKind.File;
|
||||
_fromMapping[types.SymbolKind.Module] = modes.SymbolKind.Module;
|
||||
_fromMapping[types.SymbolKind.Namespace] = modes.SymbolKind.Namespace;
|
||||
@@ -627,8 +626,8 @@ export namespace DocumentSymbol {
|
||||
|
||||
export namespace CallHierarchyItem {
|
||||
|
||||
export function to(item: extHostProtocol.ICallHierarchyItemDto): vscode.CallHierarchyItem {
|
||||
return new types.CallHierarchyItem(
|
||||
export function to(item: extHostProtocol.ICallHierarchyItemDto): types.CallHierarchyItem {
|
||||
const result = new types.CallHierarchyItem(
|
||||
SymbolKind.to(item.kind),
|
||||
item.name,
|
||||
item.detail || '',
|
||||
@@ -636,6 +635,31 @@ export namespace CallHierarchyItem {
|
||||
Range.to(item.range),
|
||||
Range.to(item.selectionRange)
|
||||
);
|
||||
|
||||
result._sessionId = item._sessionId;
|
||||
result._itemId = item._itemId;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace CallHierarchyIncomingCall {
|
||||
|
||||
export function to(item: extHostProtocol.IIncomingCallDto): types.CallHierarchyIncomingCall {
|
||||
return new types.CallHierarchyIncomingCall(
|
||||
CallHierarchyItem.to(item.from),
|
||||
item.fromRanges.map(r => Range.to(r))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export namespace CallHierarchyOutgoingCall {
|
||||
|
||||
export function to(item: extHostProtocol.IOutgoingCallDto): types.CallHierarchyOutgoingCall {
|
||||
return new types.CallHierarchyOutgoingCall(
|
||||
CallHierarchyItem.to(item.to),
|
||||
item.fromRanges.map(r => Range.to(r))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ function es5ClassCompat(target: Function): any {
|
||||
@es5ClassCompat
|
||||
export class Disposable {
|
||||
|
||||
static from(...inDisposables: { dispose(): any }[]): Disposable {
|
||||
let disposables: ReadonlyArray<{ dispose(): any }> | undefined = inDisposables;
|
||||
static from(...inDisposables: { dispose(): any; }[]): Disposable {
|
||||
let disposables: ReadonlyArray<{ dispose(): any; }> | undefined = inDisposables;
|
||||
return new Disposable(function () {
|
||||
if (disposables) {
|
||||
for (const disposable of disposables) {
|
||||
@@ -333,9 +333,9 @@ export class Range {
|
||||
return this._start.line === this._end.line;
|
||||
}
|
||||
|
||||
with(change: { start?: Position, end?: Position }): Range;
|
||||
with(change: { start?: Position, end?: Position; }): Range;
|
||||
with(start?: Position, end?: Position): Range;
|
||||
with(startOrChange: Position | undefined | { start?: Position, end?: Position }, end: Position = this.end): Range {
|
||||
with(startOrChange: Position | undefined | { start?: Position, end?: Position; }, end: Position = this.end): Range {
|
||||
|
||||
if (startOrChange === null || end === null) {
|
||||
throw illegalArgument();
|
||||
@@ -589,15 +589,15 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
|
||||
|
||||
private _edits = new Array<IFileOperation | IFileTextEdit>();
|
||||
|
||||
renameFile(from: vscode.Uri, to: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void {
|
||||
renameFile(from: vscode.Uri, to: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean; }): void {
|
||||
this._edits.push({ _type: 1, from, to, options });
|
||||
}
|
||||
|
||||
createFile(uri: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void {
|
||||
createFile(uri: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean; }): void {
|
||||
this._edits.push({ _type: 1, from: undefined, to: uri, options });
|
||||
}
|
||||
|
||||
deleteFile(uri: vscode.Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean }): void {
|
||||
deleteFile(uri: vscode.Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean; }): void {
|
||||
this._edits.push({ _type: 1, from: uri, to: undefined, options });
|
||||
}
|
||||
|
||||
@@ -740,6 +740,18 @@ export class SnippetString {
|
||||
return this;
|
||||
}
|
||||
|
||||
appendChoice(values: string[], number: number = this._tabstop++): SnippetString {
|
||||
const value = SnippetString._escape(values.toString());
|
||||
|
||||
this.value += '${';
|
||||
this.value += number;
|
||||
this.value += '|';
|
||||
this.value += value;
|
||||
this.value += '|}';
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
appendVariable(name: string, defaultValue?: string | ((snippet: SnippetString) => any)): SnippetString {
|
||||
|
||||
if (typeof defaultValue === 'function') {
|
||||
@@ -1142,6 +1154,10 @@ export class SelectionRange {
|
||||
}
|
||||
|
||||
export class CallHierarchyItem {
|
||||
|
||||
_sessionId?: string;
|
||||
_itemId?: string;
|
||||
|
||||
kind: SymbolKind;
|
||||
name: string;
|
||||
detail?: string;
|
||||
@@ -1496,7 +1512,7 @@ export class Color {
|
||||
}
|
||||
}
|
||||
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
export type IColorFormat = string | { opaque: string, transparent: string; };
|
||||
|
||||
@es5ClassCompat
|
||||
export class ColorInformation {
|
||||
@@ -2051,13 +2067,13 @@ export class TreeItem {
|
||||
|
||||
label?: string | vscode.TreeItemLabel;
|
||||
resourceUri?: URI;
|
||||
iconPath?: string | URI | { light: string | URI; dark: string | URI };
|
||||
iconPath?: string | URI | { light: string | URI; dark: string | URI; };
|
||||
command?: vscode.Command;
|
||||
contextValue?: string;
|
||||
tooltip?: string;
|
||||
|
||||
constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState)
|
||||
constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState)
|
||||
constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState);
|
||||
constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState);
|
||||
constructor(arg1: string | vscode.TreeItemLabel | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) {
|
||||
if (URI.isUri(arg1)) {
|
||||
this.resourceUri = arg1;
|
||||
|
||||
@@ -4,17 +4,20 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
||||
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
|
||||
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol';
|
||||
import { Disposable } from './extHostTypes';
|
||||
import { Disposable as VSCodeDisposable } from './extHostTypes';
|
||||
|
||||
type IconPath = URI | { light: URI, dark: URI };
|
||||
|
||||
@@ -33,6 +36,7 @@ export class ExtHostWebview implements vscode.Webview {
|
||||
private readonly _initData: WebviewInitData,
|
||||
private readonly _workspace: IExtHostWorkspace | undefined,
|
||||
private readonly _extension: IExtensionDescription,
|
||||
private readonly _logService: ILogService,
|
||||
) { }
|
||||
|
||||
public dispose() {
|
||||
@@ -61,7 +65,7 @@ export class ExtHostWebview implements vscode.Webview {
|
||||
if (this._initData.isExtensionDevelopmentDebug && !this._hasCalledAsWebviewUri) {
|
||||
if (/(["'])vscode-resource:([^\s'"]+?)(["'])/i.test(value)) {
|
||||
this._hasCalledAsWebviewUri = true;
|
||||
console.warn(`${this._extension.identifier.value} created a webview that appears to use the vscode-resource scheme directly. Please migrate to use the 'webview.asWebviewUri' api instead: https://aka.ms/vscode-webview-use-aswebviewuri`);
|
||||
this._logService.warn(`${this._extension.identifier.value} created a webview that appears to use the vscode-resource scheme directly. Please migrate to use the 'webview.asWebviewUri' api instead: https://aka.ms/vscode-webview-use-aswebviewuri`);
|
||||
}
|
||||
}
|
||||
this._proxy.$setHtml(this._handle, value);
|
||||
@@ -91,7 +95,7 @@ export class ExtHostWebview implements vscode.Webview {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostWebviewEditor implements vscode.WebviewPanel {
|
||||
export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPanel {
|
||||
|
||||
private readonly _handle: WebviewPanelHandle;
|
||||
private readonly _proxy: MainThreadWebviewsShape;
|
||||
@@ -107,12 +111,14 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel {
|
||||
|
||||
_isDisposed: boolean = false;
|
||||
|
||||
readonly _onDisposeEmitter = new Emitter<void>();
|
||||
readonly _onDisposeEmitter = this._register(new Emitter<void>());
|
||||
public readonly onDidDispose: Event<void> = this._onDisposeEmitter.event;
|
||||
|
||||
readonly _onDidChangeViewStateEmitter = new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>();
|
||||
readonly _onDidChangeViewStateEmitter = this._register(new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>());
|
||||
public readonly onDidChangeViewState: Event<vscode.WebviewPanelOnDidChangeViewStateEvent> = this._onDidChangeViewStateEmitter.event;
|
||||
|
||||
public _capabilities?: vscode.WebviewEditorCapabilities;
|
||||
|
||||
constructor(
|
||||
handle: WebviewPanelHandle,
|
||||
proxy: MainThreadWebviewsShape,
|
||||
@@ -122,6 +128,7 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel {
|
||||
editorOptions: vscode.WebviewPanelOptions,
|
||||
webview: ExtHostWebview
|
||||
) {
|
||||
super();
|
||||
this._handle = handle;
|
||||
this._proxy = proxy;
|
||||
this._viewType = viewType;
|
||||
@@ -135,16 +142,12 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDisposed = true;
|
||||
this._onDisposeEmitter.fire();
|
||||
|
||||
this._proxy.$disposeWebview(this._handle);
|
||||
|
||||
this._webview.dispose();
|
||||
|
||||
this._onDisposeEmitter.dispose();
|
||||
this._onDidChangeViewStateEmitter.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
get webview() {
|
||||
@@ -236,6 +239,23 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel {
|
||||
});
|
||||
}
|
||||
|
||||
_setCapabilities(capabilities: vscode.WebviewEditorCapabilities) {
|
||||
this._capabilities = capabilities;
|
||||
if (capabilities.editingCapability) {
|
||||
this._register(capabilities.editingCapability.onEdit(edit => {
|
||||
this._proxy.$onEdit(this._handle, JSON.stringify(edit));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
_undoEdits(edits: string[]): void {
|
||||
assertIsDefined(this._capabilities).editingCapability?.undoEdits(edits);
|
||||
}
|
||||
|
||||
_redoEdits(edits: string[]): void {
|
||||
assertIsDefined(this._capabilities).editingCapability?.applyEdits(edits);
|
||||
}
|
||||
|
||||
private assertNotDisposed() {
|
||||
if (this._isDisposed) {
|
||||
throw new Error('Webview is disposed');
|
||||
@@ -258,6 +278,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
mainContext: IMainContext,
|
||||
private readonly initData: WebviewInitData,
|
||||
private readonly workspace: IExtHostWorkspace | undefined,
|
||||
private readonly _logService: ILogService,
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadWebviews);
|
||||
}
|
||||
@@ -278,7 +299,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
const handle = ExtHostWebviews.newHandle();
|
||||
this._proxy.$createWebviewPanel({ id: extension.identifier, location: extension.extensionLocation }, handle, viewType, title, webviewShowOptions, convertWebviewOptions(extension, this.workspace, options));
|
||||
|
||||
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension);
|
||||
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
|
||||
const panel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, viewColumn, options, webview);
|
||||
this._webviewPanels.set(handle, panel);
|
||||
return panel;
|
||||
@@ -296,7 +317,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
this._serializers.set(viewType, { serializer, extension });
|
||||
this._proxy.$registerSerializer(viewType);
|
||||
|
||||
return new Disposable(() => {
|
||||
return new VSCodeDisposable(() => {
|
||||
this._serializers.delete(viewType);
|
||||
this._proxy.$unregisterSerializer(viewType);
|
||||
});
|
||||
@@ -315,7 +336,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
this._editorProviders.set(viewType, { extension, provider, });
|
||||
this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {});
|
||||
|
||||
return new Disposable(() => {
|
||||
return new VSCodeDisposable(() => {
|
||||
this._editorProviders.delete(viewType);
|
||||
this._proxy.$unregisterEditorProvider(viewType);
|
||||
});
|
||||
@@ -335,7 +356,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
_handle: WebviewPanelHandle,
|
||||
extensionId: string
|
||||
): void {
|
||||
console.warn(`${extensionId} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
|
||||
this._logService.warn(`${extensionId} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
|
||||
}
|
||||
|
||||
public $onDidChangeWebviewPanelViewStates(newStates: WebviewPanelViewStateData): void {
|
||||
@@ -373,16 +394,15 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
}
|
||||
}
|
||||
|
||||
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void> {
|
||||
async $onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void> {
|
||||
const panel = this.getWebviewPanel(handle);
|
||||
if (panel) {
|
||||
panel.dispose();
|
||||
this._webviewPanels.delete(handle);
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
$deserializeWebviewPanel(
|
||||
async $deserializeWebviewPanel(
|
||||
webviewHandle: WebviewPanelHandle,
|
||||
viewType: string,
|
||||
title: string,
|
||||
@@ -392,18 +412,14 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
): Promise<void> {
|
||||
const entry = this._serializers.get(viewType);
|
||||
if (!entry) {
|
||||
return Promise.reject(new Error(`No serializer found for '${viewType}'`));
|
||||
throw new Error(`No serializer found for '${viewType}'`);
|
||||
}
|
||||
const { serializer, extension } = entry;
|
||||
|
||||
const webview = new ExtHostWebview(webviewHandle, this._proxy, options, this.initData, this.workspace, extension);
|
||||
const webview = new ExtHostWebview(webviewHandle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
|
||||
const revivedPanel = new ExtHostWebviewEditor(webviewHandle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
|
||||
this._webviewPanels.set(webviewHandle, revivedPanel);
|
||||
return Promise.resolve(serializer.deserializeWebviewPanel(revivedPanel, state));
|
||||
}
|
||||
|
||||
private getWebviewPanel(handle: WebviewPanelHandle): ExtHostWebviewEditor | undefined {
|
||||
return this._webviewPanels.get(handle);
|
||||
await serializer.deserializeWebviewPanel(revivedPanel, state);
|
||||
}
|
||||
|
||||
async $resolveWebviewEditor(
|
||||
@@ -418,11 +434,33 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
if (!entry) {
|
||||
return Promise.reject(new Error(`No provider found for '${viewType}'`));
|
||||
}
|
||||
|
||||
const { provider, extension } = entry;
|
||||
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension);
|
||||
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
|
||||
const revivedPanel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
|
||||
this._webviewPanels.set(handle, revivedPanel);
|
||||
await Promise.resolve(provider.resolveWebviewEditor({ resource: URI.revive(resource) }, revivedPanel));
|
||||
const capabilities = await provider.resolveWebviewEditor({ resource: URI.revive(resource) }, revivedPanel);
|
||||
revivedPanel._setCapabilities(capabilities);
|
||||
}
|
||||
|
||||
$undoEdits(handle: WebviewPanelHandle, edits: string[]): void {
|
||||
const panel = this.getWebviewPanel(handle);
|
||||
if (!panel) {
|
||||
return;
|
||||
}
|
||||
panel._undoEdits(edits);
|
||||
}
|
||||
|
||||
$redoEdits(handle: WebviewPanelHandle, edits: string[]): void {
|
||||
const panel = this.getWebviewPanel(handle);
|
||||
if (!panel) {
|
||||
return;
|
||||
}
|
||||
panel._redoEdits(edits);
|
||||
}
|
||||
|
||||
private getWebviewPanel(handle: WebviewPanelHandle): ExtHostWebviewEditor | undefined {
|
||||
return this._webviewPanels.get(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +480,7 @@ function getDefaultLocalResourceRoots(
|
||||
workspace: IExtHostWorkspace | undefined,
|
||||
): URI[] {
|
||||
return [
|
||||
...(workspace && workspace.getWorkspaceFolders() || []).map(x => x.uri),
|
||||
...(workspace?.getWorkspaceFolders() || []).map(x => x.uri),
|
||||
extension.extensionLocation,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -39,7 +39,9 @@ export class ExtHostWindow implements ExtHostWindowShape {
|
||||
}
|
||||
|
||||
openUri(stringOrUri: string | URI, options: IOpenUriOptions): Promise<boolean> {
|
||||
let uriAsString: string | undefined;
|
||||
if (typeof stringOrUri === 'string') {
|
||||
uriAsString = stringOrUri;
|
||||
try {
|
||||
stringOrUri = URI.parse(stringOrUri);
|
||||
} catch (e) {
|
||||
@@ -51,7 +53,7 @@ export class ExtHostWindow implements ExtHostWindowShape {
|
||||
} else if (stringOrUri.scheme === Schemas.command) {
|
||||
return Promise.reject(`Invalid scheme '${stringOrUri.scheme}'`);
|
||||
}
|
||||
return this._proxy.$openUri(stringOrUri, options);
|
||||
return this._proxy.$openUri(stringOrUri, uriAsString, options);
|
||||
}
|
||||
|
||||
async asExternalUri(uri: URI, options: IOpenUriOptions): Promise<URI> {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
|
||||
import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
|
||||
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
|
||||
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
|
||||
import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
|
||||
import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths';
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
|
||||
@@ -38,7 +38,7 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors);
|
||||
registerSingleton(IExtHostTerminalService, ExtHostTerminalService);
|
||||
registerSingleton(IExtHostTask, ExtHostTask);
|
||||
registerSingleton(IExtHostDebugService, ExtHostDebugService);
|
||||
registerSingleton(IExtHostSearch, ExtHostSearch);
|
||||
registerSingleton(IExtHostSearch, NativeExtHostSearch);
|
||||
registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths);
|
||||
registerSingleton(IExtHostExtensionService, ExtHostExtensionService);
|
||||
registerSingleton(IExtHostStorage, ExtHostStorage);
|
||||
|
||||
@@ -38,6 +38,7 @@ import { ISignService } from 'vs/platform/sign/common/sign';
|
||||
import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugServiceShape {
|
||||
|
||||
@@ -114,7 +115,7 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
|
||||
|
||||
this._onDidStartDebugSession = new Emitter<vscode.DebugSession>();
|
||||
this._onDidTerminateDebugSession = new Emitter<vscode.DebugSession>();
|
||||
this._onDidChangeActiveDebugSession = new Emitter<vscode.DebugSession>();
|
||||
this._onDidChangeActiveDebugSession = new Emitter<vscode.DebugSession | undefined>();
|
||||
this._onDidReceiveDebugSessionCustomEvent = new Emitter<vscode.DebugSessionCustomEvent>();
|
||||
|
||||
this._debugServiceProxy = extHostRpcService.getProxy(MainContext.MainThreadDebugService);
|
||||
@@ -138,6 +139,32 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
|
||||
});
|
||||
}
|
||||
|
||||
public asDebugSourceUri(src: vscode.DebugSource, session?: vscode.DebugSession): URI {
|
||||
|
||||
const source = <any>src;
|
||||
|
||||
if (typeof source.sourceReference === 'number') {
|
||||
// src can be retrieved via DAP's "source" request
|
||||
|
||||
let debug = `debug:${encodeURIComponent(source.path || '')}`;
|
||||
let sep = '?';
|
||||
|
||||
if (session) {
|
||||
debug += `${sep}session=${encodeURIComponent(session.id)}`;
|
||||
sep = '&';
|
||||
}
|
||||
|
||||
debug += `${sep}ref=${source.sourceReference}`;
|
||||
|
||||
return URI.parse(debug);
|
||||
} else if (source.path) {
|
||||
// src is just a local file path
|
||||
return URI.file(source.path);
|
||||
} else {
|
||||
throw new Error(`cannot create uri from DAP 'source' object; properties 'path' and 'sourceReference' are both missing.`);
|
||||
}
|
||||
}
|
||||
|
||||
private registerAllDebugTypes(extensionRegistry: ExtensionDescriptionRegistry) {
|
||||
|
||||
const debugTypes: string[] = [];
|
||||
@@ -485,11 +512,11 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
|
||||
}
|
||||
this._debugServiceProxy.$acceptDAError(debugAdapterHandle, err.name, err.message, err.stack);
|
||||
});
|
||||
debugAdapter.onExit((code: number) => {
|
||||
debugAdapter.onExit((code: number | null) => {
|
||||
if (tracker && tracker.onExit) {
|
||||
tracker.onExit(code, undefined);
|
||||
tracker.onExit(withNullAsUndefined(code), undefined);
|
||||
}
|
||||
this._debugServiceProxy.$acceptDAExit(debugAdapterHandle, code, undefined);
|
||||
this._debugServiceProxy.$acceptDAExit(debugAdapterHandle, withNullAsUndefined(code), undefined);
|
||||
});
|
||||
|
||||
if (tracker && tracker.onWillStartSession) {
|
||||
|
||||
@@ -3,47 +3,37 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery, isSerializedFileMatch, ISerializedSearchProgressItem } from 'vs/workbench/services/search/common/search';
|
||||
import { FileSearchManager } from 'vs/workbench/services/search/node/fileSearchManager';
|
||||
import { IFileQuery, IRawFileQuery, ISearchCompleteStats, isSerializedFileMatch, ISerializedSearchProgressItem, ITextQuery } from 'vs/workbench/services/search/common/search';
|
||||
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
|
||||
import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrepSearchProvider';
|
||||
import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils';
|
||||
import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
import { ExtHostSearch, reviveQuery } from 'vs/workbench/api/common/extHostSearch';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
|
||||
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
|
||||
|
||||
export class ExtHostSearch implements ExtHostSearchShape {
|
||||
export class NativeExtHostSearch extends ExtHostSearch {
|
||||
|
||||
private readonly _proxy: MainThreadSearchShape;
|
||||
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider>();
|
||||
private readonly _textSearchUsedSchemes = new Set<string>();
|
||||
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider>();
|
||||
private readonly _fileSearchUsedSchemes = new Set<string>();
|
||||
private _handlePool: number = 0;
|
||||
protected _pfs: typeof pfs = pfs; // allow extending for tests
|
||||
|
||||
private _internalFileSearchHandle: number = -1;
|
||||
private _internalFileSearchProvider: SearchService | null = null;
|
||||
|
||||
private _fileSearchManager: FileSearchManager;
|
||||
|
||||
protected _pfs: typeof pfs = pfs; // allow extending for tests
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService extHostRpc: IExtHostRpcService,
|
||||
@IExtHostInitDataService initData: IExtHostInitDataService,
|
||||
@IURITransformerService private _uriTransformer: IURITransformerService,
|
||||
@ILogService private _logService: ILogService,
|
||||
@IURITransformerService _uriTransformer: IURITransformerService,
|
||||
@ILogService _logService: ILogService,
|
||||
) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadSearch);
|
||||
this._fileSearchManager = new FileSearchManager();
|
||||
super(extHostRpc, _uriTransformer, _logService);
|
||||
|
||||
if (initData.remote.isRemote && initData.remote.authority) {
|
||||
this._registerEHSearchProviders();
|
||||
@@ -52,47 +42,11 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
|
||||
private _registerEHSearchProviders(): void {
|
||||
const outputChannel = new OutputChannel(this._logService);
|
||||
this.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel));
|
||||
this.registerInternalFileSearchProvider('file', new SearchService());
|
||||
this.registerTextSearchProvider(Schemas.file, new RipgrepSearchProvider(outputChannel));
|
||||
this.registerInternalFileSearchProvider(Schemas.file, new SearchService());
|
||||
}
|
||||
|
||||
private _transformScheme(scheme: string): string {
|
||||
return this._uriTransformer.transformOutgoingScheme(scheme);
|
||||
}
|
||||
|
||||
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable {
|
||||
if (this._textSearchUsedSchemes.has(scheme)) {
|
||||
throw new Error(`a text search provider for the scheme '${scheme}' is already registered`);
|
||||
}
|
||||
|
||||
this._textSearchUsedSchemes.add(scheme);
|
||||
const handle = this._handlePool++;
|
||||
this._textSearchProvider.set(handle, provider);
|
||||
this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme));
|
||||
return toDisposable(() => {
|
||||
this._textSearchUsedSchemes.delete(scheme);
|
||||
this._textSearchProvider.delete(handle);
|
||||
this._proxy.$unregisterProvider(handle);
|
||||
});
|
||||
}
|
||||
|
||||
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable {
|
||||
if (this._fileSearchUsedSchemes.has(scheme)) {
|
||||
throw new Error(`a file search provider for the scheme '${scheme}' is already registered`);
|
||||
}
|
||||
|
||||
this._fileSearchUsedSchemes.add(scheme);
|
||||
const handle = this._handlePool++;
|
||||
this._fileSearchProvider.set(handle, provider);
|
||||
this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme));
|
||||
return toDisposable(() => {
|
||||
this._fileSearchUsedSchemes.delete(scheme);
|
||||
this._fileSearchProvider.delete(handle);
|
||||
this._proxy.$unregisterProvider(handle);
|
||||
});
|
||||
}
|
||||
|
||||
registerInternalFileSearchProvider(scheme: string, provider: SearchService): IDisposable {
|
||||
private registerInternalFileSearchProvider(scheme: string, provider: SearchService): IDisposable {
|
||||
const handle = this._handlePool++;
|
||||
this._internalFileSearchProvider = provider;
|
||||
this._internalFileSearchHandle = handle;
|
||||
@@ -103,23 +57,16 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
});
|
||||
}
|
||||
|
||||
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const query = reviveQuery(rawQuery);
|
||||
if (handle === this._internalFileSearchHandle) {
|
||||
return this.doInternalFileSearch(handle, session, query, token);
|
||||
} else {
|
||||
const provider = this._fileSearchProvider.get(handle);
|
||||
if (provider) {
|
||||
return this._fileSearchManager.fileSearch(query, provider, batch => {
|
||||
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
|
||||
}, token);
|
||||
} else {
|
||||
throw new Error('unknown provider: ' + handle);
|
||||
}
|
||||
}
|
||||
|
||||
return super.$provideFileSearchResults(handle, session, rawQuery, token);
|
||||
}
|
||||
|
||||
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const onResult = (ev: ISerializedSearchProgressItem) => {
|
||||
if (isSerializedFileMatch(ev)) {
|
||||
ev = [ev];
|
||||
@@ -147,37 +94,11 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
this._internalFileSearchProvider.clearCache(cacheKey);
|
||||
}
|
||||
|
||||
this._fileSearchManager.clearCache(cacheKey);
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
return super.$clearCache(cacheKey);
|
||||
}
|
||||
|
||||
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const provider = this._textSearchProvider.get(handle);
|
||||
if (!provider || !provider.provideTextSearchResults) {
|
||||
throw new Error(`Unknown provider ${handle}`);
|
||||
}
|
||||
|
||||
const query = reviveQuery(rawQuery);
|
||||
const engine = new TextSearchManager(query, provider, this._pfs);
|
||||
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
|
||||
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
|
||||
return new NativeTextSearchManager(query, provider);
|
||||
}
|
||||
}
|
||||
|
||||
function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
|
||||
return {
|
||||
...<any>rawQuery, // TODO
|
||||
...{
|
||||
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
|
||||
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolderQuery<URI> {
|
||||
return {
|
||||
...rawFolderQuery,
|
||||
folder: URI.revive(rawFolderQuery.folder)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export class ExtensionStoragePaths implements IExtensionStoragePaths {
|
||||
|
||||
@@ -22,7 +23,10 @@ export class ExtensionStoragePaths implements IExtensionStoragePaths {
|
||||
readonly whenReady: Promise<string | undefined>;
|
||||
private _value?: string;
|
||||
|
||||
constructor(@IExtHostInitDataService initData: IExtHostInitDataService) {
|
||||
constructor(
|
||||
@IExtHostInitDataService initData: IExtHostInitDataService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
) {
|
||||
this._workspace = withNullAsUndefined(initData.workspace);
|
||||
this._environment = initData.environment;
|
||||
this.whenReady = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value);
|
||||
@@ -69,7 +73,7 @@ export class ExtensionStoragePaths implements IExtensionStoragePaths {
|
||||
return storagePath;
|
||||
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
this._logService.error(e);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
import { ExtHostTaskBase, TaskHandleDTO, TaskDTO, CustomExecutionDTO, HandlerData } from 'vs/workbench/api/common/extHostTask';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export class ExtHostTask extends ExtHostTaskBase {
|
||||
private _variableResolver: ExtHostVariableResolverService | undefined;
|
||||
@@ -32,9 +33,10 @@ export class ExtHostTask extends ExtHostTaskBase {
|
||||
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
|
||||
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
|
||||
@IExtHostConfiguration configurationService: IExtHostConfiguration,
|
||||
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
|
||||
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
|
||||
@ILogService logService: ILogService
|
||||
) {
|
||||
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService);
|
||||
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService);
|
||||
if (initData.remote.isRemote && initData.remote.authority) {
|
||||
this.registerTaskSystem(Schemas.vscodeRemote, {
|
||||
scheme: Schemas.vscodeRemote,
|
||||
@@ -71,7 +73,7 @@ export class ExtHostTask extends ExtHostTaskBase {
|
||||
if (value) {
|
||||
for (let task of value) {
|
||||
if (!task.definition || !validTypes[task.definition.type]) {
|
||||
console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
|
||||
this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
|
||||
}
|
||||
|
||||
const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension);
|
||||
|
||||
@@ -45,14 +45,14 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
|
||||
}
|
||||
|
||||
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
|
||||
const terminal = new ExtHostTerminal(this._proxy, name);
|
||||
const terminal = new ExtHostTerminal(this._proxy, { name, shellPath, shellArgs }, name);
|
||||
terminal.create(shellPath, shellArgs);
|
||||
this._terminals.push(terminal);
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal {
|
||||
const terminal = new ExtHostTerminal(this._proxy, options.name);
|
||||
const terminal = new ExtHostTerminal(this._proxy, options, options.name);
|
||||
terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv, options.hideFromUser);
|
||||
this._terminals.push(terminal);
|
||||
return terminal;
|
||||
|
||||
Reference in New Issue
Block a user