mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-28 17:23:19 -05:00
Refresh master with initial release/0.24 snapshot (#332)
* Initial port of release/0.24 source code * Fix additional headers * Fix a typo in launch.json
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { TrieMap } from 'vs/base/common/map';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { score } from 'vs/editor/common/modes/languageSelector';
|
||||
import * as Platform from 'vs/base/common/platform';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
@@ -54,7 +54,9 @@ import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { ExtHostThreadService } from 'vs/workbench/services/thread/node/extHostThreadService';
|
||||
import { ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { ExtHostDialogs } from 'vs/workbench/api/node/extHostDialogs';
|
||||
import { MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { ExtHostFileSystem } from 'vs/workbench/api/node/extHostFileSystem';
|
||||
import { FileChangeType, FileType } from 'vs/platform/files/common/files';
|
||||
import { ExtHostDecorations } from 'vs/workbench/api/node/extHostDecorations';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription): typeof vscode;
|
||||
@@ -76,31 +78,33 @@ function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
|
||||
export function createApiFactory(
|
||||
initData: IInitData,
|
||||
threadService: ExtHostThreadService,
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration,
|
||||
extensionService: ExtHostExtensionService
|
||||
): IExtensionApiFactory {
|
||||
|
||||
const mainThreadTelemetry = threadService.get(MainContext.MainThreadTelemetry);
|
||||
|
||||
// Addressable instances
|
||||
const extHostHeapService = threadService.set(ExtHostContext.ExtHostHeapService, new ExtHostHeapService());
|
||||
const extHostDocumentsAndEditors = threadService.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(threadService, extensionService));
|
||||
const extHostDecorations = threadService.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(threadService));
|
||||
const extHostDocumentsAndEditors = threadService.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(threadService));
|
||||
const extHostDocuments = threadService.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(threadService, extHostDocumentsAndEditors));
|
||||
const extHostDocumentContentProviders = threadService.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(threadService, extHostDocumentsAndEditors));
|
||||
const extHostDocumentSaveParticipant = threadService.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostDocuments, threadService.get(MainContext.MainThreadWorkspace)));
|
||||
const extHostDocumentSaveParticipant = threadService.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostDocuments, threadService.get(MainContext.MainThreadEditors)));
|
||||
const extHostEditors = threadService.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(threadService, extHostDocumentsAndEditors));
|
||||
const extHostCommands = threadService.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(threadService, extHostHeapService));
|
||||
const extHostTreeViews = threadService.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(threadService.get(MainContext.MainThreadTreeViews), extHostCommands));
|
||||
const extHostWorkspace = threadService.set(ExtHostContext.ExtHostWorkspace, new ExtHostWorkspace(threadService, initData.workspace));
|
||||
threadService.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace);
|
||||
// {{SQL CARBON EDIT}}
|
||||
// const extHostDebugService = threadService.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(threadService, extHostWorkspace));
|
||||
const extHostConfiguration = threadService.set(ExtHostContext.ExtHostConfiguration, new ExtHostConfiguration(threadService.get(MainContext.MainThreadConfiguration), extHostWorkspace, initData.configuration));
|
||||
threadService.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration);
|
||||
const extHostDiagnostics = threadService.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(threadService));
|
||||
const languageFeatures = threadService.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(threadService, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics));
|
||||
const extHostFileSystem = threadService.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(threadService));
|
||||
const extHostFileSystemEvent = threadService.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService());
|
||||
const extHostQuickOpen = threadService.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(threadService));
|
||||
const extHostQuickOpen = threadService.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(threadService, extHostWorkspace, extHostCommands));
|
||||
const extHostTerminalService = threadService.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(threadService));
|
||||
const extHostSCM = threadService.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(threadService, extHostCommands));
|
||||
const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService));
|
||||
const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService, extHostWorkspace));
|
||||
const extHostCredentials = threadService.set(ExtHostContext.ExtHostCredentials, new ExtHostCredentials(threadService));
|
||||
const extHostWindow = threadService.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(threadService));
|
||||
threadService.set(ExtHostContext.ExtHostExtensionService, extensionService);
|
||||
@@ -138,20 +142,6 @@ export function createApiFactory(
|
||||
}
|
||||
}
|
||||
|
||||
const apiUsage = new class {
|
||||
private _seen = new Set<string>();
|
||||
publicLog(apiName: string) {
|
||||
if (this._seen.has(apiName)) {
|
||||
return undefined;
|
||||
}
|
||||
this._seen.add(apiName);
|
||||
return mainThreadTelemetry.$publicLog('apiUsage', {
|
||||
name: apiName,
|
||||
extension: extension.id
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// namespace: commands
|
||||
const commands: typeof vscode.commands = {
|
||||
registerCommand<T>(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
|
||||
@@ -283,13 +273,12 @@ export function createApiFactory(
|
||||
registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable {
|
||||
return languageFeatures.registerDocumentLinkProvider(selector, provider);
|
||||
},
|
||||
registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable {
|
||||
return languageFeatures.registerColorProvider(selector, provider);
|
||||
},
|
||||
setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
|
||||
return languageFeatures.setLanguageConfiguration(language, configuration);
|
||||
},
|
||||
// proposed API
|
||||
registerColorProvider: proposedApiFunction(extension, (selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider) => {
|
||||
return languageFeatures.registerColorProvider(selector, provider);
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// namespace: window
|
||||
@@ -335,9 +324,9 @@ export function createApiFactory(
|
||||
get state() {
|
||||
return extHostWindow.state;
|
||||
},
|
||||
onDidChangeWindowState: proposedApiFunction(extension, (listener, thisArg?, disposables?) => {
|
||||
onDidChangeWindowState(listener, thisArg?, disposables?) {
|
||||
return extHostWindow.onDidChangeWindowState(listener, thisArg, disposables);
|
||||
}),
|
||||
},
|
||||
showInformationMessage(message, first, ...rest) {
|
||||
return extHostMessageService.showMessage(extension, Severity.Info, message, first, rest);
|
||||
},
|
||||
@@ -350,9 +339,18 @@ export function createApiFactory(
|
||||
showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken) {
|
||||
return extHostQuickOpen.showQuickPick(items, options, token);
|
||||
},
|
||||
showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) {
|
||||
return extHostQuickOpen.showWorkspaceFolderPick(options);
|
||||
},
|
||||
showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) {
|
||||
return extHostQuickOpen.showInput(options, token);
|
||||
},
|
||||
showOpenDialog(options) {
|
||||
return extHostDialogs.showOpenDialog(options);
|
||||
},
|
||||
showSaveDialog(options) {
|
||||
return extHostDialogs.showSaveDialog(options);
|
||||
},
|
||||
createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem {
|
||||
return extHostStatusBar.createStatusBarEntry(extension.id, <number>position, priority);
|
||||
},
|
||||
@@ -382,15 +380,14 @@ export function createApiFactory(
|
||||
sampleFunction: proposedApiFunction(extension, () => {
|
||||
return extHostMessageService.showMessage(extension, Severity.Info, 'Hello Proposed Api!', {}, []);
|
||||
}),
|
||||
showOpenDialog: proposedApiFunction(extension, options => {
|
||||
return extHostDialogs.showOpenDialog(options);
|
||||
registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => {
|
||||
return extHostDecorations.registerDecorationProvider(provider, extension.id);
|
||||
})
|
||||
};
|
||||
|
||||
// namespace: workspace
|
||||
const workspace: typeof vscode.workspace = {
|
||||
get rootPath() {
|
||||
apiUsage.publicLog('workspace#rootPath');
|
||||
return extHostWorkspace.getPath();
|
||||
},
|
||||
set rootPath(value) {
|
||||
@@ -400,11 +397,15 @@ export function createApiFactory(
|
||||
return extHostWorkspace.getWorkspaceFolder(resource);
|
||||
},
|
||||
get workspaceFolders() {
|
||||
apiUsage.publicLog('workspace#workspaceFolders');
|
||||
return extHostWorkspace.getWorkspaceFolders();
|
||||
},
|
||||
get name() {
|
||||
return extHostWorkspace.workspace ? extHostWorkspace.workspace.name : undefined;
|
||||
},
|
||||
set name(value) {
|
||||
throw errors.readonly();
|
||||
},
|
||||
onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) {
|
||||
apiUsage.publicLog('workspace#onDidChangeWorkspaceFolders');
|
||||
return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables);
|
||||
},
|
||||
asRelativePath: (pathOrUri, includeWorkspace) => {
|
||||
@@ -417,7 +418,7 @@ export function createApiFactory(
|
||||
return extHostWorkspace.saveAll(includeUntitled);
|
||||
},
|
||||
applyEdit(edit: vscode.WorkspaceEdit): TPromise<boolean> {
|
||||
return extHostWorkspace.appyEdit(edit);
|
||||
return extHostEditors.applyWorkspaceEdit(edit);
|
||||
},
|
||||
createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => {
|
||||
return extHostFileSystemEvent.createFileSystemWatcher(pattern, ignoreCreate, ignoreChange, ignoreDelete);
|
||||
@@ -432,12 +433,12 @@ export function createApiFactory(
|
||||
let uriPromise: TPromise<URI>;
|
||||
|
||||
let options = uriOrFileNameOrOptions as { language?: string; content?: string; };
|
||||
if (!options || typeof options.language === 'string') {
|
||||
uriPromise = extHostDocuments.createDocumentData(options);
|
||||
} else if (typeof uriOrFileNameOrOptions === 'string') {
|
||||
if (typeof uriOrFileNameOrOptions === 'string') {
|
||||
uriPromise = TPromise.as(URI.file(uriOrFileNameOrOptions));
|
||||
} else if (uriOrFileNameOrOptions instanceof URI) {
|
||||
uriPromise = TPromise.as(<URI>uriOrFileNameOrOptions);
|
||||
uriPromise = TPromise.as(uriOrFileNameOrOptions);
|
||||
} else if (!options || typeof options === 'object') {
|
||||
uriPromise = extHostDocuments.createDocumentData(options);
|
||||
} else {
|
||||
throw new Error('illegal argument - uriOrFileNameOrOptions');
|
||||
}
|
||||
@@ -467,8 +468,9 @@ export function createApiFactory(
|
||||
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
|
||||
return extHostConfiguration.onDidChangeConfiguration(listener, thisArgs, disposables);
|
||||
},
|
||||
getConfiguration: (section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration => {
|
||||
return extHostConfiguration.getConfiguration(section, <URI>resource);
|
||||
getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration {
|
||||
resource = arguments.length === 1 ? void 0 : resource;
|
||||
return extHostConfiguration.getConfiguration(section, resource, extension.id);
|
||||
},
|
||||
registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
|
||||
return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
|
||||
@@ -477,7 +479,7 @@ export function createApiFactory(
|
||||
return extHostTask.registerTaskProvider(extension, provider);
|
||||
},
|
||||
registerFileSystemProvider: proposedApiFunction(extension, (authority, provider) => {
|
||||
return extHostWorkspace.registerFileSystemProvider(authority, provider);
|
||||
return extHostFileSystem.registerFileSystemProvider(authority, provider);
|
||||
})
|
||||
};
|
||||
|
||||
@@ -486,20 +488,15 @@ export function createApiFactory(
|
||||
get inputBox() {
|
||||
return extHostSCM.getLastInputBox(extension);
|
||||
},
|
||||
createSourceControl(id: string, label: string) {
|
||||
mainThreadTelemetry.$publicLog('registerSCMProvider', {
|
||||
extensionId: extension.id,
|
||||
providerId: id,
|
||||
providerLabel: label
|
||||
});
|
||||
|
||||
return extHostSCM.createSourceControl(extension, id, label);
|
||||
createSourceControl(id: string, label: string, rootUri?: vscode.Uri) {
|
||||
return extHostSCM.createSourceControl(extension, id, label, rootUri);
|
||||
}
|
||||
};
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
// delete namespace: debug
|
||||
|
||||
|
||||
// namespace: credentials
|
||||
const credentials = {
|
||||
readSecret(service: string, account: string): Thenable<string | undefined> {
|
||||
@@ -530,11 +527,13 @@ export function createApiFactory(
|
||||
CancellationTokenSource: CancellationTokenSource,
|
||||
CodeLens: extHostTypes.CodeLens,
|
||||
Color: extHostTypes.Color,
|
||||
ColorRange: extHostTypes.ColorRange,
|
||||
ColorPresentation: extHostTypes.ColorPresentation,
|
||||
ColorInformation: extHostTypes.ColorInformation,
|
||||
EndOfLine: extHostTypes.EndOfLine,
|
||||
CompletionItem: extHostTypes.CompletionItem,
|
||||
CompletionItemKind: extHostTypes.CompletionItemKind,
|
||||
CompletionList: extHostTypes.CompletionList,
|
||||
CompletionTriggerKind: extHostTypes.CompletionTriggerKind,
|
||||
Diagnostic: extHostTypes.Diagnostic,
|
||||
DiagnosticSeverity: extHostTypes.DiagnosticSeverity,
|
||||
Disposable: extHostTypes.Disposable,
|
||||
@@ -545,7 +544,7 @@ export function createApiFactory(
|
||||
Hover: extHostTypes.Hover,
|
||||
IndentAction: languageConfiguration.IndentAction,
|
||||
Location: extHostTypes.Location,
|
||||
MarkdownString: MarkdownString,
|
||||
MarkdownString: extHostTypes.MarkdownString,
|
||||
OverviewRulerLane: EditorCommon.OverviewRulerLane,
|
||||
ParameterInformation: extHostTypes.ParameterInformation,
|
||||
Position: extHostTypes.Position,
|
||||
@@ -564,7 +563,7 @@ export function createApiFactory(
|
||||
TextEditorRevealType: extHostTypes.TextEditorRevealType,
|
||||
TextEditorSelectionChangeKind: extHostTypes.TextEditorSelectionChangeKind,
|
||||
DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior,
|
||||
Uri: <any>URI,
|
||||
Uri: URI,
|
||||
ViewColumn: extHostTypes.ViewColumn,
|
||||
WorkspaceEdit: extHostTypes.WorkspaceEdit,
|
||||
ProgressLocation: extHostTypes.ProgressLocation,
|
||||
@@ -577,8 +576,14 @@ export function createApiFactory(
|
||||
TaskGroup: extHostTypes.TaskGroup,
|
||||
ProcessExecution: extHostTypes.ProcessExecution,
|
||||
ShellExecution: extHostTypes.ShellExecution,
|
||||
TaskScope: extHostTypes.TaskScope,
|
||||
Task: extHostTypes.Task,
|
||||
ConfigurationTarget: extHostTypes.ConfigurationTarget
|
||||
ConfigurationTarget: extHostTypes.ConfigurationTarget,
|
||||
RelativePattern: extHostTypes.RelativePattern,
|
||||
|
||||
// TODO@JOH,remote
|
||||
FileChangeType: <any>FileChangeType,
|
||||
FileType: <any>FileType
|
||||
};
|
||||
if (extension.enableProposedApi && extension.isBuiltin) {
|
||||
api['credentials'] = credentials;
|
||||
@@ -619,7 +624,7 @@ export function initializeExtensionApi(extensionService: ExtHostExtensionService
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie));
|
||||
}
|
||||
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TrieMap<IExtensionDescription>): void {
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>): void {
|
||||
|
||||
// each extension is meant to get its own api implementation
|
||||
const extApiImpl = new Map<string, typeof vscode>();
|
||||
|
||||
@@ -26,11 +26,9 @@ import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/pro
|
||||
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
|
||||
import { ITextSource } from 'vs/editor/common/model/textSource';
|
||||
|
||||
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
|
||||
import { IConfigurationData } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
import { IPickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
@@ -44,10 +42,14 @@ import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ISelection, Selection } from 'vs/editor/common/core/selection';
|
||||
|
||||
import { ITreeItem } from 'vs/workbench/parts/views/common/views';
|
||||
import { ITreeItem } from 'vs/workbench/common/views';
|
||||
import { ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { SerializedError } from 'vs/base/common/errors';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace';
|
||||
import { IStat, IFileChange } from 'vs/platform/files/common/files';
|
||||
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
||||
export interface IEnvironment {
|
||||
isExtensionDevelopmentDebug: boolean;
|
||||
@@ -64,7 +66,7 @@ export interface IEnvironment {
|
||||
export interface IWorkspaceData {
|
||||
id: string;
|
||||
name: string;
|
||||
roots: URI[];
|
||||
folders: IWorkspaceFolderData[];
|
||||
}
|
||||
|
||||
export interface IInitData {
|
||||
@@ -72,10 +74,19 @@ export interface IInitData {
|
||||
environment: IEnvironment;
|
||||
workspace: IWorkspaceData;
|
||||
extensions: IExtensionDescription[];
|
||||
configuration: IConfigurationData<any>;
|
||||
configuration: IConfigurationInitData;
|
||||
telemetryInfo: ITelemetryInfo;
|
||||
}
|
||||
|
||||
export interface IConfigurationInitData extends IConfigurationData {
|
||||
configurationScopes: ConfigurationScope[];
|
||||
}
|
||||
|
||||
export interface IWorkspaceConfigurationChangeEventData {
|
||||
changedConfiguration: IConfigurationModel;
|
||||
changedConfigurationByResource: { [folder: string]: IConfigurationModel };
|
||||
}
|
||||
|
||||
export interface IExtHostContext {
|
||||
/**
|
||||
* Returns a proxy to an object addressable/named in the extension host process.
|
||||
@@ -114,16 +125,30 @@ export interface MainThreadDiagnosticsShape extends IDisposable {
|
||||
$clear(owner: string): TPromise<any>;
|
||||
}
|
||||
|
||||
export interface MainThreadDialogOptions {
|
||||
uri?: URI;
|
||||
export interface MainThreadDialogOpenOptions {
|
||||
defaultUri?: URI;
|
||||
openLabel?: string;
|
||||
openFiles?: boolean;
|
||||
openFolders?: boolean;
|
||||
openMany?: boolean;
|
||||
canSelectFiles?: boolean;
|
||||
canSelectFolders?: boolean;
|
||||
canSelectMany?: boolean;
|
||||
filters?: { [name: string]: string[] };
|
||||
}
|
||||
|
||||
export interface MainThreadDialogSaveOptions {
|
||||
defaultUri?: URI;
|
||||
saveLabel?: string;
|
||||
filters?: { [name: string]: string[] };
|
||||
}
|
||||
|
||||
export interface MainThreadDiaglogsShape extends IDisposable {
|
||||
$showOpenDialog(options: MainThreadDialogOptions): TPromise<string[]>;
|
||||
$showOpenDialog(options: MainThreadDialogOpenOptions): TPromise<string[]>;
|
||||
$showSaveDialog(options: MainThreadDialogSaveOptions): TPromise<string>;
|
||||
}
|
||||
|
||||
export interface MainThreadDecorationsShape extends IDisposable {
|
||||
$registerDecorationProvider(handle: number, label: string): void;
|
||||
$unregisterDecorationProvider(handle: number): void;
|
||||
$onDidChange(handle: number, resources: URI[]): void;
|
||||
}
|
||||
|
||||
export interface MainThreadDocumentContentProvidersShape extends IDisposable {
|
||||
@@ -182,6 +207,16 @@ export interface ITextDocumentShowOptions {
|
||||
selection?: IRange;
|
||||
}
|
||||
|
||||
export interface IWorkspaceResourceEdit {
|
||||
resource: URI;
|
||||
modelVersionId?: number;
|
||||
edits: {
|
||||
range?: IRange;
|
||||
newText: string;
|
||||
newEol?: editorCommon.EndOfLineSequence;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface MainThreadEditorsShape extends IDisposable {
|
||||
$tryShowTextDocument(resource: URI, options: ITextDocumentShowOptions): TPromise<string>;
|
||||
$registerTextEditorDecorationType(key: string, options: editorCommon.IDecorationRenderOptions): void;
|
||||
@@ -190,9 +225,11 @@ export interface MainThreadEditorsShape extends IDisposable {
|
||||
$tryHideEditor(id: string): TPromise<void>;
|
||||
$trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise<any>;
|
||||
$trySetDecorations(id: string, key: string, ranges: editorCommon.IDecorationOptions[]): TPromise<any>;
|
||||
$trySetDecorationsFast(id: string, key: string, ranges: string): TPromise<any>;
|
||||
$tryRevealRange(id: string, range: IRange, revealType: TextEditorRevealType): TPromise<any>;
|
||||
$trySetSelections(id: string, selections: ISelection[]): TPromise<any>;
|
||||
$tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], opts: IApplyEditsOptions): TPromise<boolean>;
|
||||
$tryApplyWorkspaceEdit(workspaceResourceEdits: IWorkspaceResourceEdit[]): TPromise<boolean>;
|
||||
$tryInsertSnippet(id: string, template: string, selections: IRange[], opts: IUndoStopOptions): TPromise<any>;
|
||||
$getDiffInformation(id: string): TPromise<editorCommon.ILineChange[]>;
|
||||
}
|
||||
@@ -223,10 +260,9 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
||||
$registerOnTypeFormattingSupport(handle: number, selector: vscode.DocumentSelector, autoFormatTriggerCharacters: string[]): TPromise<any>;
|
||||
$registerNavigateTypeSupport(handle: number): TPromise<any>;
|
||||
$registerRenameSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any>;
|
||||
$registerSuggestSupport(handle: number, selector: vscode.DocumentSelector, triggerCharacters: string[]): TPromise<any>;
|
||||
$registerSuggestSupport(handle: number, selector: vscode.DocumentSelector, triggerCharacters: string[], supportsResolveDetails: boolean): TPromise<any>;
|
||||
$registerSignatureHelpProvider(handle: number, selector: vscode.DocumentSelector, triggerCharacter: string[]): TPromise<any>;
|
||||
$registerDocumentLinkProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any>;
|
||||
$registerColorFormats(formats: IRawColorFormatMap): TPromise<any>;
|
||||
$registerDocumentColorProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any>;
|
||||
$setLanguageConfiguration(handle: number, languageId: string, configuration: vscode.LanguageConfiguration): TPromise<any>;
|
||||
}
|
||||
@@ -260,7 +296,7 @@ export interface MainThreadProgressShape extends IDisposable {
|
||||
}
|
||||
|
||||
export interface MainThreadTerminalServiceShape extends IDisposable {
|
||||
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[], waitOnExit?: boolean): TPromise<number>;
|
||||
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[], env?: { [key: string]: string }, waitOnExit?: boolean): TPromise<number>;
|
||||
$dispose(terminalId: number): void;
|
||||
$hide(terminalId: number): void;
|
||||
$sendText(terminalId: number, text: string, addNewLine: boolean): void;
|
||||
@@ -279,7 +315,7 @@ export interface MainThreadQuickOpenShape extends IDisposable {
|
||||
|
||||
export interface MainThreadStatusBarShape extends IDisposable {
|
||||
$setEntry(id: number, extensionId: string, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: MainThreadStatusBarAlignment, priority: number): void;
|
||||
$dispose(id: number);
|
||||
$dispose(id: number): void;
|
||||
}
|
||||
|
||||
export interface MainThreadStorageShape extends IDisposable {
|
||||
@@ -292,16 +328,20 @@ export interface MainThreadTelemetryShape extends IDisposable {
|
||||
}
|
||||
|
||||
export interface MainThreadWorkspaceShape extends IDisposable {
|
||||
$startSearch(include: string, exclude: string, maxResults: number, requestId: number): Thenable<URI[]>;
|
||||
$startSearch(include: string | IRelativePattern, exclude: string | IRelativePattern, maxResults: number, requestId: number): Thenable<URI[]>;
|
||||
$cancelSearch(requestId: number): Thenable<boolean>;
|
||||
$saveAll(includeUntitled?: boolean): Thenable<boolean>;
|
||||
$applyWorkspaceEdit(edits: IResourceEdit[]): TPromise<boolean>;
|
||||
}
|
||||
|
||||
$registerFileSystemProvider(handle: number, authority: string): void;
|
||||
$unregisterFileSystemProvider(handle): void;
|
||||
$onFileSystemChange(handle: number, resource: URI): void;
|
||||
$updateSearchSession(session: number, data): void;
|
||||
$finishSearchSession(session: number, err?: any): void;
|
||||
export interface MainThreadFileSystemShape extends IDisposable {
|
||||
$registerFileSystemProvider(handle: number, scheme: string): void;
|
||||
$unregisterFileSystemProvider(handle: number): void;
|
||||
|
||||
$onDidAddFileSystemRoot(root: URI): void;
|
||||
$onFileSystemChange(handle: number, resource: IFileChange[]): void;
|
||||
$reportFileChunk(handle: number, resource: URI, chunk: number[] | null): void;
|
||||
|
||||
$handleSearchProgress(handle: number, session: number, resource: URI): void;
|
||||
}
|
||||
|
||||
export interface MainThreadTaskShape extends IDisposable {
|
||||
@@ -330,24 +370,39 @@ export interface SCMGroupFeatures {
|
||||
export type SCMRawResource = [
|
||||
number /*handle*/,
|
||||
string /*resourceUri*/,
|
||||
modes.Command /*command*/,
|
||||
string[] /*icons: light, dark*/,
|
||||
string /*tooltip*/,
|
||||
boolean /*strike through*/,
|
||||
boolean /*faded*/
|
||||
boolean /*faded*/,
|
||||
|
||||
string | undefined /*source*/,
|
||||
string | undefined /*letter*/,
|
||||
ThemeColor | null /*color*/
|
||||
];
|
||||
|
||||
export type SCMRawResourceSplice = [
|
||||
number /* start */,
|
||||
number /* delete count */,
|
||||
SCMRawResource[]
|
||||
];
|
||||
|
||||
export type SCMRawResourceSplices = [
|
||||
number, /*handle*/
|
||||
SCMRawResourceSplice[]
|
||||
];
|
||||
|
||||
export interface MainThreadSCMShape extends IDisposable {
|
||||
$registerSourceControl(handle: number, id: string, label: string): void;
|
||||
$registerSourceControl(handle: number, id: string, label: string, rootUri: string | undefined): void;
|
||||
$updateSourceControl(handle: number, features: SCMProviderFeatures): void;
|
||||
$unregisterSourceControl(handle: number): void;
|
||||
|
||||
$registerGroup(sourceControlHandle: number, handle: number, id: string, label: string): void;
|
||||
$updateGroup(sourceControlHandle: number, handle: number, features: SCMGroupFeatures): void;
|
||||
$updateGroupLabel(sourceControlHandle: number, handle: number, label: string): void;
|
||||
$updateGroupResourceStates(sourceControlHandle: number, groupHandle: number, resources: SCMRawResource[]): void;
|
||||
$unregisterGroup(sourceControlHandle: number, handle: number): void;
|
||||
|
||||
$spliceResourceStates(sourceControlHandle: number, splices: SCMRawResourceSplices[]): void;
|
||||
|
||||
$setInputBoxValue(sourceControlHandle: number, value: string): void;
|
||||
}
|
||||
|
||||
@@ -359,9 +414,9 @@ export type DebugSessionUUID = string;
|
||||
export interface MainThreadDebugServiceShape extends IDisposable {
|
||||
$registerDebugConfigurationProvider(type: string, hasProvideMethod: boolean, hasResolveMethod: boolean, handle: number): TPromise<any>;
|
||||
$unregisterDebugConfigurationProvider(handle: number): TPromise<any>;
|
||||
$startDebugging(folderUri: URI | undefined, nameOrConfig: string | vscode.DebugConfiguration): TPromise<boolean>;
|
||||
$startDebugSession(folderUri: URI | undefined, config: vscode.DebugConfiguration): TPromise<DebugSessionUUID>;
|
||||
$startDebugging(folder: URI | undefined, nameOrConfig: string | vscode.DebugConfiguration): TPromise<boolean>;
|
||||
$customDebugAdapterRequest(id: DebugSessionUUID, command: string, args: any): TPromise<any>;
|
||||
$appendDebugConsole(value: string): TPromise<any>;
|
||||
}
|
||||
*/
|
||||
export interface MainThreadCredentialsShape extends IDisposable {
|
||||
@@ -382,7 +437,7 @@ export interface ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
export interface ExtHostConfigurationShape {
|
||||
$acceptConfigurationChanged(data: IConfigurationData<any>);
|
||||
$acceptConfigurationChanged(data: IConfigurationData, eventData: IWorkspaceConfigurationChangeEventData): void;
|
||||
}
|
||||
|
||||
export interface ExtHostDiagnosticsShape {
|
||||
@@ -447,11 +502,19 @@ export interface ExtHostTreeViewsShape {
|
||||
|
||||
export interface ExtHostWorkspaceShape {
|
||||
$acceptWorkspaceData(workspace: IWorkspaceData): void;
|
||||
}
|
||||
|
||||
$resolveFile(handle: number, resource: URI): TPromise<string>;
|
||||
$storeFile(handle: number, resource: URI, content: string): TPromise<any>;
|
||||
$startSearch(handle: number, session: number, query: string): void;
|
||||
$cancelSearch(handle: number, session: number): void;
|
||||
export interface ExtHostFileSystemShape {
|
||||
$utimes(handle: number, resource: URI, mtime: number, atime: number): TPromise<IStat>;
|
||||
$stat(handle: number, resource: URI): TPromise<IStat>;
|
||||
$read(handle: number, offset: number, count: number, resource: URI): TPromise<number>;
|
||||
$write(handle: number, resource: URI, content: number[]): TPromise<void>;
|
||||
$unlink(handle: number, resource: URI): TPromise<void>;
|
||||
$move(handle: number, resource: URI, target: URI): TPromise<IStat>;
|
||||
$mkdir(handle: number, resource: URI): TPromise<IStat>;
|
||||
$readdir(handle: number, resource: URI): TPromise<[URI, IStat][]>;
|
||||
$rmdir(handle: number, resource: URI): TPromise<void>;
|
||||
$fileFiles(handle: number, session: number, query: string): TPromise<void>;
|
||||
}
|
||||
|
||||
export interface ExtHostExtensionServiceShape {
|
||||
@@ -464,7 +527,7 @@ export interface FileSystemEvents {
|
||||
deleted: URI[];
|
||||
}
|
||||
export interface ExtHostFileSystemEventServiceShape {
|
||||
$onFileEvent(events: FileSystemEvents);
|
||||
$onFileEvent(events: FileSystemEvents): void;
|
||||
}
|
||||
|
||||
export interface ObjectIdentifier {
|
||||
@@ -487,11 +550,34 @@ export interface ExtHostHeapServiceShape {
|
||||
}
|
||||
export interface IRawColorInfo {
|
||||
color: [number, number, number, number];
|
||||
availableFormats: (number | [number, number])[];
|
||||
range: IRange;
|
||||
}
|
||||
|
||||
export type IRawColorFormatMap = [number, string][];
|
||||
export interface IExtHostSuggestion extends modes.ISuggestion {
|
||||
_id: number;
|
||||
_parentId: number;
|
||||
}
|
||||
|
||||
export interface IExtHostSuggestResult {
|
||||
_id: number;
|
||||
suggestions: IExtHostSuggestion[];
|
||||
incomplete?: boolean;
|
||||
}
|
||||
|
||||
export interface IdObject {
|
||||
_id: number;
|
||||
}
|
||||
|
||||
export namespace IdObject {
|
||||
let n = 0;
|
||||
export function mixin<T extends object>(object: T): T & IdObject {
|
||||
(<any>object)._id = n++;
|
||||
return <any>object;
|
||||
}
|
||||
}
|
||||
|
||||
export type IWorkspaceSymbol = IdObject & modes.SymbolInformation;
|
||||
export interface IWorkspaceSymbols extends IdObject { symbols: IWorkspaceSymbol[]; };
|
||||
|
||||
export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentSymbols(handle: number, resource: URI): TPromise<modes.SymbolInformation[]>;
|
||||
@@ -507,15 +593,18 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentFormattingEdits(handle: number, resource: URI, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: URI, range: IRange, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
|
||||
$provideWorkspaceSymbols(handle: number, search: string): TPromise<modes.SymbolInformation[]>;
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: modes.SymbolInformation): TPromise<modes.SymbolInformation>;
|
||||
$provideWorkspaceSymbols(handle: number, search: string): TPromise<IWorkspaceSymbols>;
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: modes.SymbolInformation): TPromise<IWorkspaceSymbol>;
|
||||
$releaseWorkspaceSymbols(handle: number, id: number): void;
|
||||
$provideRenameEdits(handle: number, resource: URI, position: IPosition, newName: string): TPromise<modes.WorkspaceEdit>;
|
||||
$provideCompletionItems(handle: number, resource: URI, position: IPosition): TPromise<modes.ISuggestResult>;
|
||||
$provideCompletionItems(handle: number, resource: URI, position: IPosition, context: modes.SuggestContext): TPromise<IExtHostSuggestResult>;
|
||||
$resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion>;
|
||||
$releaseCompletionItems(handle: number, id: number): void;
|
||||
$provideSignatureHelp(handle: number, resource: URI, position: IPosition): TPromise<modes.SignatureHelp>;
|
||||
$provideDocumentLinks(handle: number, resource: URI): TPromise<modes.ILink[]>;
|
||||
$provideDocumentColors(handle: number, resource: URI): TPromise<IRawColorInfo[]>;
|
||||
$resolveDocumentLink(handle: number, link: modes.ILink): TPromise<modes.ILink>;
|
||||
$provideDocumentColors(handle: number, resource: URI): TPromise<IRawColorInfo[]>;
|
||||
$provideColorPresentations(handle: number, resource: URI, colorInfo: IRawColorInfo): TPromise<modes.IColorPresentation[]>;
|
||||
}
|
||||
|
||||
export interface ExtHostQuickOpenShape {
|
||||
@@ -531,6 +620,7 @@ export interface ExtHostTerminalServiceShape {
|
||||
export interface ExtHostSCMShape {
|
||||
$provideOriginalResource(sourceControlHandle: number, uri: URI): TPromise<URI>;
|
||||
$onInputBoxValueChange(sourceControlHandle: number, value: string): TPromise<void>;
|
||||
$executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): TPromise<void>;
|
||||
}
|
||||
|
||||
export interface ExtHostTaskShape {
|
||||
@@ -549,6 +639,12 @@ export interface ExtHostDebugServiceShape {
|
||||
}
|
||||
*/
|
||||
|
||||
export type DecorationData = [number, boolean, string, string, ThemeColor, string];
|
||||
|
||||
export interface ExtHostDecorationsShape {
|
||||
$providerDecorations(handle: number, uri: URI): TPromise<DecorationData>;
|
||||
}
|
||||
|
||||
export interface ExtHostCredentialsShape {
|
||||
}
|
||||
|
||||
@@ -563,6 +659,7 @@ export const MainContext = {
|
||||
MainThreadConfiguration: createMainId<MainThreadConfigurationShape>('MainThreadConfiguration'),
|
||||
// {{SQL CARBON EDIT}}
|
||||
// MainThreadDebugService: createMainId<MainThreadDebugServiceShape>('MainThreadDebugService'),
|
||||
MainThreadDecorations: createMainId<MainThreadDecorationsShape>('MainThreadDecorations'),
|
||||
MainThreadDiagnostics: createMainId<MainThreadDiagnosticsShape>('MainThreadDiagnostics'),
|
||||
MainThreadDialogs: createMainId<MainThreadDiaglogsShape>('MainThreadDiaglogs'),
|
||||
MainThreadDocuments: createMainId<MainThreadDocumentsShape>('MainThreadDocuments'),
|
||||
@@ -581,6 +678,7 @@ export const MainContext = {
|
||||
MainThreadTelemetry: createMainId<MainThreadTelemetryShape>('MainThreadTelemetry'),
|
||||
MainThreadTerminalService: createMainId<MainThreadTerminalServiceShape>('MainThreadTerminalService'),
|
||||
MainThreadWorkspace: createMainId<MainThreadWorkspaceShape>('MainThreadWorkspace'),
|
||||
MainThreadFileSystem: createMainId<MainThreadFileSystemShape>('MainThreadFileSystem'),
|
||||
MainThreadExtensionService: createMainId<MainThreadExtensionServiceShape>('MainThreadExtensionService'),
|
||||
MainThreadSCM: createMainId<MainThreadSCMShape>('MainThreadSCM'),
|
||||
MainThreadTask: createMainId<MainThreadTaskShape>('MainThreadTask'),
|
||||
@@ -594,12 +692,14 @@ export const ExtHostContext = {
|
||||
ExtHostDiagnostics: createExtId<ExtHostDiagnosticsShape>('ExtHostDiagnostics'),
|
||||
// {{SQL CARBON EDIT}}
|
||||
// ExtHostDebugService: createExtId<ExtHostDebugServiceShape>('ExtHostDebugService'),
|
||||
ExtHostDecorations: createExtId<ExtHostDecorationsShape>('ExtHostDecorations'),
|
||||
ExtHostDocumentsAndEditors: createExtId<ExtHostDocumentsAndEditorsShape>('ExtHostDocumentsAndEditors'),
|
||||
ExtHostDocuments: createExtId<ExtHostDocumentsShape>('ExtHostDocuments'),
|
||||
ExtHostDocumentContentProviders: createExtId<ExtHostDocumentContentProvidersShape>('ExtHostDocumentContentProviders'),
|
||||
ExtHostDocumentSaveParticipant: createExtId<ExtHostDocumentSaveParticipantShape>('ExtHostDocumentSaveParticipant'),
|
||||
ExtHostEditors: createExtId<ExtHostEditorsShape>('ExtHostEditors'),
|
||||
ExtHostTreeViews: createExtId<ExtHostTreeViewsShape>('ExtHostTreeViews'),
|
||||
ExtHostFileSystem: createExtId<ExtHostFileSystemShape>('ExtHostFileSystem'),
|
||||
ExtHostFileSystemEventService: createExtId<ExtHostFileSystemEventServiceShape>('ExtHostFileSystemEventService'),
|
||||
ExtHostHeapService: createExtId<ExtHostHeapServiceShape>('ExtHostHeapMonitor'),
|
||||
ExtHostLanguageFeatures: createExtId<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures'),
|
||||
|
||||
@@ -195,15 +195,6 @@ export class ExtHostApiCommands {
|
||||
]
|
||||
});
|
||||
|
||||
this._register('vscode.startDebug', (configuration?: any, folderUri?: URI) => {
|
||||
return this._commands.executeCommand('_workbench.startDebug', configuration, folderUri);
|
||||
}, {
|
||||
description: 'Start a debugging session.',
|
||||
args: [
|
||||
{ name: 'configuration', description: '(optional) Name of the debug configuration from \'launch.json\' to use. Or a configuration json object to use.' }
|
||||
]
|
||||
});
|
||||
|
||||
this._register('vscode.diff', (left: URI, right: URI, label: string, options?: vscode.TextDocumentShowOptions) => {
|
||||
let editorOptions: ITextEditorOptions;
|
||||
if (options) {
|
||||
@@ -376,7 +367,8 @@ export class ExtHostApiCommands {
|
||||
return this._commands.executeCommand<modes.ISuggestResult>('_executeCompletionItemProvider', args).then(result => {
|
||||
if (result) {
|
||||
const items = result.suggestions.map(suggestion => typeConverters.Suggest.to(position, suggestion));
|
||||
return new types.CompletionList(items, result.incomplete);
|
||||
// {{SQL CARBON EDIT}}
|
||||
return new types.CompletionList(<any>items, result.incomplete);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { WorkspaceConfiguration } from 'vscode';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostConfigurationShape, MainThreadConfigurationShape } from './extHost.protocol';
|
||||
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol';
|
||||
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
|
||||
import { IConfigurationData, Configuration } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
|
||||
import { IConfigurationData, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { Configuration, ConfigurationModel, ConfigurationChangeEvent } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { WorkspaceConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels';
|
||||
import { StrictResourceMap } from 'vs/base/common/map';
|
||||
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
||||
function lookUp(tree: any, key: string) {
|
||||
if (key) {
|
||||
@@ -35,30 +38,36 @@ type ConfigurationInspect<T> = {
|
||||
|
||||
export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
|
||||
private readonly _onDidChangeConfiguration = new Emitter<void>();
|
||||
private readonly _onDidChangeConfiguration = new Emitter<vscode.ConfigurationChangeEvent>();
|
||||
private readonly _proxy: MainThreadConfigurationShape;
|
||||
private readonly _extHostWorkspace: ExtHostWorkspace;
|
||||
private _configuration: Configuration<any>;
|
||||
private _configurationScopes: Map<string, ConfigurationScope>;
|
||||
private _configuration: Configuration;
|
||||
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationData<any>) {
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData) {
|
||||
this._proxy = proxy;
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._configuration = Configuration.parse(data, extHostWorkspace.workspace);
|
||||
this._configuration = Configuration.parse(data);
|
||||
this._readConfigurationScopes(data.configurationScopes);
|
||||
}
|
||||
|
||||
get onDidChangeConfiguration(): Event<void> {
|
||||
get onDidChangeConfiguration(): Event<vscode.ConfigurationChangeEvent> {
|
||||
return this._onDidChangeConfiguration && this._onDidChangeConfiguration.event;
|
||||
}
|
||||
|
||||
$acceptConfigurationChanged(data: IConfigurationData<any>) {
|
||||
this._configuration = Configuration.parse(data, this._extHostWorkspace.workspace);
|
||||
this._onDidChangeConfiguration.fire(undefined);
|
||||
$acceptConfigurationChanged(data: IConfigurationData, eventData: IWorkspaceConfigurationChangeEventData) {
|
||||
this._configuration = Configuration.parse(data);
|
||||
this._onDidChangeConfiguration.fire(this._toConfigurationChangeEvent(eventData));
|
||||
}
|
||||
|
||||
getConfiguration(section?: string, resource?: URI): WorkspaceConfiguration {
|
||||
getConfiguration(section?: string, resource?: URI, extensionId?: string): vscode.WorkspaceConfiguration {
|
||||
const config = section
|
||||
? lookUp(this._configuration.getValue(null, { resource }), section)
|
||||
: this._configuration.getValue(null, { resource });
|
||||
? lookUp(this._configuration.getSection(null, { resource }, this._extHostWorkspace.workspace), section)
|
||||
: this._configuration.getSection(null, { resource }, this._extHostWorkspace.workspace);
|
||||
|
||||
if (section) {
|
||||
this._validateConfigurationAccess(section, resource, extensionId);
|
||||
}
|
||||
|
||||
function parseConfigurationTarget(arg: boolean | ExtHostConfigurationTarget): ConfigurationTarget {
|
||||
if (arg === void 0 || arg === null) {
|
||||
@@ -71,15 +80,16 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
switch (arg) {
|
||||
case ExtHostConfigurationTarget.Global: return ConfigurationTarget.USER;
|
||||
case ExtHostConfigurationTarget.Workspace: return ConfigurationTarget.WORKSPACE;
|
||||
case ExtHostConfigurationTarget.WorkspaceFolder: return ConfigurationTarget.FOLDER;
|
||||
case ExtHostConfigurationTarget.WorkspaceFolder: return ConfigurationTarget.WORKSPACE_FOLDER;
|
||||
}
|
||||
}
|
||||
|
||||
const result: WorkspaceConfiguration = {
|
||||
const result: vscode.WorkspaceConfiguration = {
|
||||
has(key: string): boolean {
|
||||
return typeof lookUp(config, key) !== 'undefined';
|
||||
},
|
||||
get<T>(key: string, defaultValue?: T): T {
|
||||
get: <T>(key: string, defaultValue?: T) => {
|
||||
this._validateConfigurationAccess(section ? `${section}.${key}` : key, resource, extensionId);
|
||||
let result = lookUp(config, key);
|
||||
if (typeof result === 'undefined') {
|
||||
result = defaultValue;
|
||||
@@ -97,14 +107,14 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
},
|
||||
inspect: <T>(key: string): ConfigurationInspect<T> => {
|
||||
key = section ? `${section}.${key}` : key;
|
||||
const config = this._configuration.lookup<T>(key, { resource });
|
||||
const config = this._configuration.lookup<T>(key, { resource }, this._extHostWorkspace.workspace);
|
||||
if (config) {
|
||||
return {
|
||||
key,
|
||||
defaultValue: config.default,
|
||||
globalValue: config.user,
|
||||
workspaceValue: config.workspace,
|
||||
workspaceFolderValue: config.folder
|
||||
workspaceFolderValue: config.workspaceFolder
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
@@ -115,6 +125,49 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
mixin(result, config, false);
|
||||
}
|
||||
|
||||
return <WorkspaceConfiguration>Object.freeze(result);
|
||||
return <vscode.WorkspaceConfiguration>Object.freeze(result);
|
||||
}
|
||||
|
||||
private _validateConfigurationAccess(key: string, resource: URI, extensionId: string): void {
|
||||
const scope = this._configurationScopes.get(key);
|
||||
const extensionIdText = extensionId ? `[${extensionId}] ` : '';
|
||||
if (ConfigurationScope.RESOURCE === scope) {
|
||||
if (resource === void 0) {
|
||||
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.`);
|
||||
}
|
||||
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'.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private _readConfigurationScopes(scopes: ConfigurationScope[]): void {
|
||||
this._configurationScopes = new Map<string, ConfigurationScope>();
|
||||
if (scopes.length) {
|
||||
const defaultKeys = this._configuration.keys(this._extHostWorkspace.workspace).default;
|
||||
if (defaultKeys.length === scopes.length) {
|
||||
for (let i = 0; i < defaultKeys.length; i++) {
|
||||
this._configurationScopes.set(defaultKeys[i], scopes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _toConfigurationChangeEvent(data: IWorkspaceConfigurationChangeEventData): vscode.ConfigurationChangeEvent {
|
||||
const changedConfiguration = new ConfigurationModel(data.changedConfiguration.contents, data.changedConfiguration.keys, data.changedConfiguration.overrides);
|
||||
const changedConfigurationByResource: StrictResourceMap<ConfigurationModel> = new StrictResourceMap<ConfigurationModel>();
|
||||
for (const key of Object.keys(data.changedConfigurationByResource)) {
|
||||
const resource = URI.parse(key);
|
||||
const model = data.changedConfigurationByResource[key];
|
||||
changedConfigurationByResource.set(resource, new ConfigurationModel(model.contents, model.keys, model.overrides));
|
||||
}
|
||||
const event = new WorkspaceConfigurationChangeEvent(new ConfigurationChangeEvent(changedConfiguration, changedConfigurationByResource), this._extHostWorkspace.workspace);
|
||||
return Object.freeze({
|
||||
affectsConfiguration: (section: string, resource?: URI) => event.affectsConfiguration(section, resource)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
private _onDidReceiveDebugSessionCustomEvent: Emitter<vscode.DebugSessionCustomEvent>;
|
||||
get onDidReceiveDebugSessionCustomEvent(): Event<vscode.DebugSessionCustomEvent> { return this._onDidReceiveDebugSessionCustomEvent.event; }
|
||||
|
||||
private _debugConsole: ExtHostDebugConsole;
|
||||
get debugConsole(): ExtHostDebugConsole { return this._debugConsole; }
|
||||
|
||||
|
||||
constructor(mainContext: IMainContext, workspace: ExtHostWorkspace) {
|
||||
|
||||
@@ -56,6 +59,8 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
this._onDidReceiveDebugSessionCustomEvent = new Emitter<vscode.DebugSessionCustomEvent>();
|
||||
|
||||
this._debugServiceProxy = mainContext.get(MainContext.MainThreadDebugService);
|
||||
|
||||
this._debugConsole = new ExtHostDebugConsole(this._debugServiceProxy);
|
||||
}
|
||||
|
||||
public registerDebugConfigurationProvider(type: string, provider: vscode.DebugConfigurationProvider): vscode.Disposable {
|
||||
@@ -97,17 +102,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
}
|
||||
|
||||
public startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration): TPromise<boolean> {
|
||||
|
||||
return this._debugServiceProxy.$startDebugging(folder ? <URI>folder.uri : undefined, nameOrConfig);
|
||||
}
|
||||
|
||||
public startDebugSession(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration): TPromise<vscode.DebugSession> {
|
||||
|
||||
return this._debugServiceProxy.$startDebugSession(folder ? <URI>folder.uri : undefined, config).then((id: DebugSessionUUID) => {
|
||||
const debugSession = new ExtHostDebugSession(this._debugServiceProxy, id, config.type, config.name);
|
||||
this._debugSessions.set(id, debugSession);
|
||||
return debugSession;
|
||||
});
|
||||
return this._debugServiceProxy.$startDebugging(folder ? folder.uri : undefined, nameOrConfig);
|
||||
}
|
||||
|
||||
public $acceptDebugSessionStarted(id: DebugSessionUUID, type: string, name: string): void {
|
||||
@@ -190,7 +185,7 @@ export class ExtHostDebugSession implements vscode.DebugSession {
|
||||
this._id = id;
|
||||
this._type = type;
|
||||
this._name = name;
|
||||
};
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return this._id;
|
||||
@@ -209,5 +204,22 @@ export class ExtHostDebugSession implements vscode.DebugSession {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostDebugConsole implements vscode.DebugConsole {
|
||||
|
||||
private _debugServiceProxy: MainThreadDebugServiceShape;
|
||||
|
||||
constructor(proxy: MainThreadDebugServiceShape) {
|
||||
this._debugServiceProxy = proxy;
|
||||
}
|
||||
|
||||
append(value: string): void {
|
||||
this._debugServiceProxy.$appendDebugConsole(value);
|
||||
}
|
||||
|
||||
appendLine(value: string): void {
|
||||
this.append(value + '\n');
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
*/
|
||||
|
||||
47
src/vs/workbench/api/node/extHostDecorations.ts
Normal file
47
src/vs/workbench/api/node/extHostDecorations.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Disposable } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
|
||||
export class ExtHostDecorations implements ExtHostDecorationsShape {
|
||||
|
||||
private static _handlePool = 0;
|
||||
|
||||
private readonly _provider = new Map<number, vscode.DecorationProvider>();
|
||||
private readonly _proxy: MainThreadDecorationsShape;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadDecorations);
|
||||
}
|
||||
|
||||
registerDecorationProvider(provider: vscode.DecorationProvider, label: string): vscode.Disposable {
|
||||
const handle = ExtHostDecorations._handlePool++;
|
||||
this._provider.set(handle, provider);
|
||||
this._proxy.$registerDecorationProvider(handle, label);
|
||||
|
||||
const listener = provider.onDidChangeDecorations(e => {
|
||||
this._proxy.$onDidChange(handle, !e ? null : Array.isArray(e) ? e : [e]);
|
||||
});
|
||||
|
||||
return new Disposable(() => {
|
||||
listener.dispose();
|
||||
this._proxy.$unregisterDecorationProvider(handle);
|
||||
this._provider.delete(handle);
|
||||
});
|
||||
}
|
||||
|
||||
$providerDecorations(handle: number, uri: URI): TPromise<DecorationData> {
|
||||
const provider = this._provider.get(handle);
|
||||
return asWinJsPromise(token => provider.provideDecoration(uri, token)).then(data => {
|
||||
return data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
}
|
||||
}
|
||||
|
||||
entries.push([<URI>uri, marker]);
|
||||
entries.push([uri, marker]);
|
||||
}
|
||||
|
||||
this._proxy.$changeMany(this.name, entries);
|
||||
@@ -142,7 +142,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
delete(uri: vscode.Uri): void {
|
||||
this._checkDisposed();
|
||||
this._data.delete(uri.toString());
|
||||
this._proxy.$changeMany(this.name, [[<URI>uri, undefined]]);
|
||||
this._proxy.$changeMany(this.name, [[uri, undefined]]);
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
|
||||
@@ -17,8 +17,14 @@ export class ExtHostDialogs {
|
||||
}
|
||||
|
||||
showOpenDialog(options: vscode.OpenDialogOptions): Thenable<URI[]> {
|
||||
return this._proxy.$showOpenDialog(<any>options).then(filepaths => {
|
||||
return this._proxy.$showOpenDialog(options).then(filepaths => {
|
||||
return filepaths && filepaths.map(URI.file);
|
||||
});
|
||||
}
|
||||
|
||||
showSaveDialog(options: vscode.SaveDialogOptions): Thenable<URI> {
|
||||
return this._proxy.$showSaveDialog(options).then(filepath => {
|
||||
return filepath && URI.file(filepath);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
|
||||
if (typeof provider.onDidChange === 'function') {
|
||||
subscription = provider.onDidChange(uri => {
|
||||
if (this._documentsAndEditors.getDocument(uri.toString())) {
|
||||
this.$provideTextDocumentContent(handle, <URI>uri).then(value => {
|
||||
this.$provideTextDocumentContent(handle, uri).then(value => {
|
||||
|
||||
const document = this._documentsAndEditors.getDocument(uri.toString());
|
||||
if (!document) {
|
||||
@@ -60,7 +60,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
|
||||
|
||||
// broadcast event when content changed
|
||||
if (!document.equalLines(textSource)) {
|
||||
return this._proxy.$onVirtualDocumentChange(<URI>uri, textSource);
|
||||
return this._proxy.$onVirtualDocumentChange(uri, textSource);
|
||||
}
|
||||
|
||||
}, onUnexpectedError);
|
||||
|
||||
@@ -78,7 +78,7 @@ export class ExtHostDocumentData extends MirrorModel {
|
||||
getText(range?) { return range ? data._getTextInRange(range) : data.getText(); },
|
||||
get eol() { return data._eol === '\n' ? EndOfLine.LF : EndOfLine.CRLF; },
|
||||
get lineCount() { return data._lines.length; },
|
||||
lineAt(lineOrPos) { return data._lineAt(lineOrPos); },
|
||||
lineAt(lineOrPos: number | vscode.Position) { return data._lineAt(lineOrPos); },
|
||||
offsetAt(pos) { return data._offsetAt(pos); },
|
||||
positionAt(offset) { return data._positionAt(offset); },
|
||||
validateRange(ran) { return data._validateRange(ran); },
|
||||
|
||||
@@ -10,10 +10,9 @@ import URI from 'vs/base/common/uri';
|
||||
import { sequence, always } from 'vs/base/common/async';
|
||||
import { illegalState } from 'vs/base/common/errors';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { MainThreadWorkspaceShape, ExtHostDocumentSaveParticipantShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostDocumentSaveParticipantShape, MainThreadEditorsShape, IWorkspaceResourceEdit } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { TextEdit } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { fromRange, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import * as vscode from 'vscode';
|
||||
@@ -21,14 +20,14 @@ import * as vscode from 'vscode';
|
||||
export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSaveParticipantShape {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _workspace: MainThreadWorkspaceShape;
|
||||
private _mainThreadEditors: MainThreadEditorsShape;
|
||||
private _callbacks = new CallbackList();
|
||||
private _badListeners = new WeakMap<Function, number>();
|
||||
private _thresholds: { timeout: number; errors: number; };
|
||||
|
||||
constructor(documents: ExtHostDocuments, workspace: MainThreadWorkspaceShape, thresholds: { timeout: number; errors: number; } = { timeout: 1500, errors: 3 }) {
|
||||
constructor(documents: ExtHostDocuments, mainThreadEditors: MainThreadEditorsShape, thresholds: { timeout: number; errors: number; } = { timeout: 1500, errors: 3 }) {
|
||||
this._documents = documents;
|
||||
this._workspace = workspace;
|
||||
this._mainThreadEditors = mainThreadEditors;
|
||||
this._thresholds = thresholds;
|
||||
}
|
||||
|
||||
@@ -38,12 +37,8 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
|
||||
get onWillSaveTextDocumentEvent(): Event<vscode.TextDocumentWillSaveEvent> {
|
||||
return (listener, thisArg, disposables) => {
|
||||
this._callbacks.add(listener, thisArg);
|
||||
const result = {
|
||||
dispose: () => {
|
||||
this._callbacks.remove(listener, thisArg);
|
||||
}
|
||||
};
|
||||
const remove = this._callbacks.add(listener, thisArg);
|
||||
const result = { dispose: remove };
|
||||
if (Array.isArray(disposables)) {
|
||||
disposables.push(result);
|
||||
}
|
||||
@@ -133,13 +128,15 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
|
||||
}).then(values => {
|
||||
|
||||
let edits: IResourceEdit[] = [];
|
||||
let workspaceResourceEdit: IWorkspaceResourceEdit = {
|
||||
resource: document.uri,
|
||||
edits: []
|
||||
};
|
||||
|
||||
for (const value of values) {
|
||||
if (Array.isArray(value) && (<vscode.TextEdit[]>value).every(e => e instanceof TextEdit)) {
|
||||
for (const { newText, newEol, range } of value) {
|
||||
edits.push({
|
||||
resource: <URI>document.uri,
|
||||
workspaceResourceEdit.edits.push({
|
||||
range: range && fromRange(range),
|
||||
newText,
|
||||
newEol: EndOfLine.from(newEol)
|
||||
@@ -150,12 +147,12 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
|
||||
// apply edits if any and if document
|
||||
// didn't change somehow in the meantime
|
||||
if (edits.length === 0) {
|
||||
if (workspaceResourceEdit.edits.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (version === document.version) {
|
||||
return this._workspace.$applyWorkspaceEdit(edits);
|
||||
return this._mainThreadEditors.$tryApplyWorkspaceEdit([workspaceResourceEdit]);
|
||||
}
|
||||
|
||||
// TODO@joh bubble this to listener?
|
||||
|
||||
@@ -8,10 +8,9 @@ import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { MainContext, ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, IMainContext } from './extHost.protocol';
|
||||
import { ExtHostDocumentData } from './extHostDocumentData';
|
||||
import { ExtHostTextEditor, ExtHostTextEditor2 } from './extHostTextEditor';
|
||||
import { ExtHostTextEditor } from './extHostTextEditor';
|
||||
import * as assert from 'assert';
|
||||
import * as typeConverters from './extHostTypeConverters';
|
||||
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
|
||||
|
||||
export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape {
|
||||
|
||||
@@ -30,8 +29,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
readonly onDidChangeActiveTextEditor: Event<ExtHostTextEditor> = this._onDidChangeActiveTextEditor.event;
|
||||
|
||||
constructor(
|
||||
private readonly _mainContext: IMainContext,
|
||||
private readonly _extHostExtensions?: ExtHostExtensionService
|
||||
private readonly _mainContext: IMainContext
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -81,9 +79,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
assert.ok(!this._editors.has(data.id), `editor '${data.id}' already exists!`);
|
||||
|
||||
const documentData = this._documents.get(data.document.toString());
|
||||
const editor = new ExtHostTextEditor2(
|
||||
this._extHostExtensions,
|
||||
this._mainContext.get(MainContext.MainThreadTelemetry),
|
||||
const editor = new ExtHostTextEditor(
|
||||
this._mainContext.get(MainContext.MainThreadEditors),
|
||||
data.id,
|
||||
documentData,
|
||||
|
||||
@@ -18,8 +18,10 @@ import { MainContext, MainThreadExtensionServiceShape, IWorkspaceData, IEnvironm
|
||||
import { IExtensionMemento, ExtensionsActivator, ActivatedExtension, IExtensionAPI, IExtensionContext, EmptyExtension, IExtensionModule, ExtensionActivationTimesBuilder, ExtensionActivationTimes } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { Barrier } from 'vs/workbench/services/extensions/node/barrier';
|
||||
import { ExtHostThreadService } from 'vs/workbench/services/thread/node/extHostThreadService';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { realpath } from 'fs';
|
||||
import { TrieMap } from 'vs/base/common/map';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
|
||||
class ExtensionMemento implements IExtensionMemento {
|
||||
|
||||
@@ -117,11 +119,15 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
private readonly _storagePath: ExtensionStoragePath;
|
||||
private readonly _proxy: MainThreadExtensionServiceShape;
|
||||
private _activator: ExtensionsActivator;
|
||||
private _extensionPathIndex: TPromise<TrieMap<IExtensionDescription>>;
|
||||
private _extensionPathIndex: TPromise<TernarySearchTree<IExtensionDescription>>;
|
||||
/**
|
||||
* This class is constructed manually because it is a service, so it doesn't use any ctor injection
|
||||
*/
|
||||
constructor(initData: IInitData, threadService: ExtHostThreadService) {
|
||||
constructor(initData: IInitData,
|
||||
threadService: ExtHostThreadService,
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration
|
||||
) {
|
||||
this._barrier = new Barrier();
|
||||
this._registry = new ExtensionDescriptionRegistry(initData.extensions);
|
||||
this._threadService = threadService;
|
||||
@@ -132,7 +138,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
this._activator = null;
|
||||
|
||||
// initialize API first (i.e. do not release barrier until the API is initialized)
|
||||
const apiFactory = createApiFactory(initData, threadService, this);
|
||||
const apiFactory = createApiFactory(initData, threadService, extHostWorkspace, extHostConfiguration, this);
|
||||
|
||||
initializeExtensionApi(this, apiFactory).then(() => {
|
||||
|
||||
@@ -205,9 +211,9 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
}
|
||||
|
||||
// create trie to enable fast 'filename -> extension id' look up
|
||||
public getExtensionPathIndex(): TPromise<TrieMap<IExtensionDescription>> {
|
||||
public getExtensionPathIndex(): TPromise<TernarySearchTree<IExtensionDescription>> {
|
||||
if (!this._extensionPathIndex) {
|
||||
const trie = new TrieMap<IExtensionDescription>();
|
||||
const tree = TernarySearchTree.forPaths<IExtensionDescription>();
|
||||
const extensions = this.getAllExtensionDescriptions().map(ext => {
|
||||
if (!ext.main) {
|
||||
return undefined;
|
||||
@@ -217,13 +223,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
trie.insert(path, ext);
|
||||
tree.set(path, ext);
|
||||
resolve(void 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
this._extensionPathIndex = TPromise.join(extensions).then(() => trie);
|
||||
this._extensionPathIndex = TPromise.join(extensions).then(() => tree);
|
||||
}
|
||||
return this._extensionPathIndex;
|
||||
}
|
||||
@@ -282,6 +288,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
|
||||
private _doActivateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise<ActivatedExtension> {
|
||||
let event = getTelemetryActivationEvent(extensionDescription);
|
||||
/* __GDPR__
|
||||
"activatePlugin" : {
|
||||
"${include}": [
|
||||
"${TelemetryActivationEvent}"
|
||||
]
|
||||
}
|
||||
*/
|
||||
this._mainThreadTelemetry.$publicLog('activatePlugin', event);
|
||||
if (!extensionDescription.main) {
|
||||
// Treat the extension as being empty => NOT AN ERROR CASE
|
||||
@@ -343,7 +356,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
if (typeof extensionModule.activate === 'function') {
|
||||
try {
|
||||
activationTimesBuilder.activateCallStart();
|
||||
const activateResult = extensionModule.activate.apply(global, [context]);
|
||||
const activateResult: TPromise<IExtensionAPI> = extensionModule.activate.apply(global, [context]);
|
||||
activationTimesBuilder.activateCallStop();
|
||||
|
||||
activationTimesBuilder.activateResolveStart();
|
||||
@@ -381,6 +394,21 @@ function loadCommonJSModule<T>(modulePath: string, activationTimesBuilder: Exten
|
||||
}
|
||||
|
||||
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription): any {
|
||||
/* __GDPR__FRAGMENT__
|
||||
"TelemetryActivationEvent" : {
|
||||
"id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"publisherDisplayName": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"${wildcard}": [
|
||||
{
|
||||
"${prefix}": "contribution.",
|
||||
"${classification}": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
let event = {
|
||||
id: extensionDescription.id,
|
||||
name: extensionDescription.name,
|
||||
|
||||
85
src/vs/workbench/api/node/extHostFileSystem.ts
Normal file
85
src/vs/workbench/api/node/extHostFileSystem.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { MainContext, IMainContext, ExtHostFileSystemShape, MainThreadFileSystemShape } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
import { IStat } from 'vs/platform/files/common/files';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
|
||||
export class ExtHostFileSystem implements ExtHostFileSystemShape {
|
||||
|
||||
private readonly _proxy: MainThreadFileSystemShape;
|
||||
private readonly _provider = new Map<number, vscode.FileSystemProvider>();
|
||||
private _handlePool: number = 0;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadFileSystem);
|
||||
}
|
||||
|
||||
registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider) {
|
||||
const handle = this._handlePool++;
|
||||
this._provider.set(handle, provider);
|
||||
this._proxy.$registerFileSystemProvider(handle, scheme);
|
||||
this._proxy.$onDidAddFileSystemRoot(<any>provider.root);
|
||||
let reg: IDisposable;
|
||||
if (provider.onDidChange) {
|
||||
reg = provider.onDidChange(event => this._proxy.$onFileSystemChange(handle, <any>event));
|
||||
}
|
||||
return {
|
||||
dispose: () => {
|
||||
if (reg) {
|
||||
reg.dispose();
|
||||
}
|
||||
this._provider.delete(handle);
|
||||
this._proxy.$unregisterFileSystemProvider(handle);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$utimes(handle: number, resource: URI, mtime: number, atime: number): TPromise<IStat, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).utimes(resource, mtime, atime));
|
||||
}
|
||||
$stat(handle: number, resource: URI): TPromise<IStat, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).stat(resource));
|
||||
}
|
||||
$read(handle: number, offset: number, count: number, resource: URI): TPromise<number> {
|
||||
const progress = {
|
||||
report: chunk => {
|
||||
this._proxy.$reportFileChunk(handle, resource, [].slice.call(chunk));
|
||||
}
|
||||
};
|
||||
return asWinJsPromise(token => this._provider.get(handle).read(resource, offset, count, progress));
|
||||
}
|
||||
$write(handle: number, resource: URI, content: number[]): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).write(resource, Buffer.from(content)));
|
||||
}
|
||||
$unlink(handle: number, resource: URI): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).unlink(resource));
|
||||
}
|
||||
$move(handle: number, resource: URI, target: URI): TPromise<IStat, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).move(resource, target));
|
||||
}
|
||||
$mkdir(handle: number, resource: URI): TPromise<IStat, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).mkdir(resource));
|
||||
}
|
||||
$readdir(handle: number, resource: URI): TPromise<[URI, IStat][], any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).readdir(resource));
|
||||
}
|
||||
$rmdir(handle: number, resource: URI): TPromise<void, any> {
|
||||
return asWinJsPromise(token => this._provider.get(handle).rmdir(resource));
|
||||
}
|
||||
$fileFiles(handle: number, session: number, query: string): TPromise<void> {
|
||||
const provider = this._provider.get(handle);
|
||||
if (!provider.findFiles) {
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
const progress = { report: (uri) => this._proxy.$handleSearchProgress(handle, session, uri) };
|
||||
return asWinJsPromise(token => provider.findFiles(query, progress, token));
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from './extHostTypes';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
import { parse, IRelativePattern } from 'vs/base/common/glob';
|
||||
import { Uri, FileSystemWatcher as _FileSystemWatcher } from 'vscode';
|
||||
import { FileSystemEvents, ExtHostFileSystemEventServiceShape } from './extHost.protocol';
|
||||
|
||||
@@ -30,7 +30,7 @@ class FileSystemWatcher implements _FileSystemWatcher {
|
||||
return Boolean(this._config & 0b100);
|
||||
}
|
||||
|
||||
constructor(dispatcher: Event<FileSystemEvents>, globPattern: string, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean) {
|
||||
constructor(dispatcher: Event<FileSystemEvents>, globPattern: string | IRelativePattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean) {
|
||||
|
||||
this._config = 0;
|
||||
if (ignoreCreateEvents) {
|
||||
@@ -43,24 +43,26 @@ class FileSystemWatcher implements _FileSystemWatcher {
|
||||
this._config += 0b100;
|
||||
}
|
||||
|
||||
const parsedPattern = parse(globPattern);
|
||||
|
||||
let subscription = dispatcher(events => {
|
||||
if (!ignoreCreateEvents) {
|
||||
for (let created of events.created) {
|
||||
if (match(globPattern, created.fsPath)) {
|
||||
if (parsedPattern(created.fsPath)) {
|
||||
this._onDidCreate.fire(created);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ignoreChangeEvents) {
|
||||
for (let changed of events.changed) {
|
||||
if (match(globPattern, changed.fsPath)) {
|
||||
if (parsedPattern(changed.fsPath)) {
|
||||
this._onDidChange.fire(changed);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ignoreDeleteEvents) {
|
||||
for (let deleted of events.deleted) {
|
||||
if (match(globPattern, deleted.fsPath)) {
|
||||
if (parsedPattern(deleted.fsPath)) {
|
||||
this._onDidDelete.fire(deleted);
|
||||
}
|
||||
}
|
||||
@@ -94,7 +96,7 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public createFileSystemWatcher(globPattern: string, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): _FileSystemWatcher {
|
||||
public createFileSystemWatcher(globPattern: string | IRelativePattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): _FileSystemWatcher {
|
||||
return new FileSystemWatcher(this._emitter.event, globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,22 +9,19 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import * as vscode from 'vscode';
|
||||
import * as TypeConverters from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { Range, Disposable, CompletionList, CompletionItem, SnippetString } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { Range, Disposable, CompletionList, SnippetString, Color } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/editorCommon';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { MainContext, MainThreadTelemetryShape, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IRawColorFormatMap, IMainContext } from './extHost.protocol';
|
||||
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IExtHostSuggestResult, IExtHostSuggestion, IWorkspaceSymbols, IWorkspaceSymbol, IdObject } from './extHost.protocol';
|
||||
import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { containsCommandLink } from 'vs/base/common/htmlContent';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
|
||||
// --- adapter
|
||||
|
||||
@@ -179,7 +176,6 @@ class HoverAdapter {
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.HoverProvider,
|
||||
private readonly _telemetryLog: (name: string, data: object) => void,
|
||||
) {
|
||||
//
|
||||
}
|
||||
@@ -200,14 +196,7 @@ class HoverAdapter {
|
||||
value.range = new Range(pos, pos);
|
||||
}
|
||||
|
||||
const result = TypeConverters.fromHover(value);
|
||||
|
||||
// we wanna know which extension uses command links
|
||||
// because that is a potential trick-attack on users
|
||||
if (result.contents.some(h => containsCommandLink(h.value))) {
|
||||
this._telemetryLog('usesCommandLink', { from: 'hover' });
|
||||
}
|
||||
return result;
|
||||
return TypeConverters.fromHover(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -273,7 +262,7 @@ class QuickFixAdapter {
|
||||
private _diagnostics: ExtHostDiagnostics;
|
||||
private _provider: vscode.CodeActionProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, commands: CommandsConverter, diagnostics: ExtHostDiagnostics, heapService: ExtHostHeapService, provider: vscode.CodeActionProvider) {
|
||||
constructor(documents: ExtHostDocuments, commands: CommandsConverter, diagnostics: ExtHostDiagnostics, provider: vscode.CodeActionProvider) {
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._diagnostics = diagnostics;
|
||||
@@ -283,13 +272,13 @@ class QuickFixAdapter {
|
||||
provideCodeActions(resource: URI, range: IRange): TPromise<modes.Command[]> {
|
||||
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const ran = TypeConverters.toRange(range);
|
||||
const ran = <vscode.Range>TypeConverters.toRange(range);
|
||||
const allDiagnostics: vscode.Diagnostic[] = [];
|
||||
|
||||
this._diagnostics.forEach(collection => {
|
||||
if (collection.has(resource)) {
|
||||
for (let diagnostic of collection.get(resource)) {
|
||||
if (diagnostic.range.intersection(ran)) {
|
||||
if (ran.contains(diagnostic.range)) {
|
||||
allDiagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
@@ -378,45 +367,56 @@ class OnTypeFormattingAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
class NavigateTypeAdapter {
|
||||
|
||||
class NavigateTypeAdapter implements IWorkspaceSymbolProvider {
|
||||
private readonly _symbolCache: { [id: number]: vscode.SymbolInformation } = Object.create(null);
|
||||
private readonly _resultCache: { [id: number]: [number, number] } = Object.create(null);
|
||||
private readonly _provider: vscode.WorkspaceSymbolProvider;
|
||||
|
||||
private _provider: vscode.WorkspaceSymbolProvider;
|
||||
private _heapService: ExtHostHeapService;
|
||||
|
||||
constructor(provider: vscode.WorkspaceSymbolProvider, heapService: ExtHostHeapService) {
|
||||
constructor(provider: vscode.WorkspaceSymbolProvider) {
|
||||
this._provider = provider;
|
||||
this._heapService = heapService;
|
||||
}
|
||||
|
||||
provideWorkspaceSymbols(search: string): TPromise<modes.SymbolInformation[]> {
|
||||
|
||||
provideWorkspaceSymbols(search: string): TPromise<IWorkspaceSymbols> {
|
||||
const result: IWorkspaceSymbols = IdObject.mixin({ symbols: [] });
|
||||
return asWinJsPromise(token => this._provider.provideWorkspaceSymbols(search, token)).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(item => {
|
||||
const id = this._heapService.keep(item);
|
||||
const result = TypeConverters.fromSymbolInformation(item);
|
||||
return ObjectIdentifier.mixin(result, id);
|
||||
});
|
||||
if (!isFalsyOrEmpty(value)) {
|
||||
for (const item of value) {
|
||||
const symbol = IdObject.mixin(TypeConverters.fromSymbolInformation(item));
|
||||
this._symbolCache[symbol._id] = item;
|
||||
result.symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}).then(() => {
|
||||
this._resultCache[result._id] = [result.symbols[0]._id, result.symbols[result.symbols.length - 1]._id];
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
resolveWorkspaceSymbol(item: modes.SymbolInformation): TPromise<modes.SymbolInformation> {
|
||||
resolveWorkspaceSymbol(symbol: IWorkspaceSymbol): TPromise<IWorkspaceSymbol> {
|
||||
|
||||
if (typeof this._provider.resolveWorkspaceSymbol !== 'function') {
|
||||
return TPromise.as(item);
|
||||
return TPromise.as(symbol);
|
||||
}
|
||||
|
||||
const symbolInfo = this._heapService.get<vscode.SymbolInformation>(ObjectIdentifier.of(item));
|
||||
if (symbolInfo) {
|
||||
return asWinJsPromise(token => this._provider.resolveWorkspaceSymbol(symbolInfo, token)).then(value => {
|
||||
return value && TypeConverters.fromSymbolInformation(value);
|
||||
const item = this._symbolCache[symbol._id];
|
||||
if (item) {
|
||||
return asWinJsPromise(token => this._provider.resolveWorkspaceSymbol(item, token)).then(value => {
|
||||
return value && mixin(symbol, TypeConverters.fromSymbolInformation(value), true);
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
releaseWorkspaceSymbols(id: number): any {
|
||||
const range = this._resultCache[id];
|
||||
if (range) {
|
||||
for (let [from, to] = range; from <= to; from++) {
|
||||
delete this._symbolCache[from];
|
||||
}
|
||||
delete this._resultCache[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RenameAdapter {
|
||||
@@ -447,7 +447,7 @@ class RenameAdapter {
|
||||
let [uri, textEdits] = entry;
|
||||
for (let textEdit of textEdits) {
|
||||
result.edits.push({
|
||||
resource: <URI>uri,
|
||||
resource: uri,
|
||||
newText: textEdit.newText,
|
||||
range: TypeConverters.fromRange(textEdit.range)
|
||||
});
|
||||
@@ -469,26 +469,36 @@ class RenameAdapter {
|
||||
|
||||
class SuggestAdapter {
|
||||
|
||||
static supportsResolving(provider: vscode.CompletionItemProvider): boolean {
|
||||
return typeof provider.resolveCompletionItem === 'function';
|
||||
}
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: CommandsConverter;
|
||||
private _heapService: ExtHostHeapService;
|
||||
private _provider: vscode.CompletionItemProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, commands: CommandsConverter, heapService: ExtHostHeapService, provider: vscode.CompletionItemProvider) {
|
||||
private _cache = new Map<number, vscode.CompletionItem[]>();
|
||||
private _idPool = 0;
|
||||
|
||||
constructor(documents: ExtHostDocuments, commands: CommandsConverter, provider: vscode.CompletionItemProvider) {
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._heapService = heapService;
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
provideCompletionItems(resource: URI, position: IPosition): TPromise<modes.ISuggestResult> {
|
||||
provideCompletionItems(resource: URI, position: IPosition, context: modes.SuggestContext): TPromise<IExtHostSuggestResult> {
|
||||
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const pos = TypeConverters.toPosition(position);
|
||||
|
||||
return asWinJsPromise<vscode.CompletionItem[] | vscode.CompletionList>(token => this._provider.provideCompletionItems(doc, pos, token)).then(value => {
|
||||
return asWinJsPromise<vscode.CompletionItem[] | vscode.CompletionList>(token => {
|
||||
return this._provider.provideCompletionItems(doc, pos, token, TypeConverters.CompletionContext.from(context));
|
||||
}).then(value => {
|
||||
|
||||
const result: modes.ISuggestResult = {
|
||||
const _id = this._idPool++;
|
||||
|
||||
const result: IExtHostSuggestResult = {
|
||||
_id,
|
||||
suggestions: [],
|
||||
};
|
||||
|
||||
@@ -509,19 +519,15 @@ class SuggestAdapter {
|
||||
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) || new Range(pos, pos))
|
||||
.with({ end: pos });
|
||||
|
||||
for (const item of list.items) {
|
||||
|
||||
const suggestion = this._convertCompletionItem(item, pos, wordRangeBeforePos);
|
||||
|
||||
// bad completion item
|
||||
if (!suggestion) {
|
||||
// converter did warn
|
||||
continue;
|
||||
for (let i = 0; i < list.items.length; i++) {
|
||||
const suggestion = this._convertCompletionItem(list.items[i], pos, wordRangeBeforePos, i, _id);
|
||||
// check for bad completion item
|
||||
// for the converter did warn
|
||||
if (suggestion) {
|
||||
result.suggestions.push(suggestion);
|
||||
}
|
||||
|
||||
ObjectIdentifier.mixin(suggestion, this._heapService.keep(item));
|
||||
result.suggestions.push(suggestion);
|
||||
}
|
||||
this._cache.set(_id, list.items);
|
||||
|
||||
return result;
|
||||
});
|
||||
@@ -533,8 +539,8 @@ class SuggestAdapter {
|
||||
return TPromise.as(suggestion);
|
||||
}
|
||||
|
||||
const id = ObjectIdentifier.of(suggestion);
|
||||
const item = this._heapService.get<CompletionItem>(id);
|
||||
const { _parentId, _id } = (<IExtHostSuggestion>suggestion);
|
||||
const item = this._cache.has(_parentId) && this._cache.get(_parentId)[_id];
|
||||
if (!item) {
|
||||
return TPromise.as(suggestion);
|
||||
}
|
||||
@@ -548,7 +554,7 @@ class SuggestAdapter {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const pos = TypeConverters.toPosition(position);
|
||||
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) || new Range(pos, pos)).with({ end: pos });
|
||||
const newSuggestion = this._convertCompletionItem(resolvedItem, pos, wordRangeBeforePos);
|
||||
const newSuggestion = this._convertCompletionItem(resolvedItem, pos, wordRangeBeforePos, _id, _parentId);
|
||||
if (newSuggestion) {
|
||||
mixin(suggestion, newSuggestion, true);
|
||||
}
|
||||
@@ -557,13 +563,20 @@ class SuggestAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range): modes.ISuggestion {
|
||||
releaseCompletionItems(id: number): any {
|
||||
this._cache.delete(id);
|
||||
}
|
||||
|
||||
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range, _id: number, _parentId: number): IExtHostSuggestion {
|
||||
if (typeof item.label !== 'string' || item.label.length === 0) {
|
||||
console.warn('INVALID text edit -> must have at least a label');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result: modes.ISuggestion = {
|
||||
const result: IExtHostSuggestion = {
|
||||
//
|
||||
_id,
|
||||
_parentId,
|
||||
//
|
||||
label: item.label,
|
||||
type: TypeConverters.CompletionItemKind.from(item.kind),
|
||||
@@ -693,8 +706,6 @@ class LinkProviderAdapter {
|
||||
|
||||
class ColorProviderAdapter {
|
||||
|
||||
private static _colorFormatHandlePool: number = 0;
|
||||
|
||||
constructor(
|
||||
private _proxy: MainThreadLanguageFeaturesShape,
|
||||
private _documents: ExtHostDocuments,
|
||||
@@ -709,39 +720,25 @@ class ColorProviderAdapter {
|
||||
return [];
|
||||
}
|
||||
|
||||
const newRawColorFormats: IRawColorFormatMap = [];
|
||||
const getFormatId = (format: string) => {
|
||||
let id = this._colorFormatCache.get(format);
|
||||
|
||||
if (typeof id !== 'number') {
|
||||
id = ColorProviderAdapter._colorFormatHandlePool++;
|
||||
this._colorFormatCache.set(format, id);
|
||||
newRawColorFormats.push([id, format]);
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
const colorInfos: IRawColorInfo[] = colors.map(ci => {
|
||||
const availableFormats = ci.availableFormats.map(format => {
|
||||
if (typeof format === 'string') {
|
||||
return getFormatId(format);
|
||||
} else {
|
||||
return [getFormatId(format.opaque), getFormatId(format.transparent)] as [number, number];
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
color: [ci.color.red, ci.color.green, ci.color.blue, ci.color.alpha] as [number, number, number, number],
|
||||
availableFormats: availableFormats,
|
||||
range: TypeConverters.fromRange(ci.range)
|
||||
};
|
||||
});
|
||||
|
||||
this._proxy.$registerColorFormats(newRawColorFormats);
|
||||
return colorInfos;
|
||||
});
|
||||
}
|
||||
|
||||
provideColorPresentations(resource: URI, raw: IRawColorInfo): TPromise<modes.IColorPresentation[]> {
|
||||
const document = this._documents.getDocumentData(resource).document;
|
||||
const range = TypeConverters.toRange(raw.range);
|
||||
const color = new Color(raw.color[0], raw.color[1], raw.color[2], raw.color[3]);
|
||||
return asWinJsPromise(token => this._provider.provideColorPresentations(color, { document, range }, token)).then(value => {
|
||||
return value.map(TypeConverters.ColorPresentation.from);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
@@ -754,7 +751,6 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
private static _handlePool: number = 0;
|
||||
|
||||
private _proxy: MainThreadLanguageFeaturesShape;
|
||||
private _telemetry: MainThreadTelemetryShape;
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: ExtHostCommands;
|
||||
private _heapService: ExtHostHeapService;
|
||||
@@ -770,7 +766,6 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
diagnostics: ExtHostDiagnostics
|
||||
) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadLanguageFeatures);
|
||||
this._telemetry = mainContext.get(MainContext.MainThreadTelemetry);
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._heapService = heapMonitor;
|
||||
@@ -874,10 +869,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider, extensionId?: string): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new HoverAdapter(this._documents, provider, once((name, data) => {
|
||||
data['extension'] = extensionId;
|
||||
this._telemetry.$publicLog(name, data);
|
||||
})));
|
||||
this._adapter.set(handle, new HoverAdapter(this._documents, provider));
|
||||
this._proxy.$registerHoverProvider(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -916,7 +908,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, this._heapService, provider));
|
||||
this._adapter.set(handle, new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, provider));
|
||||
this._proxy.$registerQuickFixSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -964,19 +956,23 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new NavigateTypeAdapter(provider, this._heapService));
|
||||
this._adapter.set(handle, new NavigateTypeAdapter(provider));
|
||||
this._proxy.$registerNavigateTypeSupport(handle);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideWorkspaceSymbols(handle: number, search: string): TPromise<modes.SymbolInformation[]> {
|
||||
$provideWorkspaceSymbols(handle: number, search: string): TPromise<IWorkspaceSymbols> {
|
||||
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.provideWorkspaceSymbols(search));
|
||||
}
|
||||
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: modes.SymbolInformation): TPromise<modes.SymbolInformation> {
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: IWorkspaceSymbol): TPromise<IWorkspaceSymbol> {
|
||||
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.resolveWorkspaceSymbol(symbol));
|
||||
}
|
||||
|
||||
$releaseWorkspaceSymbols(handle: number, id: number) {
|
||||
this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.releaseWorkspaceSymbols(id));
|
||||
}
|
||||
|
||||
// --- rename
|
||||
|
||||
registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
|
||||
@@ -994,19 +990,23 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new SuggestAdapter(this._documents, this._commands.converter, this._heapService, provider));
|
||||
this._proxy.$registerSuggestSupport(handle, selector, triggerCharacters);
|
||||
this._adapter.set(handle, new SuggestAdapter(this._documents, this._commands.converter, provider));
|
||||
this._proxy.$registerSuggestSupport(handle, selector, triggerCharacters, SuggestAdapter.supportsResolving(provider));
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideCompletionItems(handle: number, resource: URI, position: IPosition): TPromise<modes.ISuggestResult> {
|
||||
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(resource, position));
|
||||
$provideCompletionItems(handle: number, resource: URI, position: IPosition, context: modes.SuggestContext): TPromise<IExtHostSuggestResult> {
|
||||
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(resource, position, context));
|
||||
}
|
||||
|
||||
$resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion> {
|
||||
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.resolveCompletionItem(resource, position, suggestion));
|
||||
}
|
||||
|
||||
$releaseCompletionItems(handle: number, id: number): void {
|
||||
this._withAdapter(handle, SuggestAdapter, adapter => adapter.releaseCompletionItems(id));
|
||||
}
|
||||
|
||||
// --- parameter hints
|
||||
|
||||
registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
@@ -1048,6 +1048,10 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColors(resource));
|
||||
}
|
||||
|
||||
$provideColorPresentations(handle: number, resource: URI, colorInfo: IRawColorInfo): TPromise<modes.IColorPresentation[]> {
|
||||
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColorPresentations(resource, colorInfo));
|
||||
}
|
||||
|
||||
// --- configuration
|
||||
|
||||
setLanguageConfiguration(languageId: string, configuration: vscode.LanguageConfiguration): vscode.Disposable {
|
||||
|
||||
@@ -5,21 +5,28 @@
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { wireCancellationToken } from 'vs/base/common/async';
|
||||
import { wireCancellationToken, asWinJsPromise } from 'vs/base/common/async';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { QuickPickOptions, QuickPickItem, InputBoxOptions } from 'vscode';
|
||||
import { QuickPickOptions, QuickPickItem, InputBoxOptions, WorkspaceFolderPickOptions, WorkspaceFolder } from 'vscode';
|
||||
import { MainContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, MyQuickPickItems, IMainContext } from './extHost.protocol';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
|
||||
export type Item = string | QuickPickItem;
|
||||
|
||||
export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
|
||||
private _proxy: MainThreadQuickOpenShape;
|
||||
private _onDidSelectItem: (handle: number) => void;
|
||||
private _validateInput: (input: string) => string;
|
||||
private _workspace: ExtHostWorkspace;
|
||||
private _commands: ExtHostCommands;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
private _onDidSelectItem: (handle: number) => void;
|
||||
private _validateInput: (input: string) => string | Thenable<string>;
|
||||
|
||||
constructor(mainContext: IMainContext, workspace: ExtHostWorkspace, commands: ExtHostCommands) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadQuickOpen);
|
||||
this._workspace = workspace;
|
||||
this._commands = commands;
|
||||
}
|
||||
|
||||
showQuickPick(itemsOrItemsPromise: string[] | Thenable<string[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<string | undefined>;
|
||||
@@ -113,8 +120,20 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
|
||||
$validateInput(input: string): TPromise<string> {
|
||||
if (this._validateInput) {
|
||||
return TPromise.as(this._validateInput(input));
|
||||
return asWinJsPromise(_ => this._validateInput(input));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ---- workspace folder picker
|
||||
|
||||
showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions, token = CancellationToken.None): Thenable<WorkspaceFolder> {
|
||||
return this._commands.executeCommand('_workbench.pickWorkspaceFolder', [options]).then((selectedFolder: WorkspaceFolder) => {
|
||||
if (!selectedFolder) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this._workspace.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,21 @@
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import Event, { Emitter, once } from 'vs/base/common/event';
|
||||
import { debounce } from 'vs/base/common/decorators';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { MainContext, MainThreadSCMShape, SCMRawResource, IMainContext } from './extHost.protocol';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext } from './extHost.protocol';
|
||||
import { sortedDiff } from 'vs/base/common/arrays';
|
||||
import { comparePaths } from 'vs/base/common/comparers';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
type ProviderHandle = number;
|
||||
type GroupHandle = number;
|
||||
type ResourceStateHandle = number;
|
||||
|
||||
function getIconPath(decorations: vscode.SourceControlResourceThemableDecorations) {
|
||||
if (!decorations) {
|
||||
return undefined;
|
||||
@@ -24,6 +32,82 @@ function getIconPath(decorations: vscode.SourceControlResourceThemableDecoration
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function compareResourceThemableDecorations(a: vscode.SourceControlResourceThemableDecorations, b: vscode.SourceControlResourceThemableDecorations): number {
|
||||
if (!a.iconPath && !b.iconPath) {
|
||||
return 0;
|
||||
} else if (!a.iconPath) {
|
||||
return -1;
|
||||
} else if (!b.iconPath) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const aPath = typeof a.iconPath === 'string' ? a.iconPath : a.iconPath.fsPath;
|
||||
const bPath = typeof b.iconPath === 'string' ? b.iconPath : b.iconPath.fsPath;
|
||||
return comparePaths(aPath, bPath);
|
||||
}
|
||||
|
||||
function compareResourceStatesDecorations(a: vscode.SourceControlResourceDecorations, b: vscode.SourceControlResourceDecorations): number {
|
||||
let result = 0;
|
||||
|
||||
if (a.strikeThrough !== b.strikeThrough) {
|
||||
return a.strikeThrough ? 1 : -1;
|
||||
}
|
||||
|
||||
if (a.faded !== b.faded) {
|
||||
return a.faded ? 1 : -1;
|
||||
}
|
||||
|
||||
if (a.tooltip !== b.tooltip) {
|
||||
return (a.tooltip || '').localeCompare(b.tooltip);
|
||||
}
|
||||
|
||||
result = compareResourceThemableDecorations(a, b);
|
||||
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (a.light && b.light) {
|
||||
result = compareResourceThemableDecorations(a.light, b.light);
|
||||
} else if (a.light) {
|
||||
return 1;
|
||||
} else if (b.light) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (a.dark && b.dark) {
|
||||
result = compareResourceThemableDecorations(a.dark, b.dark);
|
||||
} else if (a.dark) {
|
||||
return 1;
|
||||
} else if (b.dark) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function compareResourceStates(a: vscode.SourceControlResourceState, b: vscode.SourceControlResourceState): number {
|
||||
let result = comparePaths(a.resourceUri.fsPath, b.resourceUri.fsPath);
|
||||
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (a.decorations && b.decorations) {
|
||||
result = compareResourceStatesDecorations(a.decorations, b.decorations);
|
||||
} else if (a.decorations) {
|
||||
return 1;
|
||||
} else if (b.decorations) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export class ExtHostSCMInputBox {
|
||||
|
||||
private _value: string = '';
|
||||
@@ -62,99 +146,135 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG
|
||||
private static _handlePool: number = 0;
|
||||
private _resourceHandlePool: number = 0;
|
||||
private _resourceStates: vscode.SourceControlResourceState[] = [];
|
||||
|
||||
private _resourceStatesRollingDisposables: { (): void }[] = [];
|
||||
private _resourceStatesMap: Map<ResourceStateHandle, vscode.SourceControlResourceState> = new Map<ResourceStateHandle, vscode.SourceControlResourceState>();
|
||||
private _resourceStatesCommandsMap: Map<ResourceStateHandle, vscode.Command> = new Map<ResourceStateHandle, vscode.Command>();
|
||||
|
||||
get id(): string {
|
||||
return this._id;
|
||||
}
|
||||
private _onDidUpdateResourceStates = new Emitter<void>();
|
||||
readonly onDidUpdateResourceStates = this._onDidUpdateResourceStates.event;
|
||||
private _onDidDispose = new Emitter<void>();
|
||||
readonly onDidDispose = this._onDidDispose.event;
|
||||
|
||||
get label(): string {
|
||||
return this._label;
|
||||
}
|
||||
private _handlesSnapshot: number[] = [];
|
||||
private _resourceSnapshot: vscode.SourceControlResourceState[] = [];
|
||||
|
||||
get id(): string { return this._id; }
|
||||
|
||||
get label(): string { return this._label; }
|
||||
set label(label: string) {
|
||||
this._label = label;
|
||||
this._proxy.$updateGroupLabel(this._sourceControlHandle, this._handle, label);
|
||||
this._proxy.$updateGroupLabel(this._sourceControlHandle, this.handle, label);
|
||||
}
|
||||
|
||||
private _hideWhenEmpty: boolean | undefined = undefined;
|
||||
|
||||
get hideWhenEmpty(): boolean | undefined {
|
||||
return this._hideWhenEmpty;
|
||||
}
|
||||
|
||||
get hideWhenEmpty(): boolean | undefined { return this._hideWhenEmpty; }
|
||||
set hideWhenEmpty(hideWhenEmpty: boolean | undefined) {
|
||||
this._hideWhenEmpty = hideWhenEmpty;
|
||||
this._proxy.$updateGroup(this._sourceControlHandle, this._handle, { hideWhenEmpty });
|
||||
}
|
||||
|
||||
get resourceStates(): vscode.SourceControlResourceState[] {
|
||||
return [...this._resourceStates];
|
||||
this._proxy.$updateGroup(this._sourceControlHandle, this.handle, { hideWhenEmpty });
|
||||
}
|
||||
|
||||
get resourceStates(): vscode.SourceControlResourceState[] { return [...this._resourceStates]; }
|
||||
set resourceStates(resources: vscode.SourceControlResourceState[]) {
|
||||
this._resourceStates = [...resources];
|
||||
|
||||
const handles: number[] = [];
|
||||
const rawResources = resources.map(r => {
|
||||
const handle = this._resourceHandlePool++;
|
||||
this._resourceStatesMap.set(handle, r);
|
||||
handles.push(handle);
|
||||
|
||||
const sourceUri = r.resourceUri.toString();
|
||||
const command = this._commands.toInternal(r.command);
|
||||
const iconPath = getIconPath(r.decorations);
|
||||
const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath;
|
||||
const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath;
|
||||
const icons: string[] = [];
|
||||
|
||||
if (lightIconPath || darkIconPath) {
|
||||
icons.push(lightIconPath);
|
||||
}
|
||||
|
||||
if (darkIconPath !== lightIconPath) {
|
||||
icons.push(darkIconPath);
|
||||
}
|
||||
|
||||
const tooltip = (r.decorations && r.decorations.tooltip) || '';
|
||||
const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
|
||||
const faded = r.decorations && !!r.decorations.faded;
|
||||
|
||||
return [handle, sourceUri, command, icons, tooltip, strikeThrough, faded] as SCMRawResource;
|
||||
});
|
||||
|
||||
const disposable = () => handles.forEach(handle => this._resourceStatesMap.delete(handle));
|
||||
this._resourceStatesRollingDisposables.push(disposable);
|
||||
|
||||
while (this._resourceStatesRollingDisposables.length >= 10) {
|
||||
this._resourceStatesRollingDisposables.shift()();
|
||||
}
|
||||
|
||||
this._proxy.$updateGroupResourceStates(this._sourceControlHandle, this._handle, rawResources);
|
||||
this._onDidUpdateResourceStates.fire();
|
||||
}
|
||||
|
||||
private _handle: GroupHandle = ExtHostSourceControlResourceGroup._handlePool++;
|
||||
get handle(): GroupHandle {
|
||||
return this._handle;
|
||||
}
|
||||
readonly handle = ExtHostSourceControlResourceGroup._handlePool++;
|
||||
private _disposables: IDisposable[] = [];
|
||||
|
||||
constructor(
|
||||
private _proxy: MainThreadSCMShape,
|
||||
private _commands: CommandsConverter,
|
||||
private _commands: ExtHostCommands,
|
||||
private _sourceControlHandle: number,
|
||||
private _id: string,
|
||||
private _label: string,
|
||||
) {
|
||||
this._proxy.$registerGroup(_sourceControlHandle, this._handle, _id, _label);
|
||||
this._proxy.$registerGroup(_sourceControlHandle, this.handle, _id, _label);
|
||||
}
|
||||
|
||||
getResourceState(handle: number): vscode.SourceControlResourceState | undefined {
|
||||
return this._resourceStatesMap.get(handle);
|
||||
}
|
||||
|
||||
async $executeResourceCommand(handle: number): TPromise<void> {
|
||||
const command = this._resourceStatesCommandsMap.get(handle);
|
||||
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this._commands.executeCommand(command.command, ...command.arguments);
|
||||
}
|
||||
|
||||
_takeResourceStateSnapshot(): SCMRawResourceSplice[] {
|
||||
const snapshot = [...this._resourceStates].sort(compareResourceStates);
|
||||
const diffs = sortedDiff(this._resourceSnapshot, snapshot, compareResourceStates);
|
||||
const handlesToDelete: number[] = [];
|
||||
|
||||
const splices = diffs.map(diff => {
|
||||
const { start, deleteCount } = diff;
|
||||
const handles: number[] = [];
|
||||
|
||||
const rawResources = diff.inserted
|
||||
.map(r => {
|
||||
const handle = this._resourceHandlePool++;
|
||||
this._resourceStatesMap.set(handle, r);
|
||||
handles.push(handle);
|
||||
|
||||
const sourceUri = r.resourceUri.toString();
|
||||
const iconPath = getIconPath(r.decorations);
|
||||
const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath;
|
||||
const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath;
|
||||
const icons: string[] = [];
|
||||
|
||||
if (r.command) {
|
||||
this._resourceStatesCommandsMap.set(handle, r.command);
|
||||
}
|
||||
|
||||
if (lightIconPath || darkIconPath) {
|
||||
icons.push(lightIconPath);
|
||||
}
|
||||
|
||||
if (darkIconPath !== lightIconPath) {
|
||||
icons.push(darkIconPath);
|
||||
}
|
||||
|
||||
const tooltip = (r.decorations && r.decorations.tooltip) || '';
|
||||
const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
|
||||
const faded = r.decorations && !!r.decorations.faded;
|
||||
|
||||
const source = r.decorations && r.decorations.source || undefined;
|
||||
const letter = r.decorations && r.decorations.letter || undefined;
|
||||
const color = r.decorations && r.decorations.color || undefined;
|
||||
|
||||
return [handle, sourceUri, icons, tooltip, strikeThrough, faded, source, letter, color] as SCMRawResource;
|
||||
});
|
||||
|
||||
handlesToDelete.push(...this._handlesSnapshot.splice(start, deleteCount, ...handles));
|
||||
|
||||
return [start, deleteCount, rawResources] as SCMRawResourceSplice;
|
||||
});
|
||||
|
||||
const disposable = () => handlesToDelete.forEach(handle => {
|
||||
this._resourceStatesMap.delete(handle);
|
||||
this._resourceStatesCommandsMap.delete(handle);
|
||||
});
|
||||
|
||||
this._resourceStatesRollingDisposables.push(disposable);
|
||||
|
||||
while (this._resourceStatesRollingDisposables.length >= 10) {
|
||||
this._resourceStatesRollingDisposables.shift()();
|
||||
}
|
||||
|
||||
this._resourceSnapshot = snapshot;
|
||||
return splices;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._proxy.$unregisterGroup(this._sourceControlHandle, this._handle);
|
||||
this._proxy.$unregisterGroup(this._sourceControlHandle, this.handle);
|
||||
this._disposables = dispose(this._disposables);
|
||||
this._onDidDispose.fire();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +291,10 @@ class ExtHostSourceControl implements vscode.SourceControl {
|
||||
return this._label;
|
||||
}
|
||||
|
||||
get rootUri(): vscode.Uri | undefined {
|
||||
return this._rootUri;
|
||||
}
|
||||
|
||||
private _inputBox: ExtHostSCMInputBox;
|
||||
get inputBox(): ExtHostSCMInputBox { return this._inputBox; }
|
||||
|
||||
@@ -182,7 +306,7 @@ class ExtHostSourceControl implements vscode.SourceControl {
|
||||
|
||||
set count(count: number | undefined) {
|
||||
this._count = count;
|
||||
this._proxy.$updateSourceControl(this._handle, { count });
|
||||
this._proxy.$updateSourceControl(this.handle, { count });
|
||||
}
|
||||
|
||||
private _quickDiffProvider: vscode.QuickDiffProvider | undefined = undefined;
|
||||
@@ -193,7 +317,7 @@ class ExtHostSourceControl implements vscode.SourceControl {
|
||||
|
||||
set quickDiffProvider(quickDiffProvider: vscode.QuickDiffProvider | undefined) {
|
||||
this._quickDiffProvider = quickDiffProvider;
|
||||
this._proxy.$updateSourceControl(this._handle, { hasQuickDiffProvider: !!quickDiffProvider });
|
||||
this._proxy.$updateSourceControl(this.handle, { hasQuickDiffProvider: !!quickDiffProvider });
|
||||
}
|
||||
|
||||
private _commitTemplate: string | undefined = undefined;
|
||||
@@ -204,7 +328,7 @@ class ExtHostSourceControl implements vscode.SourceControl {
|
||||
|
||||
set commitTemplate(commitTemplate: string | undefined) {
|
||||
this._commitTemplate = commitTemplate;
|
||||
this._proxy.$updateSourceControl(this._handle, { commitTemplate });
|
||||
this._proxy.$updateSourceControl(this.handle, { commitTemplate });
|
||||
}
|
||||
|
||||
private _acceptInputCommand: vscode.Command | undefined = undefined;
|
||||
@@ -216,8 +340,8 @@ class ExtHostSourceControl implements vscode.SourceControl {
|
||||
set acceptInputCommand(acceptInputCommand: vscode.Command | undefined) {
|
||||
this._acceptInputCommand = acceptInputCommand;
|
||||
|
||||
const internal = this._commands.toInternal(acceptInputCommand);
|
||||
this._proxy.$updateSourceControl(this._handle, { acceptInputCommand: internal });
|
||||
const internal = this._commands.converter.toInternal(acceptInputCommand);
|
||||
this._proxy.$updateSourceControl(this.handle, { acceptInputCommand: internal });
|
||||
}
|
||||
|
||||
private _statusBarCommands: vscode.Command[] | undefined = undefined;
|
||||
@@ -229,41 +353,74 @@ class ExtHostSourceControl implements vscode.SourceControl {
|
||||
set statusBarCommands(statusBarCommands: vscode.Command[] | undefined) {
|
||||
this._statusBarCommands = statusBarCommands;
|
||||
|
||||
const internal = (statusBarCommands || []).map(c => this._commands.toInternal(c));
|
||||
this._proxy.$updateSourceControl(this._handle, { statusBarCommands: internal });
|
||||
const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c));
|
||||
this._proxy.$updateSourceControl(this.handle, { statusBarCommands: internal });
|
||||
}
|
||||
|
||||
private _handle: number = ExtHostSourceControl._handlePool++;
|
||||
private handle: number = ExtHostSourceControl._handlePool++;
|
||||
|
||||
constructor(
|
||||
private _proxy: MainThreadSCMShape,
|
||||
private _commands: CommandsConverter,
|
||||
private _commands: ExtHostCommands,
|
||||
private _id: string,
|
||||
private _label: string,
|
||||
private _rootUri?: vscode.Uri
|
||||
) {
|
||||
this._inputBox = new ExtHostSCMInputBox(this._proxy, this._handle);
|
||||
this._proxy.$registerSourceControl(this._handle, _id, _label);
|
||||
this._inputBox = new ExtHostSCMInputBox(this._proxy, this.handle);
|
||||
this._proxy.$registerSourceControl(this.handle, _id, _label, _rootUri && _rootUri.toString());
|
||||
}
|
||||
|
||||
private updatedResourceGroups = new Set<ExtHostSourceControlResourceGroup>();
|
||||
|
||||
createResourceGroup(id: string, label: string): ExtHostSourceControlResourceGroup {
|
||||
const group = new ExtHostSourceControlResourceGroup(this._proxy, this._commands, this._handle, id, label);
|
||||
const group = new ExtHostSourceControlResourceGroup(this._proxy, this._commands, this.handle, id, label);
|
||||
|
||||
const updateListener = group.onDidUpdateResourceStates(() => {
|
||||
this.updatedResourceGroups.add(group);
|
||||
this.eventuallyUpdateResourceStates();
|
||||
});
|
||||
|
||||
once(group.onDidDispose)(() => {
|
||||
this.updatedResourceGroups.delete(group);
|
||||
updateListener.dispose();
|
||||
this._groups.delete(group.handle);
|
||||
});
|
||||
|
||||
this._groups.set(group.handle, group);
|
||||
return group;
|
||||
}
|
||||
|
||||
@debounce(100)
|
||||
eventuallyUpdateResourceStates(): void {
|
||||
const splices: SCMRawResourceSplices[] = [];
|
||||
|
||||
this.updatedResourceGroups.forEach(group => {
|
||||
const snapshot = group._takeResourceStateSnapshot();
|
||||
|
||||
if (snapshot.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
splices.push([group.handle, snapshot]);
|
||||
});
|
||||
|
||||
if (splices.length > 0) {
|
||||
this._proxy.$spliceResourceStates(this.handle, splices);
|
||||
}
|
||||
|
||||
this.updatedResourceGroups.clear();
|
||||
}
|
||||
|
||||
getResourceGroup(handle: GroupHandle): ExtHostSourceControlResourceGroup | undefined {
|
||||
return this._groups.get(handle);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._proxy.$unregisterSourceControl(this._handle);
|
||||
this._groups.forEach(group => group.dispose());
|
||||
this._proxy.$unregisterSourceControl(this.handle);
|
||||
}
|
||||
}
|
||||
|
||||
type ProviderHandle = number;
|
||||
type GroupHandle = number;
|
||||
type ResourceStateHandle = number;
|
||||
|
||||
export class ExtHostSCM {
|
||||
|
||||
private static _handlePool: number = 0;
|
||||
@@ -320,9 +477,9 @@ export class ExtHostSCM {
|
||||
});
|
||||
}
|
||||
|
||||
createSourceControl(extension: IExtensionDescription, id: string, label: string): vscode.SourceControl {
|
||||
createSourceControl(extension: IExtensionDescription, id: string, label: string, rootUri: vscode.Uri | undefined): vscode.SourceControl {
|
||||
const handle = ExtHostSCM._handlePool++;
|
||||
const sourceControl = new ExtHostSourceControl(this._proxy, this._commands.converter, id, label);
|
||||
const sourceControl = new ExtHostSourceControl(this._proxy, this._commands, id, label, rootUri);
|
||||
this._sourceControls.set(handle, sourceControl);
|
||||
|
||||
const sourceControls = this._sourceControlsByExtension.get(extension.id) || [];
|
||||
@@ -357,11 +514,27 @@ export class ExtHostSCM {
|
||||
$onInputBoxValueChange(sourceControlHandle: number, value: string): TPromise<void> {
|
||||
const sourceControl = this._sourceControls.get(sourceControlHandle);
|
||||
|
||||
if (!sourceControl || !sourceControl.quickDiffProvider) {
|
||||
if (!sourceControl) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
sourceControl.inputBox.$onInputBoxValueChange(value);
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
async $executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): TPromise<void> {
|
||||
const sourceControl = this._sourceControls.get(sourceControlHandle);
|
||||
|
||||
if (!sourceControl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const group = sourceControl.getResourceGroup(groupHandle);
|
||||
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
|
||||
await group.$executeResourceCommand(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as nls from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as Objects from 'vs/base/common/objects';
|
||||
@@ -15,6 +16,7 @@ import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
interface StringMap<V> {
|
||||
@@ -116,7 +118,7 @@ namespace FileLocation {
|
||||
case types.FileLocationKind.Absolute:
|
||||
return { kind: Problems.FileLocationKind.Absolute };
|
||||
case types.FileLocationKind.Relative:
|
||||
return { kind: Problems.FileLocationKind.Relative, prefix: '${workspaceRoot}' };
|
||||
return { kind: Problems.FileLocationKind.Relative, prefix: '${workspaceFolder}' };
|
||||
}
|
||||
return { kind: Problems.FileLocationKind.Auto };
|
||||
}
|
||||
@@ -295,13 +297,13 @@ namespace ShellConfiguration {
|
||||
|
||||
namespace Tasks {
|
||||
|
||||
export function from(tasks: vscode.Task[], extension: IExtensionDescription): TaskSystem.Task[] {
|
||||
export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.Task[] {
|
||||
if (tasks === void 0 || tasks === null) {
|
||||
return [];
|
||||
}
|
||||
let result: TaskSystem.Task[] = [];
|
||||
for (let task of tasks) {
|
||||
let converted = fromSingle(task, extension);
|
||||
let converted = fromSingle(task, rootFolder, extension);
|
||||
if (converted) {
|
||||
result.push(converted);
|
||||
}
|
||||
@@ -309,7 +311,7 @@ namespace Tasks {
|
||||
return result;
|
||||
}
|
||||
|
||||
function fromSingle(task: vscode.Task, extension: IExtensionDescription): TaskSystem.ContributedTask {
|
||||
function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask {
|
||||
if (typeof task.name !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
@@ -326,11 +328,33 @@ namespace Tasks {
|
||||
return undefined;
|
||||
}
|
||||
command.presentation = PresentationOptions.from(task.presentationOptions);
|
||||
let source = {
|
||||
|
||||
let taskScope: types.TaskScope.Global | types.TaskScope.Workspace | vscode.WorkspaceFolder | undefined = task.scope;
|
||||
let workspaceFolder: vscode.WorkspaceFolder | undefined;
|
||||
let scope: TaskSystem.TaskScope;
|
||||
// For backwards compatibility
|
||||
if (taskScope === void 0) {
|
||||
scope = TaskSystem.TaskScope.Folder;
|
||||
workspaceFolder = rootFolder;
|
||||
} else if (taskScope === types.TaskScope.Global) {
|
||||
scope = TaskSystem.TaskScope.Global;
|
||||
} else if (taskScope === types.TaskScope.Workspace) {
|
||||
scope = TaskSystem.TaskScope.Workspace;
|
||||
} else {
|
||||
scope = TaskSystem.TaskScope.Folder;
|
||||
workspaceFolder = taskScope;
|
||||
}
|
||||
let source: TaskSystem.ExtensionTaskSource = {
|
||||
kind: TaskSystem.TaskSourceKind.Extension,
|
||||
label: typeof task.source === 'string' ? task.source : extension.name,
|
||||
extension: extension.id
|
||||
extension: extension.id,
|
||||
scope: scope,
|
||||
workspaceFolder: undefined
|
||||
};
|
||||
// We can't transfer a workspace folder object from the extension host to main since they differ
|
||||
// in shape and we don't have backwards converting function. So transfer the URI and resolve the
|
||||
// workspace folder on the main side.
|
||||
(source as any).__workspaceFolder = workspaceFolder ? workspaceFolder.uri as URI : undefined;
|
||||
let label = nls.localize('task.label', '{0}: {1}', source.label, task.name);
|
||||
let key = (task as types.Task).definitionKey;
|
||||
let kind = (task as types.Task).definition;
|
||||
@@ -398,11 +422,13 @@ interface HandlerData {
|
||||
export class ExtHostTask implements ExtHostTaskShape {
|
||||
|
||||
private _proxy: MainThreadTaskShape;
|
||||
private _extHostWorkspace: ExtHostWorkspace;
|
||||
private _handleCounter: number;
|
||||
private _handlers: Map<number, HandlerData>;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
constructor(mainContext: IMainContext, extHostWorkspace: ExtHostWorkspace) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadTask);
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._handleCounter = 0;
|
||||
this._handlers = new Map<number, HandlerData>();
|
||||
};
|
||||
@@ -426,8 +452,9 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return TPromise.wrapError<TaskSystem.TaskSet>(new Error('no handler found'));
|
||||
}
|
||||
return asWinJsPromise(token => handler.provider.provideTasks(token)).then(value => {
|
||||
let workspaceFolders = this._extHostWorkspace.getWorkspaceFolders();
|
||||
return {
|
||||
tasks: Tasks.from(value, handler.extension),
|
||||
tasks: Tasks.from(value, workspaceFolders && workspaceFolders.length > 0 ? workspaceFolders[0] : undefined, handler.extension),
|
||||
extension: handler.extension
|
||||
};
|
||||
});
|
||||
|
||||
@@ -24,6 +24,7 @@ export class ExtHostTerminal implements vscode.Terminal {
|
||||
name?: string,
|
||||
shellPath?: string,
|
||||
shellArgs?: string[],
|
||||
env?: { [key: string]: string },
|
||||
waitOnExit?: boolean
|
||||
) {
|
||||
this._name = name;
|
||||
@@ -32,7 +33,7 @@ export class ExtHostTerminal implements vscode.Terminal {
|
||||
this._pidPromise = new TPromise<number>(c => {
|
||||
this._pidPromiseComplete = c;
|
||||
});
|
||||
this._proxy.$createTerminal(name, shellPath, shellArgs, waitOnExit).then((id) => {
|
||||
this._proxy.$createTerminal(name, shellPath, shellArgs, env, waitOnExit).then((id) => {
|
||||
this._id = id;
|
||||
this._queuedRequests.forEach((r) => {
|
||||
r.run(this._proxy, this._id);
|
||||
@@ -113,7 +114,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
}
|
||||
|
||||
public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal {
|
||||
let terminal = new ExtHostTerminal(this._proxy, options.name, options.shellPath, options.shellArgs/*, options.waitOnExit*/);
|
||||
let terminal = new ExtHostTerminal(this._proxy, options.name, options.shellPath, options.shellArgs, options.env/*, options.waitOnExit*/);
|
||||
this._terminals.push(terminal);
|
||||
return terminal;
|
||||
}
|
||||
@@ -134,7 +135,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
|
||||
public $acceptTerminalProcessId(id: number, processId: number): void {
|
||||
let terminal = this._getTerminalById(id);
|
||||
terminal._setProcessId(processId);
|
||||
if (terminal) {
|
||||
terminal._setProcessId(processId);
|
||||
}
|
||||
}
|
||||
|
||||
private _getTerminalById(id: number): ExtHostTerminal {
|
||||
|
||||
@@ -6,19 +6,17 @@
|
||||
|
||||
|
||||
import { ok } from 'vs/base/common/assert';
|
||||
import { readonly, illegalArgument, V8CallSite } from 'vs/base/common/errors';
|
||||
import { readonly, illegalArgument } from 'vs/base/common/errors';
|
||||
import { IdGenerator } from 'vs/base/common/idGenerator';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ExtHostDocumentData } from 'vs/workbench/api/node/extHostDocumentData';
|
||||
import { Selection, Range, Position, EndOfLine, TextEditorRevealType, TextEditorLineNumbersStyle, SnippetString } from './extHostTypes';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/editorCommon';
|
||||
import * as TypeConverters from './extHostTypeConverters';
|
||||
import { MainThreadEditorsShape, MainThreadTelemetryShape, IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate } from './extHost.protocol';
|
||||
import { MainThreadEditorsShape, IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { containsCommandLink } from 'vs/base/common/htmlContent';
|
||||
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
|
||||
|
||||
export class TextEditorDecorationType implements vscode.TextEditorDecorationType {
|
||||
|
||||
@@ -418,11 +416,29 @@ export class ExtHostTextEditor implements vscode.TextEditor {
|
||||
|
||||
setDecorations(decorationType: vscode.TextEditorDecorationType, ranges: Range[] | vscode.DecorationOptions[]): void {
|
||||
this._runOnProxy(
|
||||
() => this._proxy.$trySetDecorations(
|
||||
this._id,
|
||||
decorationType.key,
|
||||
TypeConverters.fromRangeOrRangeWithMessage(ranges)
|
||||
)
|
||||
() => {
|
||||
if (TypeConverters.isDecorationOptionsArr(ranges)) {
|
||||
return this._proxy.$trySetDecorations(
|
||||
this._id,
|
||||
decorationType.key,
|
||||
TypeConverters.fromRangeOrRangeWithMessage(ranges)
|
||||
);
|
||||
} else {
|
||||
let _ranges: number[] = new Array<number>(4 * ranges.length);
|
||||
for (let i = 0, len = ranges.length; i < len; i++) {
|
||||
const range = ranges[i];
|
||||
_ranges[4 * i] = range.start.line + 1;
|
||||
_ranges[4 * i + 1] = range.start.character + 1;
|
||||
_ranges[4 * i + 2] = range.end.line + 1;
|
||||
_ranges[4 * i + 3] = range.end.character + 1;
|
||||
}
|
||||
return this._proxy.$trySetDecorationsFast(
|
||||
this._id,
|
||||
decorationType.key,
|
||||
/*TODO: marshaller is too slow*/JSON.stringify(_ranges)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -552,70 +568,6 @@ export class ExtHostTextEditor implements vscode.TextEditor {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostTextEditor2 extends ExtHostTextEditor {
|
||||
|
||||
constructor(
|
||||
private readonly _extHostExtensions: ExtHostExtensionService,
|
||||
private readonly _mainThreadTelemetry: MainThreadTelemetryShape,
|
||||
proxy: MainThreadEditorsShape,
|
||||
id: string,
|
||||
document: ExtHostDocumentData,
|
||||
selections: Selection[],
|
||||
options: IResolvedTextEditorConfiguration,
|
||||
viewColumn: vscode.ViewColumn
|
||||
) {
|
||||
super(proxy, id, document, selections, options, viewColumn);
|
||||
}
|
||||
|
||||
setDecorations(decorationType: vscode.TextEditorDecorationType, rangesOrOptions: Range[] | vscode.DecorationOptions[]): void {
|
||||
// (1) find out if this decoration is important for us
|
||||
let usesCommandLink = false;
|
||||
outer: for (const rangeOrOption of rangesOrOptions) {
|
||||
if (Range.isRange(rangeOrOption)) {
|
||||
break;
|
||||
}
|
||||
if (typeof rangeOrOption.hoverMessage === 'string' && containsCommandLink(rangeOrOption.hoverMessage)) {
|
||||
usesCommandLink = true;
|
||||
break;
|
||||
} else if (Array.isArray(rangeOrOption.hoverMessage)) {
|
||||
for (const message of rangeOrOption.hoverMessage) {
|
||||
if (typeof message === 'string' && containsCommandLink(message)) {
|
||||
usesCommandLink = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// (2) send event for important decorations
|
||||
if (usesCommandLink) {
|
||||
let tag = new Error();
|
||||
this._extHostExtensions.getExtensionPathIndex().then(index => {
|
||||
const oldHandler = (<any>Error).prepareStackTrace;
|
||||
(<any>Error).prepareStackTrace = (error: Error, stackTrace: V8CallSite[]) => {
|
||||
for (const call of stackTrace) {
|
||||
const extension = index.findSubstr(call.getFileName());
|
||||
if (extension) {
|
||||
this._mainThreadTelemetry.$publicLog('usesCommandLink', {
|
||||
extension: extension.id,
|
||||
from: 'decoration',
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
// it all happens here...
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
tag.stack;
|
||||
(<any>Error).prepareStackTrace = oldHandler;
|
||||
});
|
||||
}
|
||||
|
||||
// (3) do it
|
||||
super.setDecorations(decorationType, rangesOrOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function warnOnError(promise: TPromise<any>): void {
|
||||
promise.then(null, (err) => {
|
||||
console.warn(err);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { toThenable } from 'vs/base/common/async';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -13,7 +12,7 @@ import * as TypeConverters from './extHostTypeConverters';
|
||||
import { TextEditorDecorationType, ExtHostTextEditor } from './extHostTextEditor';
|
||||
import { ExtHostDocumentsAndEditors } from './extHostDocumentsAndEditors';
|
||||
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
|
||||
import { MainContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextDocumentShowOptions, ITextEditorPositionData, IResolvedTextEditorConfiguration, ISelectionChangeEvent, IMainContext } from './extHost.protocol';
|
||||
import { MainContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextDocumentShowOptions, ITextEditorPositionData, IResolvedTextEditorConfiguration, ISelectionChangeEvent, IMainContext, IWorkspaceResourceEdit } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
@@ -77,7 +76,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
};
|
||||
}
|
||||
|
||||
return this._proxy.$tryShowTextDocument(<URI>document.uri, options).then(id => {
|
||||
return this._proxy.$tryShowTextDocument(document.uri, options).then(id => {
|
||||
let editor = this._extHostDocumentsAndEditors.getEditor(id);
|
||||
if (editor) {
|
||||
return editor;
|
||||
@@ -91,6 +90,40 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
return new TextEditorDecorationType(this._proxy, options);
|
||||
}
|
||||
|
||||
applyWorkspaceEdit(edit: vscode.WorkspaceEdit): TPromise<boolean> {
|
||||
|
||||
let workspaceResourceEdits: IWorkspaceResourceEdit[] = [];
|
||||
|
||||
let entries = edit.entries();
|
||||
for (let entry of entries) {
|
||||
let [uri, edits] = entry;
|
||||
|
||||
let doc = this._extHostDocumentsAndEditors.getDocument(uri.toString());
|
||||
let docVersion: number = undefined;
|
||||
if (doc) {
|
||||
docVersion = doc.version;
|
||||
}
|
||||
|
||||
let workspaceResourceEdit: IWorkspaceResourceEdit = {
|
||||
resource: uri,
|
||||
modelVersionId: docVersion,
|
||||
edits: []
|
||||
};
|
||||
|
||||
for (let edit of edits) {
|
||||
workspaceResourceEdit.edits.push({
|
||||
newText: edit.newText,
|
||||
newEol: TypeConverters.EndOfLine.from(edit.newEol),
|
||||
range: edit.range && TypeConverters.fromRange(edit.range)
|
||||
});
|
||||
}
|
||||
|
||||
workspaceResourceEdits.push(workspaceResourceEdit);
|
||||
}
|
||||
|
||||
return this._proxy.$tryApplyWorkspaceEdit(workspaceResourceEdits);
|
||||
}
|
||||
|
||||
// --- called from main thread
|
||||
|
||||
$acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { debounceEvent } from 'vs/base/common/event';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.protocol';
|
||||
import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/parts/views/common/views';
|
||||
import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/common/views';
|
||||
import { TreeItemCollapsibleState } from './extHostTypes';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
@@ -175,7 +175,7 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
private getLightIconPath(extensionTreeItem: vscode.TreeItem) {
|
||||
private getLightIconPath(extensionTreeItem: vscode.TreeItem): string {
|
||||
if (extensionTreeItem.iconPath) {
|
||||
if (typeof extensionTreeItem.iconPath === 'string' || extensionTreeItem.iconPath instanceof URI) {
|
||||
return this.getIconPath(extensionTreeItem.iconPath);
|
||||
@@ -185,7 +185,7 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
private getDarkIconPath(extensionTreeItem: vscode.TreeItem) {
|
||||
private getDarkIconPath(extensionTreeItem: vscode.TreeItem): string {
|
||||
if (extensionTreeItem.iconPath && extensionTreeItem.iconPath['dark']) {
|
||||
return this.getIconPath(extensionTreeItem.iconPath['dark']);
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ export function fromViewColumn(column?: vscode.ViewColumn): EditorPosition {
|
||||
editorColumn = EditorPosition.TWO;
|
||||
} else if (column === <number>types.ViewColumn.Three) {
|
||||
editorColumn = EditorPosition.THREE;
|
||||
} else if (column === <number>types.ViewColumn.Active) {
|
||||
editorColumn = undefined;
|
||||
}
|
||||
return editorColumn;
|
||||
}
|
||||
@@ -137,7 +139,7 @@ function isDecorationOptions(something: any): something is vscode.DecorationOpti
|
||||
return (typeof something.range !== 'undefined');
|
||||
}
|
||||
|
||||
function isDecorationOptionsArr(something: vscode.Range[] | vscode.DecorationOptions[]): something is vscode.DecorationOptions[] {
|
||||
export function isDecorationOptionsArr(something: vscode.Range[] | vscode.DecorationOptions[]): something is vscode.DecorationOptions[] {
|
||||
if (something.length === 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -156,7 +158,7 @@ export namespace MarkdownString {
|
||||
}
|
||||
|
||||
function isCodeblock(thing: any): thing is Codeblock {
|
||||
return typeof thing === 'object'
|
||||
return thing && typeof thing === 'object'
|
||||
&& typeof (<Codeblock>thing).language === 'string'
|
||||
&& typeof (<Codeblock>thing).value === 'string';
|
||||
}
|
||||
@@ -168,7 +170,7 @@ export namespace MarkdownString {
|
||||
} else if (htmlContent.isMarkdownString(markup)) {
|
||||
return markup;
|
||||
} else if (typeof markup === 'string') {
|
||||
return { value: <string>markup, isTrusted: true };
|
||||
return { value: <string>markup };
|
||||
} else {
|
||||
return { value: '' };
|
||||
}
|
||||
@@ -178,6 +180,13 @@ export namespace MarkdownString {
|
||||
ret.isTrusted = value.isTrusted;
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function fromStrict(value: string | types.MarkdownString): undefined | string | htmlContent.IMarkdownString {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
return typeof value === 'string' ? value : MarkdownString.from(value);
|
||||
}
|
||||
}
|
||||
|
||||
export function fromRangeOrRangeWithMessage(ranges: vscode.Range[] | vscode.DecorationOptions[]): IDecorationOptions[] {
|
||||
@@ -282,7 +291,7 @@ export const location = {
|
||||
from(value: vscode.Location): modes.Location {
|
||||
return {
|
||||
range: value.range && fromRange(value.range),
|
||||
uri: <URI>value.uri
|
||||
uri: value.uri
|
||||
};
|
||||
},
|
||||
to(value: modes.Location): types.Location {
|
||||
@@ -305,6 +314,28 @@ export function toDocumentHighlight(occurrence: modes.DocumentHighlight): types.
|
||||
return new types.DocumentHighlight(toRange(occurrence.range), occurrence.kind);
|
||||
}
|
||||
|
||||
export namespace CompletionTriggerKind {
|
||||
export function from(kind: modes.SuggestTriggerKind) {
|
||||
switch (kind) {
|
||||
case modes.SuggestTriggerKind.TriggerCharacter:
|
||||
return types.CompletionTriggerKind.TriggerCharacter;
|
||||
|
||||
case modes.SuggestTriggerKind.Invoke:
|
||||
default:
|
||||
return types.CompletionTriggerKind.Invoke;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace CompletionContext {
|
||||
export function from(context: modes.SuggestContext): types.CompletionContext {
|
||||
return {
|
||||
triggerKind: CompletionTriggerKind.from(context.triggerKind),
|
||||
triggerCharacter: context.triggerCharacter
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const CompletionItemKind = {
|
||||
|
||||
from(kind: types.CompletionItemKind): modes.SuggestionType {
|
||||
@@ -354,7 +385,7 @@ export namespace Suggest {
|
||||
result.insertText = suggestion.insertText;
|
||||
result.kind = CompletionItemKind.to(suggestion.type);
|
||||
result.detail = suggestion.detail;
|
||||
result.documentation = suggestion.documentation;
|
||||
result.documentation = <string>suggestion.documentation; // htmlContent.isMarkdownString(suggestion.documentation) ? MarkdownString.to(suggestion.documentation) : suggestion.documentation;
|
||||
result.sortText = suggestion.sortText;
|
||||
result.filterText = suggestion.filterText;
|
||||
|
||||
@@ -381,14 +412,56 @@ export namespace Suggest {
|
||||
}
|
||||
};
|
||||
|
||||
export namespace SignatureHelp {
|
||||
export namespace ParameterInformation {
|
||||
export function from(info: types.ParameterInformation): modes.ParameterInformation {
|
||||
return {
|
||||
label: info.label,
|
||||
documentation: MarkdownString.fromStrict(info.documentation)
|
||||
};
|
||||
}
|
||||
export function to(info: modes.ParameterInformation): types.ParameterInformation {
|
||||
return {
|
||||
label: info.label,
|
||||
documentation: htmlContent.isMarkdownString(info.documentation) ? MarkdownString.to(info.documentation) : info.documentation
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function from(signatureHelp: types.SignatureHelp): modes.SignatureHelp {
|
||||
return signatureHelp;
|
||||
export namespace SignatureInformation {
|
||||
|
||||
export function from(info: types.SignatureInformation): modes.SignatureInformation {
|
||||
return {
|
||||
label: info.label,
|
||||
documentation: MarkdownString.fromStrict(info.documentation),
|
||||
parameters: info.parameters && info.parameters.map(ParameterInformation.from)
|
||||
};
|
||||
}
|
||||
|
||||
export function to(hints: modes.SignatureHelp): types.SignatureHelp {
|
||||
return hints;
|
||||
export function to(info: modes.SignatureInformation): types.SignatureInformation {
|
||||
return {
|
||||
label: info.label,
|
||||
documentation: htmlContent.isMarkdownString(info.documentation) ? MarkdownString.to(info.documentation) : info.documentation,
|
||||
parameters: info.parameters && info.parameters.map(ParameterInformation.to)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export namespace SignatureHelp {
|
||||
|
||||
export function from(help: types.SignatureHelp): modes.SignatureHelp {
|
||||
return {
|
||||
activeSignature: help.activeSignature,
|
||||
activeParameter: help.activeParameter,
|
||||
signatures: help.signatures && help.signatures.map(SignatureInformation.from)
|
||||
};
|
||||
}
|
||||
|
||||
export function to(help: modes.SignatureHelp): types.SignatureHelp {
|
||||
return {
|
||||
activeSignature: help.activeSignature,
|
||||
activeParameter: help.activeParameter,
|
||||
signatures: help.signatures && help.signatures.map(SignatureInformation.to)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +479,24 @@ export namespace DocumentLink {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace ColorPresentation {
|
||||
export function to(colorPresentation: modes.IColorPresentation): vscode.ColorPresentation {
|
||||
return {
|
||||
label: colorPresentation.label,
|
||||
textEdit: colorPresentation.textEdit ? TextEdit.to(colorPresentation.textEdit) : undefined,
|
||||
additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.to(value)) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
export function from(colorPresentation: vscode.ColorPresentation): modes.IColorPresentation {
|
||||
return {
|
||||
label: colorPresentation.label,
|
||||
textEdit: colorPresentation.textEdit ? TextEdit.from(colorPresentation.textEdit) : undefined,
|
||||
additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.from(value)) : undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TextDocumentSaveReason {
|
||||
|
||||
export function to(reason: SaveReason): vscode.TextDocumentSaveReason {
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { Color as BaseColor, HSLA } from 'vs/base/common/color';
|
||||
import { illegalArgument } from 'vs/base/common/errors';
|
||||
import * as vscode from 'vscode';
|
||||
import { isMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
|
||||
export class Disposable {
|
||||
|
||||
@@ -794,7 +794,7 @@ export class SymbolInformation {
|
||||
if (locationOrUri instanceof Location) {
|
||||
this.location = locationOrUri;
|
||||
} else if (rangeOrContainer instanceof Range) {
|
||||
this.location = new Location(<URI>locationOrUri, rangeOrContainer);
|
||||
this.location = new Location(locationOrUri, rangeOrContainer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,12 +824,42 @@ export class CodeLens {
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkdownString {
|
||||
|
||||
value: string;
|
||||
isTrusted?: boolean;
|
||||
|
||||
constructor(value?: string) {
|
||||
this.value = value || '';
|
||||
}
|
||||
|
||||
appendText(value: string): MarkdownString {
|
||||
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
|
||||
this.value += value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&');
|
||||
return this;
|
||||
}
|
||||
|
||||
appendMarkdown(value: string): MarkdownString {
|
||||
this.value += value;
|
||||
return this;
|
||||
}
|
||||
|
||||
appendCodeblock(code: string, language: string = ''): MarkdownString {
|
||||
this.value += '\n```';
|
||||
this.value += language;
|
||||
this.value += '\n';
|
||||
this.value += code;
|
||||
this.value += '\n```\n';
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class ParameterInformation {
|
||||
|
||||
label: string;
|
||||
documentation?: string;
|
||||
documentation?: string | MarkdownString;
|
||||
|
||||
constructor(label: string, documentation?: string) {
|
||||
constructor(label: string, documentation?: string | MarkdownString) {
|
||||
this.label = label;
|
||||
this.documentation = documentation;
|
||||
}
|
||||
@@ -838,10 +868,10 @@ export class ParameterInformation {
|
||||
export class SignatureInformation {
|
||||
|
||||
label: string;
|
||||
documentation?: string;
|
||||
documentation?: string | MarkdownString;
|
||||
parameters: ParameterInformation[];
|
||||
|
||||
constructor(label: string, documentation?: string) {
|
||||
constructor(label: string, documentation?: string | MarkdownString) {
|
||||
this.label = label;
|
||||
this.documentation = documentation;
|
||||
this.parameters = [];
|
||||
@@ -859,6 +889,16 @@ export class SignatureHelp {
|
||||
}
|
||||
}
|
||||
|
||||
export enum CompletionTriggerKind {
|
||||
Invoke = 0,
|
||||
TriggerCharacter = 1
|
||||
}
|
||||
|
||||
export interface CompletionContext {
|
||||
triggerKind: CompletionTriggerKind;
|
||||
triggerCharacter: string;
|
||||
}
|
||||
|
||||
export enum CompletionItemKind {
|
||||
Text = 0,
|
||||
Method = 1,
|
||||
@@ -892,6 +932,7 @@ export class CompletionItem {
|
||||
label: string;
|
||||
kind: CompletionItemKind;
|
||||
detail: string;
|
||||
// {{SQL CARBON EDIT}}
|
||||
documentation: string;
|
||||
sortText: string;
|
||||
filterText: string;
|
||||
@@ -933,6 +974,7 @@ export class CompletionList {
|
||||
}
|
||||
|
||||
export enum ViewColumn {
|
||||
Active = -1,
|
||||
One = 1,
|
||||
Two = 2,
|
||||
Three = 3
|
||||
@@ -1031,47 +1073,46 @@ export class Color {
|
||||
this.blue = blue;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
static fromHSLA(hue: number, saturation: number, luminance: number, alpha: number): Color {
|
||||
const color = new BaseColor(new HSLA(hue, saturation, luminance, alpha)).rgba;
|
||||
return new Color(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
static fromHex(hex: string): Color | null {
|
||||
let baseColor = BaseColor.Format.CSS.parseHex(hex);
|
||||
if (baseColor) {
|
||||
const rgba = baseColor.rgba;
|
||||
return new Color(rgba.r, rgba.g, rgba.b, rgba.a);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
|
||||
export class ColorRange {
|
||||
export class ColorInformation {
|
||||
range: Range;
|
||||
|
||||
color: Color;
|
||||
|
||||
availableFormats: IColorFormat[];
|
||||
|
||||
constructor(range: Range, color: Color, availableFormats: IColorFormat[]) {
|
||||
constructor(range: Range, color: Color) {
|
||||
if (color && !(color instanceof Color)) {
|
||||
throw illegalArgument('color');
|
||||
}
|
||||
if (availableFormats && !Array.isArray(availableFormats)) {
|
||||
throw illegalArgument('availableFormats');
|
||||
}
|
||||
if (!Range.isRange(range) || range.isEmpty) {
|
||||
throw illegalArgument('range');
|
||||
}
|
||||
this.range = range;
|
||||
this.color = color;
|
||||
this.availableFormats = availableFormats;
|
||||
}
|
||||
}
|
||||
|
||||
export class ColorPresentation {
|
||||
label: string;
|
||||
textEdit?: TextEdit;
|
||||
additionalTextEdits?: TextEdit[];
|
||||
|
||||
constructor(label: string) {
|
||||
if (!label || typeof label !== 'string') {
|
||||
throw illegalArgument('label');
|
||||
}
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
export enum ColorFormat {
|
||||
RGB = 0,
|
||||
HEX = 1,
|
||||
HSL = 2
|
||||
}
|
||||
|
||||
export enum TaskRevealKind {
|
||||
Always = 1,
|
||||
|
||||
@@ -1208,10 +1249,16 @@ export class ShellExecution implements vscode.ShellExecution {
|
||||
}
|
||||
}
|
||||
|
||||
export enum TaskScope {
|
||||
Global = 1,
|
||||
Workspace = 2
|
||||
}
|
||||
|
||||
export class Task implements vscode.Task {
|
||||
|
||||
private _definition: vscode.TaskDefinition;
|
||||
private _definitionKey: string;
|
||||
private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder;
|
||||
private _name: string;
|
||||
private _execution: ProcessExecution | ShellExecution;
|
||||
private _problemMatchers: string[];
|
||||
@@ -1221,11 +1268,29 @@ export class Task implements vscode.Task {
|
||||
private _group: TaskGroup;
|
||||
private _presentationOptions: vscode.TaskPresentationOptions;
|
||||
|
||||
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]) {
|
||||
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
|
||||
constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
|
||||
constructor(definition: vscode.TaskDefinition, arg2: string | (vscode.TaskScope.Global | vscode.TaskScope.Workspace) | vscode.WorkspaceFolder, arg3: any, arg4?: any, arg5?: any, arg6?: any) {
|
||||
this.definition = definition;
|
||||
this.name = name;
|
||||
this.source = source;
|
||||
this.execution = execution;
|
||||
let problemMatchers: string | string[];
|
||||
if (typeof arg2 === 'string') {
|
||||
this.name = arg2;
|
||||
this.source = arg3;
|
||||
this.execution = arg4;
|
||||
problemMatchers = arg5;
|
||||
} else if (arg2 === TaskScope.Global || arg2 === TaskScope.Workspace) {
|
||||
this.target = arg2;
|
||||
this.name = arg3;
|
||||
this.source = arg4;
|
||||
this.execution = arg5;
|
||||
problemMatchers = arg6;
|
||||
} else {
|
||||
this.target = arg2;
|
||||
this.name = arg3;
|
||||
this.source = arg4;
|
||||
this.execution = arg5;
|
||||
problemMatchers = arg6;
|
||||
}
|
||||
if (typeof problemMatchers === 'string') {
|
||||
this._problemMatchers = [problemMatchers];
|
||||
this._hasDefinedMatchers = true;
|
||||
@@ -1260,6 +1325,14 @@ export class Task implements vscode.Task {
|
||||
return this._definitionKey;
|
||||
}
|
||||
|
||||
get scope(): vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder {
|
||||
return this._scope;
|
||||
}
|
||||
|
||||
set target(value: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder) {
|
||||
this._scope = value;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this._name;
|
||||
}
|
||||
@@ -1383,3 +1456,23 @@ export enum ConfigurationTarget {
|
||||
|
||||
WorkspaceFolder = 3
|
||||
}
|
||||
|
||||
export class RelativePattern implements IRelativePattern {
|
||||
base: string;
|
||||
pattern: string;
|
||||
|
||||
constructor(base: vscode.WorkspaceFolder | string, pattern: string) {
|
||||
if (typeof base !== 'string') {
|
||||
if (!base || !URI.isUri(base.uri)) {
|
||||
throw illegalArgument('base');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof pattern !== 'string') {
|
||||
throw illegalArgument('pattern');
|
||||
}
|
||||
|
||||
this.base = typeof base === 'string' ? base : base.uri.fsPath;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,13 @@ import URI from 'vs/base/common/uri';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { normalize } from 'vs/base/common/paths';
|
||||
import { delta } from 'vs/base/common/arrays';
|
||||
import { relative, basename } from 'path';
|
||||
import { Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { fromRange, EndOfLine } from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { relative, dirname } from 'path';
|
||||
import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkspaceData, ExtHostWorkspaceShape, MainContext, MainThreadWorkspaceShape, IMainContext } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
import { compare } from 'vs/base/common/strings';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { TrieMap } from 'vs/base/common/map';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { Progress } from 'vs/platform/progress/common/progress';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
|
||||
class Workspace2 extends Workspace {
|
||||
|
||||
@@ -28,42 +22,30 @@ class Workspace2 extends Workspace {
|
||||
return data ? new Workspace2(data) : null;
|
||||
}
|
||||
|
||||
private readonly _folder: vscode.WorkspaceFolder[] = [];
|
||||
private readonly _structure = new TrieMap<vscode.WorkspaceFolder>(s => s.split('/'));
|
||||
private readonly _workspaceFolders: vscode.WorkspaceFolder[] = [];
|
||||
private readonly _structure = TernarySearchTree.forPaths<vscode.WorkspaceFolder>();
|
||||
|
||||
private constructor(data: IWorkspaceData) {
|
||||
super(data.id, data.name, data.roots);
|
||||
super(data.id, data.name, data.folders.map(folder => new WorkspaceFolder(folder)));
|
||||
|
||||
// setup the workspace folder data structure
|
||||
this.roots.forEach((uri, index) => {
|
||||
const folder = {
|
||||
name: basename(uri.fsPath),
|
||||
uri,
|
||||
index
|
||||
};
|
||||
this._folder.push(folder);
|
||||
this._structure.insert(folder.uri.toString(), folder);
|
||||
this.folders.forEach(({ name, uri, index }) => {
|
||||
const workspaceFolder = { name, uri, index };
|
||||
this._workspaceFolders.push(workspaceFolder);
|
||||
this._structure.set(workspaceFolder.uri.toString(), workspaceFolder);
|
||||
});
|
||||
}
|
||||
|
||||
get folders(): vscode.WorkspaceFolder[] {
|
||||
return this._folder.slice(0);
|
||||
get workspaceFolders(): vscode.WorkspaceFolder[] {
|
||||
return this._workspaceFolders.slice(0);
|
||||
}
|
||||
|
||||
getWorkspaceFolder(uri: URI): vscode.WorkspaceFolder {
|
||||
let str = uri.toString();
|
||||
let folder = this._structure.lookUp(str);
|
||||
if (folder) {
|
||||
// `uri` is a workspace folder so we
|
||||
let parts = str.split('/');
|
||||
while (parts.length) {
|
||||
if (parts.pop()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
str = parts.join('/');
|
||||
getWorkspaceFolder(uri: URI, resolveParent?: boolean): vscode.WorkspaceFolder {
|
||||
if (resolveParent && this._structure.get(uri.toString())) {
|
||||
// `uri` is a workspace folder so we check for its parent
|
||||
uri = uri.with({ path: dirname(uri.path) });
|
||||
}
|
||||
return this._structure.findSubstr(str);
|
||||
return this._structure.findSubstr(uri.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,15 +74,15 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
if (!this._workspace) {
|
||||
return undefined;
|
||||
} else {
|
||||
return this._workspace.folders.slice(0);
|
||||
return this._workspace.workspaceFolders.slice(0);
|
||||
}
|
||||
}
|
||||
|
||||
getWorkspaceFolder(uri: vscode.Uri): vscode.WorkspaceFolder {
|
||||
getWorkspaceFolder(uri: vscode.Uri, resolveParent?: boolean): vscode.WorkspaceFolder {
|
||||
if (!this._workspace) {
|
||||
return undefined;
|
||||
}
|
||||
return this._workspace.getWorkspaceFolder(<URI>uri);
|
||||
return this._workspace.getWorkspaceFolder(uri, resolveParent);
|
||||
}
|
||||
|
||||
getPath(): string {
|
||||
@@ -110,11 +92,11 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
if (!this._workspace) {
|
||||
return undefined;
|
||||
}
|
||||
const { roots } = this._workspace;
|
||||
if (roots.length === 0) {
|
||||
const { folders } = this._workspace;
|
||||
if (folders.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return roots[0].fsPath;
|
||||
return folders[0].uri.fsPath;
|
||||
}
|
||||
|
||||
getRelativePath(pathOrUri: string | vscode.Uri, includeWorkspace?: boolean): string {
|
||||
@@ -130,24 +112,24 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
return path;
|
||||
}
|
||||
|
||||
const folder = this.getWorkspaceFolder(typeof pathOrUri === 'string'
|
||||
? URI.file(pathOrUri)
|
||||
: pathOrUri
|
||||
const folder = this.getWorkspaceFolder(
|
||||
typeof pathOrUri === 'string' ? URI.file(pathOrUri) : pathOrUri,
|
||||
true
|
||||
);
|
||||
|
||||
if (!folder) {
|
||||
return normalize(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
if (typeof includeWorkspace === 'undefined') {
|
||||
includeWorkspace = this.workspace.roots.length > 1;
|
||||
includeWorkspace = this.workspace.folders.length > 1;
|
||||
}
|
||||
|
||||
let result = relative(folder.uri.fsPath, path);
|
||||
if (includeWorkspace) {
|
||||
result = `${folder.name}/${result}`;
|
||||
}
|
||||
return normalize(result);
|
||||
return normalize(result, true);
|
||||
}
|
||||
|
||||
$acceptWorkspaceData(data: IWorkspaceData): void {
|
||||
@@ -155,13 +137,12 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
// keep old workspace folder, build new workspace, and
|
||||
// capture new workspace folders. Compute delta between
|
||||
// them send that as event
|
||||
const oldRoots = this._workspace ? this._workspace.folders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
|
||||
const oldRoots = this._workspace ? this._workspace.workspaceFolders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
|
||||
|
||||
this._workspace = Workspace2.fromData(data);
|
||||
const newRoots = this._workspace ? this._workspace.folders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
|
||||
const newRoots = this._workspace ? this._workspace.workspaceFolders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
|
||||
|
||||
const { added, removed } = delta(oldRoots, newRoots, ExtHostWorkspace._compareWorkspaceFolder);
|
||||
|
||||
// {{SQL CARBON EDIT}} - fix build break Argument of type 'Readonly<...
|
||||
this._onDidChangeWorkspace.fire({
|
||||
added: added,
|
||||
@@ -175,7 +156,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
|
||||
// --- search ---
|
||||
|
||||
findFiles(include: string, exclude: string, maxResults?: number, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> {
|
||||
findFiles(include: string | IRelativePattern, exclude: string | IRelativePattern, maxResults?: number, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> {
|
||||
const requestId = ExtHostWorkspace._requestIdPool++;
|
||||
const result = this._proxy.$startSearch(include, exclude, maxResults, requestId);
|
||||
if (token) {
|
||||
@@ -187,73 +168,4 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
saveAll(includeUntitled?: boolean): Thenable<boolean> {
|
||||
return this._proxy.$saveAll(includeUntitled);
|
||||
}
|
||||
|
||||
appyEdit(edit: vscode.WorkspaceEdit): TPromise<boolean> {
|
||||
|
||||
let resourceEdits: IResourceEdit[] = [];
|
||||
|
||||
let entries = edit.entries();
|
||||
for (let entry of entries) {
|
||||
let [uri, edits] = entry;
|
||||
|
||||
for (let edit of edits) {
|
||||
resourceEdits.push({
|
||||
resource: <URI>uri,
|
||||
newText: edit.newText,
|
||||
newEol: EndOfLine.from(edit.newEol),
|
||||
range: edit.range && fromRange(edit.range)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this._proxy.$applyWorkspaceEdit(resourceEdits);
|
||||
}
|
||||
|
||||
// --- EXPERIMENT: workspace resolver
|
||||
|
||||
|
||||
private _handlePool = 0;
|
||||
private readonly _fsProvider = new Map<number, vscode.FileSystemProvider>();
|
||||
private readonly _searchSession = new Map<number, CancellationTokenSource>();
|
||||
|
||||
registerFileSystemProvider(authority: string, provider: vscode.FileSystemProvider): vscode.Disposable {
|
||||
const handle = ++this._handlePool;
|
||||
this._fsProvider.set(handle, provider);
|
||||
const reg = provider.onDidChange(e => this._proxy.$onFileSystemChange(handle, <URI>e));
|
||||
this._proxy.$registerFileSystemProvider(handle, authority);
|
||||
return new Disposable(() => {
|
||||
this._fsProvider.delete(handle);
|
||||
reg.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
$resolveFile(handle: number, resource: URI): TPromise<string> {
|
||||
const provider = this._fsProvider.get(handle);
|
||||
return asWinJsPromise(token => provider.resolveContents(resource));
|
||||
}
|
||||
|
||||
$storeFile(handle: number, resource: URI, content: string): TPromise<any> {
|
||||
const provider = this._fsProvider.get(handle);
|
||||
return asWinJsPromise(token => provider.writeContents(resource, content));
|
||||
}
|
||||
|
||||
$startSearch(handle: number, session: number, query: string): void {
|
||||
const provider = this._fsProvider.get(handle);
|
||||
const source = new CancellationTokenSource();
|
||||
const progress = new Progress<any>(chunk => this._proxy.$updateSearchSession(session, chunk));
|
||||
|
||||
this._searchSession.set(session, source);
|
||||
TPromise.wrap(provider.findFiles(query, progress, source.token)).then(() => {
|
||||
this._proxy.$finishSearchSession(session);
|
||||
}, err => {
|
||||
this._proxy.$finishSearchSession(session, err);
|
||||
});
|
||||
}
|
||||
|
||||
$cancelSearch(handle: number, session: number): void {
|
||||
if (this._searchSession.has(session)) {
|
||||
this._searchSession.get(session).cancel();
|
||||
this._searchSession.delete(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user