mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd (#5074)
* Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd * fix tests
This commit is contained in:
@@ -362,13 +362,6 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
return Promise.reject(new ExtensionManagementError(nls.localize('notFoundCompatibleDependency', "Unable to install because, the extension '{0}' compatible with current version '{1}' of VS Code is not found.", extension.identifier.id, pkg.version), INSTALL_ERROR_INCOMPATIBLE));
|
||||
}
|
||||
|
||||
if (this.remote) {
|
||||
const manifest = await this.galleryService.getManifest(extension, CancellationToken.None);
|
||||
if (manifest && isUIExtension(manifest, [], this.configurationService) && !isLanguagePackExtension(manifest)) {
|
||||
return Promise.reject(new Error(nls.localize('notSupportedUIExtension', "Can't install extension {0} since UI Extensions are not supported", extension.identifier.id)));
|
||||
}
|
||||
}
|
||||
|
||||
return compatibleExtension;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,13 @@ import product from 'vs/platform/product/node/product';
|
||||
|
||||
export function isUIExtension(manifest: IExtensionManifest, uiContributions: string[], configurationService: IConfigurationService): boolean {
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
const configuredUIExtensions = configurationService.getValue<string[]>('_workbench.uiExtensions') || [];
|
||||
if (configuredUIExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) {
|
||||
return true;
|
||||
}
|
||||
if (configuredUIExtensions.some(id => areSameExtensions({ id }, { id: `-${extensionId}` }))) {
|
||||
const { ui, workspace } = configurationService.getValue<{ ui: string[], workspace: string[] }>('extensions.extensionKind') || { ui: [], workspace: [] };
|
||||
if (isNonEmptyArray(workspace) && workspace.some(id => areSameExtensions({ id }, { id: extensionId }))) {
|
||||
return false;
|
||||
}
|
||||
if (isNonEmptyArray(ui) && ui.some(id => areSameExtensions({ id }, { id: extensionId }))) {
|
||||
return true;
|
||||
}
|
||||
switch (manifest.extensionKind) {
|
||||
case 'ui': return true;
|
||||
case 'workspace': return false;
|
||||
|
||||
@@ -13,25 +13,14 @@ import { startsWithIgnoreCase } from 'vs/base/common/strings';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { isEqualOrParent, isEqual } from 'vs/base/common/resources';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
|
||||
import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer';
|
||||
|
||||
export const IFileService = createDecorator<IFileService>('fileService');
|
||||
|
||||
export interface IResourceEncodings {
|
||||
getWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding;
|
||||
}
|
||||
|
||||
export interface IResourceEncoding {
|
||||
encoding: string;
|
||||
hasBOM: boolean;
|
||||
}
|
||||
|
||||
export interface IFileService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
|
||||
//#region File System Provider
|
||||
|
||||
/**
|
||||
* An event that is fired when a file system provider is added or removed
|
||||
*/
|
||||
@@ -63,13 +52,6 @@ export interface IFileService {
|
||||
*/
|
||||
hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean;
|
||||
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* Helper to determine read/write encoding for resources.
|
||||
*/
|
||||
encoding: IResourceEncodings;
|
||||
|
||||
/**
|
||||
* Allows to listen for file changes. The event will fire for every file within the opened workspace
|
||||
* (if any) as well as all files that have been watched explicitly using the #watch() API.
|
||||
@@ -111,18 +93,14 @@ export interface IFileService {
|
||||
exists(resource: URI): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Resolve the contents of a file identified by the resource.
|
||||
*
|
||||
* The returned object contains properties of the file and the full value as string.
|
||||
* Read the contents of the provided resource unbuffered.
|
||||
*/
|
||||
resolveContent(resource: URI, options?: IResolveContentOptions): Promise<IContent>;
|
||||
readFile(resource: URI, options?: IReadFileOptions): Promise<IFileContent>;
|
||||
|
||||
/**
|
||||
* Resolve the contents of a file identified by the resource.
|
||||
*
|
||||
* The returned object contains properties of the file and the value as a readable stream.
|
||||
* Read the contents of the provided resource buffered as stream.
|
||||
*/
|
||||
resolveStreamContent(resource: URI, options?: IResolveContentOptions): Promise<IStreamContent>;
|
||||
readFileStream(resource: URI, options?: IReadFileOptions): Promise<IFileStreamContent>;
|
||||
|
||||
/**
|
||||
* Updates the content replacing its previous value.
|
||||
@@ -228,11 +206,11 @@ export const enum FileSystemProviderCapabilities {
|
||||
export interface IFileSystemProvider {
|
||||
|
||||
readonly capabilities: FileSystemProviderCapabilities;
|
||||
onDidChangeCapabilities: Event<void>;
|
||||
readonly onDidChangeCapabilities: Event<void>;
|
||||
|
||||
onDidErrorOccur?: Event<Error>; // TODO@ben remove once file watchers are solid
|
||||
readonly onDidErrorOccur?: Event<Error>; // TODO@ben remove once file watchers are solid
|
||||
|
||||
onDidChangeFile: Event<IFileChange[]>;
|
||||
readonly onDidChangeFile: Event<IFileChange[]>;
|
||||
watch(resource: URI, opts: IWatchOptions): IDisposable;
|
||||
|
||||
stat(resource: URI): Promise<IStat>;
|
||||
@@ -337,6 +315,13 @@ export function toFileSystemProviderErrorCode(error: Error): FileSystemProviderE
|
||||
}
|
||||
|
||||
export function toFileOperationResult(error: Error): FileOperationResult {
|
||||
|
||||
// FileSystemProviderError comes with the result already
|
||||
if (error instanceof FileOperationError) {
|
||||
return error.fileOperationResult;
|
||||
}
|
||||
|
||||
// Otherwise try to find from code
|
||||
switch (toFileSystemProviderErrorCode(error)) {
|
||||
case FileSystemProviderErrorCode.FileNotFound:
|
||||
return FileOperationResult.FILE_NOT_FOUND;
|
||||
@@ -576,8 +561,7 @@ export interface IBaseStatWithMetadata extends IBaseStat {
|
||||
export interface IFileStat extends IBaseStat {
|
||||
|
||||
/**
|
||||
* The resource is a directory. if {{true}}
|
||||
* {{encoding}} has no meaning.
|
||||
* The resource is a directory
|
||||
*/
|
||||
isDirectory: boolean;
|
||||
|
||||
@@ -608,147 +592,23 @@ export interface IResolveFileResultWithMetadata extends IResolveFileResult {
|
||||
stat?: IFileStatWithMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content and meta information of a file.
|
||||
*/
|
||||
export interface IContent extends IBaseStatWithMetadata {
|
||||
export interface IFileContent extends IBaseStatWithMetadata {
|
||||
|
||||
/**
|
||||
* The content of a text file.
|
||||
* The content of a file as buffer.
|
||||
*/
|
||||
value: string;
|
||||
value: VSBuffer;
|
||||
}
|
||||
|
||||
export interface IFileStreamContent extends IBaseStatWithMetadata {
|
||||
|
||||
/**
|
||||
* The encoding of the content if known.
|
||||
* The content of a file as stream.
|
||||
*/
|
||||
encoding: string;
|
||||
value: VSBufferReadableStream;
|
||||
}
|
||||
|
||||
// this should eventually replace IContent such
|
||||
// that we have a clear separation between content
|
||||
// and metadata (TODO@Joh, TODO@Ben)
|
||||
export interface IContentData {
|
||||
encoding: string;
|
||||
stream: IStringStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Stream emitting strings.
|
||||
*/
|
||||
export interface IStringStream {
|
||||
on(event: 'data', callback: (chunk: string) => void): void;
|
||||
on(event: 'error', callback: (err: any) => void): void;
|
||||
on(event: 'end', callback: () => void): void;
|
||||
on(event: string, callback: any): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text snapshot that works like an iterator.
|
||||
* Will try to return chunks of roughly ~64KB size.
|
||||
* Will return null when finished.
|
||||
*/
|
||||
export interface ITextSnapshot {
|
||||
read(): string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to convert a snapshot into its full string form.
|
||||
*/
|
||||
export function snapshotToString(snapshot: ITextSnapshot): string {
|
||||
const chunks: string[] = [];
|
||||
|
||||
let chunk: string | null;
|
||||
while (typeof (chunk = snapshot.read()) === 'string') {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
|
||||
return chunks.join('');
|
||||
}
|
||||
|
||||
export function stringToSnapshot(value: string): ITextSnapshot {
|
||||
let done = false;
|
||||
|
||||
return {
|
||||
read(): string | null {
|
||||
if (!done) {
|
||||
done = true;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class TextSnapshotReadable implements VSBufferReadable {
|
||||
private preambleHandled: boolean;
|
||||
|
||||
constructor(private snapshot: ITextSnapshot, private preamble?: string) { }
|
||||
|
||||
read(): VSBuffer | null {
|
||||
let value = this.snapshot.read();
|
||||
|
||||
// Handle preamble if provided
|
||||
if (!this.preambleHandled) {
|
||||
this.preambleHandled = true;
|
||||
|
||||
if (typeof this.preamble === 'string') {
|
||||
if (typeof value === 'string') {
|
||||
value = this.preamble + value;
|
||||
} else {
|
||||
value = this.preamble;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return VSBuffer.fromString(value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function toBufferOrReadable(value: string): VSBuffer;
|
||||
export function toBufferOrReadable(value: ITextSnapshot): VSBufferReadable;
|
||||
export function toBufferOrReadable(value: string | ITextSnapshot): VSBuffer | VSBufferReadable;
|
||||
export function toBufferOrReadable(value: string | ITextSnapshot | undefined): VSBuffer | VSBufferReadable | undefined;
|
||||
export function toBufferOrReadable(value: string | ITextSnapshot | undefined): VSBuffer | VSBufferReadable | undefined {
|
||||
if (typeof value === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return VSBuffer.fromString(value);
|
||||
}
|
||||
|
||||
return new TextSnapshotReadable(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Streamable content and meta information of a file.
|
||||
*/
|
||||
export interface IStreamContent extends IBaseStatWithMetadata {
|
||||
|
||||
/**
|
||||
* The streamable content of a text file.
|
||||
*/
|
||||
value: IStringStream;
|
||||
|
||||
/**
|
||||
* The encoding of the content if known.
|
||||
*/
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
export interface IResolveContentOptions {
|
||||
|
||||
/**
|
||||
* The optional acceptTextOnly parameter allows to fail this request early if the file
|
||||
* contents are not textual.
|
||||
*/
|
||||
acceptTextOnly?: boolean;
|
||||
export interface IReadFileOptions {
|
||||
|
||||
/**
|
||||
* The optional etag parameter allows to return early from resolving the resource if
|
||||
@@ -758,22 +618,25 @@ export interface IResolveContentOptions {
|
||||
*/
|
||||
etag?: string;
|
||||
|
||||
/**
|
||||
* The optional encoding parameter allows to specify the desired encoding when resolving
|
||||
* the contents of the file.
|
||||
*/
|
||||
encoding?: string;
|
||||
|
||||
/**
|
||||
* The optional guessEncoding parameter allows to guess encoding from content of the file.
|
||||
*/
|
||||
autoGuessEncoding?: boolean;
|
||||
|
||||
/**
|
||||
* Is an integer specifying where to begin reading from in the file. If position is null,
|
||||
* data will be read from the current file position.
|
||||
*/
|
||||
position?: number;
|
||||
|
||||
/**
|
||||
* Is an integer specifying how many bytes to read from the file. By default, all bytes
|
||||
* will be read.
|
||||
*/
|
||||
length?: number;
|
||||
|
||||
/**
|
||||
* If provided, the size of the file will be checked against the limits.
|
||||
*/
|
||||
limits?: {
|
||||
size?: number;
|
||||
memory?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IWriteFileOptions {
|
||||
@@ -789,30 +652,6 @@ export interface IWriteFileOptions {
|
||||
etag?: string;
|
||||
}
|
||||
|
||||
export interface IWriteTextFileOptions extends IWriteFileOptions {
|
||||
|
||||
/**
|
||||
* The encoding to use when updating a file.
|
||||
*/
|
||||
encoding?: string;
|
||||
|
||||
/**
|
||||
* If set to true, will enforce the selected encoding and not perform any detection using BOMs.
|
||||
*/
|
||||
overwriteEncoding?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to overwrite a file even if it is readonly.
|
||||
*/
|
||||
overwriteReadonly?: boolean;
|
||||
|
||||
/**
|
||||
* Wether to write to the file as elevated (admin) user. When setting this option a prompt will
|
||||
* ask the user to authenticate as super user.
|
||||
*/
|
||||
writeElevated?: boolean;
|
||||
}
|
||||
|
||||
export interface IResolveFileOptions {
|
||||
|
||||
/**
|
||||
@@ -847,7 +686,7 @@ export interface ICreateFileOptions {
|
||||
}
|
||||
|
||||
export class FileOperationError extends Error {
|
||||
constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IResolveContentOptions & IWriteTextFileOptions & ICreateFileOptions) {
|
||||
constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IReadFileOptions & IWriteFileOptions & ICreateFileOptions) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -857,7 +696,6 @@ export class FileOperationError extends Error {
|
||||
}
|
||||
|
||||
export const enum FileOperationResult {
|
||||
FILE_IS_BINARY,
|
||||
FILE_IS_DIRECTORY,
|
||||
FILE_NOT_FOUND,
|
||||
FILE_NOT_MODIFIED_SINCE,
|
||||
@@ -906,247 +744,6 @@ export interface IFilesConfiguration {
|
||||
};
|
||||
}
|
||||
|
||||
export const SUPPORTED_ENCODINGS: { [encoding: string]: { labelLong: string; labelShort: string; order: number; encodeOnly?: boolean; alias?: string } } = {
|
||||
utf8: {
|
||||
labelLong: 'UTF-8',
|
||||
labelShort: 'UTF-8',
|
||||
order: 1,
|
||||
alias: 'utf8bom'
|
||||
},
|
||||
utf8bom: {
|
||||
labelLong: 'UTF-8 with BOM',
|
||||
labelShort: 'UTF-8 with BOM',
|
||||
encodeOnly: true,
|
||||
order: 2,
|
||||
alias: 'utf8'
|
||||
},
|
||||
utf16le: {
|
||||
labelLong: 'UTF-16 LE',
|
||||
labelShort: 'UTF-16 LE',
|
||||
order: 3
|
||||
},
|
||||
utf16be: {
|
||||
labelLong: 'UTF-16 BE',
|
||||
labelShort: 'UTF-16 BE',
|
||||
order: 4
|
||||
},
|
||||
windows1252: {
|
||||
labelLong: 'Western (Windows 1252)',
|
||||
labelShort: 'Windows 1252',
|
||||
order: 5
|
||||
},
|
||||
iso88591: {
|
||||
labelLong: 'Western (ISO 8859-1)',
|
||||
labelShort: 'ISO 8859-1',
|
||||
order: 6
|
||||
},
|
||||
iso88593: {
|
||||
labelLong: 'Western (ISO 8859-3)',
|
||||
labelShort: 'ISO 8859-3',
|
||||
order: 7
|
||||
},
|
||||
iso885915: {
|
||||
labelLong: 'Western (ISO 8859-15)',
|
||||
labelShort: 'ISO 8859-15',
|
||||
order: 8
|
||||
},
|
||||
macroman: {
|
||||
labelLong: 'Western (Mac Roman)',
|
||||
labelShort: 'Mac Roman',
|
||||
order: 9
|
||||
},
|
||||
cp437: {
|
||||
labelLong: 'DOS (CP 437)',
|
||||
labelShort: 'CP437',
|
||||
order: 10
|
||||
},
|
||||
windows1256: {
|
||||
labelLong: 'Arabic (Windows 1256)',
|
||||
labelShort: 'Windows 1256',
|
||||
order: 11
|
||||
},
|
||||
iso88596: {
|
||||
labelLong: 'Arabic (ISO 8859-6)',
|
||||
labelShort: 'ISO 8859-6',
|
||||
order: 12
|
||||
},
|
||||
windows1257: {
|
||||
labelLong: 'Baltic (Windows 1257)',
|
||||
labelShort: 'Windows 1257',
|
||||
order: 13
|
||||
},
|
||||
iso88594: {
|
||||
labelLong: 'Baltic (ISO 8859-4)',
|
||||
labelShort: 'ISO 8859-4',
|
||||
order: 14
|
||||
},
|
||||
iso885914: {
|
||||
labelLong: 'Celtic (ISO 8859-14)',
|
||||
labelShort: 'ISO 8859-14',
|
||||
order: 15
|
||||
},
|
||||
windows1250: {
|
||||
labelLong: 'Central European (Windows 1250)',
|
||||
labelShort: 'Windows 1250',
|
||||
order: 16
|
||||
},
|
||||
iso88592: {
|
||||
labelLong: 'Central European (ISO 8859-2)',
|
||||
labelShort: 'ISO 8859-2',
|
||||
order: 17
|
||||
},
|
||||
cp852: {
|
||||
labelLong: 'Central European (CP 852)',
|
||||
labelShort: 'CP 852',
|
||||
order: 18
|
||||
},
|
||||
windows1251: {
|
||||
labelLong: 'Cyrillic (Windows 1251)',
|
||||
labelShort: 'Windows 1251',
|
||||
order: 19
|
||||
},
|
||||
cp866: {
|
||||
labelLong: 'Cyrillic (CP 866)',
|
||||
labelShort: 'CP 866',
|
||||
order: 20
|
||||
},
|
||||
iso88595: {
|
||||
labelLong: 'Cyrillic (ISO 8859-5)',
|
||||
labelShort: 'ISO 8859-5',
|
||||
order: 21
|
||||
},
|
||||
koi8r: {
|
||||
labelLong: 'Cyrillic (KOI8-R)',
|
||||
labelShort: 'KOI8-R',
|
||||
order: 22
|
||||
},
|
||||
koi8u: {
|
||||
labelLong: 'Cyrillic (KOI8-U)',
|
||||
labelShort: 'KOI8-U',
|
||||
order: 23
|
||||
},
|
||||
iso885913: {
|
||||
labelLong: 'Estonian (ISO 8859-13)',
|
||||
labelShort: 'ISO 8859-13',
|
||||
order: 24
|
||||
},
|
||||
windows1253: {
|
||||
labelLong: 'Greek (Windows 1253)',
|
||||
labelShort: 'Windows 1253',
|
||||
order: 25
|
||||
},
|
||||
iso88597: {
|
||||
labelLong: 'Greek (ISO 8859-7)',
|
||||
labelShort: 'ISO 8859-7',
|
||||
order: 26
|
||||
},
|
||||
windows1255: {
|
||||
labelLong: 'Hebrew (Windows 1255)',
|
||||
labelShort: 'Windows 1255',
|
||||
order: 27
|
||||
},
|
||||
iso88598: {
|
||||
labelLong: 'Hebrew (ISO 8859-8)',
|
||||
labelShort: 'ISO 8859-8',
|
||||
order: 28
|
||||
},
|
||||
iso885910: {
|
||||
labelLong: 'Nordic (ISO 8859-10)',
|
||||
labelShort: 'ISO 8859-10',
|
||||
order: 29
|
||||
},
|
||||
iso885916: {
|
||||
labelLong: 'Romanian (ISO 8859-16)',
|
||||
labelShort: 'ISO 8859-16',
|
||||
order: 30
|
||||
},
|
||||
windows1254: {
|
||||
labelLong: 'Turkish (Windows 1254)',
|
||||
labelShort: 'Windows 1254',
|
||||
order: 31
|
||||
},
|
||||
iso88599: {
|
||||
labelLong: 'Turkish (ISO 8859-9)',
|
||||
labelShort: 'ISO 8859-9',
|
||||
order: 32
|
||||
},
|
||||
windows1258: {
|
||||
labelLong: 'Vietnamese (Windows 1258)',
|
||||
labelShort: 'Windows 1258',
|
||||
order: 33
|
||||
},
|
||||
gbk: {
|
||||
labelLong: 'Simplified Chinese (GBK)',
|
||||
labelShort: 'GBK',
|
||||
order: 34
|
||||
},
|
||||
gb18030: {
|
||||
labelLong: 'Simplified Chinese (GB18030)',
|
||||
labelShort: 'GB18030',
|
||||
order: 35
|
||||
},
|
||||
cp950: {
|
||||
labelLong: 'Traditional Chinese (Big5)',
|
||||
labelShort: 'Big5',
|
||||
order: 36
|
||||
},
|
||||
big5hkscs: {
|
||||
labelLong: 'Traditional Chinese (Big5-HKSCS)',
|
||||
labelShort: 'Big5-HKSCS',
|
||||
order: 37
|
||||
},
|
||||
shiftjis: {
|
||||
labelLong: 'Japanese (Shift JIS)',
|
||||
labelShort: 'Shift JIS',
|
||||
order: 38
|
||||
},
|
||||
eucjp: {
|
||||
labelLong: 'Japanese (EUC-JP)',
|
||||
labelShort: 'EUC-JP',
|
||||
order: 39
|
||||
},
|
||||
euckr: {
|
||||
labelLong: 'Korean (EUC-KR)',
|
||||
labelShort: 'EUC-KR',
|
||||
order: 40
|
||||
},
|
||||
windows874: {
|
||||
labelLong: 'Thai (Windows 874)',
|
||||
labelShort: 'Windows 874',
|
||||
order: 41
|
||||
},
|
||||
iso885911: {
|
||||
labelLong: 'Latin/Thai (ISO 8859-11)',
|
||||
labelShort: 'ISO 8859-11',
|
||||
order: 42
|
||||
},
|
||||
koi8ru: {
|
||||
labelLong: 'Cyrillic (KOI8-RU)',
|
||||
labelShort: 'KOI8-RU',
|
||||
order: 43
|
||||
},
|
||||
koi8t: {
|
||||
labelLong: 'Tajik (KOI8-T)',
|
||||
labelShort: 'KOI8-T',
|
||||
order: 44
|
||||
},
|
||||
gb2312: {
|
||||
labelLong: 'Simplified Chinese (GB 2312)',
|
||||
labelShort: 'GB 2312',
|
||||
order: 45
|
||||
},
|
||||
cp865: {
|
||||
labelLong: 'Nordic DOS (CP 865)',
|
||||
labelShort: 'CP 865',
|
||||
order: 46
|
||||
},
|
||||
cp850: {
|
||||
labelLong: 'Western European DOS (CP 850)',
|
||||
labelShort: 'CP 850',
|
||||
order: 47
|
||||
}
|
||||
};
|
||||
|
||||
export enum FileKind {
|
||||
FILE,
|
||||
FOLDER,
|
||||
@@ -1165,20 +762,3 @@ export function etag(mtime: number | undefined, size: number | undefined): strin
|
||||
|
||||
return mtime.toString(29) + size.toString(31);
|
||||
}
|
||||
|
||||
|
||||
// TODO@ben remove traces of legacy file service
|
||||
export const ILegacyFileService = createDecorator<ILegacyFileService>('legacyFileService');
|
||||
export interface ILegacyFileService extends IDisposable {
|
||||
_serviceBrand: any;
|
||||
|
||||
encoding: IResourceEncodings;
|
||||
|
||||
onAfterOperation: Event<FileOperationEvent>;
|
||||
|
||||
registerProvider(scheme: string, provider: IFileSystemProvider): IDisposable;
|
||||
|
||||
resolveContent(resource: URI, options?: IResolveContentOptions): Promise<IContent>;
|
||||
|
||||
resolveStreamContent(resource: URI, options?: IResolveContentOptions): Promise<IStreamContent>;
|
||||
}
|
||||
@@ -13,6 +13,49 @@ export interface ResolvedAuthority {
|
||||
readonly port: number;
|
||||
}
|
||||
|
||||
export enum RemoteAuthorityResolverErrorCode {
|
||||
Unknown = 'Unknown',
|
||||
NotAvailable = 'NotAvailable',
|
||||
TemporarilyNotAvailable = 'TemporarilyNotAvailable',
|
||||
}
|
||||
|
||||
export class RemoteAuthorityResolverError extends Error {
|
||||
|
||||
public static isHandledNotAvailable(err: any): boolean {
|
||||
if (err instanceof RemoteAuthorityResolverError) {
|
||||
if (err._code === RemoteAuthorityResolverErrorCode.NotAvailable && err._detail === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static isTemporarilyNotAvailable(err: any): boolean {
|
||||
if (err instanceof RemoteAuthorityResolverError) {
|
||||
return err._code === RemoteAuthorityResolverErrorCode.TemporarilyNotAvailable;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public readonly _message: string | undefined;
|
||||
public readonly _code: RemoteAuthorityResolverErrorCode;
|
||||
public readonly _detail: any;
|
||||
|
||||
constructor(message?: string, code: RemoteAuthorityResolverErrorCode = RemoteAuthorityResolverErrorCode.Unknown, detail?: any) {
|
||||
super(message);
|
||||
|
||||
this._message = message;
|
||||
this._code = code;
|
||||
this._detail = detail;
|
||||
|
||||
// workaround when extending builtin objects and when compiling to ES5, see:
|
||||
// https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
(<any>Object).setPrototypeOf(this, RemoteAuthorityResolverError.prototype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface IRemoteAuthorityResolverService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
@@ -4,14 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isAbsolute } from 'vs/base/common/path';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IWorkspaceIdentifier, IStoredWorkspaceFolder, isRawFileWorkspaceFolder, isRawUriWorkspaceFolder, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { coalesce, distinct } from 'vs/base/common/arrays';
|
||||
import { isLinux } from 'vs/base/common/platform';
|
||||
|
||||
export const IWorkspaceContextService = createDecorator<IWorkspaceContextService>('contextService');
|
||||
|
||||
@@ -225,17 +222,21 @@ export class WorkspaceFolder implements IWorkspaceFolder {
|
||||
}
|
||||
}
|
||||
|
||||
export function toWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], relativeTo?: URI): WorkspaceFolder[] {
|
||||
let workspaceFolders = parseWorkspaceFolders(configuredFolders, relativeTo);
|
||||
return ensureUnique(coalesce(workspaceFolders))
|
||||
.map(({ uri, raw, name }, index) => new WorkspaceFolder({ uri, name: name || resources.basenameOrAuthority(uri), index }, raw));
|
||||
export function toWorkspaceFolder(resource: URI): WorkspaceFolder {
|
||||
return new WorkspaceFolder({ uri: resource, index: 0, name: resources.basenameOrAuthority(resource) }, { uri: resource.toString() });
|
||||
}
|
||||
|
||||
function parseWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], relativeTo: URI | undefined): Array<WorkspaceFolder | undefined> {
|
||||
return configuredFolders.map((configuredFolder, index) => {
|
||||
export function toWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], workspaceConfigFile: URI): WorkspaceFolder[] {
|
||||
let result: WorkspaceFolder[] = [];
|
||||
let seen: { [uri: string]: boolean } = Object.create(null);
|
||||
|
||||
const relativeTo = resources.dirname(workspaceConfigFile);
|
||||
for (let configuredFolder of configuredFolders) {
|
||||
let uri: URI | null = null;
|
||||
if (isRawFileWorkspaceFolder(configuredFolder)) {
|
||||
uri = toUri(configuredFolder.path, relativeTo);
|
||||
if (configuredFolder.path) {
|
||||
uri = resources.resolvePath(relativeTo, configuredFolder.path);
|
||||
}
|
||||
} else if (isRawUriWorkspaceFolder(configuredFolder)) {
|
||||
try {
|
||||
uri = URI.parse(configuredFolder.uri);
|
||||
@@ -248,25 +249,16 @@ function parseWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], rela
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (!uri) {
|
||||
return undefined;
|
||||
}
|
||||
return new WorkspaceFolder({ uri, name: configuredFolder.name! /*is ensured in caller*/, index }, configuredFolder);
|
||||
});
|
||||
}
|
||||
if (uri) {
|
||||
// remove duplicates
|
||||
let comparisonKey = resources.getComparisonKey(uri);
|
||||
if (!seen[comparisonKey]) {
|
||||
seen[comparisonKey] = true;
|
||||
|
||||
function toUri(path: string, relativeTo: URI | undefined): URI | null {
|
||||
if (path) {
|
||||
if (isAbsolute(path)) {
|
||||
return URI.file(path);
|
||||
}
|
||||
if (relativeTo) {
|
||||
return resources.joinPath(relativeTo, path);
|
||||
const name = configuredFolder.name || resources.basenameOrAuthority(uri);
|
||||
result.push(new WorkspaceFolder({ uri, name, index: result.length }, configuredFolder));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function ensureUnique(folders: WorkspaceFolder[]): WorkspaceFolder[] {
|
||||
return distinct(folders, folder => isLinux ? folder.uri.toString() : folder.uri.toString().toLowerCase());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -4,15 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
|
||||
import { Workspace, toWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
|
||||
const wsUri = URI.file(isWindows ? 'C:\\testWorkspace' : '/testWorkspace');
|
||||
export const TestWorkspace = testWorkspace(wsUri);
|
||||
|
||||
export function testWorkspace(resource: URI): Workspace {
|
||||
return new Workspace(
|
||||
resource.toString(),
|
||||
toWorkspaceFolders([{ path: resource.fsPath }])
|
||||
);
|
||||
return new Workspace(resource.toString(), [toWorkspaceFolder(resource)]);
|
||||
}
|
||||
|
||||
@@ -4,15 +4,30 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import { Workspace, toWorkspaceFolders, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IRawFileWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
|
||||
suite('Workspace', () => {
|
||||
|
||||
const fileFolder = isWindows ? 'c:\\src' : '/src';
|
||||
const abcFolder = isWindows ? 'c:\\abc' : '/abc';
|
||||
|
||||
const testFolderUri = URI.file(path.join(fileFolder, 'test'));
|
||||
const mainFolderUri = URI.file(path.join(fileFolder, 'main'));
|
||||
const test1FolderUri = URI.file(path.join(fileFolder, 'test1'));
|
||||
const test2FolderUri = URI.file(path.join(fileFolder, 'test2'));
|
||||
const test3FolderUri = URI.file(path.join(fileFolder, 'test3'));
|
||||
const abcTest1FolderUri = URI.file(path.join(abcFolder, 'test1'));
|
||||
const abcTest3FolderUri = URI.file(path.join(abcFolder, 'test3'));
|
||||
|
||||
const workspaceConfigUri = URI.file(path.join(fileFolder, 'test.code-workspace'));
|
||||
|
||||
test('getFolder returns the folder with given uri', () => {
|
||||
const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 2 });
|
||||
let testObject = new Workspace('', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), expected, new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]);
|
||||
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 2 });
|
||||
let testObject = new Workspace('', [new WorkspaceFolder({ uri: mainFolderUri, name: '', index: 0 }), expected, new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]);
|
||||
|
||||
const actual = testObject.getFolder(expected.uri);
|
||||
|
||||
@@ -20,172 +35,172 @@ suite('Workspace', () => {
|
||||
});
|
||||
|
||||
test('getFolder returns the folder if the uri is sub', () => {
|
||||
const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 });
|
||||
let testObject = new Workspace('', [expected, new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 1 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]);
|
||||
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 0 });
|
||||
let testObject = new Workspace('', [expected, new WorkspaceFolder({ uri: mainFolderUri, name: '', index: 1 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]);
|
||||
|
||||
const actual = testObject.getFolder(URI.file('/src/test/a'));
|
||||
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'test/a')));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
test('getFolder returns the closest folder if the uri is sub', () => {
|
||||
const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 2 });
|
||||
let testObject = new Workspace('', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected]);
|
||||
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 2 });
|
||||
let testObject = new Workspace('', [new WorkspaceFolder({ uri: mainFolderUri, name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected]);
|
||||
|
||||
const actual = testObject.getFolder(URI.file('/src/test/a'));
|
||||
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'test/a')));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
test('getFolder returns null if the uri is not sub', () => {
|
||||
let testObject = new Workspace('', [new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 })]);
|
||||
let testObject = new Workspace('', [new WorkspaceFolder({ uri: testFolderUri, name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 })]);
|
||||
|
||||
const actual = testObject.getFolder(URI.file('/src/main/a'));
|
||||
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'main/a')));
|
||||
|
||||
assert.equal(actual, undefined);
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with single absolute folder', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test' }]);
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 1);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, testFolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with single relative folder', () => {
|
||||
const actual = toWorkspaceFolders([{ path: './test' }], URI.file('src'));
|
||||
const actual = toWorkspaceFolders([{ path: './test' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 1);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, testFolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, './test');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with single absolute folder with name', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test', name: 'hello' }]);
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test', name: 'hello' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 1);
|
||||
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, testFolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'hello');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with multiple unique absolute folders', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3' }, { path: '/src/test1' }]);
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3' }, { path: '/src/test1' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 3);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test2').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test2');
|
||||
|
||||
assert.equal(actual[1].uri.fsPath, URI.file('/src/test3').fsPath);
|
||||
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
|
||||
assert.equal(actual[1].index, 1);
|
||||
assert.equal(actual[1].name, 'test3');
|
||||
|
||||
assert.equal(actual[2].uri.fsPath, URI.file('/src/test1').fsPath);
|
||||
assert.equal(actual[2].uri.fsPath, test1FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/src/test1');
|
||||
assert.equal(actual[2].index, 2);
|
||||
assert.equal(actual[2].name, 'test1');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with multiple unique absolute folders with names', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3', name: 'noName' }, { path: '/src/test1' }]);
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3', name: 'noName' }, { path: '/src/test1' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 3);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test2').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test2');
|
||||
|
||||
assert.equal(actual[1].uri.fsPath, URI.file('/src/test3').fsPath);
|
||||
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
|
||||
assert.equal(actual[1].index, 1);
|
||||
assert.equal(actual[1].name, 'noName');
|
||||
|
||||
assert.equal(actual[2].uri.fsPath, URI.file('/src/test1').fsPath);
|
||||
assert.equal(actual[2].uri.fsPath, test1FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/src/test1');
|
||||
assert.equal(actual[2].index, 2);
|
||||
assert.equal(actual[2].name, 'test1');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with multiple unique absolute and relative folders', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/abc/test3', name: 'noName' }, { path: './test1' }], URI.file('src'));
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/abc/test3', name: 'noName' }, { path: './test1' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 3);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test2').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test2');
|
||||
|
||||
assert.equal(actual[1].uri.fsPath, URI.file('/abc/test3').fsPath);
|
||||
assert.equal(actual[1].uri.fsPath, abcTest3FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/abc/test3');
|
||||
assert.equal(actual[1].index, 1);
|
||||
assert.equal(actual[1].name, 'noName');
|
||||
|
||||
assert.equal(actual[2].uri.fsPath, URI.file('/src/test1').fsPath);
|
||||
assert.equal(actual[2].uri.fsPath, test1FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, './test1');
|
||||
assert.equal(actual[2].index, 2);
|
||||
assert.equal(actual[2].name, 'test1');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with multiple absolute folders with duplicates', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test2', name: 'noName' }, { path: '/src/test1' }]);
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test2', name: 'noName' }, { path: '/src/test1' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 2);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test2').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test2');
|
||||
|
||||
assert.equal(actual[1].uri.fsPath, URI.file('/src/test1').fsPath);
|
||||
assert.equal(actual[1].uri.fsPath, test1FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test1');
|
||||
assert.equal(actual[1].index, 1);
|
||||
assert.equal(actual[1].name, 'test1');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with multiple absolute and relative folders with duplicates', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3', name: 'noName' }, { path: './test3' }, { path: '/abc/test1' }], URI.file('src'));
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3', name: 'noName' }, { path: './test3' }, { path: '/abc/test1' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 3);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test2').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test2');
|
||||
|
||||
assert.equal(actual[1].uri.fsPath, URI.file('/src/test3').fsPath);
|
||||
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
|
||||
assert.equal(actual[1].index, 1);
|
||||
assert.equal(actual[1].name, 'noName');
|
||||
|
||||
assert.equal(actual[2].uri.fsPath, URI.file('/abc/test1').fsPath);
|
||||
assert.equal(actual[2].uri.fsPath, abcTest1FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/abc/test1');
|
||||
assert.equal(actual[2].index, 2);
|
||||
assert.equal(actual[2].name, 'test1');
|
||||
});
|
||||
|
||||
test('toWorkspaceFolders with multiple absolute and relative folders with invalid paths', () => {
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '', name: 'noName' }, { path: './test3' }, { path: '/abc/test1' }], URI.file('src'));
|
||||
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '', name: 'noName' }, { path: './test3' }, { path: '/abc/test1' }], workspaceConfigUri);
|
||||
|
||||
assert.equal(actual.length, 3);
|
||||
assert.equal(actual[0].uri.fsPath, URI.file('/src/test2').fsPath);
|
||||
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
|
||||
assert.equal(actual[0].index, 0);
|
||||
assert.equal(actual[0].name, 'test2');
|
||||
|
||||
assert.equal(actual[1].uri.fsPath, URI.file('/src/test3').fsPath);
|
||||
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, './test3');
|
||||
assert.equal(actual[1].index, 1);
|
||||
assert.equal(actual[1].name, 'test3');
|
||||
|
||||
assert.equal(actual[2].uri.fsPath, URI.file('/abc/test1').fsPath);
|
||||
assert.equal(actual[2].uri.fsPath, abcTest1FolderUri.fsPath);
|
||||
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/abc/test1');
|
||||
assert.equal(actual[2].index, 2);
|
||||
assert.equal(actual[2].name, 'test1');
|
||||
|
||||
@@ -17,7 +17,7 @@ import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { originalFSPath, dirname as resourcesDirname, isEqualOrParent, joinPath } from 'vs/base/common/resources';
|
||||
import { originalFSPath, isEqualOrParent, joinPath } from 'vs/base/common/resources';
|
||||
|
||||
export interface IStoredWorkspace {
|
||||
folders: IStoredWorkspaceFolder[];
|
||||
@@ -71,7 +71,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
|
||||
return {
|
||||
id: workspaceIdentifier.id,
|
||||
configPath: workspaceIdentifier.configPath,
|
||||
folders: toWorkspaceFolders(workspace.folders, resourcesDirname(path)),
|
||||
folders: toWorkspaceFolders(workspace.folders, workspaceIdentifier.configPath),
|
||||
remoteAuthority: workspace.remoteAuthority
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user